summaryrefslogtreecommitdiffstats
path: root/Lib/warnings.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-03-19 00:03:51 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-03-19 00:03:51 (GMT)
commit914cde89d4c94b0b9206d0fa22322a1142833a56 (patch)
tree7eed294f0da18437f719df470dbee278cfb40787 /Lib/warnings.py
parent1231a4615fd447f0988a72a134a1fc5e7d4e8d69 (diff)
downloadcpython-914cde89d4c94b0b9206d0fa22322a1142833a56.zip
cpython-914cde89d4c94b0b9206d0fa22322a1142833a56.tar.gz
cpython-914cde89d4c94b0b9206d0fa22322a1142833a56.tar.bz2
On ResourceWarning, log traceback where the object was allocated
Issue #26567: * Add a new function PyErr_ResourceWarning() function to pass the destroyed object * Add a source attribute to warnings.WarningMessage * Add warnings._showwarnmsg() which uses tracemalloc to get the traceback where source object was allocated.
Diffstat (limited to 'Lib/warnings.py')
-rw-r--r--Lib/warnings.py22
1 files changed, 18 insertions, 4 deletions
diff --git a/Lib/warnings.py b/Lib/warnings.py
index f54726a..1566065 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -2,6 +2,7 @@
import sys
+
__all__ = ["warn", "warn_explicit", "showwarning",
"formatwarning", "filterwarnings", "simplefilter",
"resetwarnings", "catch_warnings"]
@@ -66,6 +67,18 @@ def _formatwarnmsg(msg):
if line:
line = line.strip()
s += " %s\n" % line
+ if msg.source is not None:
+ import tracemalloc
+ tb = tracemalloc.get_object_traceback(msg.source)
+ if tb is not None:
+ s += 'Object allocated at (most recent call first):\n'
+ for frame in tb:
+ s += (' File "%s", lineno %s\n'
+ % (frame.filename, frame.lineno))
+ line = linecache.getline(frame.filename, frame.lineno)
+ if line:
+ line = line.strip()
+ s += ' %s\n' % line
return s
def filterwarnings(action, message="", category=Warning, module="", lineno=0,
@@ -267,7 +280,8 @@ def warn(message, category=None, stacklevel=1):
globals)
def warn_explicit(message, category, filename, lineno,
- module=None, registry=None, module_globals=None):
+ module=None, registry=None, module_globals=None,
+ source=None):
lineno = int(lineno)
if module is None:
module = filename or "<unknown>"
@@ -333,17 +347,17 @@ def warn_explicit(message, category, filename, lineno,
"Unrecognized action (%r) in warnings.filters:\n %s" %
(action, item))
# Print message and context
- msg = WarningMessage(message, category, filename, lineno)
+ msg = WarningMessage(message, category, filename, lineno, source)
_showwarnmsg(msg)
class WarningMessage(object):
_WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
- "line")
+ "line", "source")
def __init__(self, message, category, filename, lineno, file=None,
- line=None):
+ line=None, source=None):
local_values = locals()
for attr in self._WARNING_DETAILS:
setattr(self, attr, local_values[attr])