Skip to content

Commit e9deda3

Browse files
committed
tests: add test for the Python build config
Signed-off-by: Filipe Laíns <[email protected]>
1 parent 9b725a1 commit e9deda3

File tree

4 files changed

+177
-0
lines changed

4 files changed

+177
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"schema_version": "1.0",
3+
"base_interpreter": "/usr/bin/python",
4+
"base_prefix": "/usr",
5+
"platform": "linux-x86_64",
6+
"language": {
7+
"version": "3.14",
8+
"version_info": {
9+
"major": 3,
10+
"minor": 14,
11+
"micro": 0,
12+
"releaselevel": "alpha",
13+
"serial": 0
14+
}
15+
},
16+
"implementation": {
17+
"name": "cpython",
18+
"version": {
19+
"major": 3,
20+
"minor": 14,
21+
"micro": 0,
22+
"releaselevel": "alpha",
23+
"serial": 0
24+
},
25+
"hexversion": 51249312,
26+
"cache_tag": "cpython-314",
27+
"_multiarch": "x86_64-linux-gnu"
28+
},
29+
"abi": {
30+
"flags": ["t", "d"],
31+
"extension_suffix": ".cpython-314-x86_64-linux-gnu.so",
32+
"stable_abi_suffix": ".abi3.so"
33+
},
34+
"suffixes": {
35+
"source": [".py"],
36+
"bytecode": [".pyc"],
37+
"optimized_bytecode": [".pyc"],
38+
"debug_bytecode": [".pyc"],
39+
"extensions": [".cpython-314-x86_64-linux-gnu.so", ".abi3.so", ".so"]
40+
},
41+
"libpython": {
42+
"dynamic": "/usr/lib/libpython3.14.so.1.0",
43+
"dynamic_stableabi": "/usr/lib/libpython3.so",
44+
"static": "/usr/lib/python3.14/config-3.14-x86_64-linux-gnu/libpython3.14.a",
45+
"link_extensions": true
46+
},
47+
"c_api": {
48+
"headers": "/usr/include/python3.14",
49+
"pkgconfig_path": "/usr/lib/pkgconfig"
50+
}
51+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#define PY_SSIZE_T_CLEAN
2+
#include <Python.h>
3+
4+
5+
static PyObject *
6+
bar_impl(PyObject *self)
7+
{
8+
return Py_None;
9+
}
10+
11+
12+
static PyMethodDef foo_methods[] = {
13+
{"bar", bar_impl, METH_NOARGS, NULL},
14+
{NULL, NULL, 0, NULL} /* sentinel */
15+
};
16+
17+
18+
static struct PyModuleDef foo_module = {
19+
PyModuleDef_HEAD_INIT,
20+
"foo", /* m_name */
21+
NULL, /* m_doc */
22+
-1, /* m_size */
23+
foo_methods, /* m_methods */
24+
};
25+
26+
27+
PyMODINIT_FUNC
28+
PyInit_foo(void)
29+
{
30+
return PyModule_Create(&foo_module);
31+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
project('python extension', 'c')
2+
3+
py = import('python').find_installation('')
4+
5+
py.extension_module(
6+
'foo', 'foo.c',
7+
install: true,
8+
)
9+
10+
py.extension_module(
11+
'foo_stable', 'foo.c',
12+
install: true,
13+
limited_api: '3.2',
14+
)
15+

unittests/allplatformstests.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import pickle
1313
import zipfile, tarfile
1414
import sys
15+
import sysconfig
1516
from unittest import mock, SkipTest, skipIf, skipUnless
1617
from contextlib import contextmanager
1718
from glob import glob
@@ -2929,6 +2930,85 @@ def test_pkg_config_libdir(self):
29292930
self.wipe()
29302931
self.init(testdir, extra_args=['-Dstart_native=true'], override_envvars=env)
29312932

2933+
@skipIf(is_windows(), 'POSIX only')
2934+
def test_python_build_config_extensions(self):
2935+
testdir = os.path.join(self.unit_test_dir,
2936+
'125 python extension')
2937+
2938+
VERSION_INFO_KEYS = ('major', 'minor', 'micro', 'releaselevel', 'serial')
2939+
EXTENSION_SUFFIX = '.extension-suffix.so'
2940+
STABLE_ABI_SUFFIX = '.stable-abi-suffix.so'
2941+
2942+
python_build_config = {
2943+
'schema_version': '1.0',
2944+
'base_interpreter': sys.executable,
2945+
'base_prefix': '/usr',
2946+
'platform': sysconfig.get_platform(),
2947+
'language': {
2948+
'version': sysconfig.get_python_version(),
2949+
'version_info': {key: getattr(sys.version_info, key) for key in VERSION_INFO_KEYS}
2950+
},
2951+
'implementation': {
2952+
attr: (
2953+
getattr(sys.implementation, attr)
2954+
if attr != 'version' else
2955+
{key: getattr(sys.implementation.version, key) for key in VERSION_INFO_KEYS}
2956+
)
2957+
for attr in dir(sys.implementation)
2958+
if not attr.startswith('__')
2959+
},
2960+
'abi': {
2961+
'flags': [],
2962+
'extension_suffix': EXTENSION_SUFFIX,
2963+
'stable_abi_suffix': STABLE_ABI_SUFFIX,
2964+
},
2965+
'suffixes': {
2966+
'source': ['.py'],
2967+
'bytecode': ['.pyc'],
2968+
'optimized_bytecode': ['.pyc'],
2969+
'debug_bytecode': ['.pyc'],
2970+
'extensions': [EXTENSION_SUFFIX, STABLE_ABI_SUFFIX, '.so'],
2971+
},
2972+
'libpython': {
2973+
'dynamic': sysconfig.get_config_var('LDLIBRARY'),
2974+
'dynamic_stableabi': sysconfig.get_config_var('PY3LIBRARY'),
2975+
'static': sysconfig.get_config_var('LIBRARY'),
2976+
'link_extensions': True,
2977+
},
2978+
'c_api': {
2979+
'headers': sysconfig.get_path('include'),
2980+
'pkgconfig_path': sysconfig.get_config_var('LIBPC'),
2981+
}
2982+
}
2983+
with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as python_build_config_file:
2984+
json.dump(python_build_config, fp=python_build_config_file)
2985+
2986+
with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as cross_file:
2987+
cross_file.write(
2988+
textwrap.dedent(f'''
2989+
[properties]
2990+
python_build_config = '{python_build_config_file}'
2991+
'''.strip())
2992+
)
2993+
cross_file.flush()
2994+
2995+
intro_installed_file = os.path.join(self.builddir, 'meson-info', 'intro-installed.json')
2996+
expected_files = [
2997+
os.path.join(self.builddir, 'foo' + EXTENSION_SUFFIX),
2998+
os.path.join(self.builddir, 'foo_stable' + STABLE_ABI_SUFFIX),
2999+
]
3000+
3001+
for extra_args in (
3002+
['--python.build-config', python_build_config_file.name],
3003+
['--cross-file', cross_file.name],
3004+
):
3005+
with self.subTest(extra_args=extra_args):
3006+
self.init(testdir, extra_args=extra_args)
3007+
with open(intro_installed_file) as f:
3008+
intro_installed = json.load(f)
3009+
print(intro_installed.keys())
3010+
self.assertEqual(expected_files, list(intro_installed))
3011+
29323012
def __reconfigure(self):
29333013
# Set an older version to force a reconfigure from scratch
29343014
filename = os.path.join(self.privatedir, 'coredata.dat')

0 commit comments

Comments
 (0)