mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
154 lines
6.3 KiB
Python
154 lines
6.3 KiB
Python
import sys
|
|
import unittest
|
|
import sysconfig
|
|
|
|
from test.support import subTests
|
|
from test.support import import_helper
|
|
|
|
_testcapi = import_helper.import_module('_testcapi')
|
|
|
|
|
|
class Test_ABIInfo_Check(unittest.TestCase):
|
|
@subTests('modname', (None, 'test_mod'))
|
|
def test_zero(self, modname):
|
|
_testcapi.pyabiinfo_check(modname, 0, 0, 0, 0, 0)
|
|
_testcapi.pyabiinfo_check(modname, 1, 0, 0, 0, 0)
|
|
|
|
def test_large_major_version(self):
|
|
with self.assertRaisesRegex(ImportError,
|
|
'^PyABIInfo version too high$'):
|
|
_testcapi.pyabiinfo_check(None, 2, 0, 0, 0, 0)
|
|
with self.assertRaisesRegex(ImportError,
|
|
'^test_mod: PyABIInfo version too high$'):
|
|
_testcapi.pyabiinfo_check("test_mod", 2, 0, 0, 0, 0)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
def test_large_minor_version(self, modname):
|
|
_testcapi.pyabiinfo_check(modname, 1, 2, 0, 0, 0)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('major', (0, 1))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
def test_positive_regular(self, modname, major, minor, build):
|
|
ver = sys.hexversion
|
|
truncated = ver & 0xffff0000
|
|
filled = truncated | 0x12b8
|
|
maxed = truncated | 0xffff
|
|
for abi_version in (0, ver, truncated, filled, maxed):
|
|
with self.subTest(abi_version=abi_version):
|
|
_testcapi.pyabiinfo_check(modname, major, minor, 0,
|
|
build, abi_version)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
@subTests('offset', (+0x00010000, -0x00010000))
|
|
def test_negative_regular(self, modname, minor, build, offset):
|
|
ver = sys.hexversion + offset
|
|
truncated = ver & 0xffff0000
|
|
filled = truncated | 0x12b8
|
|
maxed = truncated | 0xffff
|
|
for abi_version in (ver, truncated, filled, maxed):
|
|
with self.subTest(abi_version=abi_version):
|
|
with self.assertRaisesRegex(
|
|
ImportError,
|
|
r'incompatible ABI version \(3\.\d+\)$'):
|
|
_testcapi.pyabiinfo_check(modname, 1, minor, 0,
|
|
build,
|
|
abi_version)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('major', (0, 1))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
@subTests('abi_version', (
|
|
0,
|
|
0x03020000,
|
|
sys.hexversion,
|
|
sys.hexversion & 0xffff0000,
|
|
sys.hexversion - 0x00010000,
|
|
))
|
|
def test_positive_stable(self, modname, major, minor, build, abi_version):
|
|
_testcapi.pyabiinfo_check(modname, major, minor,
|
|
_testcapi.PyABIInfo_STABLE,
|
|
build,
|
|
abi_version)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
@subTests('abi_version_and_msg', (
|
|
(1, 'invalid'),
|
|
(3, 'invalid'),
|
|
(0x0301ffff, 'invalid'),
|
|
((sys.hexversion & 0xffff0000) + 0x00010000, 'incompatible future'),
|
|
(sys.hexversion + 0x00010000, 'incompatible future'),
|
|
(0x04000000, 'incompatible future'),
|
|
))
|
|
def test_negative_stable(self, modname, minor, build, abi_version_and_msg):
|
|
abi_version, msg = abi_version_and_msg
|
|
with self.assertRaisesRegex(
|
|
ImportError,
|
|
rf'{msg} stable ABI version \(\d+\.\d+\)$'):
|
|
_testcapi.pyabiinfo_check(modname, 1, minor,
|
|
_testcapi.PyABIInfo_STABLE,
|
|
build,
|
|
abi_version)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('major', (0, 1))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
@subTests('abi_version', (0, sys.hexversion))
|
|
def test_positive_internal(self, modname, major, minor, build, abi_version):
|
|
_testcapi.pyabiinfo_check(modname, major, minor,
|
|
_testcapi.PyABIInfo_INTERNAL,
|
|
build,
|
|
abi_version)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
@subTests('abi_version', (
|
|
sys.hexversion - 0x00010000,
|
|
sys.hexversion - 1,
|
|
sys.hexversion + 1,
|
|
sys.hexversion + 0x00010000,
|
|
))
|
|
def test_negative_internal(self, modname, minor, build, abi_version):
|
|
with self.assertRaisesRegex(
|
|
ImportError,
|
|
r'incompatible internal ABI \(0x[\da-f]+ != 0x[\da-f]+\)$'):
|
|
_testcapi.pyabiinfo_check(modname, 1, minor,
|
|
_testcapi.PyABIInfo_INTERNAL,
|
|
build,
|
|
abi_version)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
@subTests('ft_flag', (
|
|
0,
|
|
(_testcapi.PyABIInfo_FREETHREADED
|
|
if sysconfig.get_config_var("Py_GIL_DISABLED")
|
|
else _testcapi.PyABIInfo_GIL),
|
|
_testcapi.PyABIInfo_FREETHREADING_AGNOSTIC,
|
|
))
|
|
def test_positive_freethreading(self, modname, minor, build, ft_flag):
|
|
self.assertEqual(ft_flag & _testcapi.PyABIInfo_FREETHREADING_AGNOSTIC,
|
|
ft_flag)
|
|
_testcapi.pyabiinfo_check(modname, 1, minor, ft_flag, build, 0)
|
|
|
|
@subTests('modname', (None, 'test_mod'))
|
|
@subTests('minor', (0, 1, 9))
|
|
@subTests('build', (0, sys.hexversion))
|
|
def test_negative_freethreading(self, modname, minor, build):
|
|
if sysconfig.get_config_var("Py_GIL_DISABLED"):
|
|
ft_flag = _testcapi.PyABIInfo_GIL
|
|
msg = "incompatible with free-threaded CPython"
|
|
else:
|
|
ft_flag = _testcapi.PyABIInfo_FREETHREADED
|
|
msg = "only compatible with free-threaded CPython"
|
|
with self.assertRaisesRegex(ImportError, msg):
|
|
_testcapi.pyabiinfo_check(modname, 1, minor, ft_flag, build, 0)
|