[Python-checkins] cpython: #17323: The "[X refs, Y blocks]" printed by debug builds has been disabled by

ezio.melotti python-checkins at python.org
Tue Mar 26 01:00:10 CET 2013


http://hg.python.org/cpython/rev/367167f93c30
changeset:   82956:367167f93c30
parent:      82954:5022ee7e13a2
user:        Ezio Melotti <ezio.melotti at gmail.com>
date:        Tue Mar 26 01:59:56 2013 +0200
summary:
  #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.

files:
  Doc/using/cmdline.rst     |  14 ++++++++++--
  Lib/test/test_cmd_line.py |  28 +++++++++++++++++++++++++++
  Misc/NEWS                 |   3 ++
  Python/pythonrun.c        |  24 +++++++++++++++++++---
  4 files changed, 62 insertions(+), 7 deletions(-)


diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -358,13 +358,21 @@
 .. cmdoption:: -X
 
    Reserved for various implementation-specific options.  CPython currently
-   defines just one, you can use ``-X faulthander`` to enable
-   :data:`faulthandler`. It also allows to pass arbitrary values and retrieve
-   them through the :data:`sys._xoptions` dictionary.
+   defines two possible values:
+
+   * ``-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
       It is now allowed to pass :option:`-X` with CPython.
 
+   .. versionadded:: 3.4
+      The ``-X showrefcount`` option.
+
 
 Options you shouldn't use
 ~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -62,6 +62,34 @@
         opts = eval(out.splitlines()[0])
         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):
         # Test expected operation of the '-m' switch
         # Switch needs an argument
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 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 #16475: Support object instancing, recursion and interned strings
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -35,13 +35,29 @@
 #define PATH_MAX MAXPATHLEN
 #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
 #define PRINT_TOTAL_REFS()
 #else /* Py_REF_DEBUG */
-#define PRINT_TOTAL_REFS() fprintf(stderr,                   \
-                   "[%" PY_FORMAT_SIZE_T "d refs, "          \
-                   "%" PY_FORMAT_SIZE_T "d blocks]\n",       \
-                   _Py_GetRefTotal(), _Py_GetAllocatedBlocks())
+#define PRINT_TOTAL_REFS() _print_total_refs()
 #endif
 
 #ifdef __cplusplus

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list