GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-142417: Add PyInitConfig_SetInitCallback() function by vstinner · Pull Request #142420 · python/cpython Conversation
|
|
Current documentation:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@indygreg: Hi, would such C API fit your needs for PyOxidizer? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
That is extremely vague. If there are no concrete promises about what's available, and what APIs can be called, new versions of CPython are theoretically allowed to "break" callers. Is the callback better than restoring older private "multi-phase" API? Would it be better to add API specifically for adding a simple metapath entry? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
It's vague on purpose, but you're right that it should be better specified. Python 3.13 documentation specify what is available at the "core" phase and what is the "main" phase: https://docs.python.org/3.13/c-api/init_config.html#multi-phase-initialization-private-provisional-api
Good question. I just tested: you can import built-in modules at this point, but only built-in modules.
The old API (Python 3.13 and older) allows not executing the "main" initialization phase, but IMO it makes no sense (there is not use case for that). What's needed is only to inject code (callback) between the "core" and the "main" initialization phase. IMO a callback API better fits the use case.
I'm not aware of other points which would be interesting during the initialization.
The bypy code to inject the The PyOxidizer code is also complex: |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I completed the documentation using Python 3.13 doc. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
That's worrying: it means that if we rewrite a module in Python, we break people's code. (For example, the
What's worrying for metapath entries is that "importlib", "Path Configuration" and " This does look like it should be unstable at least. But, I believe it would be best to bring the old private API back (deprecated) while a better alternative is designed: |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
These things changed multiple times since PEP 587 (PyConfig C API) has been implemented, and it was just fine with users of the "Multi-Phase Initialization Private Provisional API". For example, the path configuration has been reimplemented in Python in Python 3.11 (
Well, a provisional API has a different backward compatibility contract: https://docs.python.org/dev/glossary.html#term-provisional-API
Anyway, the API has already been removed from Python 3.14. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
It also says:
What are the serious fundamental flaws that were missed? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
and
These issues already existed in Python 3.13 with the provisional
I removed the
Python 3.13 API allows to not execute the "main" initialization phase. This is not needed by 3rd party projects and I would like to avoid that. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Right.
Is that the only benefit?
Where did you look? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I propose replacing
I don't recall, but I likely looked in PyPI top 15,000 projects. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Fair. I don't think that qualifies as a serious fundamental flaw though.
Yeah. The extension module index isn't a good place for users of runtime initialization API. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I think we should, though not necessarily under these names. There's no reasons why embedders shouldn't be able to "initialize up to pre-importlib", do stuff, and then "initialize importlib and anything after it". That's more or less what we currently do, where the "do stuff" is running getpath.py. It would also help our own tools, where we need to half-initialize the runtime in order to freeze modules during build, etc. It might not directly fix the problem being looked at here, but it's the design we've been aiming towards for a decade now, so it ought to be the goal. If that means bringing back the API that was removed in the meantime, that seems fine. The only thing we gain by rushing initialisation API changes is cruft, so we're better off keeping the cruft we already have and getting the API design right. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Oh, I'll also point out that I think it makes perfect structural sense for For practical reasons, we wouldn't make that a real move, but structurally I think it helps to visualise importlib as part of "Python the command-line tool" rather than "Python the embeddable library" (since when embedding, you often want a different kind of importer than importlib's defaults). |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@encukou and @zooba dislike the callback approach (PR gh-142420), so I wrote PR gh-143877 to add |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Unfortunately, I think that would break a number of use-cases, but we could definitely move the C API towards that. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I assume this is agreeing with the half of my post saying that we couldn't actually remove getpath from libpython? It's unclear whether you're agreeing that removing getpath would break people who assume it'll be there or not, since more than half the quoted text is saying that it would break people if we actually did it. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
(I'm currently reviewing the API at a high level from the docs only)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| Set an initialization callback. It allows executing code as soon as the | ||
| Python interpreter is initialized, before the first import. For example, it | ||
| can be used to add a meta path importer into :data:`sys.meta_path`. | ||
|
|
||
| When the callback is called, Python is only partially initialized. What's | ||
| available at this point: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
"executing code as soon as the Python interpreter is initialized"
vs
"Python is only partially initialized. What's available ...:"
two different values of "initialized" here. That's a small list of what is available. Should we bother allowing people to call into Python at all or calling equivalent C Python C APIs from such an API? it feels maybe vaguely defined and hard to support and like something we might change the hyrum's law shape of what is available here?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I changed the documentation to:
It allows executing code during the Python interpreter, before the first import.
Should we bother allowing people to call into Python at all or calling equivalent C Python C APIs from such an API?
Most of the C API is available when the callback is called, including PyRun_SimpleString() high-level function.
it feels maybe vaguely defined and hard to support and like something we might change the hyrum's law shape of what is available here?
It's vaguely defined on purpose, since the Python runtime is a complex beast, and it's hard to fully described its state while it's being initialized.
What can we do to make such API more future proof?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| A single callback can be registered. If this function is called more than | ||
| once, the previous callback is overridden. |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
We should probably start out by returning an error in this case. This is useful for embedding, it feels like multiple calls is always a bug until someone can make an argument otherwise.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ok, I modified the API to fail if it's called twice.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I updated my PR to address @gpshead's review. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Closed in favor of PR gh-145472. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.