Skip to content

Commit

Permalink
pythonGH-127178: install a _sysconfig_vars_(...).json in the stdlib d…
Browse files Browse the repository at this point in the history
…irectory

Signed-off-by: Filipe Laíns <[email protected]>
  • Loading branch information
FFY00 committed Nov 26, 2024
1 parent dcf6292 commit 99b8236
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 13 deletions.
37 changes: 28 additions & 9 deletions Lib/sysconfig/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import json
import os
import sys
import types
from sysconfig import (
_ALWAYS_STR,
_PYTHON_BUILD,
Expand Down Expand Up @@ -157,6 +159,19 @@ def _print_config_dict(d, stream):
print ("}", file=stream)


def _get_pybuilddir():
pybuilddir = f'build/lib.{get_platform()}-{get_python_version()}'
if hasattr(sys, "gettotalrefcount"):
pybuilddir += '-pydebug'
return pybuilddir


def _get_json_data_name():
name = _get_sysconfigdata_name()
assert name.startswith('_sysconfigdata')
return name.replace('_sysconfigdata', '_sysconfig_vars') + '.json'


def _generate_posix_vars():
"""Generate the Python module containing build-time variables."""
vars = {}
Expand Down Expand Up @@ -185,6 +200,8 @@ def _generate_posix_vars():
if _PYTHON_BUILD:
vars['BLDSHARED'] = vars['LDSHARED']

name = _get_sysconfigdata_name()

# There's a chicken-and-egg situation on OS X with regards to the
# _sysconfigdata module after the changes introduced by #15298:
# get_config_vars() is called by get_platform() as part of the
Expand All @@ -196,16 +213,13 @@ def _generate_posix_vars():
# _sysconfigdata module manually and populate it with the build vars.
# This is more than sufficient for ensuring the subsequent call to
# get_platform() succeeds.
name = _get_sysconfigdata_name()
if 'darwin' in sys.platform:
import types
module = types.ModuleType(name)
module.build_time_vars = vars
sys.modules[name] = module
# GH-127178: Since we started generating a .json file, we also need this to
# be able to run sysconfig.get_config_vars().
module = types.ModuleType(name)
module.build_time_vars = vars
sys.modules[name] = module

pybuilddir = f'build/lib.{get_platform()}-{get_python_version()}'
if hasattr(sys, "gettotalrefcount"):
pybuilddir += '-pydebug'
pybuilddir = _get_pybuilddir()
os.makedirs(pybuilddir, exist_ok=True)
destfile = os.path.join(pybuilddir, name + '.py')

Expand All @@ -215,6 +229,11 @@ def _generate_posix_vars():
f.write('build_time_vars = ')
_print_config_dict(vars, stream=f)

# Write a JSON file with the output of sysconfig.get_config_vars
jsonfile = os.path.join(pybuilddir, _get_json_data_name())
with open(jsonfile, 'w') as f:
json.dump(get_config_vars(), f, indent=2)

# Create file used for sys.path fixup -- see Modules/getpath.c
with open('pybuilddir.txt', 'w', encoding='utf8') as f:
f.write(pybuilddir)
Expand Down
21 changes: 19 additions & 2 deletions Lib/test/test_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
from sysconfig import (get_paths, get_platform, get_config_vars,
get_path, get_path_names, _INSTALL_SCHEMES,
get_default_scheme, get_scheme_names, get_config_var,
_expand_vars, _get_preferred_schemes)
from sysconfig.__main__ import _main, _parse_makefile
_expand_vars, _get_preferred_schemes,
is_python_build, _PROJECT_BASE)
from sysconfig.__main__ import _main, _parse_makefile, _get_pybuilddir, _get_json_data_name
import _imp
import _osx_support
import _sysconfig
Expand Down Expand Up @@ -625,6 +626,22 @@ def test_makefile_overwrites_config_vars(self):
self.assertNotEqual(data['prefix'], data['base_prefix'])
self.assertNotEqual(data['exec_prefix'], data['base_exec_prefix'])

def test_sysconfigdata_json(self):
if '_PYTHON_SYSCONFIGDATA_PATH' in os.environ:
data_dir = os.environ['_PYTHON_SYSCONFIGDATA_PATH']
elif is_python_build():
data_dir = os.path.join(_PROJECT_BASE, _get_pybuilddir())
else:
data_dir = sys._stdlib_dir

json_data_path = os.path.join(data_dir, _get_json_data_name())

with open(json_data_path) as f:
json_config_vars = json.load(f)

self.assertEqual(get_config_vars(), json_config_vars)


class MakefileTests(unittest.TestCase):

@unittest.skipIf(sys.platform.startswith('win'),
Expand Down
4 changes: 2 additions & 2 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -2645,8 +2645,8 @@ libinstall: all $(srcdir)/Modules/xxmodule.c
esac; \
done; \
done
$(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py \
$(DESTDIR)$(LIBDEST); \
$(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py $(DESTDIR)$(LIBDEST); \
$(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfig_vars_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).json $(DESTDIR)$(LIBDEST); \
$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
@ # If app store compliance has been configured, apply the patch to the
@ # installed library code. The patch has been previously validated against
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
A ``_sysconfig_vars_(...).json`` file is now shipped in the standard library
directory. It contains the output of :func:`sysconfig.get_config_vars` on
the default environment encoded as JSON data. This is an implementation
detail, and may change at any time.

0 comments on commit 99b8236

Please sign in to comment.