Skip to content

Commit e6222d2

Browse files
FFY00mgorny
authored andcommitted
tests: add test for the Python build config
Signed-off-by: Filipe Laíns <[email protected]>
1 parent bd20380 commit e6222d2

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed
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: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import pickle
1414
import zipfile, tarfile
1515
import sys
16+
import sysconfig
1617
from unittest import mock, SkipTest, skipIf, skipUnless, expectedFailure
1718
from contextlib import contextmanager
1819
from glob import glob
@@ -3055,6 +3056,88 @@ def test_pkg_config_libdir(self):
30553056
self.wipe()
30563057
self.init(testdir, extra_args=['-Dstart_native=true'], override_envvars=env)
30573058

3059+
@skipIf(is_windows(), 'POSIX only')
3060+
def test_python_build_config_extensions(self):
3061+
testdir = os.path.join(self.unit_test_dir,
3062+
'125 python extension')
3063+
3064+
VERSION_INFO_KEYS = ('major', 'minor', 'micro', 'releaselevel', 'serial')
3065+
EXTENSION_SUFFIX = '.extension-suffix.so'
3066+
STABLE_ABI_SUFFIX = '.stable-abi-suffix.so'
3067+
3068+
python_build_config = {
3069+
'schema_version': '1.0',
3070+
'base_interpreter': sys.executable,
3071+
'base_prefix': '/usr',
3072+
'platform': sysconfig.get_platform(),
3073+
'language': {
3074+
'version': sysconfig.get_python_version(),
3075+
'version_info': {key: getattr(sys.version_info, key) for key in VERSION_INFO_KEYS}
3076+
},
3077+
'implementation': {
3078+
attr: (
3079+
getattr(sys.implementation, attr)
3080+
if attr != 'version' else
3081+
{key: getattr(sys.implementation.version, key) for key in VERSION_INFO_KEYS}
3082+
)
3083+
for attr in dir(sys.implementation)
3084+
if not attr.startswith('__')
3085+
},
3086+
'abi': {
3087+
'flags': [],
3088+
'extension_suffix': EXTENSION_SUFFIX,
3089+
'stable_abi_suffix': STABLE_ABI_SUFFIX,
3090+
},
3091+
'suffixes': {
3092+
'source': ['.py'],
3093+
'bytecode': ['.pyc'],
3094+
'optimized_bytecode': ['.pyc'],
3095+
'debug_bytecode': ['.pyc'],
3096+
'extensions': [EXTENSION_SUFFIX, STABLE_ABI_SUFFIX, '.so'],
3097+
},
3098+
'libpython': {
3099+
'dynamic': sysconfig.get_config_var('LDLIBRARY'),
3100+
'dynamic_stableabi': sysconfig.get_config_var('PY3LIBRARY'),
3101+
'static': sysconfig.get_config_var('LIBRARY'),
3102+
'link_extensions': True,
3103+
},
3104+
'c_api': {
3105+
'headers': sysconfig.get_path('include'),
3106+
'pkgconfig_path': sysconfig.get_config_var('LIBPC'),
3107+
}
3108+
}
3109+
with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as python_build_config_file:
3110+
json.dump(python_build_config, fp=python_build_config_file)
3111+
3112+
with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as cross_file:
3113+
cross_file.write(
3114+
textwrap.dedent(f'''
3115+
[binaries]
3116+
pkg-config = 'pkg-config'
3117+
3118+
[built-in options]
3119+
python.build_config = '{python_build_config_file.name}'
3120+
'''.strip())
3121+
)
3122+
cross_file.flush()
3123+
3124+
intro_installed_file = os.path.join(self.builddir, 'meson-info', 'intro-installed.json')
3125+
expected_files = [
3126+
os.path.join(self.builddir, 'foo' + EXTENSION_SUFFIX),
3127+
os.path.join(self.builddir, 'foo_stable' + STABLE_ABI_SUFFIX),
3128+
]
3129+
3130+
for extra_args in (
3131+
['--python.build-config', python_build_config_file.name],
3132+
['--cross-file', cross_file.name],
3133+
):
3134+
with self.subTest(extra_args=extra_args):
3135+
self.init(testdir, extra_args=extra_args)
3136+
with open(intro_installed_file) as f:
3137+
intro_installed = json.load(f)
3138+
self.assertEqual(expected_files, list(intro_installed))
3139+
self.wipe()
3140+
30583141
def __reconfigure(self):
30593142
# Set an older version to force a reconfigure from scratch
30603143
filename = os.path.join(self.privatedir, 'coredata.dat')

0 commit comments

Comments
 (0)