From 2f1fae1bfceb88cf812a45c44cd18ce604b69c69 Mon Sep 17 00:00:00 2001 From: mattip Date: Mon, 29 Jun 2020 00:25:26 +0300 Subject: [PATCH 1/5] add pypy schemas --- distutils/command/install.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/distutils/command/install.py b/distutils/command/install.py index 21f8c27c8b..13feeb890f 100644 --- a/distutils/command/install.py +++ b/distutils/command/install.py @@ -43,6 +43,20 @@ 'data' : '$base', }, 'nt': WINDOWS_SCHEME, + 'pypy': { + 'purelib': '$base/site-packages', + 'platlib': '$base/site-packages', + 'headers': '$base/include/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'pypy_nt': { + 'purelib': '$base/site-packages', + 'platlib': '$base/site-packages', + 'headers': '$base/include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, } # user site schemes @@ -455,6 +469,12 @@ def finalize_other(self): def select_scheme(self, name): """Sets the install directories by applying the install schemes.""" # it's the caller's problem if they supply a bad name! + if (hasattr(sys, 'pypy_version_info') and + not name.endswith(('_user', '_home'))): + if os.name == 'nt': + name = 'pypy_nt' + else: + name = 'pypy' scheme = INSTALL_SCHEMES[name] for key in SCHEME_KEYS: attrname = 'install_' + key From 12f74fb9280897a07199db0df76103487263136b Mon Sep 17 00:00:00 2001 From: mattip Date: Mon, 29 Jun 2020 20:00:07 +0300 Subject: [PATCH 2/5] do the minimum to fix sysconfig.py for PyPy, more will probably be needed --- distutils/sysconfig.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index 79391e8671..255243ade5 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -16,6 +16,8 @@ from .errors import DistutilsPlatformError +IS_PYPY = '__pypy__' in sys.builtin_module_names + # These are needed in a couple of spots, so just compute them once. PREFIX = os.path.normpath(sys.prefix) EXEC_PREFIX = os.path.normpath(sys.exec_prefix) @@ -97,7 +99,9 @@ def get_python_inc(plat_specific=0, prefix=None): """ if prefix is None: prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX - if os.name == "posix": + if IS_PYPY: + return os.path.join(prefix, 'include') + elif os.name == "posix": if python_build: # Assume the executable is in the build directory. The # pyconfig.h file should be in the same directory. Since From 50d17611942813f840a69c4838173b2c4dc27f24 Mon Sep 17 00:00:00 2001 From: mattip Date: Mon, 29 Jun 2020 20:23:28 +0300 Subject: [PATCH 3/5] no Makefile with PyPy and has own layout for python stdlib, site-packages --- distutils/sysconfig.py | 79 +++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index 255243ade5..879b6981ed 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -142,6 +142,14 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): If 'prefix' is supplied, use it instead of sys.base_prefix or sys.base_exec_prefix -- i.e., ignore 'plat_specific'. """ + if IS_PYPY: + # PyPy-specific schema + if prefix is None: + prefix = PREFIX + if standard_lib: + return os.path.join(prefix, "lib-python", sys.version[0]) + return os.path.join(prefix, 'site-packages') + if prefix is None: if standard_lib: prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX @@ -503,41 +511,42 @@ def get_config_vars(*args): _config_vars['prefix'] = PREFIX _config_vars['exec_prefix'] = EXEC_PREFIX - # For backward compatibility, see issue19555 - SO = _config_vars.get('EXT_SUFFIX') - if SO is not None: - _config_vars['SO'] = SO - - # Always convert srcdir to an absolute path - srcdir = _config_vars.get('srcdir', project_base) - if os.name == 'posix': - if python_build: - # If srcdir is a relative path (typically '.' or '..') - # then it should be interpreted relative to the directory - # containing Makefile. - base = os.path.dirname(get_makefile_filename()) - srcdir = os.path.join(base, srcdir) - else: - # srcdir is not meaningful since the installation is - # spread about the filesystem. We choose the - # directory containing the Makefile since we know it - # exists. - srcdir = os.path.dirname(get_makefile_filename()) - _config_vars['srcdir'] = os.path.abspath(os.path.normpath(srcdir)) - - # Convert srcdir into an absolute path if it appears necessary. - # Normally it is relative to the build directory. However, during - # testing, for example, we might be running a non-installed python - # from a different directory. - if python_build and os.name == "posix": - base = project_base - if (not os.path.isabs(_config_vars['srcdir']) and - base != os.getcwd()): - # srcdir is relative and we are not in the same directory - # as the executable. Assume executable is in the build - # directory and make srcdir absolute. - srcdir = os.path.join(base, _config_vars['srcdir']) - _config_vars['srcdir'] = os.path.normpath(srcdir) + if not IS_PYPY: + # For backward compatibility, see issue19555 + SO = _config_vars.get('EXT_SUFFIX') + if SO is not None: + _config_vars['SO'] = SO + + # Always convert srcdir to an absolute path + srcdir = _config_vars.get('srcdir', project_base) + if os.name == 'posix': + if python_build: + # If srcdir is a relative path (typically '.' or '..') + # then it should be interpreted relative to the directory + # containing Makefile. + base = os.path.dirname(get_makefile_filename()) + srcdir = os.path.join(base, srcdir) + else: + # srcdir is not meaningful since the installation is + # spread about the filesystem. We choose the + # directory containing the Makefile since we know it + # exists. + srcdir = os.path.dirname(get_makefile_filename()) + _config_vars['srcdir'] = os.path.abspath(os.path.normpath(srcdir)) + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if python_build and os.name == "posix": + base = project_base + if (not os.path.isabs(_config_vars['srcdir']) and + base != os.getcwd()): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _config_vars['srcdir']) + _config_vars['srcdir'] = os.path.normpath(srcdir) # OS X platforms require special customization to handle # multi-architecture, multi-os-version installers From 89d64e81e194d5b8b8a500e837b9cea4f2e1063e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 1 Jul 2020 22:09:26 -0400 Subject: [PATCH 4/5] Skip test on PyPy where the functionality is disabled. --- distutils/tests/test_sysconfig.py | 1 + 1 file changed, 1 insertion(+) diff --git a/distutils/tests/test_sysconfig.py b/distutils/tests/test_sysconfig.py index 236755d095..d5076391fc 100644 --- a/distutils/tests/test_sysconfig.py +++ b/distutils/tests/test_sysconfig.py @@ -45,6 +45,7 @@ def test_get_config_vars(self): self.assertIsInstance(cvars, dict) self.assertTrue(cvars) + @unittest.skip('sysconfig.IS_PYPY') def test_srcdir(self): # See Issues #15322, #15364. srcdir = sysconfig.get_config_var('srcdir') From c3a052aefbba0d5fda10790e676223c0dc12f0ed Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 2 Jul 2020 05:06:16 -0400 Subject: [PATCH 5/5] In test_unixcompiler.test_osx*, also patch sysconfig.get_config_vars following the patterns of prior implementations. --- distutils/tests/test_unixccompiler.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/distutils/tests/test_unixccompiler.py b/distutils/tests/test_unixccompiler.py index eef702cf01..f2159662fd 100644 --- a/distutils/tests/test_unixccompiler.py +++ b/distutils/tests/test_unixccompiler.py @@ -11,6 +11,7 @@ class UnixCCompilerTestCase(unittest.TestCase): def setUp(self): self._backup_platform = sys.platform self._backup_get_config_var = sysconfig.get_config_var + self._backup_get_config_vars = sysconfig.get_config_vars class CompilerWrapper(UnixCCompiler): def rpath_foo(self): return self.runtime_library_dir_option('/foo') @@ -19,6 +20,7 @@ def rpath_foo(self): def tearDown(self): sys.platform = self._backup_platform sysconfig.get_config_var = self._backup_get_config_var + sysconfig.get_config_vars = self._backup_get_config_vars @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") def test_runtime_libdir_option(self): @@ -110,7 +112,13 @@ def gcv(v): if v == 'LDSHARED': return 'gcc-4.2 -bundle -undefined dynamic_lookup ' return 'gcc-4.2' + + def gcvs(*args, _orig=sysconfig.get_config_vars): + if args: + return list(map(sysconfig.get_config_var, args)) + return _orig() sysconfig.get_config_var = gcv + sysconfig.get_config_vars = gcvs with EnvironmentVarGuard() as env: env['CC'] = 'my_cc' del env['LDSHARED'] @@ -126,7 +134,13 @@ def gcv(v): if v == 'LDSHARED': return 'gcc-4.2 -bundle -undefined dynamic_lookup ' return 'gcc-4.2' + + def gcvs(*args, _orig=sysconfig.get_config_vars): + if args: + return list(map(sysconfig.get_config_var, args)) + return _orig() sysconfig.get_config_var = gcv + sysconfig.get_config_vars = gcvs with EnvironmentVarGuard() as env: env['CC'] = 'my_cc' env['LDSHARED'] = 'my_ld -bundle -dynamic'