aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_argparse.py2
-rw-r--r--Lib/test/test_cext/__init__.py47
-rw-r--r--Lib/test/test_cext/extension.c20
-rw-r--r--Lib/test/test_cext/setup.py33
-rw-r--r--Lib/test/test_cppext/__init__.py24
-rw-r--r--Lib/test/test_cppext/extension.cpp9
-rw-r--r--Lib/test/test_cppext/setup.py4
-rw-r--r--Lib/test/test_dictcomps.py2
-rw-r--r--Lib/test/test_enum.py37
-rw-r--r--Lib/test/test_setcomps.py2
-rw-r--r--Lib/test/test_tempfile.py24
-rw-r--r--Lib/test/test_zipfile/_path/test_path.py2
12 files changed, 144 insertions, 62 deletions
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 08ff41368d9..ddd48b1bc0c 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1829,7 +1829,7 @@ BIN_STDERR_SENTINEL = object()
class StdStreamComparer:
def __init__(self, attr):
# We try to use the actual stdXXX.buffer attribute as our
- # marker, but but under some test environments,
+ # marker, but under some test environments,
# sys.stdout/err are replaced by io.StringIO which won't have .buffer,
# so we use a sentinel simply to show that the tests do the right thing
# for any buffer supporting object
diff --git a/Lib/test/test_cext/__init__.py b/Lib/test/test_cext/__init__.py
index 46fde541494..93e7b2043d3 100644
--- a/Lib/test/test_cext/__init__.py
+++ b/Lib/test/test_cext/__init__.py
@@ -28,29 +28,13 @@ SETUP = os.path.join(os.path.dirname(__file__), 'setup.py')
@support.requires_venv_with_pip()
@support.requires_subprocess()
@support.requires_resource('cpu')
-class TestExt(unittest.TestCase):
+class BaseTests:
+ TEST_INTERNAL_C_API = False
+
# Default build with no options
def test_build(self):
self.check_build('_test_cext')
- def test_build_c11(self):
- self.check_build('_test_c11_cext', std='c11')
-
- @unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support /std:c99")
- def test_build_c99(self):
- # In public docs, we say C API is compatible with C11. However,
- # in practice we do maintain C99 compatibility in public headers.
- # Please ask the C API WG before adding a new C11-only feature.
- self.check_build('_test_c99_cext', std='c99')
-
- @support.requires_gil_enabled('incompatible with Free Threading')
- def test_build_limited(self):
- self.check_build('_test_limited_cext', limited=True)
-
- @support.requires_gil_enabled('broken for now with Free Threading')
- def test_build_limited_c11(self):
- self.check_build('_test_limited_c11_cext', limited=True, std='c11')
-
def check_build(self, extension_name, std=None, limited=False):
venv_dir = 'env'
with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe:
@@ -70,6 +54,7 @@ class TestExt(unittest.TestCase):
if limited:
env['CPYTHON_TEST_LIMITED'] = '1'
env['CPYTHON_TEST_EXT_NAME'] = extension_name
+ env['TEST_INTERNAL_C_API'] = str(int(self.TEST_INTERNAL_C_API))
if support.verbose:
print('Run:', ' '.join(map(shlex.quote, cmd)))
subprocess.run(cmd, check=True, env=env)
@@ -110,5 +95,29 @@ class TestExt(unittest.TestCase):
run_cmd('Import', cmd)
+class TestPublicCAPI(BaseTests, unittest.TestCase):
+ @support.requires_gil_enabled('incompatible with Free Threading')
+ def test_build_limited(self):
+ self.check_build('_test_limited_cext', limited=True)
+
+ @support.requires_gil_enabled('broken for now with Free Threading')
+ def test_build_limited_c11(self):
+ self.check_build('_test_limited_c11_cext', limited=True, std='c11')
+
+ def test_build_c11(self):
+ self.check_build('_test_c11_cext', std='c11')
+
+ @unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support /std:c99")
+ def test_build_c99(self):
+ # In public docs, we say C API is compatible with C11. However,
+ # in practice we do maintain C99 compatibility in public headers.
+ # Please ask the C API WG before adding a new C11-only feature.
+ self.check_build('_test_c99_cext', std='c99')
+
+
+class TestInteralCAPI(BaseTests, unittest.TestCase):
+ TEST_INTERNAL_C_API = True
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c
index 64629c5a6da..4be2f24c60d 100644
--- a/Lib/test/test_cext/extension.c
+++ b/Lib/test/test_cext/extension.c
@@ -1,11 +1,31 @@
// gh-116869: Basic C test extension to check that the Python C API
// does not emit C compiler warnings.
+//
+// Test also the internal C API if the TEST_INTERNAL_C_API macro is defined.
// Always enable assertions
#undef NDEBUG
+#ifdef TEST_INTERNAL_C_API
+# define Py_BUILD_CORE_MODULE 1
+#endif
+
#include "Python.h"
+#ifdef TEST_INTERNAL_C_API
+ // gh-135906: Check for compiler warnings in the internal C API.
+ // - Cython uses pycore_frame.h.
+ // - greenlet uses pycore_frame.h, pycore_interpframe_structs.h and
+ // pycore_interpframe.h.
+# include "internal/pycore_frame.h"
+# include "internal/pycore_gc.h"
+# include "internal/pycore_interp.h"
+# include "internal/pycore_interpframe.h"
+# include "internal/pycore_interpframe_structs.h"
+# include "internal/pycore_object.h"
+# include "internal/pycore_pystate.h"
+#endif
+
#ifndef MODULE_NAME
# error "MODULE_NAME macro must be defined"
#endif
diff --git a/Lib/test/test_cext/setup.py b/Lib/test/test_cext/setup.py
index 1275282983f..587585e8086 100644
--- a/Lib/test/test_cext/setup.py
+++ b/Lib/test/test_cext/setup.py
@@ -14,10 +14,15 @@ SOURCE = 'extension.c'
if not support.MS_WINDOWS:
# C compiler flags for GCC and clang
- CFLAGS = [
+ BASE_CFLAGS = [
# The purpose of test_cext extension is to check that building a C
# extension using the Python C API does not emit C compiler warnings.
'-Werror',
+ ]
+
+ # C compiler flags for GCC and clang
+ PUBLIC_CFLAGS = [
+ *BASE_CFLAGS,
# gh-120593: Check the 'const' qualifier
'-Wcast-qual',
@@ -26,27 +31,40 @@ if not support.MS_WINDOWS:
'-pedantic-errors',
]
if not support.Py_GIL_DISABLED:
- CFLAGS.append(
+ PUBLIC_CFLAGS.append(
# gh-116869: The Python C API must be compatible with building
# with the -Werror=declaration-after-statement compiler flag.
'-Werror=declaration-after-statement',
)
+ INTERNAL_CFLAGS = [*BASE_CFLAGS]
else:
# MSVC compiler flags
- CFLAGS = [
- # Display warnings level 1 to 4
- '/W4',
+ BASE_CFLAGS = [
# Treat all compiler warnings as compiler errors
'/WX',
]
+ PUBLIC_CFLAGS = [
+ *BASE_CFLAGS,
+ # Display warnings level 1 to 4
+ '/W4',
+ ]
+ INTERNAL_CFLAGS = [
+ *BASE_CFLAGS,
+ # Display warnings level 1 to 3
+ '/W3',
+ ]
def main():
std = os.environ.get("CPYTHON_TEST_STD", "")
module_name = os.environ["CPYTHON_TEST_EXT_NAME"]
limited = bool(os.environ.get("CPYTHON_TEST_LIMITED", ""))
+ internal = bool(int(os.environ.get("TEST_INTERNAL_C_API", "0")))
- cflags = list(CFLAGS)
+ if not internal:
+ cflags = list(PUBLIC_CFLAGS)
+ else:
+ cflags = list(INTERNAL_CFLAGS)
cflags.append(f'-DMODULE_NAME={module_name}')
# Add -std=STD or /std:STD (MSVC) compiler flag
@@ -75,6 +93,9 @@ def main():
version = sys.hexversion
cflags.append(f'-DPy_LIMITED_API={version:#x}')
+ if internal:
+ cflags.append('-DTEST_INTERNAL_C_API=1')
+
# On Windows, add PCbuild\amd64\ to include and library directories
include_dirs = []
library_dirs = []
diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py
index 2b7adac4bcc..2f54b3ccb35 100644
--- a/Lib/test/test_cppext/__init__.py
+++ b/Lib/test/test_cppext/__init__.py
@@ -24,7 +24,7 @@ SETUP = os.path.join(os.path.dirname(__file__), 'setup.py')
@support.requires_venv_with_pip()
@support.requires_subprocess()
@support.requires_resource('cpu')
-class TestCPPExt(unittest.TestCase):
+class BaseTests:
def test_build(self):
self.check_build('_testcppext')
@@ -34,10 +34,6 @@ class TestCPPExt(unittest.TestCase):
# Please ask the C API WG before adding a new C++11-only feature.
self.check_build('_testcpp03ext', std='c++03')
- @support.requires_gil_enabled('incompatible with Free Threading')
- def test_build_limited_cpp03(self):
- self.check_build('_test_limited_cpp03ext', std='c++03', limited=True)
-
@unittest.skipIf(support.MS_WINDOWS, "MSVC doesn't support /std:c++11")
def test_build_cpp11(self):
self.check_build('_testcpp11ext', std='c++11')
@@ -48,10 +44,6 @@ class TestCPPExt(unittest.TestCase):
def test_build_cpp14(self):
self.check_build('_testcpp14ext', std='c++14')
- @support.requires_gil_enabled('incompatible with Free Threading')
- def test_build_limited(self):
- self.check_build('_testcppext_limited', limited=True)
-
def check_build(self, extension_name, std=None, limited=False):
venv_dir = 'env'
with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe:
@@ -111,5 +103,19 @@ class TestCPPExt(unittest.TestCase):
run_cmd('Import', cmd)
+class TestPublicCAPI(BaseTests, unittest.TestCase):
+ @support.requires_gil_enabled('incompatible with Free Threading')
+ def test_build_limited_cpp03(self):
+ self.check_build('_test_limited_cpp03ext', std='c++03', limited=True)
+
+ @support.requires_gil_enabled('incompatible with Free Threading')
+ def test_build_limited(self):
+ self.check_build('_testcppext_limited', limited=True)
+
+
+class TestInteralCAPI(BaseTests, unittest.TestCase):
+ TEST_INTERNAL_C_API = True
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_cppext/extension.cpp b/Lib/test/test_cppext/extension.cpp
index 5b3571b295b..1affa176088 100644
--- a/Lib/test/test_cppext/extension.cpp
+++ b/Lib/test/test_cppext/extension.cpp
@@ -6,8 +6,17 @@
// Always enable assertions
#undef NDEBUG
+#ifdef TEST_INTERNAL_C_API
+# define Py_BUILD_CORE 1
+#endif
+
#include "Python.h"
+#ifdef TEST_INTERNAL_C_API
+ // gh-135906: Check for compiler warnings in the internal C API
+# include "internal/pycore_frame.h"
+#endif
+
#ifndef MODULE_NAME
# error "MODULE_NAME macro must be defined"
#endif
diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py
index ea1ed64bf7a..98442b106b6 100644
--- a/Lib/test/test_cppext/setup.py
+++ b/Lib/test/test_cppext/setup.py
@@ -47,6 +47,7 @@ def main():
std = os.environ.get("CPYTHON_TEST_CPP_STD", "")
module_name = os.environ["CPYTHON_TEST_EXT_NAME"]
limited = bool(os.environ.get("CPYTHON_TEST_LIMITED", ""))
+ internal = bool(int(os.environ.get("TEST_INTERNAL_C_API", "0")))
cppflags = list(CPPFLAGS)
cppflags.append(f'-DMODULE_NAME={module_name}')
@@ -82,6 +83,9 @@ def main():
version = sys.hexversion
cppflags.append(f'-DPy_LIMITED_API={version:#x}')
+ if internal:
+ cppflags.append('-DTEST_INTERNAL_C_API=1')
+
# On Windows, add PCbuild\amd64\ to include and library directories
include_dirs = []
library_dirs = []
diff --git a/Lib/test/test_dictcomps.py b/Lib/test/test_dictcomps.py
index 26b56dac503..a7a46216787 100644
--- a/Lib/test/test_dictcomps.py
+++ b/Lib/test/test_dictcomps.py
@@ -132,7 +132,7 @@ class DictComprehensionTest(unittest.TestCase):
def test_exception_locations(self):
# The location of an exception raised from __init__ or
- # __next__ should should be the iterator expression
+ # __next__ should be the iterator expression
def init_raises():
try:
{x:x for x in BrokenIter(init_raises=True)}
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index bbc7630fa83..2dd585f246d 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -1002,12 +1002,18 @@ class _FlagTests:
self.assertIs(~(A|B), OpenAB(252))
self.assertIs(~AB_MASK, OpenAB(0))
self.assertIs(~OpenAB(0), AB_MASK)
+ self.assertIs(OpenAB(~4), OpenAB(251))
else:
self.assertIs(~A, B)
self.assertIs(~B, A)
+ self.assertIs(OpenAB(~1), B)
+ self.assertIs(OpenAB(~2), A)
self.assertIs(~(A|B), OpenAB(0))
self.assertIs(~AB_MASK, OpenAB(0))
self.assertIs(~OpenAB(0), (A|B))
+ self.assertIs(OpenAB(~3), OpenAB(0))
+ self.assertIs(OpenAB(~4), OpenAB(3))
+ self.assertIs(OpenAB(~33), B)
#
class OpenXYZ(self.enum_type):
X = 4
@@ -1031,6 +1037,9 @@ class _FlagTests:
self.assertIs(~X, Y|Z)
self.assertIs(~Y, X|Z)
self.assertIs(~Z, X|Y)
+ self.assertIs(OpenXYZ(~4), Y|Z)
+ self.assertIs(OpenXYZ(~2), X|Z)
+ self.assertIs(OpenXYZ(~1), X|Y)
self.assertIs(~(X|Y), Z)
self.assertIs(~(X|Z), Y)
self.assertIs(~(Y|Z), X)
@@ -1038,6 +1047,28 @@ class _FlagTests:
self.assertIs(~XYZ_MASK, OpenXYZ(0))
self.assertTrue(~OpenXYZ(0), (X|Y|Z))
+ def test_assigned_negative_value(self):
+ class X(self.enum_type):
+ A = auto()
+ B = auto()
+ C = A | B
+ D = ~A
+ self.assertEqual(list(X), [X.A, X.B])
+ self.assertIs(~X.A, X.B)
+ self.assertIs(X.D, X.B)
+ self.assertEqual(X.D.value, 2)
+ #
+ class Y(self.enum_type):
+ A = auto()
+ B = auto()
+ C = A | B
+ D = ~A
+ E = auto()
+ self.assertEqual(list(Y), [Y.A, Y.B, Y.E])
+ self.assertIs(~Y.A, Y.B|Y.E)
+ self.assertIs(Y.D, Y.B|Y.E)
+ self.assertEqual(Y.D.value, 6)
+
class TestPlainEnumClass(_EnumTests, _PlainOutputTests, unittest.TestCase):
enum_type = Enum
@@ -3680,6 +3711,8 @@ class OldTestFlag(unittest.TestCase):
C = 4 | B
#
self.assertTrue(SkipFlag.C in (SkipFlag.A|SkipFlag.C))
+ self.assertTrue(SkipFlag.B in SkipFlag.C)
+ self.assertIs(SkipFlag(~1), SkipFlag.B)
self.assertRaisesRegex(ValueError, 'SkipFlag.. invalid value 42', SkipFlag, 42)
#
class SkipIntFlag(enum.IntFlag):
@@ -3688,6 +3721,8 @@ class OldTestFlag(unittest.TestCase):
C = 4 | B
#
self.assertTrue(SkipIntFlag.C in (SkipIntFlag.A|SkipIntFlag.C))
+ self.assertTrue(SkipIntFlag.B in SkipIntFlag.C)
+ self.assertIs(SkipIntFlag(~1), SkipIntFlag.B|SkipIntFlag.C)
self.assertEqual(SkipIntFlag(42).value, 42)
#
class MethodHint(Flag):
@@ -4727,6 +4762,8 @@ class TestVerify(unittest.TestCase):
BLUE = 4
WHITE = -1
# no error means success
+ self.assertEqual(list(Color.WHITE), [Color.RED, Color.GREEN, Color.BLUE])
+ self.assertEqual(Color.WHITE.value, 7)
class TestInternals(unittest.TestCase):
diff --git a/Lib/test/test_setcomps.py b/Lib/test/test_setcomps.py
index 0bb02ef11f6..6fc5bb74036 100644
--- a/Lib/test/test_setcomps.py
+++ b/Lib/test/test_setcomps.py
@@ -154,7 +154,7 @@ We also repeat each of the above scoping tests inside a function
class SetComprehensionTest(unittest.TestCase):
def test_exception_locations(self):
# The location of an exception raised from __init__ or
- # __next__ should should be the iterator expression
+ # __next__ should be the iterator expression
def init_raises():
try:
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index aeca62cf256..52b13b98cbc 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -1594,30 +1594,6 @@ if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
mock_close.assert_called()
self.assertEqual(os.listdir(dir), [])
- @os_helper.skip_unless_hardlink
- @unittest.skipUnless(tempfile._O_TMPFILE_WORKS, 'need os.O_TMPFILE')
- @unittest.skipUnless(os.path.exists('/proc/self/fd'),
- 'need /proc/self/fd')
- def test_link_tmpfile(self):
- dir = tempfile.mkdtemp()
- self.addCleanup(os_helper.rmtree, dir)
- filename = os.path.join(dir, "link")
-
- with tempfile.TemporaryFile('w', dir=dir) as tmp:
- # the flag can become False on Linux <= 3.11
- if not tempfile._O_TMPFILE_WORKS:
- self.skipTest("O_TMPFILE doesn't work")
-
- tmp.write("hello")
- tmp.flush()
- fd = tmp.fileno()
-
- os.link(f'/proc/self/fd/{fd}',
- filename,
- follow_symlinks=True)
- with open(filename) as fp:
- self.assertEqual(fp.read(), "hello")
-
# Helper for test_del_on_shutdown
class NulledModules:
diff --git a/Lib/test/test_zipfile/_path/test_path.py b/Lib/test/test_zipfile/_path/test_path.py
index 696134023a5..958a586b0dc 100644
--- a/Lib/test/test_zipfile/_path/test_path.py
+++ b/Lib/test/test_zipfile/_path/test_path.py
@@ -316,7 +316,7 @@ class TestPath(unittest.TestCase):
HUGE_ZIPFILE_NUM_ENTRIES = 2**13
def huge_zipfile(self):
- """Create a read-only zipfile with a huge number of entries entries."""
+ """Create a read-only zipfile with a huge number of entries."""
strm = io.BytesIO()
zf = zipfile.ZipFile(strm, "w")
for entry in map(str, range(self.HUGE_ZIPFILE_NUM_ENTRIES)):