Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions Lib/sysconfig/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Access to Python's configuration information."""

import _sysconfig
import os
import sys
import threading
Expand Down Expand Up @@ -172,9 +173,6 @@ def joinuser(*args):
_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
'scripts', 'data')

_PY_VERSION = sys.version.split()[0]
_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}'
_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}'
_BASE_PREFIX = os.path.normpath(sys.base_prefix)
_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
# Mutex guarding initialization of _CONFIG_VARS.
Expand Down Expand Up @@ -323,7 +321,8 @@ def get_makefile_filename():
return os.path.join(_PROJECT_BASE, "Makefile")

if hasattr(sys, 'abiflags'):
config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}'
py_version_short = f'{sys.version_info[0]}.{sys.version_info[1]}'
config_dir_name = f'config-{py_version_short}{sys.abiflags}'
else:
config_dir_name = 'config'

Expand Down Expand Up @@ -385,14 +384,10 @@ def _init_non_posix(vars):
"""Initialize the module as appropriate for NT"""
# set basic install directories
import _winapi
import _sysconfig
vars['LIBDEST'] = get_path('stdlib')
vars['BINLIBDEST'] = get_path('platstdlib')
vars['INCLUDEPY'] = get_path('include')

# Add EXT_SUFFIX, SOABI, Py_DEBUG, and Py_GIL_DISABLED
vars.update(_sysconfig.config_vars())

# NOTE: ABIFLAGS is only an emulated value. It is not present during build
# on Windows. sys.abiflags is absent on Windows and vars['abiflags']
# is already widely used to calculate paths, so it should remain an
Expand All @@ -410,7 +405,7 @@ def _init_non_posix(vars):
vars['LIBRARY'] = os.path.basename(_safe_realpath(dllhandle))
vars['LDLIBRARY'] = vars['LIBRARY']
vars['EXE'] = '.exe'
vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
vars['VERSION'] = vars['py_version_nodot']
vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
# No standard path exists on Windows for this, but we'll check
# whether someone is imitating a POSIX-like layout
Expand Down Expand Up @@ -505,6 +500,10 @@ def _init_config_vars():
global _CONFIG_VARS
_CONFIG_VARS = {}

# Add py_version, Py_DEBUG, and Py_GIL_DISABLED.
# On Windows, add also EXT_SUFFIX and SOABI.
_CONFIG_VARS.update(_sysconfig.config_vars())

prefix = os.path.normpath(sys.prefix)
exec_prefix = os.path.normpath(sys.exec_prefix)
base_prefix = _BASE_PREFIX
Expand All @@ -530,9 +529,6 @@ def _init_config_vars():
# Distutils.
_CONFIG_VARS['prefix'] = prefix
_CONFIG_VARS['exec_prefix'] = exec_prefix
_CONFIG_VARS['py_version'] = _PY_VERSION
_CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
_CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT
Comment on lines -534 to -535
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it's worth it to move py_version_short and py_version_nodot to _sysconfig, since they can be easily built in Python.

_CONFIG_VARS['installed_base'] = base_prefix
_CONFIG_VARS['base'] = prefix
_CONFIG_VARS['installed_platbase'] = base_exec_prefix
Expand Down Expand Up @@ -665,7 +661,6 @@ def get_platform():

For other non-POSIX platforms, currently just returns :data:`sys.platform`."""
if os.name == 'nt':
import _sysconfig
platform = _sysconfig.get_platform()
if platform:
return platform
Expand Down Expand Up @@ -740,11 +735,11 @@ def get_platform():


def get_python_version():
return _PY_VERSION_SHORT
return get_config_var('py_version_short')


def _get_python_version_abi():
return _PY_VERSION_SHORT + get_config_var("abi_thread")
return get_config_var('py_version_short') + get_config_var('abi_thread')


def expand_makefile_vars(s, vars):
Expand Down
21 changes: 21 additions & 0 deletions Lib/test/test_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,27 @@ def test_sysconfig_config_vars_no_prefix_cache(self):
self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
self.assertEqual(config_vars['platbase'], sys.exec_prefix)

def test_py_version(self):
# Test py_version
config_vars = sysconfig.get_config_vars()
self.assertIsInstance(config_vars['py_version'], str)
ver = sys.version_info
version = f'{ver.major}.{ver.minor}.{ver.micro}'
# py_version can be longer such as "3.15.0a7+" instead of "3.15.0"
self.assertStartsWith(config_vars['py_version'], version)

# Test py_version_short and get_python_version()
self.assertIsInstance(config_vars['py_version_short'], str)
self.assertEqual(config_vars['py_version_short'],
f'{ver.major}.{ver.minor}')
self.assertEqual(sysconfig.get_python_version(),
config_vars['py_version_short'])

# Test py_version_nodot
self.assertIsInstance(config_vars['py_version_nodot'], str)
self.assertEqual(config_vars['py_version_nodot'],
f'{ver.major}{ver.minor}')


class MakefileTests(unittest.TestCase):

Expand Down
37 changes: 27 additions & 10 deletions Modules/_sysconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ module _sysconfig

#include "clinic/_sysconfig.c.h"

#ifdef MS_WINDOWS

#define py_version_short() \
(Py_STRINGIFY(PY_MAJOR_VERSION) "." Py_STRINGIFY(PY_MINOR_VERSION))
#define py_version_nodot() \
(Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION))


static int
add_string_value(PyObject *dict, const char *key, const char *str_value)
{
Expand All @@ -29,7 +35,7 @@ add_string_value(PyObject *dict, const char *key, const char *str_value)
Py_DECREF(value);
return err;
}
#endif


/*[clinic input]
@permit_long_summary
Expand All @@ -47,14 +53,23 @@ _sysconfig_config_vars_impl(PyObject *module)
return NULL;
}

// Python version
if (add_string_value(config, "py_version", PY_VERSION) < 0) {
goto error;
}
if (add_string_value(config, "py_version_short", py_version_short()) < 0) {
goto error;
}
if (add_string_value(config, "py_version_nodot", py_version_nodot()) < 0) {
goto error;
}

#ifdef MS_WINDOWS
if (add_string_value(config, "EXT_SUFFIX", PYD_TAGGED_SUFFIX) < 0) {
Py_DECREF(config);
return NULL;
goto error;
}
if (add_string_value(config, "SOABI", PYD_SOABI) < 0) {
Py_DECREF(config);
return NULL;
goto error;
}
#endif

Expand All @@ -64,8 +79,7 @@ _sysconfig_config_vars_impl(PyObject *module)
PyObject *py_gil_disabled = _PyLong_GetZero();
#endif
if (PyDict_SetItemString(config, "Py_GIL_DISABLED", py_gil_disabled) < 0) {
Py_DECREF(config);
return NULL;
goto error;
}

#ifdef Py_DEBUG
Expand All @@ -74,11 +88,14 @@ _sysconfig_config_vars_impl(PyObject *module)
PyObject *py_debug = _PyLong_GetZero();
#endif
if (PyDict_SetItemString(config, "Py_DEBUG", py_debug) < 0) {
Py_DECREF(config);
return NULL;
goto error;
}

return config;

error:
Py_DECREF(config);
return NULL;
}

#ifdef MS_WINDOWS
Expand Down
Loading