https://github.com/python/cpython/commit/a5a4659548ed112692c7617a295577f0e6eee6df
commit: a5a4659548ed112692c7617a295577f0e6eee6df
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-09-24T12:52:54+02:00
summary:
gh-158001: Remove Py_SetProgramName() function (#158024)
Remove Py_SetProgramName(), Py_SetPythonHome(), PySys_SetArgv() and
PySys_SetArgvEx() functions, deprecated since Python 3.11.
Mark the 4 functions as abi_only in stable_abi.toml.
files:
A Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst
M Doc/c-api/interp-lifecycle.rst
M Doc/data/refcounts.dat
M Doc/data/stable_abi.dat
M Doc/tools/removed-ids.txt
M Doc/whatsnew/3.16.rst
M Include/pylifecycle.h
M Include/sysmodule.h
M Misc/stable_abi.toml
M Programs/_testembed.c
M Python/pathconfig.c
M Python/sysmodule.c
diff --git a/Doc/c-api/interp-lifecycle.rst b/Doc/c-api/interp-lifecycle.rst
index a38d8cec827746..6f832b7a34b10b 100644
--- a/Doc/c-api/interp-lifecycle.rst
+++ b/Doc/c-api/interp-lifecycle.rst
@@ -37,8 +37,6 @@ The following functions can be safely called before Python is
initialized:
* :c:func:`PyMem_SetAllocator`
* :c:func:`PyMem_SetupDebugHooks`
* :c:func:`PyObject_SetArenaAllocator`
- * :c:func:`Py_SetProgramName`
- * :c:func:`Py_SetPythonHome`
* the configuration functions covered in :ref:`init-config`
* Informative functions:
@@ -778,33 +776,6 @@ deleted. This can be done using interpreter views.
Process-wide parameters
-----------------------
-.. c:function:: void Py_SetProgramName(const wchar_t *name)
-
- .. index::
- single: Py_Initialize()
- single: main()
-
- 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 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_t*` string.
-
- .. deprecated-removed:: 3.11 3.16
-
-
.. c:function:: const char* Py_GetVersion()
Return the version of this Python interpreter. This is a string that looks
@@ -873,100 +844,3 @@ Process-wide parameters
The returned string points into static storage; the caller should not
modify its
value. The value is available to Python code as part of the variable
``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_t*` 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`.
-
- 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
-
- .. deprecated-removed:: 3.11 3.16
-
-
-.. 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_t*` 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-removed:: 3.11 3.16
-
-
-.. 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_t*` string.
-
- .. deprecated-removed:: 3.11 3.16
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 60c02aabeb89c5..c19a8a3083a430 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -2265,15 +2265,6 @@ PySys_GetObject:const char*:name::
PySys_GetXOptions:PyObject*::0:
-PySys_SetArgv:void:::
-PySys_SetArgv:int:argc::
-PySys_SetArgv:wchar_t**:argv::
-
-PySys_SetArgvEx:void:::
-PySys_SetArgvEx:int:argc::
-PySys_SetArgvEx:wchar_t**:argv::
-PySys_SetArgvEx:int:updatepath::
-
PySys_SetObject:int:::
PySys_SetObject:const char*:name::
PySys_SetObject:PyObject*:v:+1:
@@ -3085,9 +3076,6 @@ Py_ReprEnter:PyObject*:object:+1:
Py_ReprLeave:void:::
Py_ReprLeave:PyObject*:object:-1:
-Py_SetProgramName:void:::
-Py_SetProgramName:const wchar_t*:name::
-
Py_XDECREF:void:::
Py_XDECREF:PyObject*:o:-1:if o is not NULL
diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index 65f0e5f52bd936..662158323c5d30 100644
--- a/Doc/data/stable_abi.dat
+++ b/Doc/data/stable_abi.dat
@@ -717,8 +717,6 @@ func,PySys_GetObject,3.2,,
func,PySys_GetOptionalAttr,3.15,,
func,PySys_GetOptionalAttrString,3.15,,
func,PySys_GetXOptions,3.7,,
-func,PySys_SetArgv,3.2,,
-func,PySys_SetArgvEx,3.2,,
func,PySys_SetObject,3.2,,
func,PySys_WriteStderr,3.2,,
func,PySys_WriteStdout,3.2,,
@@ -993,8 +991,6 @@ func,Py_ReprEnter,3.2,,
func,Py_ReprLeave,3.2,,
func,Py_SET_SIZE,3.15,,
func,Py_SIZE,3.15,,
-func,Py_SetProgramName,3.2,,
-func,Py_SetPythonHome,3.2,,
func,Py_SetRecursionLimit,3.2,,
macro,Py_TPFLAGS_BASETYPE,3.2,,
macro,Py_TPFLAGS_DEFAULT,3.2,,
diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt
index a6fb127a1e92ae..3f7906ee84ec14 100644
--- a/Doc/tools/removed-ids.txt
+++ b/Doc/tools/removed-ids.txt
@@ -3,6 +3,10 @@
# Remove from here in 3.16
c-api/allocation.html: deprecated-aliases
c-api/file.html: deprecated-api
+c-api/interp-lifecycle.html: c.PySys_SetArgv
+c-api/interp-lifecycle.html: c.PySys_SetArgvEx
+c-api/interp-lifecycle.html: c.Py_SetProgramName
+c-api/interp-lifecycle.html: c.Py_SetPythonHome
c-api/threads.html: c.PyEval_InitThreads
# Removed sections
diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst
index 8010379323e721..c76681261f6746 100644
--- a/Doc/whatsnew/3.16.rst
+++ b/Doc/whatsnew/3.16.rst
@@ -1145,6 +1145,17 @@ Removed C APIs
3.7 and was deprecated since Python 3.9.
(Contributed by Victor Stinner in :gh:`154757`.)
+* Remove :c:func:`!Py_SetProgramName` and :c:func:`!Py_SetPythonHome`
+ functions, deprecated since Python 3.11. Instead, use :ref:`PyInitConfig C
+ API <pyinitconfig_api>` to set respectively ``"program_name"`` and
+ ``"home"``.
+ (Contributed by Victor Stinner in :gh:`158001`.)
+
+* Remove :c:func:`!PySys_SetArgv` and :c:func:`!PySys_SetArgvEx` functions,
+ deprecated since Python 3.11. Instead, set directly :data:`sys.argv`, and
+ maybe also :data:`sys.path`.
+ (Contributed by Victor Stinner in :gh:`158001`.)
+
* The :c:var:`!PyUnstable_ExecutableKinds` array, as well as the macros
:c:macro:`!PyUnstable_EXECUTABLE_KIND_SKIP`,
:c:macro:`!PyUnstable_EXECUTABLE_KIND_PY_FUNCTION`,
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index 4b3474035cec19..f11ac4d2a9f10e 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -33,10 +33,6 @@ PyAPI_FUNC(void) _Py_NO_RETURN Py_Exit(int);
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv);
-/* In pathconfig.c */
-Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *);
-Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *);
-
#ifdef MS_WINDOWS
int _Py_CheckPython3(void);
#endif
diff --git a/Include/sysmodule.h b/Include/sysmodule.h
index b7d800c5e5db0b..fc6da6f4c797b3 100644
--- a/Include/sysmodule.h
+++ b/Include/sysmodule.h
@@ -13,9 +13,6 @@ PyAPI_FUNC(int) PySys_GetOptionalAttrString(const char *,
PyObject **);
PyAPI_FUNC(PyObject *) PySys_GetObject(const char *);
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, ...)
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...)
diff --git
a/Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst
b/Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst
new file mode 100644
index 00000000000000..2da45967b24597
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2026-09-23-21-45-43.gh-issue-158001.R_wX4E.rst
@@ -0,0 +1,3 @@
+Remove :c:func:`!Py_SetProgramName`, :c:func:`!Py_SetPythonHome`,
+:c:func:`!PySys_SetArgv` and :c:func:`!PySys_SetArgvEx` functions, deprecated
+since Python 3.11. Patch by Victor Stinner.
diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml
index b7a1e49c8bf480..08fd7009dbc4b8 100644
--- a/Misc/stable_abi.toml
+++ b/Misc/stable_abi.toml
@@ -1350,8 +1350,10 @@
abi_only = true
[function.PySys_SetArgv]
added = '3.2'
+ abi_only = true
[function.PySys_SetArgvEx]
added = '3.2'
+ abi_only = true
[function.PySys_SetObject]
added = '3.2'
[function.PySys_SetPath]
@@ -1695,8 +1697,10 @@
added = '3.2'
[function.Py_SetProgramName]
added = '3.2'
+ abi_only = true
[function.Py_SetPythonHome]
added = '3.2'
+ abi_only = true
[function.Py_SetRecursionLimit]
added = '3.2'
[function.Py_VaBuildValue]
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 17b93ba47caac4..7e82a6365d9808 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -23,6 +23,10 @@ extern void PySys_AddWarnOption(const wchar_t *s);
extern void PySys_AddXOption(const wchar_t *s);
extern void Py_SetPath(const wchar_t *path);
+// Functions removed from Python 3.16 API but still exported for the stable
+// ABI.
+extern void Py_SetPythonHome(const wchar_t *);
+
// These functions were removed from Python 3.15 API but are still exported
// for the stable ABI. We want to test them in this program.
extern void PySys_ResetWarnOptions(void);
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index d034562c43f23c..b4ba1c52066879 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -236,7 +236,8 @@ Py_SetPath(const wchar_t *path)
}
-void
+// Function removed from Python 3.16 limited C API, but kept in the stable ABI
+PyAPI_FUNC(void)
Py_SetPythonHome(const wchar_t *home)
{
int has_value = home && home[0];
@@ -254,7 +255,8 @@ Py_SetPythonHome(const wchar_t *home)
}
-void
+// Function removed from Python 3.16 limited C API, but kept in the stable ABI
+PyAPI_FUNC(void)
Py_SetProgramName(const wchar_t *program_name)
{
int has_value = program_name && program_name[0];
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index b3ec8461485de1..718ae51944faf2 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -4490,7 +4490,8 @@ make_sys_argv(int argc, wchar_t * const * argv)
return list;
}
-void
+// Function removed from Python 3.16 limited C API, but kept in the stable ABI
+PyAPI_FUNC(void)
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
{
wchar_t* empty_argv[1] = {L""};
@@ -4537,7 +4538,8 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
}
}
-void
+// Function removed from Python 3.16 limited C API, but kept in the stable ABI
+PyAPI_FUNC(void)
PySys_SetArgv(int argc, wchar_t **argv)
{
int isolated = 0;
@@ -4547,10 +4549,7 @@ PySys_SetArgv(int argc, wchar_t **argv)
isolated = config->isolated;
}
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
PySys_SetArgvEx(argc, argv, isolated == 0);
-_Py_COMP_DIAG_POP
}
/* Reimplementation of PyFile_WriteString() no calling indirectly
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]