Skip to content

Commit 5185956

Browse files
authored
gh-69443: Add test.support.Py_DEBUG constant (#93226)
1 parent ca58e4a commit 5185956

13 files changed

+45
-45
lines changed

Doc/library/test.rst

+9
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,15 @@ The :mod:`test.support` module defines the following constants:
319319
to make writes blocking.
320320

321321

322+
.. data:: Py_DEBUG
323+
324+
True if Python is built with the :c:macro:`Py_DEBUG` macro defined: if
325+
Python is :ref:`built in debug mode <debug-build>`
326+
(:option:`./configure --with-pydebug <--with-pydebug>`).
327+
328+
.. versionadded:: 3.12
329+
330+
322331
.. data:: SOCK_MAX_SIZE
323332

324333
A constant that is likely larger than the underlying OS socket buffer size,

Lib/test/support/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"run_with_tz", "PGO", "missing_compiler_executable",
6060
"ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST",
6161
"LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT",
62+
"Py_DEBUG",
6263
]
6364

6465

@@ -2205,3 +2206,8 @@ def requires_venv_with_pip():
22052206
except ImportError:
22062207
ctypes = None
22072208
return unittest.skipUnless(ctypes, 'venv: pip requires ctypes')
2209+
2210+
2211+
# True if Python is built with the Py_DEBUG macro defined: if
2212+
# Python is built in debug mode (./configure --with-pydebug).
2213+
Py_DEBUG = hasattr(sys, 'gettotalrefcount')

Lib/test/test_capi.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@
3636

3737
import _testinternalcapi
3838

39-
# Were we compiled --with-pydebug or with #define Py_DEBUG?
40-
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
41-
4239

4340
def decode_stderr(err):
4441
return err.decode('utf-8', 'replace').replace('\r', '')
@@ -230,7 +227,7 @@ def test_c_type_with_ipow(self):
230227
def test_return_null_without_error(self):
231228
# Issue #23571: A function must not return NULL without setting an
232229
# error
233-
if Py_DEBUG:
230+
if support.Py_DEBUG:
234231
code = textwrap.dedent("""
235232
import _testcapi
236233
from test import support
@@ -258,7 +255,7 @@ def test_return_null_without_error(self):
258255

259256
def test_return_result_with_error(self):
260257
# Issue #23571: A function must not return a result with an error set
261-
if Py_DEBUG:
258+
if support.Py_DEBUG:
262259
code = textwrap.dedent("""
263260
import _testcapi
264261
from test import support
@@ -516,7 +513,7 @@ def __del__(self):
516513
del subclass_instance
517514

518515
# Test that setting __class__ modified the reference counts of the types
519-
if Py_DEBUG:
516+
if support.Py_DEBUG:
520517
# gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference
521518
# to the type while calling tp_dealloc()
522519
self.assertEqual(type_refcnt, B.refcnt_in_del)
@@ -586,7 +583,7 @@ def test_c_subclass_of_heap_ctype_with_del_modifying_dunder_class_only_decrefs_o
586583
del subclass_instance
587584

588585
# Test that setting __class__ modified the reference counts of the types
589-
if Py_DEBUG:
586+
if support.Py_DEBUG:
590587
# gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference
591588
# to the type while calling tp_dealloc()
592589
self.assertEqual(type_refcnt, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del)
@@ -1029,7 +1026,7 @@ class PyMemPymallocDebugTests(PyMemDebugTests):
10291026
PYTHONMALLOC = 'pymalloc_debug'
10301027

10311028

1032-
@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG')
1029+
@unittest.skipUnless(support.Py_DEBUG, 'need Py_DEBUG')
10331030
class PyMemDefaultTests(PyMemDebugTests):
10341031
# test default allocator of Python compiled in debug mode
10351032
PYTHONMALLOC = ''

Lib/test/test_cmd_line.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
if not support.has_subprocess_support:
1919
raise unittest.SkipTest("test module requires subprocess")
2020

21-
# Debug build?
22-
Py_DEBUG = hasattr(sys, "gettotalrefcount")
23-
2421

2522
# XXX (ncoghlan): Move to script_helper and make consistent with run_python
2623
def _kill_python_and_exit_code(p):
@@ -120,7 +117,7 @@ def run_python(*args):
120117
# "-X showrefcount" shows the refcount, but only in debug builds
121118
rc, out, err = run_python('-I', '-X', 'showrefcount', '-c', code)
122119
self.assertEqual(out.rstrip(), b"{'showrefcount': True}")
123-
if Py_DEBUG:
120+
if support.Py_DEBUG:
124121
# bpo-46417: Tolerate negative reference count which can occur
125122
# because of bugs in C extensions. This test is only about checking
126123
# the showrefcount feature.
@@ -685,7 +682,7 @@ def test_xdev(self):
685682
code = ("import warnings; "
686683
"print(' '.join('%s::%s' % (f[0], f[2].__name__) "
687684
"for f in warnings.filters))")
688-
if Py_DEBUG:
685+
if support.Py_DEBUG:
689686
expected_filters = "default::Warning"
690687
else:
691688
expected_filters = ("default::Warning "
@@ -757,7 +754,7 @@ def test_warnings_filter_precedence(self):
757754
expected_filters = ("error::BytesWarning "
758755
"once::UserWarning "
759756
"always::UserWarning")
760-
if not Py_DEBUG:
757+
if not support.Py_DEBUG:
761758
expected_filters += (" "
762759
"default::DeprecationWarning "
763760
"ignore::DeprecationWarning "
@@ -795,10 +792,10 @@ def test_pythonmalloc(self):
795792
# Test the PYTHONMALLOC environment variable
796793
pymalloc = support.with_pymalloc()
797794
if pymalloc:
798-
default_name = 'pymalloc_debug' if Py_DEBUG else 'pymalloc'
795+
default_name = 'pymalloc_debug' if support.Py_DEBUG else 'pymalloc'
799796
default_name_debug = 'pymalloc_debug'
800797
else:
801-
default_name = 'malloc_debug' if Py_DEBUG else 'malloc'
798+
default_name = 'malloc_debug' if support.Py_DEBUG else 'malloc'
802799
default_name_debug = 'malloc_debug'
803800

804801
tests = [

Lib/test/test_embed.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
MS_WINDOWS = (os.name == 'nt')
2424
MACOS = (sys.platform == 'darwin')
25-
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
2625
PYMEM_ALLOCATOR_NOT_SET = 0
2726
PYMEM_ALLOCATOR_DEBUG = 2
2827
PYMEM_ALLOCATOR_MALLOC = 3
@@ -498,7 +497,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
498497
'pathconfig_warnings': 1,
499498
'_init_main': 1,
500499
'_isolated_interpreter': 0,
501-
'use_frozen_modules': not Py_DEBUG,
500+
'use_frozen_modules': not support.Py_DEBUG,
502501
'safe_path': 0,
503502
'_is_python_build': IGNORE_CONFIG,
504503
}
@@ -1206,7 +1205,7 @@ def test_init_setpath_config(self):
12061205
# The current getpath.c doesn't determine the stdlib dir
12071206
# in this case.
12081207
'stdlib_dir': '',
1209-
'use_frozen_modules': not Py_DEBUG,
1208+
'use_frozen_modules': not support.Py_DEBUG,
12101209
# overridden by PyConfig
12111210
'program_name': 'conf_program_name',
12121211
'base_executable': 'conf_executable',
@@ -1445,12 +1444,12 @@ def test_init_pyvenv_cfg(self):
14451444
config['base_prefix'] = pyvenv_home
14461445
config['prefix'] = pyvenv_home
14471446
config['stdlib_dir'] = os.path.join(pyvenv_home, 'Lib')
1448-
config['use_frozen_modules'] = not Py_DEBUG
1447+
config['use_frozen_modules'] = not support.Py_DEBUG
14491448
else:
14501449
# cannot reliably assume stdlib_dir here because it
14511450
# depends too much on our build. But it ought to be found
14521451
config['stdlib_dir'] = self.IGNORE_CONFIG
1453-
config['use_frozen_modules'] = not Py_DEBUG
1452+
config['use_frozen_modules'] = not support.Py_DEBUG
14541453

14551454
env = self.copy_paths_by_env(config)
14561455
self.check_all_configs("test_init_compat_config", config,
@@ -1680,7 +1679,7 @@ def test_frozenmain(self):
16801679
""").lstrip()
16811680
self.assertEqual(out, expected)
16821681

1683-
@unittest.skipUnless(hasattr(sys, 'gettotalrefcount'),
1682+
@unittest.skipUnless(support.Py_DEBUG,
16841683
'-X showrefcount requires a Python debug build')
16851684
def test_no_memleak(self):
16861685
# bpo-1635741: Python must release all memory at exit

Lib/test/test_hashlib.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
from test.support import warnings_helper
2727
from http.client import HTTPException
2828

29-
# Were we compiled --with-pydebug or with #define Py_DEBUG?
30-
COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount')
3129

3230
# default builtin hash module
3331
default_builtin_hashes = {'md5', 'sha1', 'sha256', 'sha512', 'sha3', 'blake2'}
@@ -109,7 +107,7 @@ class HashLibTestCase(unittest.TestCase):
109107
shakes = {'shake_128', 'shake_256'}
110108

111109
# Issue #14693: fallback modules are always compiled under POSIX
112-
_warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG
110+
_warn_on_extension_import = (os.name == 'posix' or support.Py_DEBUG)
113111

114112
def _conditional_import_module(self, module_name):
115113
"""Import a module and return a reference to it or None on failure."""

Lib/test/test_io.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class EmptyStruct(ctypes.Structure):
6868

6969
# Does io.IOBase finalizer log the exception if the close() method fails?
7070
# The exception is ignored silently by default in release build.
71-
IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode)
71+
IOBASE_EMITS_UNRAISABLE = (support.Py_DEBUG or sys.flags.dev_mode)
7272

7373

7474
def _default_chunk_size():

Lib/test/test_lltrace.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import textwrap
44
import unittest
55

6-
from test.support import os_helper, verbose
6+
from test import support
7+
from test.support import os_helper
78
from test.support.script_helper import assert_python_ok
89

910
def example():
@@ -14,9 +15,8 @@ def example():
1415
y = "an example"
1516
print(x, y)
1617

17-
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
1818

19-
@unittest.skipUnless(Py_DEBUG, "lltrace requires Py_DEBUG")
19+
@unittest.skipUnless(support.Py_DEBUG, "lltrace requires Py_DEBUG")
2020
class TestLLTrace(unittest.TestCase):
2121

2222
def run_code(self, code):
@@ -28,7 +28,7 @@ def run_code(self, code):
2828
self.assertEqual(stderr, b"")
2929
self.assertEqual(status, 0)
3030
result = stdout.decode('utf-8')
31-
if verbose:
31+
if support.verbose:
3232
print("\n\n--- code ---")
3333
print(code)
3434
print("\n--- stdout ---")

Lib/test/test_marshal.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def test_recursion_limit(self):
256256
# The max stack depth should match the value in Python/marshal.c.
257257
# BUG: https://bugs.python.org/issue33720
258258
# Windows always limits the maximum depth on release and debug builds
259-
#if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'):
259+
#if os.name == 'nt' and support.Py_DEBUG:
260260
if os.name == 'nt':
261261
MAX_MARSHAL_STACK_DEPTH = 1000
262262
else:

Lib/test/test_regrtest.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
if not support.has_subprocess_support:
2626
raise unittest.SkipTest("test module requires subprocess")
2727

28-
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
2928
ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..')
3029
ROOT_DIR = os.path.abspath(os.path.normpath(ROOT_DIR))
3130
LOG_PREFIX = r'[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?'
@@ -665,7 +664,7 @@ def test_tools_buildbot_test(self):
665664
test_args.append('-arm32') # 32-bit ARM build
666665
elif platform.architecture()[0] == '64bit':
667666
test_args.append('-x64') # 64-bit build
668-
if not Py_DEBUG:
667+
if not support.Py_DEBUG:
669668
test_args.append('+d') # Release build, use python.exe
670669
self.run_batch(script, *test_args, *self.tests)
671670

@@ -682,7 +681,7 @@ def test_pcbuild_rt(self):
682681
rt_args.append('-arm32') # 32-bit ARM build
683682
elif platform.architecture()[0] == '64bit':
684683
rt_args.append('-x64') # 64-bit build
685-
if Py_DEBUG:
684+
if support.Py_DEBUG:
686685
rt_args.append('-d') # Debug build, use python_d.exe
687686
self.run_batch(script, *rt_args, *self.regrtest_args, *self.tests)
688687

@@ -903,7 +902,7 @@ def check_leak(self, code, what):
903902
reflog = fp.read()
904903
self.assertIn(line2, reflog)
905904

906-
@unittest.skipUnless(Py_DEBUG, 'need a debug build')
905+
@unittest.skipUnless(support.Py_DEBUG, 'need a debug build')
907906
def test_huntrleaks(self):
908907
# test --huntrleaks
909908
code = textwrap.dedent("""
@@ -917,7 +916,7 @@ def test_leak(self):
917916
""")
918917
self.check_leak(code, 'references')
919918

920-
@unittest.skipUnless(Py_DEBUG, 'need a debug build')
919+
@unittest.skipUnless(support.Py_DEBUG, 'need a debug build')
921920
def test_huntrleaks_fd_leak(self):
922921
# test --huntrleaks for file descriptor leak
923922
code = textwrap.dedent("""

Lib/test/test_ssl.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838

3939
from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType
4040

41-
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
42-
Py_DEBUG_WIN32 = Py_DEBUG and sys.platform == 'win32'
41+
Py_DEBUG_WIN32 = support.Py_DEBUG and sys.platform == 'win32'
4342

4443
PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
4544
HOST = socket_helper.HOST
@@ -1657,7 +1656,8 @@ def test_load_default_certs_env(self):
16571656
self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})
16581657

16591658
@unittest.skipUnless(sys.platform == "win32", "Windows specific")
1660-
@unittest.skipIf(hasattr(sys, "gettotalrefcount"), "Debug build does not share environment between CRTs")
1659+
@unittest.skipIf(support.Py_DEBUG,
1660+
"Debug build does not share environment between CRTs")
16611661
def test_load_default_certs_env_windows(self):
16621662
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
16631663
ctx.load_default_certs()

Lib/test/test_threading.py

-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@
3333
# on platforms known to behave badly.
3434
platforms_to_skip = ('netbsd5', 'hp-ux11')
3535

36-
# Is Python built with Py_DEBUG macro defined?
37-
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
38-
3936

4037
def restore_default_excepthook(testcase):
4138
testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook)

Lib/test/test_warnings/__init__.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
c_warnings = import_helper.import_fresh_module('warnings',
2323
fresh=['_warnings'])
2424

25-
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
26-
2725
@contextmanager
2826
def warnings_state(module):
2927
"""Use a specific warnings implementation in warning_tests."""
@@ -1191,7 +1189,7 @@ def test_conflicting_envvar_and_command_line(self):
11911189

11921190
def test_default_filter_configuration(self):
11931191
pure_python_api = self.module is py_warnings
1194-
if Py_DEBUG:
1192+
if support.Py_DEBUG:
11951193
expected_default_filters = []
11961194
else:
11971195
if pure_python_api:

0 commit comments

Comments
 (0)