PEP 741: Remove the Python API (#3711)

This commit is contained in:
Victor Stinner 2024-03-10 00:54:18 +01:00 committed by GitHub
parent 5a8622e004
commit 4352a4a56c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 194 additions and 252 deletions

View File

@ -16,15 +16,13 @@ Add a C API to the limited C API to configure the Python initialization,
and to get the current configuration. It can be used with the stable and to get the current configuration. It can be used with the stable
ABI. ABI.
Add ``sys.get_config(name)`` and ``sys.get_config_names()`` functions to
get the current configuration. Add ``sys.set_config(name, value)``
function to set a configuration option. Unified API to access all
configuration options.
Complete :pep:`587` API by adding ``PyInitConfig_AddModule()`` which can be Complete :pep:`587` API by adding ``PyInitConfig_AddModule()`` which can be
used to add a built-in extension module; feature previously referred to used to add a built-in extension module; feature previously referred to
as the "inittab". as the "inittab".
Add ``PyConfig_Get()`` and ``PyConfig_Set()`` functions to
get and set the current configuration at runtime.
:pep:`587` "Python Initialization Configuration" unified all the ways to :pep:`587` "Python Initialization Configuration" unified all the ways to
configure the Python **initialization**. This PEP (almost fully) unifies configure the Python **initialization**. This PEP (almost fully) unifies
also the configuration of the Python **preinitialization** and the also the configuration of the Python **preinitialization** and the
@ -123,7 +121,7 @@ Cython needs to access the ``optimization_level`` configuration option:
When global configuration variables were deprecated in 2022, `Marc-André When global configuration variables were deprecated in 2022, `Marc-André
Lemburg requested Lemburg requested
<https://github.com/python/cpython/issues/93103#issuecomment-1136462708>`__ <https://github.com/python/cpython/issues/93103#issuecomment-1136462708>`__
an API to access these configuration variables at runtime (not only a C API to access these configuration variables at runtime (not only
during Python initialization). during Python initialization).
@ -366,7 +364,7 @@ Set the current configuration
`Marc-André Lemburg requested `Marc-André Lemburg requested
<https://discuss.python.org/t/fr-allow-private-runtime-config-to-enable-extending-without-breaking-the-pyconfig-abi/18004/34>`__ <https://discuss.python.org/t/fr-allow-private-runtime-config-to-enable-extending-without-breaking-the-pyconfig-abi/18004/34>`__
an API to **set** the value of some configuration options at runtime: a C API to **set** the value of some configuration options at runtime:
* ``optimization_level`` * ``optimization_level``
* ``verbose`` * ``verbose``
@ -374,22 +372,6 @@ an API to **set** the value of some configuration options at runtime:
* ``inspect`` * ``inspect``
* ``write_bytecode`` * ``write_bytecode``
Moreover, currently, when a new configuration option is added, usually
"get" and "set" functions should be added as well. It makes the ``sys``
module bigger and bigger, whereas not all options deserves dedicated
functions. For example, when the ``int_max_str_digits`` option was
added, ``sys.get_int_max_str_digits()`` and
``sys.set_int_max_str_digits()`` functions were added as well.
Some options are exposed directly as ``sys`` attributes. For example,
the ``module_search_paths`` option is expoed as ``sys.path``. The
problem is that there is no validation when the attribute is modified
which can lead to various bugs or even crashes. The attribute can even
be removed: ``del sys.path``.
Having a single unified API with generic "get" and "set" functions would
avoid these issues and give access to all configuration options.
Specification Specification
============= =============
@ -397,10 +379,15 @@ Specification
Add C API functions and structure to configure the Python Add C API functions and structure to configure the Python
initialization: initialization:
* Create config:
* ``PyInitConfig`` opaque structure. * ``PyInitConfig`` opaque structure.
* ``PyInitConfig_CreatePython()``. * ``PyInitConfig_CreatePython()``.
* ``PyInitConfig_CreateIsolated()``. * ``PyInitConfig_CreateIsolated()``.
* ``PyInitConfig_Free(config)``. * ``PyInitConfig_Free(config)``.
* Get options:
* ``PyInitConfig_HasOption(config, name)``. * ``PyInitConfig_HasOption(config, name)``.
* ``PyInitConfig_GetInt(config, name, &value)``. * ``PyInitConfig_GetInt(config, name, &value)``.
* ``PyInitConfig_GetStr(config, name, &value)``. * ``PyInitConfig_GetStr(config, name, &value)``.
@ -409,6 +396,9 @@ initialization:
* ``PyInitConfig_FreeStrList()``. * ``PyInitConfig_FreeStrList()``.
* ``PyInitConfig_GetWStrList(config, name, &length, &items)``. * ``PyInitConfig_GetWStrList(config, name, &length, &items)``.
* ``PyInitConfig_FreeWStrList()``. * ``PyInitConfig_FreeWStrList()``.
* Set optons:
* ``PyInitConfig_SetInt(config, name, value)``. * ``PyInitConfig_SetInt(config, name, value)``.
* ``PyInitConfig_SetStr(config, name, value)``. * ``PyInitConfig_SetStr(config, name, value)``.
* ``PyInitConfig_SetStrLocale(config, name, value)``. * ``PyInitConfig_SetStrLocale(config, name, value)``.
@ -417,19 +407,22 @@ initialization:
* ``PyInitConfig_SetStrLocaleList(config, name, length, items)``. * ``PyInitConfig_SetStrLocaleList(config, name, length, items)``.
* ``PyInitConfig_SetWStrList(config, name, length, items)``. * ``PyInitConfig_SetWStrList(config, name, length, items)``.
* ``PyInitConfig_AddModule(config, name, initfunc)`` * ``PyInitConfig_AddModule(config, name, initfunc)``
* Initialize:
* ``Py_PreInitializeFromInitConfig(config)``. * ``Py_PreInitializeFromInitConfig(config)``.
* ``Py_InitializeFromInitConfig(config)``. * ``Py_InitializeFromInitConfig(config)``.
* Error handling:
* ``PyInitConfig_GetError(config, &err_msg)``. * ``PyInitConfig_GetError(config, &err_msg)``.
Add C API and Python functions to get the current configuration: Add C API functions to get and set the current configuration:
* ``PyConfig_Get(name)``. * ``PyConfig_Get(name)````object``.
* ``PyConfig_GetInt(name, &value)``. * ``PyConfig_GetInt(name, &value)``.
* ``PyConfig_Set(name)``. * ``PyConfig_Set(name)``.
* ``PyConfig_Keys()``. * ``PyConfig_Names()````frozenset``.
* ``sys.get_config(name)``.
* ``sys.get_config_names()``.
* ``sys.set_config(name, value)``.
The C API uses null-terminated UTF-8 encoded strings to refer to a The C API uses null-terminated UTF-8 encoded strings to refer to a
configuration option. configuration option.
@ -464,8 +457,8 @@ the PEP and should be discussed on a case by case basis.
Public configuration options Public configuration options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Following options can be get by ``sys.get_config()`` and set and Following options can be get by ``PyConfig_Get()`` and set and
``sys.set_config()``. ``PyConfig_Set()``.
.. list-table:: .. list-table::
:widths: 20 20 50 :widths: 20 20 50
@ -474,88 +467,87 @@ Following options can be get by ``sys.get_config()`` and set and
* - Option * - Option
- Type - Type
- Comment - Comment
* - ``"argv"`` * - ``argv``
- ``list[str]`` - ``list[str]``
- API: ``sys.argv`` (``list[str]``). - API: ``sys.argv``.
* - ``"base_exec_prefix"`` * - ``base_exec_prefix``
- ``str`` - ``str``
- API: ``sys.base_exec_prefix`` (``str``). - API: ``sys.base_exec_prefix``.
* - ``"base_executable"`` * - ``base_executable``
- ``str`` - ``str``
- API: ``sys.base_executable`` (``str``). - API: ``sys.base_executable``.
* - ``"base_prefix"`` * - ``base_prefix``
- ``str`` - ``str``
- API: ``sys.base_prefix`` (``str``). - API: ``sys.base_prefix``.
* - ``"bytes_warning"`` * - ``bytes_warning``
- ``int`` - ``int``
- API: ``sys.flags.bytes_warning`` (``int``). - API: ``sys.flags.bytes_warning``.
* - ``"exec_prefix"`` * - ``exec_prefix``
- ``str`` - ``str``
- API: ``sys.base_prefix`` (``str``). - API: ``sys.base_prefix``.
* - ``"executable"`` * - ``executable``
- ``str`` - ``str``
- API: ``sys.executable`` (``str``). - API: ``sys.executable``.
* - ``"inspect"`` * - ``inspect``
- ``bool`` - ``bool``
- API: ``sys.flags.inspect`` (``int``). - API: ``sys.flags.inspect`` (``int``).
* - ``"int_max_str_digits"`` * - ``int_max_str_digits``
- ``int`` - ``int``
- API: ``sys.flags.int_max_str_digits`` (``int``), - API: ``sys.flags.int_max_str_digits``,
``sys.get_int_max_str_digits()`` and ``sys.get_int_max_str_digits()`` and
``sys.set_int_max_str_digits()``. ``sys.set_int_max_str_digits()``.
* - ``"interactive"`` * - ``interactive``
- ``bool`` - ``bool``
- API: ``sys.flags.interactive`` (``int``). - API: ``sys.flags.interactive``.
* - ``"module_search_paths"`` * - ``module_search_paths``
- ``list[str]`` - ``list[str]``
- API: ``sys.path`` (``list[str]``). - API: ``sys.path``.
* - ``"optimization_level"`` * - ``optimization_level``
- ``int`` - ``int``
- API: ``sys.flags.optimize`` (``int``). - API: ``sys.flags.optimize``.
* - ``"parser_debug"`` * - ``parser_debug``
- ``bool`` - ``bool``
- API: ``sys.flags.debug`` (``int``). - API: ``sys.flags.debug`` (``int``).
* - ``"platlibdir"`` * - ``platlibdir``
- ``str`` - ``str``
- API: ``sys.platlibdir`` (``str``). - API: ``sys.platlibdir``.
* - ``"prefix"`` * - ``prefix``
- ``str`` - ``str``
- API: ``sys.base_prefix`` (``str``). - API: ``sys.base_prefix``.
* - ``"pycache_prefix"`` * - ``pycache_prefix``
- ``str`` - ``str``
- API: ``sys.pycache_prefix`` (``str``). - API: ``sys.pycache_prefix``.
* - ``"quiet"`` * - ``quiet``
- ``bool`` - ``bool``
- API: ``sys.flags.quiet`` (``int``). - API: ``sys.flags.quiet`` (``int``).
* - ``"stdlib_dir"`` * - ``stdlib_dir``
- ``str`` - ``str``
- API: ``sys._stdlib_dir`` (``str``). - API: ``sys._stdlib_dir``.
* - ``"use_environment"`` * - ``use_environment``
- ``bool`` - ``bool``
- API: ``sys.flags.ignore_environment`` (``int``). - API: ``sys.flags.ignore_environment`` (``int``).
* - ``"verbose"`` * - ``verbose``
- ``int`` - ``int``
- API: ``sys.flags.verbose`` (``int``). - API: ``sys.flags.verbose``.
* - ``"warnoptions"`` * - ``warnoptions``
- ``list[str]`` - ``list[str]``
- API: ``sys.warnoptions`` (``list[str]``). - API: ``sys.warnoptions``.
* - ``"write_bytecode"`` * - ``write_bytecode``
- ``bool`` - ``bool``
- API: ``sys.flags.dont_write_bytecode`` (``int``) and ``sys.dont_write_bytecode`` (``bool``). - API: ``sys.flags.dont_write_bytecode`` (``int``) and ``sys.dont_write_bytecode`` (``bool``).
* - ``"xoptions"`` * - ``xoptions``
- ``dict[str, str]`` - ``dict[str, str]``
- API: ``sys._xoptions`` (``dict[str, str]``). - API: ``sys._xoptions``.
Some option names are different than ``sys`` attributes, such as Some option names are different than ``sys`` attributes, such as
``"optimization_level"`` option and ``sys.flags.optimize`` attribute. ``optimization_level`` option and ``sys.flags.optimize`` attribute.
``sys.set_config(name, value)`` sets the corresponding ``sys`` ``PyConfig_Set()`` sets the corresponding ``sys`` attribute.
attribute.
Read-only configuration options Read-only configuration options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Following options can be get ``sys.get_config()``, but cannot be set by Following options can be get ``PyConfig_Get()``, but cannot be set by
``sys.set_config()``. ``PyConfig_Set()``.
.. list-table:: .. list-table::
:widths: 20 20 50 :widths: 20 20 50
@ -564,180 +556,166 @@ Following options can be get ``sys.get_config()``, but cannot be set by
* - Option * - Option
- Type - Type
- Comment - Comment
* - ``"check_hash_pycs_mode"`` * - ``allocator``
- ``int``
-
* - ``buffered_stdio``
- ``bool``
-
* - ``check_hash_pycs_mode``
- ``str`` - ``str``
- API: ``imp.check_hash_pycs_mode`` (``str``). - API: ``imp.check_hash_pycs_mode``.
* - ``"code_debug_ranges"`` * - ``code_debug_ranges``
- ``bool`` - ``bool``
- -
* - ``"coerce_c_locale"`` * - ``coerce_c_locale``
- ``bool`` - ``bool``
- -
* - ``"coerce_c_locale_warn"`` * - ``coerce_c_locale_warn``
- ``bool`` - ``bool``
- -
* - ``"configure_locale"`` * - ``configure_c_stdio``
- ``bool`` - ``bool``
- -
* - ``"cpu_count"`` * - ``configure_locale``
- ``bool``
-
* - ``cpu_count``
- ``int`` - ``int``
- API: ``os.cpu_count()`` (``int | None``). - API: ``os.cpu_count()`` (``int | None``).
* - ``"dev_mode"`` * - ``dev_mode``
- ``bool`` - ``bool``
- API: ``sys.flags.dev_mode`` (``bool``). - API: ``sys.flags.dev_mode``.
* - ``"filesystem_encoding"`` * - ``dump_refs``
- ``str``
- API: ``sys.getfilesystemencoding()`` (``str``).
* - ``"filesystem_errors"``
- ``str``
- API: ``sys.getfilesystemencodeerrors()`` (``str``).
* - ``"import_time"``
- ``bool`` - ``bool``
- -
* - ``"isolated"`` * - ``dump_refs_file``
- ``str``
-
* - ``faulthandler``
- ``bool``
- API: ``faulthandler.is_enabled()``.
* - ``filesystem_encoding``
- ``str``
- API: ``sys.getfilesystemencoding()``.
* - ``filesystem_errors``
- ``str``
- API: ``sys.getfilesystemencodeerrors()``.
* - ``hash_seed``
- ``int``
-
* - ``home``
- ``str``
-
* - ``import_time``
- ``bool``
-
* - ``install_signal_handlers``
- ``bool``
-
* - ``isolated``
- ``bool`` - ``bool``
- API: ``sys.flags.isolated`` (``int``). - API: ``sys.flags.isolated`` (``int``).
* - ``"legacy_windows_fs_encoding"`` * - ``legacy_windows_fs_encoding``
- ``bool`` - ``bool``
- -
* - ``"orig_argv"`` * - ``legacy_windows_stdio``
- ``list[str]``
- API: ``sys.orig_argv`` (``list[str]``).
* - ``"perf_profiling"``
- ``bool``
- API: ``sys.is_stack_trampoline_active()``.
* - ``"site_import"``
- ``bool``
- API: ``sys.flags.no_site`` (``int``).
* - ``"utf8_mode"``
- ``bool``
-
Initialization-only configuration options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Following options are only to initialize Python, are not in
``sys.get_config_names()``, and cannot be get with ``sys.get_config()``.
.. list-table::
:widths: 20 20 50
:header-rows: 1
* - Option
- Type
- Comment
* - ``"allocator"``
- ``int``
-
* - ``"buffered_stdio"``
- ``bool``
-
* - ``"configure_c_stdio"``
- ``bool``
-
* - ``"dump_refs"``
- ``bool``
-
* - ``"dump_refs_file"``
- ``str``
-
* - ``"faulthandler"``
- ``bool``
- API: ``faulthandler.is_enabled()`` (``bool``).
* - ``"hash_seed"``
- ``int``
-
* - ``"home"``
- ``str``
-
* - ``"install_signal_handlers"``
- ``bool``
-
* - ``"legacy_windows_stdio"``
- ``bool`` - ``bool``
- Windows only - Windows only
* - ``"malloc_stats"`` * - ``malloc_stats``
- ``bool`` - ``bool``
- -
* - ``"module_search_paths_set"`` * - ``module_search_paths_set``
- ``bool`` - ``bool``
- -
* - ``"pathconfig_warnings"`` * - ``orig_argv``
- ``list[str]``
- API: ``sys.orig_argv``.
* - ``pathconfig_warnings``
- ``bool`` - ``bool``
- -
* - ``"parse_argv"`` * - ``parse_argv``
- ``bool`` - ``bool``
- -
* - ``"program_name"`` * - ``perf_profiling``
- ``bool``
- API: ``sys.is_stack_trampoline_active()``.
* - ``program_name``
- ``str`` - ``str``
- -
* - ``"pythonpath_env"`` * - ``pythonpath_env``
- ``str`` - ``str``
- -
* - ``"run_command"`` * - ``run_command``
- ``str`` - ``str``
- -
* - ``"run_filename"`` * - ``run_filename``
- ``str`` - ``str``
- -
* - ``"run_module"`` * - ``run_module``
- ``str`` - ``str``
- -
* - ``"run_presite"`` * - ``run_presite``
- ``str`` - ``str``
- need a debug build. - need a debug build.
* - ``"safe_path"`` * - ``safe_path``
- ``bool`` - ``bool``
- -
* - ``"show_ref_count"`` * - ``show_ref_count``
- ``bool`` - ``bool``
- -
* - ``"skip_source_first_line"`` * - ``site_import``
- ``bool``
- API: ``sys.flags.no_site`` (``int``).
* - ``skip_source_first_line``
- ``bool`` - ``bool``
- -
* - ``"stdio_encoding"`` * - ``stdio_encoding``
- ``str`` - ``str``
- API: ``sys.stdin.encoding``, ``sys.stdout.encoding`` and - API: ``sys.stdin.encoding``, ``sys.stdout.encoding`` and
``sys.stderr.encoding`` (``str``). ``sys.stderr.encoding``.
* - ``"stdio_errors"`` * - ``stdio_errors``
- ``str`` - ``str``
- API: ``sys.stdin.errors``, ``sys.stdout.errors`` and - API: ``sys.stdin.errors``, ``sys.stdout.errors`` and
``sys.stderr.errors`` (``str``). ``sys.stderr.errors``.
* - ``"sys_path_0"`` * - ``sys_path_0``
- ``str`` - ``str``
- -
* - ``"tracemalloc"`` * - ``tracemalloc``
- ``int`` - ``int``
- API: ``tracemalloc.is_tracing()`` (``bool``). - API: ``tracemalloc.is_tracing()`` (``bool``).
* - ``"use_frozen_modules"`` * - ``use_frozen_modules``
- ``bool`` - ``bool``
- -
* - ``"use_hash_seed"`` * - ``use_hash_seed``
- ``bool`` - ``bool``
- -
* - ``"user_site_directory"`` * - ``utf8_mode``
- ``bool``
-
* - ``user_site_directory``
- ``bool`` - ``bool``
- API: ``sys.flags.no_user_site`` (``int``). - API: ``sys.flags.no_user_site`` (``int``).
* - ``"warn_default_encoding"`` * - ``warn_default_encoding``
- ``bool`` - ``bool``
- -
* - ``"_install_importlib"`` * - ``_install_importlib``
- ``bool`` - ``bool``
- -
* - ``"_init_main"`` * - ``_init_main``
- ``bool`` - ``bool``
- -
* - ``"_is_python_build"`` * - ``_is_python_build``
- ``bool`` - ``bool``
- -
* - ``"_pystats"`` * - ``_pystats``
- ``bool`` - ``bool``
- API: ``sys._stats_on()``, ``sys._stats_off()``. - API: ``sys._stats_on()``, ``sys._stats_off()``.
Need a ``Py_STATS`` build. Need a ``Py_STATS`` build.
Preconfiguration Preinitialization
---------------- -----------------
Calling ``Py_PreInitializeFromInitConfig()`` preinitializes Python. For Calling ``Py_PreInitializeFromInitConfig()`` preinitializes Python. For
example, it sets the memory allocator, and can configure the example, it sets the memory allocator, and can configure the
@ -747,18 +725,19 @@ example, it sets the memory allocator, and can configure the
The following option names can only be set during the Python The following option names can only be set during the Python
preconfiguration: preconfiguration:
* ``"allocator"``, * ``allocator``,
* ``"coerce_c_locale"``, * ``coerce_c_locale``,
* ``"coerce_c_locale_warn"``, * ``coerce_c_locale_warn``,
* ``"configure_locale"``, * ``configure_locale``,
* ``"legacy_windows_fs_encoding"``, * ``legacy_windows_fs_encoding``,
* ``"utf8_mode"``. * ``utf8_mode``.
Trying to set these options after Python preinitialization fails with an Trying to set these options after Python preinitialization fails with an
error. error.
``PyInitConfig_SetStrLocale()`` and ``PyInitConfig_SetStrLocaleList()`` ``PyInitConfig_SetStrLocale()`` and ``PyInitConfig_SetStrLocaleList()``
functions cannot be called before the Python preinitialization. functions call ``Py_PreInitializeFromInitConfig()`` if Python is not
already preinitialized.
Create PyInitConfig Create PyInitConfig
@ -857,7 +836,7 @@ null-terminated UTF-8 encoded string.
Some configuration options have side effects on other options. This Some configuration options have side effects on other options. This
logic is only implemented when ``Py_InitializeFromInitConfig()`` is logic is only implemented when ``Py_InitializeFromInitConfig()`` is
called, not by the "Set" functions below. For example, setting called, not by the "Set" functions below. For example, setting
``"dev_mode"`` to ``1`` does not set ``"faulthandler"`` to ``1``. ``dev_mode`` to ``1`` does not set ``faulthandler`` to ``1``.
``int PyInitConfig_SetInt(PyInitConfig *config, const char *name, int64_t value)``: ``int PyInitConfig_SetInt(PyInitConfig *config, const char *name, int64_t value)``:
Set an integer configuration option. Set an integer configuration option.
@ -971,37 +950,14 @@ Get and set the current configuration
The configuration option *name* parameter must be a non-NULL The configuration option *name* parameter must be a non-NULL
null-terminated UTF-8 encoded string. null-terminated UTF-8 encoded string.
Not all configuration options are accessible at runtime: see
`Configuration Options`_. For example, ``"module_search_paths_set"`` is
not relevant and cannot be accessed. Some options are read-only and can
only be read, such as ``"utf8_mode"``.
``PyObject* PyConfig_Get(const char *name)``: ``PyObject* PyConfig_Get(const char *name)``:
Get the current value of a configuration option as an object. Get the current value of a configuration option as an object.
* Return a new reference on success. * Return a new reference on success.
* Set an exception and return ``NULL`` on error. * Set an exception and return ``NULL`` on error.
The object type depends on the option. The object type depends on the option: see `Configuration Options`_
tables.
The following options are read from the ``sys`` modules.
* ``"argv"``: ``sys.argv``.
* ``"base_exec_prefix"``: ``sys.base_exec_prefix``.
* ``"base_executable"``: ``sys._base_executable``.
* ``"base_prefix"``: ``sys.base_prefix``.
* ``"exec_prefix"``: ``sys.exec_prefix``.
* ``"executable"``: ``sys.executable``.
* ``"module_search_paths"``: ``sys.path``.
* ``"orig_argv"``: ``sys.orig_argv``.
* ``"platlibdir"``: ``sys.platlibdir``.
* ``"prefix"``: ``sys.prefix``.
* ``"pycache_prefix"``: ``sys.pycache_prefix``.
* ``"stdlib_dir"``: ``sys._stdlib_dir``.
* ``"warnoptions"``: ``sys.warnoptions``.
* ``"write_bytecode"``: ``not sys.dont_write_bytecode``
(opposite value).
* ``"xoptions"``: ``sys._xoptions``.
Other options are get from internal ``PyPreConfig`` and ``PyConfig`` structures. Other options are get from internal ``PyPreConfig`` and ``PyConfig`` structures.
@ -1014,7 +970,7 @@ only be read, such as ``"utf8_mode"``.
* Set ``*value`` and return ``0`` success. * Set ``*value`` and return ``0`` success.
* Set an exception and return ``-1`` on error. * Set an exception and return ``-1`` on error.
``PyObject* PyConfig_Keys(void)``: ``PyObject* PyConfig_Names(void)``:
Get all configuration option names as a ``frozenset``. Get all configuration option names as a ``frozenset``.
Set an exception and return ``NULL`` on error. Set an exception and return ``NULL`` on error.
@ -1029,26 +985,12 @@ only be read, such as ``"utf8_mode"``.
* Raise a ``ValueError`` if *value* is an invalid value. * Raise a ``ValueError`` if *value* is an invalid value.
* Raise a ``ValueError`` if the option is read-only: cannot be set. * Raise a ``ValueError`` if the option is read-only: cannot be set.
`Read-only configuration options`_ cannot be set.
The caller must hold the GIL. The function cannot be called before The caller must hold the GIL. The function cannot be called before
Python initialization nor after Python finalization. Python initialization nor after Python finalization.
Add sys functions
-----------------
* Add ``sys.get_config(name: str)`` function which calls
``PyConfig_Get()``:
* Return the configuration option value on success.
* Raise an exception on error.
* Add ``sys.get_config_names()`` function which gets all configuration
option names as a ``frozenset``.
* Add ``sys.get_config(name: str, value)`` function which calls
``PyConfig_Set(name, value)``. Raise an exception on error.
Scope of the stable ABI Scope of the stable ABI
----------------------- -----------------------
@ -1087,7 +1029,7 @@ return -1 on error:
} }
// Set a list of wide strings (argv) // Set a list of wide strings (argv)
wchar_t *argv[] = {L"my_program"", L"-c", L"pass"}; wchar_t *argv[] = {L"my_program", L"-c", L"pass"};
if (PyInitConfig_SetWStrList(config, "argv", if (PyInitConfig_SetWStrList(config, "argv",
Py_ARRAY_LENGTH(argv), argv) < 0) { Py_ARRAY_LENGTH(argv), argv) < 0) {
goto error; goto error;