classification
Title: PyIter_Check fails when compiling in the Limited API
Type: compile error Stage: resolved
Components: C API Versions: Python 3.8
process
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: Nosy List: scoder, tekknolagi
Priority: normal Keywords: patch

Created on 2020-05-20 22:09 by tekknolagi, last changed 2020-06-19 20:34 by scoder. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 7477 tekknolagi, 2020-06-19 17:45
Messages (5)
msg369479 - (view) Author: Maxwell Bernstein (tekknolagi) * Date: 2020-05-20 22:09
PyIter_Check is itself marked as available in the Limited API but:

a) it's a macro, and
b) it pokes directly at tp_iternext

This means that it's functionally impossible to use PyIter_Check
when working with the Limited API.
msg369481 - (view) Author: Maxwell Bernstein (tekknolagi) * Date: 2020-05-20 22:13
See for example the following C program:

```
#define Py_LIMITED_API

#include "Python.h"

int main() {
  Py_Initialize();
  PyObject* foo;
  PyIter_Check(foo);
}
```

when compiled (gcc test.c `pkg-config --cflags python3`) produces:

```
In file included from /usr/include/python3.6m/Python.h:135:0,
                 from test.c:3:
test.c: In function ‘main’:
/usr/include/python3.6m/abstract.h:712:20: error: dereferencing pointer to incomplete type ‘struct _typeobject’
     ((obj)->ob_type->tp_iternext != NULL && \
                    ^
test.c:8:3: note: in expansion of macro ‘PyIter_Check’
   PyIter_Check(foo);
   ^~~~~~~~~~~~
/usr/include/python3.6m/abstract.h:713:38: error: ‘_PyObject_NextNotImplemented’ undeclared (first use in this function); did you mean ‘PyObject_HashNotImplemented’?
      (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
                                      ^
test.c:8:3: note: in expansion of macro ‘PyIter_Check’
   PyIter_Check(foo);
   ^~~~~~~~~~~~
/usr/include/python3.6m/abstract.h:713:38: note: each undeclared identifier is reported only once for each function it appears in
      (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
                                      ^
test.c:8:3: note: in expansion of macro ‘PyIter_Check’
   PyIter_Check(foo);
   ^~~~~~~~~~~~
```
msg371883 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2020-06-19 14:01
It should be replaced with an actual function, which can be inline in the non-limited case.
msg371896 - (view) Author: Maxwell Bernstein (tekknolagi) * Date: 2020-06-19 17:45
Oh, it looks like this has been done: https://github.com/python/cpython/commit/ea62ce7f4fefc66bc0adba16bcd7666d5bbd5b44

Although I am not sure what version this made it into. So maybe this does not affect versions 3.9/3.10. I've seen it in 3.6/6, for sure.
msg371898 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2020-06-19 20:34
You can see it from the tags on the commit, it was fixed in Py3.8.

Duplicate of issue 33738.
History
Date User Action Args
2020-06-19 20:34:52scodersetstatus: open -> closed
versions: + Python 3.8, - Python 3.6, Python 3.7
messages: + msg371898

resolution: duplicate
stage: patch review -> resolved
2020-06-19 17:45:24tekknolagisetkeywords: + patch
stage: needs patch -> patch review
pull_requests: + pull_request20165
2020-06-19 17:45:04tekknolagisetmessages: + msg371896
versions: + Python 3.6, Python 3.7, - Python 3.9, Python 3.10
2020-06-19 14:01:19scodersetversions: + Python 3.9, Python 3.10, - Python 3.6, Python 3.7
nosy: + scoder

messages: + msg371883

type: compile error
stage: needs patch
2020-05-20 22:13:33tekknolagisetmessages: + msg369481
2020-05-20 22:09:55tekknolagicreate