# HG changeset patch # Parent a970054a93fb0861edef6c6701b37ba6f5772ac8 Issues #15322, #15364: Fix sysconfig.get_config_var('srcdir') Make sysconfig.get_config_var('srcdir') and the distutils equivalent return absolute paths. diff -r a970054a93fb Lib/distutils/sysconfig.py --- a/Lib/distutils/sysconfig.py Mon Jul 16 18:30:03 2012 +0100 +++ b/Lib/distutils/sysconfig.py Wed Jul 18 13:25:35 2012 +0100 @@ -541,19 +541,22 @@ _config_vars['prefix'] = PREFIX _config_vars['exec_prefix'] = EXEC_PREFIX - # 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 = os.path.dirname(os.path.abspath(sys.executable)) - 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) + # 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)) if sys.platform == 'darwin': from distutils.spawn import find_executable diff -r a970054a93fb Lib/distutils/tests/test_sysconfig.py --- a/Lib/distutils/tests/test_sysconfig.py Mon Jul 16 18:30:03 2012 +0100 +++ b/Lib/distutils/tests/test_sysconfig.py Wed Jul 18 13:25:35 2012 +0100 @@ -53,6 +53,35 @@ self.assertTrue(isinstance(cvars, dict)) self.assertTrue(cvars) + def test_srcdir(self): + # See Issues #15322, #15364. + srcdir = sysconfig.get_config_var('srcdir') + + self.assertTrue(os.path.isabs(srcdir), srcdir) + self.assertTrue(os.path.isdir(srcdir), srcdir) + + if sysconfig.python_build: + # The python executable has not been installed so srcdir + # should be a full source checkout. + Python_h = os.path.join(srcdir, 'Include', 'Python.h') + self.assertTrue(os.path.exists(Python_h), Python_h) + self.assertTrue(sysconfig._is_python_source_dir(srcdir)) + elif os.name == 'posix': + makefile_dir = os.path.dirname(sysconfig.get_makefile_filename()) + self.assertEqual(makefile_dir, srcdir) + + def test_srcdir_independent_of_cwd(self): + # srcdir should be independent of the current working directory + # See Issues #15322, #15364. + srcdir = sysconfig.get_config_var('srcdir') + cwd = os.getcwd() + try: + os.chdir('..') + srcdir2 = sysconfig.get_config_var('srcdir') + finally: + os.chdir(cwd) + self.assertEqual(srcdir, srcdir2) + def test_customize_compiler(self): # not testing if default compiler is not unix diff -r a970054a93fb Lib/sysconfig.py --- a/Lib/sysconfig.py Mon Jul 16 18:30:03 2012 +0100 +++ b/Lib/sysconfig.py Wed Jul 18 13:25:35 2012 +0100 @@ -533,28 +533,22 @@ # the init-function. _CONFIG_VARS['userbase'] = _getuserbase() - if 'srcdir' not in _CONFIG_VARS: - _CONFIG_VARS['srcdir'] = _PROJECT_BASE - else: - _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['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 - try: - cwd = os.getcwd() - except OSError: - cwd = None - if (not os.path.isabs(_CONFIG_VARS['srcdir']) and - base != cwd): - # 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) + # 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'] = _safe_realpath(srcdir) if sys.platform == 'darwin': kernel_version = os.uname().release # Kernel version (8.4.3) diff -r a970054a93fb Lib/test/test_sysconfig.py --- a/Lib/test/test_sysconfig.py Mon Jul 16 18:30:03 2012 +0100 +++ b/Lib/test/test_sysconfig.py Wed Jul 18 13:25:35 2012 +0100 @@ -332,6 +332,35 @@ self.assertEqual(status, 0) self.assertEqual(my_platform, test_platform) + def test_srcdir(self): + # See Issues #15322, #15364. + srcdir = sysconfig.get_config_var('srcdir') + + self.assertTrue(os.path.isabs(srcdir), srcdir) + self.assertTrue(os.path.isdir(srcdir), srcdir) + + if sysconfig._PYTHON_BUILD: + # The python executable has not been installed so srcdir + # should be a full source checkout. + Python_h = os.path.join(srcdir, 'Include', 'Python.h') + self.assertTrue(os.path.exists(Python_h), Python_h) + self.assertTrue(sysconfig._is_python_source_dir(srcdir)) + elif os.name == 'posix': + makefile_dir = os.path.dirname(sysconfig.get_makefile_filename()) + self.assertEqual(makefile_dir, srcdir) + + def test_srcdir_independent_of_cwd(self): + # srcdir should be independent of the current working directory + # See Issues #15322, #15364. + srcdir = sysconfig.get_config_var('srcdir') + cwd = os.getcwd() + try: + os.chdir('..') + srcdir2 = sysconfig.get_config_var('srcdir') + finally: + os.chdir(cwd) + self.assertEqual(srcdir, srcdir2) + class MakefileTests(unittest.TestCase):