gh-91321: Fix compatibility with C++ older than C++11 (#93784) (#93802) · python/cpython@ef591cf

GitHub

@@ -1,91 +1,73 @@

11# gh-91321: Build a basic C++ test extension to check that the Python C API is

22# compatible with C++ and does not emit C++ compiler warnings.

3-importcontextlib

4-importos

3+importos.path

54importsys

65importunittest

7-importwarnings

6+importsubprocess

87fromtestimportsupport

98fromtest.supportimportos_helper

10911-withwarnings.catch_warnings():

12-warnings.simplefilter('ignore', DeprecationWarning)

13-fromdistutils.coreimportsetup, Extension

14-importdistutils.sysconfig

15-16101711MS_WINDOWS= (sys.platform=='win32')

1812191320-SOURCE=support.findfile('_testcppext.cpp')

21-ifnotMS_WINDOWS:

22-# C++ compiler flags for GCC and clang

23-CPPFLAGS= [

24-# Python currently targets C++11

25-'-std=c++11',

26-# gh-91321: The purpose of _testcppext extension is to check that building

27-# a C++ extension using the Python C API does not emit C++ compiler

28-# warnings

29-'-Werror',

30-# Warn on old-style cast (C cast) like: (PyObject*)op

31-'-Wold-style-cast',

32-# Warn when using NULL rather than _Py_NULL in static inline functions

33-'-Wzero-as-null-pointer-constant',

34- ]

35-else:

36-# Don't pass any compiler flag to MSVC

37-CPPFLAGS= []

14+SETUP_TESTCPPEXT=support.findfile('setup_testcppext.py')

[email protected]_subprocess()

4118classTestCPPExt(unittest.TestCase):

42-defbuild(self):

43-cpp_ext=Extension(

44-'_testcppext',

45-sources=[SOURCE],

46-language='c++',

47-extra_compile_args=CPPFLAGS)

48-capture_stdout= (notsupport.verbose)

19+deftest_build_cpp11(self):

20+self.check_build(False)

492150-try:

51-try:

52-ifcapture_stdout:

53-stdout=support.captured_stdout()

54-else:

55-print()

56-stdout=contextlib.nullcontext()

57-with (stdout,

58-support.swap_attr(sys, 'argv', ['setup.py', 'build_ext', '--verbose'])):

59-setup(name="_testcppext", ext_modules=[cpp_ext])

60-return

61-except:

62-ifcapture_stdout:

63-# Show output on error

64-print()

65-print(stdout.getvalue())

66-raise

67-exceptSystemExit:

68-self.fail("Build failed")

22+deftest_build_cpp03(self):

23+self.check_build(True)

69247025# With MSVC, the linker fails with: cannot open file 'python311.lib'

7126# https://github.com/python/cpython/pull/32175#issuecomment-1111175897

[email protected](MS_WINDOWS, 'test fails on Windows')

73-deftest_build(self):

74-# save/restore os.environ

75-defrestore_env(old_env):

76-os.environ.clear()

77-os.environ.update(old_env)

78-self.addCleanup(restore_env, dict(os.environ))

79-80-defrestore_sysconfig_vars(old_config_vars):

81-distutils.sysconfig._config_vars.clear()

82-distutils.sysconfig._config_vars.update(old_config_vars)

83-self.addCleanup(restore_sysconfig_vars,

84-dict(distutils.sysconfig._config_vars))

85-28+# the test uses venv+pip: skip if it's not available

[email protected]_venv_with_pip()

30+defcheck_build(self, std_cpp03):

8631# Build in a temporary directory

8732withos_helper.temp_cwd():

88-self.build()

33+self._check_build(std_cpp03)

34+35+def_check_build(self, std_cpp03):

36+venv_dir='env'

37+verbose=support.verbose

38+39+# Create virtual environment to get setuptools

40+cmd= [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir]

41+ifverbose:

42+print()

43+print('Run:', ' '.join(cmd))

44+subprocess.run(cmd, check=True)

45+46+# Get the Python executable of the venv

47+python_exe='python'

48+ifsys.executable.endswith('.exe'):

49+python_exe+='.exe'

50+ifMS_WINDOWS:

51+python=os.path.join(venv_dir, 'Scripts', python_exe)

52+else:

53+python=os.path.join(venv_dir, 'bin', python_exe)

54+55+# Build the C++ extension

56+cmd= [python, '-X', 'dev',

57+SETUP_TESTCPPEXT, 'build_ext', '--verbose']

58+ifstd_cpp03:

59+cmd.append('-std=c++03')

60+ifverbose:

61+print('Run:', ' '.join(cmd))

62+subprocess.run(cmd, check=True)

63+else:

64+proc=subprocess.run(cmd,

65+stdout=subprocess.PIPE,

66+stderr=subprocess.STDOUT,

67+text=True)

68+ifproc.returncode:

69+print(proc.stdout, end='')

70+self.fail(f"Build failed with exit code {proc.returncode}")

897190729173if__name__=="__main__":