cfbolz changed the topic of #pypy to: PyPy, the flexible snake (IRC logs: https://quodlibet.duckdns.org/irc/pypy/latest.log.html#irc-end ) | use cffi for calling C | if a pep adds a mere 25-30 [C-API] functions or so, it's a drop in the ocean (cough) - Armin
<vstinner>
hi. i wrote pythoncapi_compat.h: a header file providing new Python C API functions to old Python versions (up to Python 2.7). i just ported it to PyPy 2.7, 3.6 and 3.7, and i have a few questions
<vstinner>
in PyPy, the PyThreadState structure only has 'interp' and 'dict' members
<vstinner>
so it's not possible to implement PyThreadState_GetFrame() on PyPy, right? the function was added in CPython 3.9, and pythoncapi_compat.h simply implements it by reading tstate->frame on Python 3.8 and older
<vstinner>
by the way, CPython 3.7 added an 'id' member to PyThreadState, but PyPy 3.7 doesn't have it. so i simply don't provide PyThreadState_GetID() on PyPy 3.7
<vstinner>
in PyPy, PyFrameObject has no 'f_back' member, so I don't provide PyFrame_GetBack() on PyPy
<vstinner>
mattip: ah right, so it just works on PyPy :)
<vstinner>
mattip: include/pybind11/pybind11.h#L2127 nice. running Python code looks like a good solution, no?
<mattip>
are you sure you need PyThreadState_GetID() ? Why not use std::thread::id get_id() ?
<mattip>
or any of the other ways to get a thread ID from C?
<vstinner>
ok, another question: Python 3.1 added gc.is_tracked(), I don't see this function in PyPy 3.6. i know that the PyPy GC is very different. does it have a concept of objects tracked or not by the GC?
<vstinner>
mattip: i'm not sure how PyThreadState.id is used (in Python or C extensions). there is also PyThreadState.thread_id. i don't know why the 'id' member was added
<vstinner>
i just wanted to make sure that PyPy doesn't have this function
<vstinner>
PyThreadState.id was added by the implementation of the PEP 567
<vstinner>
it's used by the asyncio module for an internal get_running_loop() function, the ID is used by an internal cache
<mattip>
so it is internal, and does not need to be exposed
<vstinner>
mattip: hum. the PyThreadState structure is public, PyThreadState.id is public, and I added PyThreadState_GetID() to Python 3.9
<vstinner>
mattip: my plan is to make PyThreadState opaque, so we can properly decide what's internal or not. but right now, in CPython, everything is public :-p (which is an issue)
<vstinner>
IMO it's was bad idea to make PyThreadState public in the first place :-p
<vstinner>
it's too "low-level" to be exposed directly
<mattip>
so remove PyThreadState_GetID from python 3.10 before people start using it
<vstinner>
mattip: i asked the author of the PyThreadState.id member what he thinks about it :)
<vstinner>
"before people start using it" adding a getter or not doesn't change anything, since the structure is public, people can already uses the new member since Python 3.7
<mattip>
gc.is_tracked(): I guess we could add a "is_tracked = lambda x: True" to gc
<mattip>
:)
<mattip>
adding a function is very different from field lookup in C: it communicates that "we thought about this and decided to add a getter function"
<mattip>
s/function/macro/static inline function/
<vstinner>
"we thought" in PyThreadState_GetID() case, it was only me :-p most people don't care about the API at all :-p
<vstinner>
i conducted a study to see which PyThreadState members are used and how: see https://bugs.python.org/issue39947 if you are curious
<vstinner>
for example, i didn't know if some members are only read, or if setters would also be needed
<vstinner>
so far, i didn't add any setter for PyFrameObject or PyThreadState
<mattip>
nimaje: you cannot really hid anything in C
<mattip>
nimaje: the question is what is "sanctioned" by having a function/macro to access it, and why people are using internal implementation details
<mattip>
is there a use pattern that can be avoided by providing a different API?
<simpson>
There is a pattern for encapsulation in C, pointer to typedef struct, but it's not airtight and so folks will occasionally dig under it. An example in the C stdlib is FILE*.