Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ec5db53

Browse filesBrowse files
authored
gh-94751: Install, import and run the test C++ extension (MVP) (GH-94754)
This is a quick-and-dirty way to run the C++ tests. It can definitely be improved in the future, but it should fail when things go wrong. - Run test functions on import (yes, this can definitely be improved) - Fudge setuptools metadata (name & version) to make the extension installable - Install and import the extension in test_cppext
1 parent cfafd3a commit ec5db53
Copy full SHA for ec5db53

File tree

Expand file treeCollapse file tree

3 files changed

+56
-17
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+56
-17
lines changed

‎Lib/test/_testcppext.cpp

Copy file name to clipboardExpand all lines: Lib/test/_testcppext.cpp
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ static PyMethodDef _testcppext_methods[] = {
128128
{"add", _testcppext_add, METH_VARARGS, _testcppext_add_doc},
129129
{"test_api_casts", test_api_casts, METH_NOARGS, _Py_NULL},
130130
{"test_unicode", test_unicode, METH_NOARGS, _Py_NULL},
131+
// Note: _testcppext_exec currently runs all test functions directly.
132+
// When adding a new one, add a call there.
133+
131134
{_Py_NULL, _Py_NULL, 0, _Py_NULL} /* sentinel */
132135
};
133136

@@ -138,6 +141,17 @@ _testcppext_exec(PyObject *module)
138141
if (PyModule_AddIntMacro(module, __cplusplus) < 0) {
139142
return -1;
140143
}
144+
145+
PyObject *result;
146+
147+
result = PyObject_CallMethod(module, "test_api_casts", "");
148+
if (!result) return -1;
149+
Py_DECREF(result);
150+
151+
result = PyObject_CallMethod(module, "test_unicode", "");
152+
if (!result) return -1;
153+
Py_DECREF(result);
154+
141155
return 0;
142156
}
143157

‎Lib/test/setup_testcppext.py

Copy file name to clipboardExpand all lines: Lib/test/setup_testcppext.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def main():
4646
sources=[SOURCE],
4747
language='c++',
4848
extra_compile_args=cppflags)
49-
setup(name=name, ext_modules=[cpp_ext])
49+
setup(name='internal' + name, version='0.0', ext_modules=[cpp_ext])
5050

5151

5252
if __name__ == "__main__":

‎Lib/test/test_cppext.py

Copy file name to clipboardExpand all lines: Lib/test/test_cppext.py
+41-16Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@
1717
@support.requires_subprocess()
1818
class TestCPPExt(unittest.TestCase):
1919
def test_build_cpp11(self):
20-
self.check_build(False)
20+
self.check_build(False, '_testcpp11ext')
2121

2222
def test_build_cpp03(self):
23-
self.check_build(True)
23+
self.check_build(True, '_testcpp03ext')
2424

2525
# With MSVC, the linker fails with: cannot open file 'python311.lib'
2626
# https://github.com/python/cpython/pull/32175#issuecomment-1111175897
2727
@unittest.skipIf(MS_WINDOWS, 'test fails on Windows')
2828
# the test uses venv+pip: skip if it's not available
2929
@support.requires_venv_with_pip()
30-
def check_build(self, std_cpp03):
30+
def check_build(self, std_cpp03, extension_name):
3131
# Build in a temporary directory
3232
with os_helper.temp_cwd():
33-
self._check_build(std_cpp03)
33+
self._check_build(std_cpp03, extension_name)
3434

35-
def _check_build(self, std_cpp03):
35+
def _check_build(self, std_cpp03, extension_name):
3636
venv_dir = 'env'
3737
verbose = support.verbose
3838

@@ -52,22 +52,47 @@ def _check_build(self, std_cpp03):
5252
else:
5353
python = os.path.join(venv_dir, 'bin', python_exe)
5454

55+
def run_cmd(operation, cmd):
56+
if verbose:
57+
print('Run:', ' '.join(cmd))
58+
subprocess.run(cmd, check=True)
59+
else:
60+
proc = subprocess.run(cmd,
61+
stdout=subprocess.PIPE,
62+
stderr=subprocess.STDOUT,
63+
text=True)
64+
if proc.returncode:
65+
print(proc.stdout, end='')
66+
self.fail(
67+
f"{operation} failed with exit code {proc.returncode}")
68+
5569
# Build the C++ extension
5670
cmd = [python, '-X', 'dev',
5771
SETUP_TESTCPPEXT, 'build_ext', '--verbose']
5872
if std_cpp03:
5973
cmd.append('-std=c++03')
60-
if verbose:
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-
if proc.returncode:
69-
print(proc.stdout, end='')
70-
self.fail(f"Build failed with exit code {proc.returncode}")
74+
run_cmd('Build', cmd)
75+
76+
# Install the C++ extension
77+
cmd = [python, '-X', 'dev',
78+
SETUP_TESTCPPEXT, 'install']
79+
run_cmd('Install', cmd)
80+
81+
# Do a reference run. Until we test that running python
82+
# doesn't leak references (gh-94755), run it so one can manually check
83+
# -X showrefcount results against this baseline.
84+
cmd = [python,
85+
'-X', 'dev',
86+
'-X', 'showrefcount',
87+
'-c', 'pass']
88+
run_cmd('Reference run', cmd)
89+
90+
# Import the C++ extension
91+
cmd = [python,
92+
'-X', 'dev',
93+
'-X', 'showrefcount',
94+
'-c', f"import {extension_name}"]
95+
run_cmd('Import', cmd)
7196

7297

7398
if __name__ == "__main__":

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.