New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Isolate the _datetime extension module #117398
Comments
PR #117399 fails except Windows. Is there an easy way to access a |
I briefly discussed the C API capsule with @pganssle on the 2023 (or was it 2022?) language summit. I also asked the Steering Council to comment about backwards compatibility concerns regarding datetime.h (which is not included by Python.h): Putting it in the |
Move types to the datetime_state structure of the _datetime extension.
Move types to the datetime_state structure of the _datetime extension.
Converting the _datetime extension to multiphase initialization and/or converting static types to heap types is complicated because:
It reminds me the very complicated case of the PyAST C API. We managed to convert the _ast extension to heap types and multiphase init by moving state to the interpreter state. Other "trade offs" attemps for the _ast extension ended by introducing crashes which were hard to trigger and hard to fix. So I propose this plan to isolate the datetime module:
|
Where can we see your rationale for the inflating How do you associate the PyAST issue with PyDateTime in terms of the mechanizm and impact? |
Both provide a C API and we wanted to isolate their C extension.
I will try to dig into the bug tracker later. In short, there were 2-3 crashes related to the isolation of the _ast extension. Crashes related to the C API. |
Move types to the datetime_state structure of the _datetime extension.
|
Move types to the datetime_state structure of the _datetime extension.
The purpose of this issue is to convert the _datetime extension to the multiphase C API. The problem is to make sure that we are dealing with the same types if multiple instances of the extension are created. Example: import sys
import _datetime
now = _datetime.datetime.now()
del _datetime
del sys.modules['_datetime']
import _datetime
print(isinstance(now, _datetime.datetime)) In general, we don't require this. For example, it's false with the _random extension: import sys
import _random
rng = _random.Random()
del _random
del sys.modules['_random']
import _random
print(isinstance(rng, _random.Random)) The problem for _datetime is the C API and the capsule. Currently, the C API is based on I would care less if the C API would be stateful: pass explicitly a module/state/something. But changing the C API is out of the scope of this issue. |
The SC said that the datetime C API is protected by PEP-387, even though datetime.h is not explicitly included in Python.h. IMO, we should deprecate the current C API and introduce a new one. That is the easiest solution technically, and the easiest to relate to for users. I agree with Victor that it deserves its own issue (and perhaps also a Discourse topic). |
Move types to the datetime_state structure of the _datetime extension.
I merged my first change "Move types to datetime state". @neonene: Do you want to propose changes to convert static types to heap types? Maybe start with a PR to convert only 4 types to make the PR short enough so it's easier to review. Types:
|
If we manage to isolate the _datetime extension without breaking the C API, I'm not sure that it's needed. |
I'll wait python/steering-council#243, which is a necessary procedure. |
A key functional test case in relation to python/steering-council#243 is ensuring that previous references to the capsule API still work after a module reload. Specifically, this sequence:
This will have historically worked due to the implicit module caching in the single-phase init support for extension modules, but I'm concerned that a full migration to true reload support will break it (and likely crash the interpreter in the process). I'd also be genuinely surprised if such a test case already exists, hence the green CI on #118337 may not be enough to show that the migration to multi-phase init hasn't broken anything. |
Any reasonable producer is welcome. I think the concern about the capsule is equivalent to that about the module state, because the capsule reference is in sync with the new module. If the behavior were problematic, not only |
FYI, I'm hoping to wrap this up (or get really close) during the PyCon US sprints. I'll be here through Thursday. @pganssle and @erlend-aasland are here too, so I'll get as much help as I can. CC @1st1 |
@neonene the missing test coverage I was referring to on the SC issue is described in this comment: #117398 (comment) |
Can you explain what needs to be tested, using Concerning the new generic C-API design, I doubt at this point the need to keep pointers unchanged across module-reloads. The new API can be offered exclusively for third-party modules with new usage, and the migration will not be required if the module-authors care about backwards compatibility. |
FYI, I chatted with @pganssle and @erlend-aasland (and @encukou) at the PyCon US sprints and we resolved on the following plan for beta 2:
Then we can separately tackle getting the C-API working for subinterpreters. @erlend-aasland is planning on tackling the first three, since he's mostly done it all gh-102995. I'm making a plan for step 4. The timeline is short (beta 2 is in ~10 days, per Thomas), but given all the prior work I'm confident we can get it done in time. FWIW, various previously merged PRs will help make some of these steps easier, so thanks! |
Here's my tentative plan for the datetime C-API:
I'll need to double-check that the difference between per-interpreter and per-module is benign. |
@neonene does that plan make sense based on the work you have done? |
Does the |
tp_dict, tp_sublasses, and the weakrefs are all a problem. I'd like to see if we can use the same solution as for the builtin static types. |
At least the (Sorry for the close by mistake) |
That step 4 is mostly obsolete. With the solution I merged for the datetime C-API, the problems of isolation for subinterpreters there are mostly resolved. We only have to make sure the exposed types are isolated (e.g. by applying the same solution as for builtin types). |
Feature or enhancement
Proposal:
I hope this issue will complete
_datetime
isolation.My concerns (and answers)
Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
should be applied in sync with_zoninfo
?Can a module state have a C-API structure, keeping a capsule just for comatibility?
C-API supports only the main interpreter? Otherwise,
PyInterpreterState
is acceptable to point each structure?PyDateTimeAPI
cannot emit an error. Also, noPyInterpreterState
member is accessible fromdatetime.h
. UPDATE: Seems to be possible by using a global function pointer instead of a function.Specific issue:
Links to previous discussion of this feature:
_datetime
#102995_datetime
#110475Linked PRs (closed)
PyInterpreterState
#118357Linked PRs
The text was updated successfully, but these errors were encountered: