← 返回首页
GH-137630: Convert ``_interpreters`` to use Argument Clinic by AA-Turner · Pull Request #137631 · python/cpython · GitHub
Skip to content

Navigation Menu

Toggle navigation
Sign in
Appearance settings
Search or jump to...

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Resetting focus

GH-137630: Convert _interpreters to use Argument Clinic #137631

Merged
AA-Turner merged 27 commits into
python:mainfrom
AA-Turner:clinic/_interpretersmodule
Aug 12, 2025
Merged

GH-137630: Convert _interpreters to use Argument Clinic #137631
AA-Turner merged 27 commits into
python:mainfrom
AA-Turner:clinic/_interpretersmodule

Conversation

AA-Turner commented Aug 11, 2025
edited
Loading

Copy link
Copy Markdown
Member

cc @ericsnowcurrently @serhiy-storchaka

Changes split up into commits, one per module-level function. If this PR is too large, happy to break it up into smaller pieces. The only unconverted function is _interpreters.new_config(), which AC does't support.

The pydoc diff is below.

$ diff -u --color pydoc-interpreters-HEAD.txt pydoc-interpreters-AC.txt --- pydoc-interpreters-HEAD.txt 2025-08-11 05:05:56.067834200 +0100 +++ pydoc-interpreters-AC.txt 2025-08-11 05:07:05.140207800 +0100 @@ -185,23 +185,18 @@ | args FUNCTIONS - call(...) - call(id, callable, args=None, kwargs=None, *, restrict=False) - + call(id, /, callable, args=(), kwargs={}, *, preserve_exc=False, restrict=False) Call the provided object in the identified interpreter. - Pass the given args and kwargs, if possible. - capture_exception(...) - capture_exception(exc=None) -> types.SimpleNamespace + Pass the given args and kwargs, if possible. - Return a snapshot of an exception. If "exc" is None - then the current exception, if any, is used (but not cleared). + capture_exception(exc_arg=None, /) + Return a snapshot of an exception. + If *exc* is None then the current exception, if any, is used (but not cleared). The returned snapshot is the same as what _interpreters.exec() returns. - create(...) - create([config], *, reqrefs=False) -> ID - + create(config='isolated', /, *, reqrefs=False) Create a new interpreter and return a unique generated ID. The caller is responsible for destroying the interpreter before exiting, @@ -209,29 +204,26 @@ automatically by passing "reqrefs=True" and then using _incref() and _decref() appropriately. - "config" must be a valid interpreter config or the name of a - predefined config ("isolated" or "legacy"). The default - is "isolated". - - decref(...) + *config* must be a valid interpreter config or the name of a + predefined config ('isolated' or 'legacy'). The default + is 'isolated'. - destroy(...) - destroy(id, *, restrict=False) + decref(id, /, *, restrict=False) + destroy(id, /, *, restrict=False) Destroy the identified interpreter. Attempting to destroy the current interpreter raises InterpreterError. So does an unrecognized ID. - exec(...) - exec(id, code, shared=None, *, restrict=False) - + exec(id, /, code, shared={}, *, restrict=False) Execute the provided code in the identified interpreter. + This is equivalent to running the builtin exec() under the target interpreter, using the __dict__ of its __main__ module as both globals and locals. - "code" may be a string containing the text of a Python script. + *code* may be a string containing the text of a Python script. Functions (and code objects) are also supported, with some restrictions. The code/function must not take any arguments or be a closure @@ -240,42 +232,27 @@ If a function is provided, its code object is used and all its state is ignored, including its __globals__ dict. - get_config(...) - get_config(id, *, restrict=False) -> types.SimpleNamespace - + get_config(id, /, *, restrict=False) Return a representation of the config used to initialize the interpreter. get_current() - get_current() -> (ID, whence) - Return the ID of current interpreter. get_main() - get_main() -> (ID, whence) - - Return the ID of main interpreter. + Return the ID of main interpreter. - incref(...) - - is_running(...) - is_running(id, *, restrict=False) -> bool + incref(id, /, *, implieslink=False, restrict=False) + is_running(id, /, *, restrict=False) Return whether or not the identified interpreter is running. - is_shareable(...) - is_shareable(obj) -> bool - - Return True if the object's data may be shared between interpreters and - False otherwise. - - list_all(...) - list_all() -> [(ID, whence)] + is_shareable(obj, /) + Return True if the object's data may be shared between interpreters and False otherwise. + list_all(*, require_ready=False) Return a list containing the ID of every existing interpreter. - new_config(...) - new_config(name='isolated', /, **overrides) -> type.SimpleNamespace - + new_config(name='isolated', /, **overrides) Return a representation of a new PyInterpreterConfig. The name determines the initial values of the config. Supported named @@ -284,30 +261,23 @@ Any keyword arguments are set on the corresponding config fields, overriding the initial values. - run_func(...) - run_func(id, func, shared=None, *, restrict=False) - + run_func(id, /, func, shared={}, *, restrict=False) Execute the body of the provided function in the identified interpreter. + Code objects are also supported. In both cases, closures and args are not supported. Methods and other callables are not supported either. - (See _interpreters.exec(). - - run_string(...) - run_string(id, script, shared=None, *, restrict=False) + (See _interpreters.exec().) + run_string(id, /, script, shared={}, *, restrict=False) Execute the provided string in the identified interpreter. - (See _interpreters.exec(). - - set___main___attrs(...) - set___main___attrs(id, ns, *, restrict=False) + (See _interpreters.exec().) + set___main___attrs(id, ns, /, *, restrict=False) Bind the given attributes in the interpreter's __main__ module. - whence(...) - whence(id) -> int - + whence(id, /) Return an identifier for where the interpreter was created. DATA

serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality Hide comment
  • Many keyword-or-positional parameters were made positional-only.
  • Incorrect names of some parameters.
  • Mark up does not work here.

Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved

/*[clinic input]
_interpreters.create
config as configobj: object(py_default="'isolated'") = NULL

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality Hide comment

Isn't the default value None?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality Hide comment

Per the docstring, "The default is 'isolated'.". I think showing this is more helpful than None, what do you think?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality Hide comment

In the code the default is equivalent to None. I did not look deeper. @ericsnowcurrently?

Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved
Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved
Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved
9 hidden conversations Load more…
Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved
Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved
Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved
Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved
Comment thread Modules/_interpretersmodule.c Outdated Show resolved Hide resolved

serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality Hide comment

I think that in long term, it would be better to rename "restricted" to "restrict" and get rid of "restrict as restricted". That syntax is used to avoid name conflicts (with C keywords and other variable) and too large diffs, but if the parameter is only used once and does not conflict with other names, it is worth to rename it.

I would prefer to backport this to 3.14, but it is too late to break ABI.

Copy link
Copy Markdown
Member Author

I think that in long term, it would be better to rename "restricted" to "restrict" and get rid of "restrict as restricted".

I agree. It would be good to have clarity on the status as a verb or a noun, though -- is the parameter taking an action to restrict an interpreter, or is it communicating that the interpreter is already restricted.

The 'restricted' arguments were introduced via #117490. The only effect at the C level is checking for a _PyInterpreterState_WHENCE_STDLIB whence value & failing otherwise, so I would suggest it is more correct to use 'restrict' as the argument name. This would make sense as in we restrict .call() to only operate on interpreters from the stdlib module.

Should we make the change in this PR? _interpreters is a private module, and we can't backport these AC changes anyway due to the ABI breakage (which is annoying, I had also wanted to backport).

A

serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality Hide comment

I meant renaming the C variable to match the parameter name.

Anyway, this is not so important. LGTM. 👍

Hide details View details
AA-Turner merged commit be56464 into python:main Aug 12, 2025
46 checks passed
AA-Turner deleted the clinic/_interpretersmodule branch August 12, 2025 15:23

Copy link
Copy Markdown
Member Author

Thank you for the reviews @serhiy-storchaka!

A

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Footer

© 2026 GitHub, Inc.