gh-133644: Remove deprecated Python initialization getter functions (#133661)

Remove functions:

* Py_GetExecPrefix()
* Py_GetPath()
* Py_GetPrefix()
* Py_GetProgramFullPath()
* Py_GetProgramName()
* Py_GetPythonHome()
This commit is contained in:
Bénédikt Tran 2025-05-09 13:39:23 +02:00 committed by GitHub
parent f52de8a937
commit 5044e85265
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 93 additions and 238 deletions

View file

@ -77,10 +77,7 @@ The following functions can be safely called before Python is initialized:
Despite their apparent similarity to some of the functions listed above,
the following functions **should not be called** before the interpreter has
been initialized: :c:func:`Py_EncodeLocale`, :c:func:`Py_GetPath`,
:c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`,
:c:func:`Py_GetProgramFullPath`, :c:func:`Py_GetPythonHome`,
:c:func:`Py_GetProgramName`, :c:func:`PyEval_InitThreads`, and
been initialized: :c:func:`Py_EncodeLocale`, :c:func:`PyEval_InitThreads`, and
:c:func:`Py_RunMain`.
@ -145,9 +142,6 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
:c:member:`PyConfig.pathconfig_warnings` should be used instead, see
:ref:`Python Initialization Configuration <init-config>`.
Suppress error messages when calculating the module search path in
:c:func:`Py_GetPath`.
Private flag used by ``_freeze_module`` and ``frozenmain`` programs.
.. deprecated-removed:: 3.12 3.15
@ -586,7 +580,6 @@ Process-wide parameters
.. 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
@ -596,7 +589,7 @@ Process-wide parameters
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
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
@ -609,146 +602,6 @@ Process-wide parameters
.. deprecated-removed:: 3.11 3.15
.. c:function:: wchar_t* Py_GetProgramName()
Return the program name set with :c:member:`PyConfig.program_name`, or the default.
The returned string points into static storage; the caller should not modify its
value.
This function should not be called before :c:func:`Py_Initialize`, otherwise
it returns ``NULL``.
.. versionchanged:: 3.10
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.
.. deprecated-removed:: 3.13 3.15
Use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
(:data:`sys.executable`) instead.
.. c:function:: wchar_t* Py_GetPrefix()
Return the *prefix* for installed platform-independent files. This is derived
through a number of complicated rules from the program name set with
:c:member:`PyConfig.program_name` and some environment variables; for example, if the
program name is ``'/usr/local/bin/python'``, the prefix is ``'/usr/local'``. The
returned string points into static storage; the caller should not modify its
value. This corresponds to the :makevar:`prefix` variable in the top-level
:file:`Makefile` and the :option:`--prefix` argument to the :program:`configure`
script at build time. The value is available to Python code as ``sys.base_prefix``.
It is only useful on Unix. See also the next function.
This function should not be called before :c:func:`Py_Initialize`, otherwise
it returns ``NULL``.
.. versionchanged:: 3.10
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.
.. deprecated-removed:: 3.13 3.15
Use :c:func:`PyConfig_Get("base_prefix") <PyConfig_Get>`
(:data:`sys.base_prefix`) instead. Use :c:func:`PyConfig_Get("prefix")
<PyConfig_Get>` (:data:`sys.prefix`) if :ref:`virtual environments
<venv-def>` need to be handled.
.. c:function:: wchar_t* Py_GetExecPrefix()
Return the *exec-prefix* for installed platform-*dependent* files. This is
derived through a number of complicated rules from the program name set with
:c:member:`PyConfig.program_name` and some environment variables; for example, if the
program name is ``'/usr/local/bin/python'``, the exec-prefix is
``'/usr/local'``. The returned string points into static storage; the caller
should not modify its value. This corresponds to the :makevar:`exec_prefix`
variable in the top-level :file:`Makefile` and the ``--exec-prefix``
argument to the :program:`configure` script at build time. The value is
available to Python code as ``sys.base_exec_prefix``. It is only useful on
Unix.
Background: The exec-prefix differs from the prefix when platform dependent
files (such as executables and shared libraries) are installed in a different
directory tree. In a typical installation, platform dependent files may be
installed in the :file:`/usr/local/plat` subtree while platform independent may
be installed in :file:`/usr/local`.
Generally speaking, a platform is a combination of hardware and software
families, e.g. Sparc machines running the Solaris 2.x operating system are
considered the same platform, but Intel machines running Solaris 2.x are another
platform, and Intel machines running Linux are yet another platform. Different
major revisions of the same operating system generally also form different
platforms. Non-Unix operating systems are a different story; the installation
strategies on those systems are so different that the prefix and exec-prefix are
meaningless, and set to the empty string. Note that compiled Python bytecode
files are platform independent (but not independent from the Python version by
which they were compiled!).
System administrators will know how to configure the :program:`mount` or
:program:`automount` programs to share :file:`/usr/local` between platforms
while having :file:`/usr/local/plat` be a different filesystem for each
platform.
This function should not be called before :c:func:`Py_Initialize`, otherwise
it returns ``NULL``.
.. versionchanged:: 3.10
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.
.. deprecated-removed:: 3.13 3.15
Use :c:func:`PyConfig_Get("base_exec_prefix") <PyConfig_Get>`
(:data:`sys.base_exec_prefix`) instead. Use
:c:func:`PyConfig_Get("exec_prefix") <PyConfig_Get>`
(:data:`sys.exec_prefix`) if :ref:`virtual environments <venv-def>` need
to be handled.
.. c:function:: wchar_t* Py_GetProgramFullPath()
.. index::
single: executable (in module sys)
Return the full program name of the Python executable; this is computed as a
side-effect of deriving the default module search path from the program name
(set by :c:member:`PyConfig.program_name`). The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as ``sys.executable``.
This function should not be called before :c:func:`Py_Initialize`, otherwise
it returns ``NULL``.
.. versionchanged:: 3.10
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.
.. deprecated-removed:: 3.13 3.15
Use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
(:data:`sys.executable`) instead.
.. c:function:: wchar_t* Py_GetPath()
.. index::
triple: module; search; path
single: path (in module sys)
Return the default module search path; this is computed from the program name
(set by :c:member:`PyConfig.program_name`) and some environment variables.
The returned string consists of a series of directory names separated by a
platform dependent delimiter character. The delimiter character is ``':'``
on Unix and macOS, ``';'`` on Windows. The returned string points into
static storage; the caller should not modify its value. The list
:data:`sys.path` is initialized with this value on interpreter startup; it
can be (and usually is) modified later to change the search path for loading
modules.
This function should not be called before :c:func:`Py_Initialize`, otherwise
it returns ``NULL``.
.. XXX should give the exact rules
.. versionchanged:: 3.10
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.
.. deprecated-removed:: 3.13 3.15
Use :c:func:`PyConfig_Get("module_search_paths") <PyConfig_Get>`
(:data:`sys.path`) instead.
.. c:function:: const char* Py_GetVersion()
Return the version of this Python interpreter. This is a string that looks
@ -919,23 +772,6 @@ Process-wide parameters
.. deprecated-removed:: 3.11 3.15
.. c:function:: wchar_t* Py_GetPythonHome()
Return the default "home", that is, the value set by
:c:member:`PyConfig.home`, or the value of the :envvar:`PYTHONHOME`
environment variable if it is set.
This function should not be called before :c:func:`Py_Initialize`, otherwise
it returns ``NULL``.
.. versionchanged:: 3.10
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.
.. deprecated-removed:: 3.13 3.15
Use :c:func:`PyConfig_Get("home") <PyConfig_Get>` or the
:envvar:`PYTHONHOME` environment variable instead.
.. _threads:
Thread State and the Global Interpreter Lock

View file

@ -779,20 +779,11 @@ found along :envvar:`PATH`.) The user can override this behavior by setting the
environment variable :envvar:`PYTHONHOME`, or insert additional directories in
front of the standard path by setting :envvar:`PYTHONPATH`.
.. index::
single: Py_GetPath (C function)
single: Py_GetPrefix (C function)
single: Py_GetExecPrefix (C function)
single: Py_GetProgramFullPath (C function)
The embedding application can steer the search by setting
:c:member:`PyConfig.program_name` *before* calling
:c:func:`Py_InitializeFromConfig`. Note that
:envvar:`PYTHONHOME` still overrides this and :envvar:`PYTHONPATH` is still
inserted in front of the standard path. An application that requires total
control has to provide its own implementation of :c:func:`Py_GetPath`,
:c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`, and
:c:func:`Py_GetProgramFullPath` (all defined in :file:`Modules/getpath.c`).
inserted in front of the standard path.
.. index:: single: Py_IsInitialized (C function)

View file

@ -3004,18 +3004,8 @@ Py_GetCompiler:const char*:::
Py_GetCopyright:const char*:::
Py_GetExecPrefix:wchar_t*:::
Py_GetPath:wchar_t*:::
Py_GetPlatform:const char*:::
Py_GetPrefix:wchar_t*:::
Py_GetProgramFullPath:wchar_t*:::
Py_GetProgramName:wchar_t*:::
Py_GetVersion:const char*:::
Py_INCREF:void:::

View file

@ -861,13 +861,7 @@ func,Py_GetCompiler,3.2,,
func,Py_GetConstant,3.13,,
func,Py_GetConstantBorrowed,3.13,,
func,Py_GetCopyright,3.2,,
func,Py_GetExecPrefix,3.2,,
func,Py_GetPath,3.2,,
func,Py_GetPlatform,3.2,,
func,Py_GetPrefix,3.2,,
func,Py_GetProgramFullPath,3.2,,
func,Py_GetProgramName,3.2,,
func,Py_GetPythonHome,3.2,,
func,Py_GetRecursionLimit,3.2,,
func,Py_GetVersion,3.2,,
data,Py_HasFileSystemDefaultEncoding,3.2,,

View file

@ -22,27 +22,27 @@ Pending removal in Python 3.15
may return a type other than :class:`bytes`, such as :class:`str`.
* Python initialization functions, deprecated in Python 3.13:
* :c:func:`Py_GetPath`:
* :c:func:`!Py_GetPath`:
Use :c:func:`PyConfig_Get("module_search_paths") <PyConfig_Get>`
(:data:`sys.path`) instead.
* :c:func:`Py_GetPrefix`:
* :c:func:`!Py_GetPrefix`:
Use :c:func:`PyConfig_Get("base_prefix") <PyConfig_Get>`
(:data:`sys.base_prefix`) instead. Use :c:func:`PyConfig_Get("prefix")
<PyConfig_Get>` (:data:`sys.prefix`) if :ref:`virtual environments
<venv-def>` need to be handled.
* :c:func:`Py_GetExecPrefix`:
* :c:func:`!Py_GetExecPrefix`:
Use :c:func:`PyConfig_Get("base_exec_prefix") <PyConfig_Get>`
(:data:`sys.base_exec_prefix`) instead. Use
:c:func:`PyConfig_Get("exec_prefix") <PyConfig_Get>`
(:data:`sys.exec_prefix`) if :ref:`virtual environments <venv-def>` need to
be handled.
* :c:func:`Py_GetProgramFullPath`:
* :c:func:`!Py_GetProgramFullPath`:
Use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
(:data:`sys.executable`) instead.
* :c:func:`Py_GetProgramName`:
* :c:func:`!Py_GetProgramName`:
Use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
(:data:`sys.executable`) instead.
* :c:func:`Py_GetPythonHome`:
* :c:func:`!Py_GetPythonHome`:
Use :c:func:`PyConfig_Get("home") <PyConfig_Get>` or the
:envvar:`PYTHONHOME` environment variable instead.

View file

@ -2176,9 +2176,9 @@ Porting to Python 3.10
``unicodedata.ucnhash_CAPI`` has been moved to the internal C API.
(Contributed by Victor Stinner in :issue:`42157`.)
* :c:func:`Py_GetPath`, :c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`,
:c:func:`Py_GetProgramFullPath`, :c:func:`Py_GetPythonHome` and
:c:func:`Py_GetProgramName` functions now return ``NULL`` if called before
* :c:func:`!Py_GetPath`, :c:func:`!Py_GetPrefix`, :c:func:`!Py_GetExecPrefix`,
:c:func:`!Py_GetProgramFullPath`, :c:func:`!Py_GetPythonHome` and
:c:func:`!Py_GetProgramName` functions now return ``NULL`` if called before
:c:func:`Py_Initialize` (before Python is initialized). Use the new
:ref:`init-config` API to get the :ref:`init-path-config`.
(Contributed by Victor Stinner in :issue:`42260`.)

View file

@ -2477,17 +2477,17 @@ Deprecated C APIs
* :c:func:`PySys_ResetWarnOptions`:
Clear :data:`sys.warnoptions` and :data:`!warnings.filters` instead.
* :c:func:`Py_GetExecPrefix`:
* :c:func:`!Py_GetExecPrefix`:
Get :data:`sys.exec_prefix` instead.
* :c:func:`Py_GetPath`:
* :c:func:`!Py_GetPath`:
Get :data:`sys.path` instead.
* :c:func:`Py_GetPrefix`:
* :c:func:`!Py_GetPrefix`:
Get :data:`sys.prefix` instead.
* :c:func:`Py_GetProgramFullPath`:
* :c:func:`!Py_GetProgramFullPath`:
Get :data:`sys.executable` instead.
* :c:func:`Py_GetProgramName`:
* :c:func:`!Py_GetProgramName`:
Get :data:`sys.executable` instead.
* :c:func:`Py_GetPythonHome`:
* :c:func:`!Py_GetPythonHome`:
Get :c:member:`PyConfig.home`
or the :envvar:`PYTHONHOME` environment variable instead.

View file

@ -169,3 +169,38 @@ Removed C APIs
* :c:func:`!PyImport_ImportModuleNoBlock`: deprecated alias
of :c:func:`PyImport_ImportModule`.
The following functions are removed in favor of :c:func:`PyConfig_Get`.
The |pythoncapi_compat_project| can be used to get :c:func:`!PyConfig_Get`
on Python 3.13 and older.
* Python initialization functions:
* :c:func:`!Py_GetExecPrefix`:
use :c:func:`PyConfig_Get("base_exec_prefix") <PyConfig_Get>`
(:data:`sys.base_exec_prefix`) instead.
Use :c:func:`PyConfig_Get("exec_prefix") <PyConfig_Get>`
(:data:`sys.exec_prefix`) if :ref:`virtual environments <venv-def>`
need to be handled.
* :c:func:`!Py_GetPath`:
use :c:func:`PyConfig_Get("module_search_paths") <PyConfig_Get>`
(:data:`sys.path`) instead.
* :c:func:`!Py_GetPrefix`:
use :c:func:`PyConfig_Get("base_prefix") <PyConfig_Get>`
(:data:`sys.base_prefix`) instead.
Use :c:func:`PyConfig_Get("prefix") <PyConfig_Get>`
(:data:`sys.prefix`) if :ref:`virtual environments <venv-def>`
need to be handled.
* :c:func:`!Py_GetProgramFullPath`:
use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
(:data:`sys.executable`) instead.
* :c:func:`!Py_GetProgramName`:
use :c:func:`PyConfig_Get("executable") <PyConfig_Get>`
(:data:`sys.executable`) instead.
* :c:func:`!Py_GetPythonHome`:
use :c:func:`PyConfig_Get("home") <PyConfig_Get>` or the
:envvar:`PYTHONHOME` environment variable instead.
.. |pythoncapi_compat_project| replace:: |pythoncapi_compat_project_link|_
.. |pythoncapi_compat_project_link| replace:: pythoncapi-compat project
.. _pythoncapi_compat_project_link: https://github.com/python/pythoncapi-compat

View file

@ -1629,8 +1629,8 @@ Build and C API Changes
(Contributed by Pablo Galindo in :issue:`37221`.)
* :c:func:`!Py_SetPath` now sets :data:`sys.executable` to the program full
path (:c:func:`Py_GetProgramFullPath`) rather than to the program name
(:c:func:`Py_GetProgramName`).
path (:c:func:`!Py_GetProgramFullPath`) rather than to the program name
(:c:func:`!Py_GetProgramName`).
(Contributed by Victor Stinner in :issue:`38234`.)

View file

@ -35,15 +35,8 @@ 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.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_GetProgramFullPath(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_GetPath(void);
#ifdef MS_WINDOWS
int _Py_CheckPython3(void);
#endif

View file

@ -6146,12 +6146,14 @@ class TestRepl(unittest.TestCase):
object.
"""
# TODO(picnixz): refactor this as it's used by test_repl.py
# To run the REPL without using a terminal, spawn python with the command
# line option '-i' and the process name set to '<stdin>'.
# The directory of argv[0] must match the directory of the Python
# executable for the Popen() call to python to succeed as the directory
# path may be used by Py_GetPath() to build the default module search
# path.
# path may be used by PyConfig_Get("module_search_paths") to build the
# default module search path.
stdin_fname = os.path.join(os.path.dirname(sys.executable), "<stdin>")
cmd_line = [stdin_fname, '-E', '-i']
cmd_line.extend(args)

View file

@ -38,8 +38,8 @@ def spawn_repl(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
# line option '-i' and the process name set to '<stdin>'.
# The directory of argv[0] must match the directory of the Python
# executable for the Popen() call to python to succeed as the directory
# path may be used by Py_GetPath() to build the default module search
# path.
# path may be used by PyConfig_Get("module_search_paths") to build the
# default module search path.
stdin_fname = os.path.join(os.path.dirname(sys.executable), "<stdin>")
cmd_line = [stdin_fname, '-I', '-i']
cmd_line.extend(args)

View file

@ -1395,9 +1395,9 @@ but now can get the condition by calling the new private
.. nonce: -Br3Co
.. section: C API
:c:func:`Py_GetPath`, :c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`,
:c:func:`Py_GetProgramFullPath`, :c:func:`Py_GetPythonHome` and
:c:func:`Py_GetProgramName` functions now return ``NULL`` if called before
:c:func:`!Py_GetPath`, :c:func:`!Py_GetPrefix`, :c:func:`!Py_GetExecPrefix`,
:c:func:`!Py_GetProgramFullPath`, :c:func:`!Py_GetPythonHome` and
:c:func:`!Py_GetProgramName` functions now return ``NULL`` if called before
:c:func:`Py_Initialize` (before Python is initialized). Use the new
:ref:`Python Initialization Configuration API <init-config>` to get the
:ref:`Python Path Configuration. <init-path-config>`. Patch by Victor

View file

@ -6593,12 +6593,12 @@ functions, deprecated in Python 3.9. Patch by Victor Stinner.
Deprecate old Python initialization functions:
* :c:func:`PySys_ResetWarnOptions`
* :c:func:`Py_GetExecPrefix`
* :c:func:`Py_GetPath`
* :c:func:`Py_GetPrefix`
* :c:func:`Py_GetProgramFullPath`
* :c:func:`Py_GetProgramName`
* :c:func:`Py_GetPythonHome`
* :c:func:`!Py_GetExecPrefix`
* :c:func:`!Py_GetPath`
* :c:func:`!Py_GetPrefix`
* :c:func:`!Py_GetProgramFullPath`
* :c:func:`!Py_GetProgramName`
* :c:func:`!Py_GetPythonHome`
Patch by Victor Stinner.

View file

@ -5536,8 +5536,8 @@ Tyler Kieft.
.. section: C API
:c:func:`!Py_SetPath` now sets :data:`sys.executable` to the program full
path (:c:func:`Py_GetProgramFullPath`) rather than to the program name
(:c:func:`Py_GetProgramName`).
path (:c:func:`!Py_GetProgramFullPath`) rather than to the program name
(:c:func:`!Py_GetProgramName`).
..

View file

@ -0,0 +1,2 @@
Remove deprecated Python initialization getter functions ``Py_Get*``.
Patch by Bénédikt Tran.

View file

@ -1633,18 +1633,24 @@
added = '3.2'
[function.Py_GetExecPrefix]
added = '3.2'
abi_only = true
[function.Py_GetPath]
added = '3.2'
abi_only = true
[function.Py_GetPlatform]
added = '3.2'
[function.Py_GetPrefix]
added = '3.2'
abi_only = true
[function.Py_GetProgramFullPath]
added = '3.2'
abi_only = true
[function.Py_GetProgramName]
added = '3.2'
abi_only = true
[function.Py_GetPythonHome]
added = '3.2'
abi_only = true
[function.Py_GetRecursionLimit]
added = '3.2'
[function.Py_GetVersion]

View file

@ -272,7 +272,8 @@ Py_SetProgramName(const wchar_t *program_name)
}
wchar_t *
/* removed in 3.15, but kept for stable ABI compatibility */
PyAPI_FUNC(wchar_t *)
Py_GetPath(void)
{
/* If the user has provided a path, return that */
@ -284,7 +285,7 @@ Py_GetPath(void)
}
wchar_t *
PyAPI_FUNC(wchar_t *)
_Py_GetStdlibDir(void)
{
wchar_t *stdlib_dir = _Py_path_config.stdlib_dir;
@ -295,35 +296,40 @@ _Py_GetStdlibDir(void)
}
wchar_t *
/* removed in 3.15, but kept for stable ABI compatibility */
PyAPI_FUNC(wchar_t *)
Py_GetPrefix(void)
{
return _Py_path_config.prefix;
}
wchar_t *
/* removed in 3.15, but kept for stable ABI compatibility */
PyAPI_FUNC(wchar_t *)
Py_GetExecPrefix(void)
{
return _Py_path_config.exec_prefix;
}
wchar_t *
/* removed in 3.15, but kept for stable ABI compatibility */
PyAPI_FUNC(wchar_t *)
Py_GetProgramFullPath(void)
{
return _Py_path_config.program_full_path;
}
wchar_t*
/* removed in 3.15, but kept for stable ABI compatibility */
PyAPI_FUNC(wchar_t *)
Py_GetPythonHome(void)
{
return _Py_path_config.home;
}
wchar_t *
/* removed in 3.15, but kept for stable ABI compatibility */
PyAPI_FUNC(wchar_t *)
Py_GetProgramName(void)
{
return _Py_path_config.program_name;