This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: regex code re-raises exceptions on success
Type: Stage: resolved
Components: Documentation Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Zdeněk.Pavlas, amaury.forgeotdarc, docs@python, ezio.melotti, mrabarnett, serhiy.storchaka
Priority: normal Keywords:

Created on 2013-03-25 15:27 by Zdeněk.Pavlas, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (6)
msg185205 - (view) Author: Zdeněk Pavlas (Zdeněk.Pavlas) Date: 2013-03-25 15:27
<documentation>
There is a global indicator (per thread) of the last error that occurred. Most functions do not clear this on success, but will set it to indicate the cause of the error on failure. Most functions also return an error indicator, usually NULL if they are supposed to return a pointer, or -1 if they return an integer.
</documentation>

AIUI, the last error global variable should be ignored, unless function fails.  This is not the case.  To reproduce:

1. call a C function that sets TypeError, but does not return NULL.
2. run a lot of python code, do some I/O.. everything runs fine.
3. run a regexp match, or import the re module.  TypeError is raised.
msg185223 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2013-03-25 18:44
Can you provide an actual example to reproduce the error?
msg185227 - (view) Author: Zdeněk Pavlas (Zdeněk.Pavlas) Date: 2013-03-25 19:40
static PyObject*
foo(PyObject *, PyObject *arg)
{
    void *buf;
    Py_ssize_t size;
    if (PyObject_AsReadBuffer(arg, &buf, &size))
        size = -1;
    return PyInt_FromLong(size);
}

>>> import tst, re
>>> re.search("a", "a")
<_sre.SRE_Match object at 0xb76d0950>
>>> tst.foo("abc")
3
>>> re.search("a", "a")
<_sre.SRE_Match object at 0xb76d0950>
>>> tst.foo(None)
-1
>>> re.search("a", "a")
TypeError: expected a readable buffer object
>>>
msg185230 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2013-03-25 20:22
The returned value and the global indicator are not independent.  C functions should not set an error while returning a valid value.

The same behavior will occur in random places -- for example, "for x in range(2): pass" also triggers the issue, this is not specific to the re module.

If you compile python in debug mode (--with-pydebug) an additional (and expensive) check is done and will print "XXX undetected error".

One of the reasons is that accessing the global indicator is an expensive operation, compared to checking the returned value.
But there are cases when this cannot be done. For example, PyIter_Next() returns NULL at the end of the loop, and one must call PyErr_Occurred() to check for errors.

In the _sre.c case though, it looks more like laziness: intermediate returned values are not checked, and PyErr_Occurred() is called at the end.  Bad.
msg185261 - (view) Author: Zdeněk Pavlas (Zdeněk.Pavlas) Date: 2013-03-26 08:22
Yes, found that *certain* IO operations re-raise the error, too.  However, if the Python runtime expects extension writers to keep tstate->curexc_type clear, it should be documented in

http://docs.python.org/2/c-api/exceptions.html

There's not a single use case of PyErr_Clear() mentioned.
msg370461 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-05-31 14:21
When function sets an exception, it should return NULL. Otherwise the behavior of the interpreter is undefined, it can crash in debug build or developing mode.

See for example https://docs.python.org/3/extending/extending.html#intermezzo-errors-and-exceptions
History
Date User Action Args
2022-04-11 14:57:43adminsetgithub: 61744
2020-05-31 14:21:45serhiy.storchakasetstatus: open -> closed

nosy: + serhiy.storchaka
messages: + msg370461

resolution: not a bug
stage: resolved
2013-03-26 08:22:29Zdeněk.Pavlassetnosy: + docs@python
messages: + msg185261

assignee: docs@python
components: + Documentation, - Regular Expressions
2013-03-25 20:22:52amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg185230
2013-03-25 19:40:28Zdeněk.Pavlassetmessages: + msg185227
2013-03-25 18:44:14ezio.melottisetmessages: + msg185223
2013-03-25 15:27:28Zdeněk.Pavlascreate