Skip to content

Commit 340a02b

Browse files
authored
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()
1 parent 0a0756c commit 340a02b

File tree

10 files changed

+163
-18
lines changed

10 files changed

+163
-18
lines changed

Doc/c-api/init.rst

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ The following functions can be safely called before Python is initialized:
2929
* :c:func:`PyMem_SetAllocator`
3030
* :c:func:`PyMem_SetupDebugHooks`
3131
* :c:func:`PyObject_SetArenaAllocator`
32+
* :c:func:`Py_SetProgramName`
33+
* :c:func:`Py_SetPythonHome`
3234
* :c:func:`PySys_ResetWarnOptions`
3335

3436
* Informative functions:
@@ -426,6 +428,34 @@ Process-wide parameters
426428
=======================
427429
428430
431+
.. c:function:: void Py_SetProgramName(const wchar_t *name)
432+
433+
.. index::
434+
single: Py_Initialize()
435+
single: main()
436+
single: Py_GetPath()
437+
438+
This API is kept for backward compatibility: setting
439+
:c:member:`PyConfig.program_name` should be used instead, see :ref:`Python
440+
Initialization Configuration <init-config>`.
441+
442+
This function should be called before :c:func:`Py_Initialize` is called for
443+
the first time, if it is called at all. It tells the interpreter the value
444+
of the ``argv[0]`` argument to the :c:func:`main` function of the program
445+
(converted to wide characters).
446+
This is used by :c:func:`Py_GetPath` and some other functions below to find
447+
the Python run-time libraries relative to the interpreter executable. The
448+
default value is ``'python'``. The argument should point to a
449+
zero-terminated wide character string in static storage whose contents will not
450+
change for the duration of the program's execution. No code in the Python
451+
interpreter will change the contents of this storage.
452+
453+
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
454+
:c:expr:`wchar_*` string.
455+
456+
.. deprecated:: 3.11
457+
458+
429459
.. c:function:: wchar_t* Py_GetProgramName()
430460
431461
Return the program name set with :c:member:`PyConfig.program_name`, or the default.
@@ -627,6 +657,106 @@ Process-wide parameters
627657
``sys.version``.
628658
629659
660+
.. c:function:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
661+
662+
.. index::
663+
single: main()
664+
single: Py_FatalError()
665+
single: argv (in module sys)
666+
667+
This API is kept for backward compatibility: setting
668+
:c:member:`PyConfig.argv`, :c:member:`PyConfig.parse_argv` and
669+
:c:member:`PyConfig.safe_path` should be used instead, see :ref:`Python
670+
Initialization Configuration <init-config>`.
671+
672+
Set :data:`sys.argv` based on *argc* and *argv*. These parameters are
673+
similar to those passed to the program's :c:func:`main` function with the
674+
difference that the first entry should refer to the script file to be
675+
executed rather than the executable hosting the Python interpreter. If there
676+
isn't a script that will be run, the first entry in *argv* can be an empty
677+
string. If this function fails to initialize :data:`sys.argv`, a fatal
678+
condition is signalled using :c:func:`Py_FatalError`.
679+
680+
If *updatepath* is zero, this is all the function does. If *updatepath*
681+
is non-zero, the function also modifies :data:`sys.path` according to the
682+
following algorithm:
683+
684+
- If the name of an existing script is passed in ``argv[0]``, the absolute
685+
path of the directory where the script is located is prepended to
686+
:data:`sys.path`.
687+
- Otherwise (that is, if *argc* is ``0`` or ``argv[0]`` doesn't point
688+
to an existing file name), an empty string is prepended to
689+
:data:`sys.path`, which is the same as prepending the current working
690+
directory (``"."``).
691+
692+
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
693+
:c:expr:`wchar_*` string.
694+
695+
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
696+
members of the :ref:`Python Initialization Configuration <init-config>`.
697+
698+
.. note::
699+
It is recommended that applications embedding the Python interpreter
700+
for purposes other than executing a single script pass ``0`` as *updatepath*,
701+
and update :data:`sys.path` themselves if desired.
702+
See `CVE-2008-5983 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983>`_.
703+
704+
On versions before 3.1.3, you can achieve the same effect by manually
705+
popping the first :data:`sys.path` element after having called
706+
:c:func:`PySys_SetArgv`, for example using::
707+
708+
PyRun_SimpleString("import sys; sys.path.pop(0)\n");
709+
710+
.. versionadded:: 3.1.3
711+
712+
.. XXX impl. doesn't seem consistent in allowing ``0``/``NULL`` for the params;
713+
check w/ Guido.
714+
715+
.. deprecated:: 3.11
716+
717+
718+
.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv)
719+
720+
This API is kept for backward compatibility: setting
721+
:c:member:`PyConfig.argv` and :c:member:`PyConfig.parse_argv` should be used
722+
instead, see :ref:`Python Initialization Configuration <init-config>`.
723+
724+
This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set
725+
to ``1`` unless the :program:`python` interpreter was started with the
726+
:option:`-I`.
727+
728+
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
729+
:c:expr:`wchar_*` string.
730+
731+
See also :c:member:`PyConfig.orig_argv` and :c:member:`PyConfig.argv`
732+
members of the :ref:`Python Initialization Configuration <init-config>`.
733+
734+
.. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`.
735+
736+
.. deprecated:: 3.11
737+
738+
739+
.. c:function:: void Py_SetPythonHome(const wchar_t *home)
740+
741+
This API is kept for backward compatibility: setting
742+
:c:member:`PyConfig.home` should be used instead, see :ref:`Python
743+
Initialization Configuration <init-config>`.
744+
745+
Set the default "home" directory, that is, the location of the standard
746+
Python libraries. See :envvar:`PYTHONHOME` for the meaning of the
747+
argument string.
748+
749+
The argument should point to a zero-terminated character string in static
750+
storage whose contents will not change for the duration of the program's
751+
execution. No code in the Python interpreter will change the contents of
752+
this storage.
753+
754+
Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a
755+
:c:expr:`wchar_*` string.
756+
757+
.. deprecated:: 3.11
758+
759+
630760
.. c:function:: wchar_t* Py_GetPythonHome()
631761
632762
Return the default "home", that is, the value set by

Doc/data/stable_abi.dat

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Doc/whatsnew/3.13.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,12 +2011,8 @@ Removed
20112011
* ``PySys_AddWarnOption()``: use :c:member:`PyConfig.warnoptions` instead.
20122012
* ``PySys_AddXOption()``: use :c:member:`PyConfig.xoptions` instead.
20132013
* ``PySys_HasWarnOptions()``: use :c:member:`PyConfig.xoptions` instead.
2014-
* ``PySys_SetArgvEx()``: set :c:member:`PyConfig.argv` instead.
2015-
* ``PySys_SetArgv()``: set :c:member:`PyConfig.argv` instead.
20162014
* ``PySys_SetPath()``: set :c:member:`PyConfig.module_search_paths` instead.
20172015
* ``Py_SetPath()``: set :c:member:`PyConfig.module_search_paths` instead.
2018-
* ``Py_SetProgramName()``: set :c:member:`PyConfig.program_name` instead.
2019-
* ``Py_SetPythonHome()``: set :c:member:`PyConfig.home` instead.
20202016
* ``Py_SetStandardStreamEncoding()``: set :c:member:`PyConfig.stdio_encoding`
20212017
instead, and set also maybe :c:member:`PyConfig.legacy_windows_stdio` (on
20222018
Windows).
@@ -2073,6 +2069,16 @@ Pending Removal in Python 3.14
20732069

20742070
* Creating immutable types (:c:macro:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable
20752071
bases using the C API.
2072+
* Functions to configure the Python initialization, deprecated in Python 3.11:
2073+
2074+
* ``PySys_SetArgvEx()``: set :c:member:`PyConfig.argv` instead.
2075+
* ``PySys_SetArgv()``: set :c:member:`PyConfig.argv` instead.
2076+
* ``Py_SetProgramName()``: set :c:member:`PyConfig.program_name` instead.
2077+
* ``Py_SetPythonHome()``: set :c:member:`PyConfig.home` instead.
2078+
2079+
The :c:func:`Py_InitializeFromConfig` API should be used with
2080+
:c:type:`PyConfig` instead.
2081+
20762082
* Global configuration variables:
20772083

20782084
* :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug`

Include/pylifecycle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@ PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
3434
PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv);
3535

3636
/* In pathconfig.c */
37+
Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *);
3738
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
39+
40+
Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *);
3841
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
42+
3943
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
4044
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetPrefix(void);
4145
Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);

Include/sysmodule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ extern "C" {
77
PyAPI_FUNC(PyObject *) PySys_GetObject(const char *);
88
PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *);
99

10+
Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **);
11+
Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int);
12+
1013
PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
1114
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
1215
PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Restore functions removed in Python 3.13 alpha 1:
2+
3+
* :c:func:`Py_SetPythonHome`
4+
* :c:func:`Py_SetProgramName`
5+
* :c:func:`PySys_SetArgvEx`
6+
* :c:func:`PySys_SetArgv`
7+
8+
Patch by Victor Stinner.

Misc/stable_abi.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,10 +1336,8 @@
13361336
added = '3.2'
13371337
[function.PySys_SetArgv]
13381338
added = '3.2'
1339-
abi_only = true
13401339
[function.PySys_SetArgvEx]
13411340
added = '3.2'
1342-
abi_only = true
13431341
[function.PySys_SetObject]
13441342
added = '3.2'
13451343
[function.PySys_SetPath]
@@ -1672,10 +1670,8 @@
16721670
added = '3.2'
16731671
[function.Py_SetProgramName]
16741672
added = '3.2'
1675-
abi_only = true
16761673
[function.Py_SetPythonHome]
16771674
added = '3.2'
1678-
abi_only = true
16791675
[function.Py_SetRecursionLimit]
16801676
added = '3.2'
16811677
[function.Py_VaBuildValue]

Programs/_testembed.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616

1717
// These functions were removed from Python 3.13 API but are still exported
1818
// for the stable ABI. We want to test them in this program.
19-
extern void Py_SetProgramName(const wchar_t *program_name);
2019
extern void PySys_AddWarnOption(const wchar_t *s);
2120
extern void PySys_AddXOption(const wchar_t *s);
2221
extern void Py_SetPath(const wchar_t *path);
23-
extern void Py_SetPythonHome(const wchar_t *home);
2422

2523

2624
int main_argc;

Python/pathconfig.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ Py_SetPath(const wchar_t *path)
251251
}
252252

253253

254-
// Removed in Python 3.13 API, but kept for the stable ABI
255-
PyAPI_FUNC(void)
254+
void
256255
Py_SetPythonHome(const wchar_t *home)
257256
{
258257
int has_value = home && home[0];
@@ -275,8 +274,7 @@ Py_SetPythonHome(const wchar_t *home)
275274
}
276275

277276

278-
// Removed in Python 3.13 API, but kept for the stable ABI
279-
PyAPI_FUNC(void)
277+
void
280278
Py_SetProgramName(const wchar_t *program_name)
281279
{
282280
int has_value = program_name && program_name[0];

Python/sysmodule.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3872,8 +3872,7 @@ make_sys_argv(int argc, wchar_t * const * argv)
38723872
return list;
38733873
}
38743874

3875-
// Removed in Python 3.13 API, but kept for the stable ABI
3876-
PyAPI_FUNC(void)
3875+
void
38773876
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
38783877
{
38793878
wchar_t* empty_argv[1] = {L""};
@@ -3917,8 +3916,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
39173916
}
39183917
}
39193918

3920-
// Removed in Python 3.13 API, but kept for the stable ABI
3921-
PyAPI_FUNC(void)
3919+
void
39223920
PySys_SetArgv(int argc, wchar_t **argv)
39233921
{
39243922
_Py_COMP_DIAG_PUSH

0 commit comments

Comments
 (0)