Skip to content
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

[C API] PEP 741: Add stable ABI to customize Python initialization #107954

Open
vstinner opened this issue Aug 14, 2023 · 9 comments
Open

[C API] PEP 741: Add stable ABI to customize Python initialization #107954

vstinner opened this issue Aug 14, 2023 · 9 comments
Labels
topic-C-API type-feature A feature request or enhancement

Comments

@vstinner
Copy link
Member

vstinner commented Aug 14, 2023

Links to previous discussion of this feature:

https://discuss.python.org/t/fr-allow-private-runtime-config-to-enable-extending-without-breaking-the-pyconfig-abi/18004

Summary of proposal:

Add a text-based configuration to Python initialization

Pitch:

An API should be added to the limited C API customize the Python initialization (PyConfig API, PEP 587).

The problem is that the PyConfig C API is excluded from the limited C API, whereas the legacy initialization API is deprecated (ex: Py_VerboseFlag in Python 3.12) and being removed in Python 3.13 (ex: PySys_SetPath()).

Linked PRs

@vstinner vstinner added type-feature A feature request or enhancement topic-C-API labels Aug 14, 2023
@LostTime76
Copy link

LostTime76 commented Aug 15, 2023

As discussed in discourse, I do not think the text file is the best option for embedding. Depending on the embedding scenario, I think we will run into issues of finding the file due to how python is currently resolving paths. I have a very specific scenario that may be solved in easier ways. Even if you by chance get python to find the file in my particular scenario, I don't want the user of my embedded python exe to have to specify package paths that my exe should be able to set itself.

Its not as easy as putting the file in the same directory as the embedded exe or the main script. Take the scenario that the embedding exe is using the global python install or the embedding exe is launched as a child process from an external process where the process path is not the path of the embedded exe.

I think there may be much easier ways to solve my specific scenario. I would like to use as few APIs as possible and not duplicate how python is already parsing the options from the command line.

What about adding additional command line options that can be set from argv? If we could set additional package paths from argv, it would allow us to directly point to where we need to without hassle.

Environment variables do not work nicely in the embedded scenario, even though we have PYTHONPATH, because there is no way to cleanly set an environment variable from an already running process to be accessible from a loaded python dll.

@vstinner
Copy link
Member Author

I'm thinking about a function taking a string, not a file.

vstinner added a commit to vstinner/cpython that referenced this issue Sep 30, 2023
vstinner added a commit to vstinner/cpython that referenced this issue Sep 30, 2023
Add a specification of the PyConfig structure to factorize the code.
vstinner added a commit to vstinner/cpython that referenced this issue Sep 30, 2023
Add a specification of the PyConfig structure to factorize the code.
vstinner added a commit to vstinner/cpython that referenced this issue Sep 30, 2023
Add a specification of the PyConfig structure to factorize the code.
vstinner added a commit to vstinner/cpython that referenced this issue Sep 30, 2023
vstinner added a commit to vstinner/cpython that referenced this issue Sep 30, 2023
Add a specification of the PyConfig structure to factorize the code.
vstinner added a commit that referenced this issue Sep 30, 2023
Add a specification of the PyConfig structure to factorize the code.
vstinner added a commit to vstinner/cpython that referenced this issue Sep 30, 2023
vstinner added a commit to vstinner/cpython that referenced this issue Oct 1, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetString(config, key, value)
* PyInitConfig_SetList(config, key, length, items)
* PyInitConfig_GetErrorMsg(config)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Changes:

* Add Include/initconfig.h header.
vstinner added a commit to vstinner/cpython that referenced this issue Oct 1, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_GetErrorMsg(config)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Changes:

* Add Include/initconfig.h header.
vstinner added a commit to vstinner/cpython that referenced this issue Oct 1, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_GetErrorMsg(config)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Add these 11 functions to the limited C API.

Changes:

* Add Include/initconfig.h header.
vstinner added a commit to vstinner/cpython that referenced this issue Oct 3, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_GetErrorMsg(config)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Add these 11 functions to the limited C API.

Changes:

* Add Include/initconfig.h header.
vstinner added a commit to vstinner/cpython that referenced this issue Nov 30, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_GetErrorMsg(config)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

* Add functions to get runtime config:

  * PyConfig_GetInt()
  * PyConfig_GetStr()
  * PyConfig_GetStrList()

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
* Add Modules/_testcapi/config.c
* Add Lib/test/test_capi/test_config.py.
vstinner added a commit to vstinner/cpython that referenced this issue Nov 30, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_GetErrorMsg(config)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

* Add functions to get runtime config:

  * PyConfig_GetInt()
  * PyConfig_GetStr()
  * PyConfig_GetStrList()

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
* Add Modules/_testcapi/config.c
* Add Lib/test/test_capi/test_config.py.
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_Exception(config)
* PyInitConfig_GetError(config, &err_msg)
* PyInitConfig_GetExitCode(config, &exitcode)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

* Add functions to get runtime config:

  * PyConfig_GetInt()
  * PyConfig_GetStr()
  * PyConfig_GetStrList()

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
* Add Modules/_testcapi/config.c
* Add Lib/test/test_capi/test_config.py.
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_Exception(config)
* PyInitConfig_GetError(config, &err_msg)
* PyInitConfig_GetExitCode(config, &exitcode)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

* Add functions to get runtime config:

  * PyConfig_GetInt()
  * PyConfig_GetStr()
  * PyConfig_GetStrList()

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
* Add Modules/_testcapi/config.c
* Add Lib/test/test_capi/test_config.py.
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
Add PyConfig_Get() and PyConfig_GetInt() functions to get the current
Python configuration.
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
Add PyConfig_Get() and PyConfig_GetInt() functions to get the current
Python configuration.

_PyConfig_AsDict() now converts PyConfig.xoptions as a dictionary.
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
Add PyConfig_Get() and PyConfig_GetInt() functions to get the current
Python configuration.

_PyConfig_AsDict() now converts PyConfig.xoptions as a dictionary.
vstinner added a commit to vstinner/cpython that referenced this issue Dec 1, 2023
Add PyConfig_Get() and PyConfig_GetInt() functions to get the current
Python configuration.

_PyConfig_AsDict() now converts PyConfig.xoptions as a dictionary.
@vstinner
Copy link
Member Author

vstinner commented Dec 1, 2023

I wrote PR #112609 to read configuration options such as "verbose" or "argv" as a C int or as a Python object.

vstinner added a commit to vstinner/cpython that referenced this issue Dec 12, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_Exception(config)
* PyInitConfig_GetError(config, &err_msg)
* PyInitConfig_GetExitCode(config, &exitcode)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
* Add Modules/_testcapi/config.c
* Add Lib/test/test_capi/test_config.py.
vstinner added a commit to vstinner/cpython that referenced this issue Dec 12, 2023
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_Exception(config)
* PyInitConfig_GetError(config, &err_msg)
* PyInitConfig_GetExitCode(config, &exitcode)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
@vstinner
Copy link
Member Author

I close the issue: #110176 (comment)

@milianw
Copy link

milianw commented Jan 16, 2024

Hey @vstinner - IIUC then there's still no non-deprecated API in the limited C API to customize the initialization, right? Can you then please reopen this task to indicate that this? Or should I report a separate issue to track this?

Thank you

@vstinner
Copy link
Member Author

Can you then please reopen this task to indicate that this?

Ok, I reopen the issue.

@vstinner
Copy link
Member Author

Hey @vstinner - IIUC then there's still no non-deprecated API in the limited C API to customize the initialization, right? Can you then please reopen this task to indicate that this? Or should I report a separate issue to track this?

I wrote PEP 741 – Python Configuration C API. Can you please elaborate your use case to motivate the usage of the limited C API to customize the Python initialization, rather than using the non-limited PyConfig C API? I was asked for such rationale.

@vstinner vstinner changed the title [C API] No limited C API to customize Python initialization (PyConfig, PEP 587) [C API] PEP 741: No limited C API to customize Python initialization (PyConfig, PEP 587) Jan 24, 2024
@milianw
Copy link

milianw commented Jan 26, 2024

We have a large old code base with an embedded python/jupyter console in a graphical application.

We call Py_SetProgramName and Py_SetPythonHome - though to be frank our test suite seems to pass even without calls to these two functions, but maybe not in a packaged environment without any system python available, I have to double check that - but I believe this was the initial idea - to tell python where to look for its bundled libraries in a subfolder of our application directory.

@vstinner vstinner changed the title [C API] PEP 741: No limited C API to customize Python initialization (PyConfig, PEP 587) [C API] PEP 741: Add stable ABI to customize Python initialization (PyConfig, PEP 587) Feb 15, 2024
@vstinner vstinner changed the title [C API] PEP 741: Add stable ABI to customize Python initialization (PyConfig, PEP 587) [C API] PEP 741: Add stable ABI to customize Python initialization Feb 15, 2024
vstinner added a commit to vstinner/cpython that referenced this issue Feb 19, 2024
Add PyConfig_Get() and PyConfig_GetInt() functions to get the current
Python configuration.

_PyConfig_AsDict() now converts PyConfig.xoptions as a dictionary.
vstinner added a commit to vstinner/cpython that referenced this issue Mar 5, 2024
_PyConfig_AsDict() now returns bool objects for options using the new
PyConfig_MEMBER_BOOL type.

Update tests for these changes.
vstinner added a commit that referenced this issue Mar 6, 2024
_PyConfig_AsDict() now returns bool objects for options using the new
PyConfig_MEMBER_BOOL type.

Update tests for these changes.
@vstinner
Copy link
Member Author

vstinner commented Mar 7, 2024

See also #99872 "Allow efficient read access to PyConfig options".

vstinner added a commit to vstinner/cpython that referenced this issue Mar 14, 2024
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_Exception(config)
* PyInitConfig_GetError(config, &err_msg)
* PyInitConfig_GetExitCode(config, &exitcode)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
adorilson pushed a commit to adorilson/cpython that referenced this issue Mar 25, 2024
…n#116359)

_PyConfig_AsDict() now returns bool objects for options using the new
PyConfig_MEMBER_BOOL type.

Update tests for these changes.
diegorusso pushed a commit to diegorusso/cpython that referenced this issue Apr 17, 2024
…n#116359)

_PyConfig_AsDict() now returns bool objects for options using the new
PyConfig_MEMBER_BOOL type.

Update tests for these changes.
vstinner added a commit to vstinner/cpython that referenced this issue May 23, 2024
Add PyInitConfig functions:

* PyInitConfig_Python_New()
* PyInitConfig_Isolated_New()
* PyInitConfig_Free(config)
* PyInitConfig_SetInt(config, key, value)
* PyInitConfig_SetStr(config, key, value)
* PyInitConfig_SetWStr(config, key, value)
* PyInitConfig_SetStrList(config, key, length, items)
* PyInitConfig_SetWStrList(config, key, length, items)
* PyInitConfig_Exception(config)
* PyInitConfig_GetError(config, &err_msg)
* PyInitConfig_GetExitCode(config, &exitcode)

Add also functions using it:

* Py_InitializeFromInitConfig(config)
* Py_ExitWithInitConfig(config)

Add these functions to the limited C API.

Changes:

* Add Doc/c-api/config.rst.
* Add Include/initconfig.h header.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-C-API type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants