gh-117987: Restore several functions removed in Python 3.13 alpha 1 (GH-117993)

Restore these functions removed in Python 3.13 alpha 1:

* Py_SetPythonHome()
* Py_SetProgramName()
* PySys_SetArgvEx()
* PySys_SetArgv()
This commit is contained in:
Victor Stinner 2024-04-18 15:20:38 +02:00 committed by GitHub
parent 0a0756c5ed
commit 340a02b590
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 163 additions and 18 deletions

View File

@ -29,6 +29,8 @@ The following functions can be safely called before Python is initialized:
* :c:func:`PyMem_SetAllocator` * :c:func:`PyMem_SetAllocator`
* :c:func:`PyMem_SetupDebugHooks` * :c:func:`PyMem_SetupDebugHooks`
* :c:func:`PyObject_SetArenaAllocator` * :c:func:`PyObject_SetArenaAllocator`
* :c:func:`Py_SetProgramName`
* :c:func:`Py_SetPythonHome`
* :c:func:`PySys_ResetWarnOptions` * :c:func:`PySys_ResetWarnOptions`
* Informative functions: * Informative functions:
@ -426,6 +428,34 @@ Process-wide parameters
======================= =======================
.. c:function:: void Py_SetProgramName(const wchar_t *name)
.. index::
single: Py_Initialize()
single: main()
single: Py_GetPath()
This API is kept for backward compatibility: setting
:c:member:`PyConfig.program_name` should be used instead, see :ref:`Python
Initialization Configuration <init-config>`.
This function should be called before :c:func:`Py_Initialize` is called for
the first time, if it is called at all. It tells the interpreter the value
of the ``argv[0]`` argument to the :c:func:`main` function of the program
(converted to wide characters).
This is used by :c:func:`Py_GetPath` and some other functions below to find
the Python run-time libraries relative to the interpreter executable. The
default value is ``'python'``. The argument should point to a
zero-terminated wide character string in static storage whose contents will not
change for the duration of the program's execution. No code in the Python
interpreter will change the contents of this storage.
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
:c:expr:`wchar_*` string.
.. deprecated:: 3.11
.. c:function:: wchar_t* Py_GetProgramName() .. c:function:: wchar_t* Py_GetProgramName()
Return the program name set with :c:member:`PyConfig.program_name`, or the default. Return the program name set with :c:member:`PyConfig.program_name`, or the default.
@ -627,6 +657,106 @@ Process-wide parameters
``sys.version``. ``sys.version``.
.. c:function:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
.. index::
single: main()
single: Py_FatalError()
single: argv (in module sys)
This API is kept for backward compatibility: setting
:c:member:`PyConfig.argv`, :c:member:`PyConfig.parse_argv` and
:c:member:`PyConfig.safe_path` should be used instead, see :ref:`Python
Initialization Configuration <init-config>`.
Set :data:`sys.argv` based on *argc* and *argv*. These parameters are
similar to those passed to the program's :c:func:`main` function with the
difference that the first entry should refer to the script file to be
executed rather than the executable hosting the Python interpreter. If there
isn't a script that will be run, the first entry in *argv* can be an empty
string. If this function fails to initialize :data:`sys.argv`, a fatal
condition is signalled using :c:func:`Py_FatalError`.
If *updatepath* is zero, this is all the function does. If *updatepath*
is non-zero, the function also modifies :data:`sys.path` according to the
following algorithm:
- If the name of an existing script is passed in ``argv[0]``, the absolute
path of the directory where the script is located is prepended to
:data:`sys.path`.
- Otherwise (that is, if *argc* is ``0`` or ``argv[0]`` doesn't point
to an existing file name), an empty string is prepended to
:data:`sys.path`, which is the same as prepending the current working
directory (``"."``).
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
:c:expr:`wchar_*` string.
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
members of the :ref:`Python Initialization Configuration <init-config>`.
.. note::
It is recommended that applications embedding the Python interpreter
for purposes other than executing a single script pass ``0`` as *updatepath*,
and update :data:`sys.path` themselves if desired.
See `CVE-2008-5983 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983>`_.
On versions before 3.1.3, you can achieve the same effect by manually
popping the first :data:`sys.path` element after having called
:c:func:`PySys_SetArgv`, for example using::
PyRun_SimpleString("import sys; sys.path.pop(0)\n");
.. versionadded:: 3.1.3
.. XXX impl. doesn't seem consistent in allowing ``0``/``NULL`` for the params;
check w/ Guido.
.. deprecated:: 3.11
.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv)
This API is kept for backward compatibility: setting
:c:member:`PyConfig.argv` and :c:member:`PyConfig.parse_argv` should be used
instead, see :ref:`Python Initialization Configuration <init-config>`.
This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set
to ``1`` unless the :program:`python` interpreter was started with the
:option:`-I`.
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
:c:expr:`wchar_*` string.
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
members of the :ref:`Python Initialization Configuration <init-config>`.
.. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`.
.. deprecated:: 3.11
.. c:function:: void Py_SetPythonHome(const wchar_t *home)
This API is kept for backward compatibility: setting
:c:member:`PyConfig.home` should be used instead, see :ref:`Python
Initialization Configuration <init-config>`.
Set the default "home" directory, that is, the location of the standard
Python libraries. See :envvar:`PYTHONHOME` for the meaning of the
argument string.
The argument should point to a zero-terminated character string in static
storage whose contents will not change for the duration of the program's
execution. No code in the Python interpreter will change the contents of
this storage.
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
:c:expr:`wchar_*` string.
.. deprecated:: 3.11
.. c:function:: wchar_t* Py_GetPythonHome() .. c:function:: wchar_t* Py_GetPythonHome()
Return the default "home", that is, the value set by Return the default "home", that is, the value set by

View File

@ -618,6 +618,8 @@ function,PySys_FormatStdout,3.2,,
function,PySys_GetObject,3.2,, function,PySys_GetObject,3.2,,
function,PySys_GetXOptions,3.7,, function,PySys_GetXOptions,3.7,,
function,PySys_ResetWarnOptions,3.2,, function,PySys_ResetWarnOptions,3.2,,
function,PySys_SetArgv,3.2,,
function,PySys_SetArgvEx,3.2,,
function,PySys_SetObject,3.2,, function,PySys_SetObject,3.2,,
function,PySys_WriteStderr,3.2,, function,PySys_WriteStderr,3.2,,
function,PySys_WriteStdout,3.2,, function,PySys_WriteStdout,3.2,,
@ -869,6 +871,8 @@ function,Py_NewInterpreter,3.2,,
function,Py_NewRef,3.10,, function,Py_NewRef,3.10,,
function,Py_ReprEnter,3.2,, function,Py_ReprEnter,3.2,,
function,Py_ReprLeave,3.2,, function,Py_ReprLeave,3.2,,
function,Py_SetProgramName,3.2,,
function,Py_SetPythonHome,3.2,,
function,Py_SetRecursionLimit,3.2,, function,Py_SetRecursionLimit,3.2,,
type,Py_UCS4,3.2,, type,Py_UCS4,3.2,,
macro,Py_UNBLOCK_THREADS,3.2,, macro,Py_UNBLOCK_THREADS,3.2,,

View File

@ -2011,12 +2011,8 @@ Removed
* ``PySys_AddWarnOption()``: use :c:member:`PyConfig.warnoptions` instead. * ``PySys_AddWarnOption()``: use :c:member:`PyConfig.warnoptions` instead.
* ``PySys_AddXOption()``: use :c:member:`PyConfig.xoptions` instead. * ``PySys_AddXOption()``: use :c:member:`PyConfig.xoptions` instead.
* ``PySys_HasWarnOptions()``: use :c:member:`PyConfig.xoptions` instead. * ``PySys_HasWarnOptions()``: use :c:member:`PyConfig.xoptions` instead.
* ``PySys_SetArgvEx()``: set :c:member:`PyConfig.argv` instead.
* ``PySys_SetArgv()``: set :c:member:`PyConfig.argv` instead.
* ``PySys_SetPath()``: set :c:member:`PyConfig.module_search_paths` instead. * ``PySys_SetPath()``: set :c:member:`PyConfig.module_search_paths` instead.
* ``Py_SetPath()``: set :c:member:`PyConfig.module_search_paths` instead. * ``Py_SetPath()``: set :c:member:`PyConfig.module_search_paths` instead.
* ``Py_SetProgramName()``: set :c:member:`PyConfig.program_name` instead.
* ``Py_SetPythonHome()``: set :c:member:`PyConfig.home` instead.
* ``Py_SetStandardStreamEncoding()``: set :c:member:`PyConfig.stdio_encoding` * ``Py_SetStandardStreamEncoding()``: set :c:member:`PyConfig.stdio_encoding`
instead, and set also maybe :c:member:`PyConfig.legacy_windows_stdio` (on instead, and set also maybe :c:member:`PyConfig.legacy_windows_stdio` (on
Windows). Windows).
@ -2073,6 +2069,16 @@ Pending Removal in Python 3.14
* Creating immutable types (:c:macro:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable * Creating immutable types (:c:macro:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable
bases using the C API. bases using the C API.
* Functions to configure the Python initialization, deprecated in Python 3.11:
* ``PySys_SetArgvEx()``: set :c:member:`PyConfig.argv` instead.
* ``PySys_SetArgv()``: set :c:member:`PyConfig.argv` instead.
* ``Py_SetProgramName()``: set :c:member:`PyConfig.program_name` instead.
* ``Py_SetPythonHome()``: set :c:member:`PyConfig.home` instead.
The :c:func:`Py_InitializeFromConfig` API should be used with
:c:type:`PyConfig` instead.
* Global configuration variables: * Global configuration variables:
* :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug`

View File

@ -34,8 +34,12 @@ PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv); PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv);
/* In pathconfig.c */ /* In pathconfig.c */
Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *);
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *);
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetPrefix(void); Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetPrefix(void);
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);

View File

@ -7,6 +7,9 @@ extern "C" {
PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); PyAPI_FUNC(PyObject *) PySys_GetObject(const char *);
PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *);
Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **);
Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int);
PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
Py_GCC_ATTRIBUTE((format(printf, 1, 2))); Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...)

View File

@ -0,0 +1,8 @@
Restore functions removed in Python 3.13 alpha 1:
* :c:func:`Py_SetPythonHome`
* :c:func:`Py_SetProgramName`
* :c:func:`PySys_SetArgvEx`
* :c:func:`PySys_SetArgv`
Patch by Victor Stinner.

View File

@ -1336,10 +1336,8 @@
added = '3.2' added = '3.2'
[function.PySys_SetArgv] [function.PySys_SetArgv]
added = '3.2' added = '3.2'
abi_only = true
[function.PySys_SetArgvEx] [function.PySys_SetArgvEx]
added = '3.2' added = '3.2'
abi_only = true
[function.PySys_SetObject] [function.PySys_SetObject]
added = '3.2' added = '3.2'
[function.PySys_SetPath] [function.PySys_SetPath]
@ -1672,10 +1670,8 @@
added = '3.2' added = '3.2'
[function.Py_SetProgramName] [function.Py_SetProgramName]
added = '3.2' added = '3.2'
abi_only = true
[function.Py_SetPythonHome] [function.Py_SetPythonHome]
added = '3.2' added = '3.2'
abi_only = true
[function.Py_SetRecursionLimit] [function.Py_SetRecursionLimit]
added = '3.2' added = '3.2'
[function.Py_VaBuildValue] [function.Py_VaBuildValue]

View File

@ -16,11 +16,9 @@
// These functions were removed from Python 3.13 API but are still exported // These functions were removed from Python 3.13 API but are still exported
// for the stable ABI. We want to test them in this program. // for the stable ABI. We want to test them in this program.
extern void Py_SetProgramName(const wchar_t *program_name);
extern void PySys_AddWarnOption(const wchar_t *s); extern void PySys_AddWarnOption(const wchar_t *s);
extern void PySys_AddXOption(const wchar_t *s); extern void PySys_AddXOption(const wchar_t *s);
extern void Py_SetPath(const wchar_t *path); extern void Py_SetPath(const wchar_t *path);
extern void Py_SetPythonHome(const wchar_t *home);
int main_argc; int main_argc;

View File

@ -251,8 +251,7 @@ Py_SetPath(const wchar_t *path)
} }
// Removed in Python 3.13 API, but kept for the stable ABI void
PyAPI_FUNC(void)
Py_SetPythonHome(const wchar_t *home) Py_SetPythonHome(const wchar_t *home)
{ {
int has_value = home && home[0]; int has_value = home && home[0];
@ -275,8 +274,7 @@ Py_SetPythonHome(const wchar_t *home)
} }
// Removed in Python 3.13 API, but kept for the stable ABI void
PyAPI_FUNC(void)
Py_SetProgramName(const wchar_t *program_name) Py_SetProgramName(const wchar_t *program_name)
{ {
int has_value = program_name && program_name[0]; int has_value = program_name && program_name[0];

View File

@ -3872,8 +3872,7 @@ make_sys_argv(int argc, wchar_t * const * argv)
return list; return list;
} }
// Removed in Python 3.13 API, but kept for the stable ABI void
PyAPI_FUNC(void)
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
{ {
wchar_t* empty_argv[1] = {L""}; wchar_t* empty_argv[1] = {L""};
@ -3917,8 +3916,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
} }
} }
// Removed in Python 3.13 API, but kept for the stable ABI void
PyAPI_FUNC(void)
PySys_SetArgv(int argc, wchar_t **argv) PySys_SetArgv(int argc, wchar_t **argv)
{ {
_Py_COMP_DIAG_PUSH _Py_COMP_DIAG_PUSH