mirror of https://github.com/python/cpython
#17323: The "[X refs, Y blocks]" printed by debug builds has been disabled by default. It can be re-enabled with the `-X showrefcount` option.
This commit is contained in:
parent
84e4316489
commit
1f8898a591
|
@ -358,13 +358,21 @@ Miscellaneous options
|
||||||
.. cmdoption:: -X
|
.. cmdoption:: -X
|
||||||
|
|
||||||
Reserved for various implementation-specific options. CPython currently
|
Reserved for various implementation-specific options. CPython currently
|
||||||
defines just one, you can use ``-X faulthander`` to enable
|
defines two possible values:
|
||||||
:data:`faulthandler`. It also allows to pass arbitrary values and retrieve
|
|
||||||
them through the :data:`sys._xoptions` dictionary.
|
* ``-X faulthander`` to enable :mod:`faulthandler`;
|
||||||
|
* ``-X showrefcount`` to enable the output of the total reference count
|
||||||
|
and memory blocks (only works on debug builds);
|
||||||
|
|
||||||
|
It also allows to pass arbitrary values and retrieve them through the
|
||||||
|
:data:`sys._xoptions` dictionary.
|
||||||
|
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
It is now allowed to pass :option:`-X` with CPython.
|
It is now allowed to pass :option:`-X` with CPython.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
The ``-X showrefcount`` option.
|
||||||
|
|
||||||
|
|
||||||
Options you shouldn't use
|
Options you shouldn't use
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -62,6 +62,34 @@ class CmdLineTest(unittest.TestCase):
|
||||||
opts = eval(out.splitlines()[0])
|
opts = eval(out.splitlines()[0])
|
||||||
self.assertEqual(opts, {'a': True, 'b': 'c,d=e'})
|
self.assertEqual(opts, {'a': True, 'b': 'c,d=e'})
|
||||||
|
|
||||||
|
def test_showrefcount(self):
|
||||||
|
def run_python(*args):
|
||||||
|
# this is similar to assert_python_ok but doesn't strip
|
||||||
|
# the refcount from stderr. It can be replaced once
|
||||||
|
# assert_python_ok stops doing that.
|
||||||
|
cmd = [sys.executable]
|
||||||
|
cmd.extend(args)
|
||||||
|
PIPE = subprocess.PIPE
|
||||||
|
p = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||||
|
out, err = p.communicate()
|
||||||
|
p.stdout.close()
|
||||||
|
p.stderr.close()
|
||||||
|
rc = p.returncode
|
||||||
|
self.assertEqual(rc, 0)
|
||||||
|
return rc, out, err
|
||||||
|
code = 'import sys; print(sys._xoptions)'
|
||||||
|
# normally the refcount is hidden
|
||||||
|
rc, out, err = run_python('-c', code)
|
||||||
|
self.assertEqual(out.rstrip(), b'{}')
|
||||||
|
self.assertEqual(err, b'')
|
||||||
|
# "-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
|
||||||
|
self.assertRegex(err, br'^\[\d+ refs, \d+ blocks\]')
|
||||||
|
else:
|
||||||
|
self.assertEqual(err, b'')
|
||||||
|
|
||||||
def test_run_module(self):
|
def test_run_module(self):
|
||||||
# Test expected operation of the '-m' switch
|
# Test expected operation of the '-m' switch
|
||||||
# Switch needs an argument
|
# Switch needs an argument
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #17323: The "[X refs, Y blocks]" printed by debug builds has been
|
||||||
|
disabled by default. It can be re-enabled with the `-X showrefcount` option.
|
||||||
|
|
||||||
- Issue #17522: Add the PyGILState_Check() API.
|
- Issue #17522: Add the PyGILState_Check() API.
|
||||||
|
|
||||||
- Issue #16475: Support object instancing, recursion and interned strings
|
- Issue #16475: Support object instancing, recursion and interned strings
|
||||||
|
|
|
@ -35,13 +35,29 @@
|
||||||
#define PATH_MAX MAXPATHLEN
|
#define PATH_MAX MAXPATHLEN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Py_REF_DEBUG
|
||||||
|
void _print_total_refs() {
|
||||||
|
PyObject *xoptions, *key, *value;
|
||||||
|
xoptions = PySys_GetXOptions();
|
||||||
|
if (xoptions == NULL)
|
||||||
|
return;
|
||||||
|
key = PyUnicode_FromString("showrefcount");
|
||||||
|
if (key == NULL)
|
||||||
|
return;
|
||||||
|
value = PyDict_GetItem(xoptions, key);
|
||||||
|
Py_DECREF(key);
|
||||||
|
if (value == Py_True)
|
||||||
|
fprintf(stderr,
|
||||||
|
"[%" PY_FORMAT_SIZE_T "d refs, "
|
||||||
|
"%" PY_FORMAT_SIZE_T "d blocks]\n",
|
||||||
|
_Py_GetRefTotal(), _Py_GetAllocatedBlocks());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef Py_REF_DEBUG
|
#ifndef Py_REF_DEBUG
|
||||||
#define PRINT_TOTAL_REFS()
|
#define PRINT_TOTAL_REFS()
|
||||||
#else /* Py_REF_DEBUG */
|
#else /* Py_REF_DEBUG */
|
||||||
#define PRINT_TOTAL_REFS() fprintf(stderr, \
|
#define PRINT_TOTAL_REFS() _print_total_refs()
|
||||||
"[%" PY_FORMAT_SIZE_T "d refs, " \
|
|
||||||
"%" PY_FORMAT_SIZE_T "d blocks]\n", \
|
|
||||||
_Py_GetRefTotal(), _Py_GetAllocatedBlocks())
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue