diff -r 0f10e0b3e76d Doc/library/sys.rst --- a/Doc/library/sys.rst Thu Oct 01 00:53:09 2015 +0200 +++ b/Doc/library/sys.rst Thu Oct 01 01:15:06 2015 +0200 @@ -124,6 +124,14 @@ always available. defined here, and may change. +.. data:: debug_build + + :const:`True` if the Python executable was compiled in debug mode, + :const:`False` if it was compiled in release mode. + + .. versionadded:: 3.6 + + .. data:: dllhandle Integer specifying the handle of the Python DLL. Availability: Windows. diff -r 0f10e0b3e76d Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst Thu Oct 01 00:53:09 2015 +0200 +++ b/Doc/whatsnew/3.6.rst Thu Oct 01 01:15:06 2015 +0200 @@ -102,6 +102,11 @@ operator indexers. For example: ``subscript[0:10:2] == slice(0, 10, 2)`` (Contributed by Joe Jevnik in :issue:`24379`.) +operator +-------- + +* New variable :data:`sys.debug_build`: :const:`True` if the Python executable + was compiled in debug mode, `False` if it was compiled in release mode. rlcomplete ---------- diff -r 0f10e0b3e76d Lib/distutils/command/build.py --- a/Lib/distutils/command/build.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/distutils/command/build.py Thu Oct 01 01:15:06 2015 +0200 @@ -86,7 +86,7 @@ class build(Command): # Make it so Python 2.x and Python 2.x with --with-pydebug don't # share the same build directories. Doing so confuses the build # process for C modules - if hasattr(sys, 'gettotalrefcount'): + if sys.debug_build: plat_specifier += '-pydebug' # 'build_purelib' and 'build_platlib' just default to 'lib' and diff -r 0f10e0b3e76d Lib/distutils/tests/test_build.py --- a/Lib/distutils/tests/test_build.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/distutils/tests/test_build.py Thu Oct 01 01:15:06 2015 +0200 @@ -28,7 +28,7 @@ class BuildTestCase(support.TempdirManag # examples: # build/lib.macosx-10.3-i386-2.7 plat_spec = '.%s-%s' % (cmd.plat_name, sys.version[0:3]) - if hasattr(sys, 'gettotalrefcount'): + if sys.debug_build: self.assertTrue(cmd.build_platlib.endswith('-pydebug')) plat_spec += '-pydebug' wanted = os.path.join(cmd.build_base, 'lib' + plat_spec) diff -r 0f10e0b3e76d Lib/sysconfig.py --- a/Lib/sysconfig.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/sysconfig.py Thu Oct 01 01:15:06 2015 +0200 @@ -382,7 +382,7 @@ def _generate_posix_vars(): sys.modules[name] = module pybuilddir = 'build/lib.%s-%s' % (get_platform(), sys.version[:3]) - if hasattr(sys, "gettotalrefcount"): + if sys.debug_build: pybuilddir += '-pydebug' os.makedirs(pybuilddir, exist_ok=True) destfile = os.path.join(pybuilddir, name + '.py') diff -r 0f10e0b3e76d Lib/test/libregrtest/refleak.py --- a/Lib/test/libregrtest/refleak.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/libregrtest/refleak.py Thu Oct 01 01:15:06 2015 +0200 @@ -16,7 +16,7 @@ def dash_R(the_module, test, indirect_te import copyreg import collections.abc - if not hasattr(sys, 'gettotalrefcount'): + if not sys.debug_build: raise Exception("Tracking reference leaks requires a debug build " "of Python") diff -r 0f10e0b3e76d Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/support/__init__.py Thu Oct 01 01:15:06 2015 +0200 @@ -1446,7 +1446,7 @@ def python_is_optimized(): _header = 'nP' _align = '0n' -if hasattr(sys, "gettotalrefcount"): +if sys.debug_build: _header = '2P' + _header _align = '0P' _vheader = _header + 'n' diff -r 0f10e0b3e76d Lib/test/test_capi.py --- a/Lib/test/test_capi.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/test_capi.py Thu Oct 01 01:15:06 2015 +0200 @@ -23,9 +23,6 @@ except ImportError: # Skip this test if the _testcapi module isn't available. _testcapi = support.import_module('_testcapi') -# Were we compiled --with-pydebug or with #define Py_DEBUG? -Py_DEBUG = hasattr(sys, 'gettotalrefcount') - def testfunction(self): """some doc""" @@ -179,7 +176,7 @@ class CAPITest(unittest.TestCase): def test_return_null_without_error(self): # Issue #23571: A function must not return NULL without setting an # error - if Py_DEBUG: + if sys.debug_build: code = textwrap.dedent(""" import _testcapi from test import support @@ -206,7 +203,7 @@ class CAPITest(unittest.TestCase): def test_return_result_with_error(self): # Issue #23571: A function must not return a result with an error set - if Py_DEBUG: + if sys.debug_build: code = textwrap.dedent(""" import _testcapi from test import support diff -r 0f10e0b3e76d Lib/test/test_cmd_line.py --- a/Lib/test/test_cmd_line.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/test_cmd_line.py Thu Oct 01 01:15:06 2015 +0200 @@ -96,7 +96,7 @@ class CmdLineTest(unittest.TestCase): # "-X showrefcount" shows the refcount, but only in debug builds rc, out, err = run_python('-X', 'showrefcount', '-c', code) self.assertEqual(out.rstrip(), b"{'showrefcount': True}") - if hasattr(sys, 'gettotalrefcount'): # debug build + if sys.debug_build: self.assertRegex(err, br'^\[\d+ refs, \d+ blocks\]') else: self.assertEqual(err, b'') diff -r 0f10e0b3e76d Lib/test/test_hashlib.py --- a/Lib/test/test_hashlib.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/test_hashlib.py Thu Oct 01 01:15:06 2015 +0200 @@ -20,9 +20,6 @@ import warnings from test import support from test.support import _4G, bigmemtest, import_fresh_module -# Were we compiled --with-pydebug or with #define Py_DEBUG? -COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') - c_hashlib = import_fresh_module('hashlib', fresh=['_hashlib']) py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib']) @@ -41,7 +38,7 @@ class HashLibTestCase(unittest.TestCase) 'sha384', 'SHA384', 'sha512', 'SHA512') # Issue #14693: fallback modules are always compiled under POSIX - _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG + _warn_on_extension_import = os.name == 'posix' or sys.debug_build def _conditional_import_module(self, module_name): """Import a module and return a reference to it or None on failure.""" diff -r 0f10e0b3e76d Lib/test/test_marshal.py --- a/Lib/test/test_marshal.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/test_marshal.py Thu Oct 01 01:15:06 2015 +0200 @@ -192,7 +192,7 @@ class BugsTestCase(unittest.TestCase): # Create a deeply nested structure. head = last = [] # The max stack depth should match the value in Python/marshal.c. - if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'): + if os.name == 'nt' and sys.debug_build: MAX_MARSHAL_STACK_DEPTH = 1000 else: MAX_MARSHAL_STACK_DEPTH = 2000 diff -r 0f10e0b3e76d Lib/test/test_regrtest.py --- a/Lib/test/test_regrtest.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/test_regrtest.py Thu Oct 01 01:15:06 2015 +0200 @@ -494,7 +494,7 @@ class ProgramsTestCase(BaseTestCase): test_args = [] if platform.architecture()[0] == '64bit': test_args.append('-x64') # 64-bit build - if not Py_DEBUG: + if not sys.debug_build: test_args.append('+d') # Release build, use python.exe self.run_batch(script, *test_args, *self.tests) @@ -505,7 +505,7 @@ class ProgramsTestCase(BaseTestCase): rt_args = ["-q"] # Quick, don't run tests twice if platform.architecture()[0] == '64bit': rt_args.append('-x64') # 64-bit build - if Py_DEBUG: + if sys.debug_build: rt_args.append('-d') # Debug build, use python_d.exe self.run_batch(script, *rt_args, *self.regrtest_args, *self.tests) diff -r 0f10e0b3e76d Lib/test/test_sys.py --- a/Lib/test/test_sys.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/test/test_sys.py Thu Oct 01 01:15:06 2015 +0200 @@ -769,6 +769,15 @@ class SysModuleTest(unittest.TestCase): rc, stdout, stderr = assert_python_ok('-c', code) self.assertEqual(stdout.rstrip(), b'True') + def test_debug_build(self): + self.assertIsInstance(sys.debug_build, bool) + + @test.support.cpython_only + def test_debug_build_cpython(self): + self.assertEqual(sys.debug_build, + # Py_DEBUG implies Py_TRACE_REFS + hasattr(sys, 'getobjects')) + @test.support.cpython_only class SizeofTest(unittest.TestCase): diff -r 0f10e0b3e76d Lib/warnings.py --- a/Lib/warnings.py Thu Oct 01 00:53:09 2015 +0200 +++ b/Lib/warnings.py Thu Oct 01 01:15:06 2015 +0200 @@ -426,7 +426,7 @@ if not _warnings_defaults: bytes_action = "ignore" simplefilter(bytes_action, category=BytesWarning, append=1) # resource usage warnings are enabled by default in pydebug mode - if hasattr(sys, 'gettotalrefcount'): + if sys.debug_build: resource_action = "always" else: resource_action = "ignore" diff -r 0f10e0b3e76d Python/sysmodule.c --- a/Python/sysmodule.c Thu Oct 01 00:53:09 2015 +0200 +++ b/Python/sysmodule.c Thu Oct 01 01:15:06 2015 +0200 @@ -1795,6 +1795,12 @@ PyObject * PyLong_FromLong(0x10FFFF)); SET_SYS_FROM_STRING("builtin_module_names", list_builtin_module_names()); +#ifdef Py_DEBUG + SET_SYS_FROM_STRING("debug_build", PyBool_FromLong(1)); +#else + SET_SYS_FROM_STRING("debug_build", PyBool_FromLong(0)); +#endif + #if PY_BIG_ENDIAN SET_SYS_FROM_STRING("byteorder", PyUnicode_FromString("big"));