summaryrefslogtreecommitdiffstats
path: root/Lib/inspect.py
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2015-04-14 22:41:29 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2015-04-14 22:41:29 (GMT)
commita8723a02ea109beabe2dfe1bbe18958afc5b7af9 (patch)
treebea4acb5ca96a4fd4387461f365f477eb77d5ced /Lib/inspect.py
parent97100c0e3d0e2bd907b41e5583b1f9cb6d9c1a36 (diff)
downloadcpython-a8723a02ea109beabe2dfe1bbe18958afc5b7af9.zip
cpython-a8723a02ea109beabe2dfe1bbe18958afc5b7af9.tar.gz
cpython-a8723a02ea109beabe2dfe1bbe18958afc5b7af9.tar.bz2
Issue #21217: inspect.getsourcelines() now tries to compute the start and
end lines from the code object, fixing an issue when a lambda function is used as decorator argument. Patch by Thomas Ballinger.
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r--Lib/inspect.py37
1 files changed, 23 insertions, 14 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 81b1ce8..60890f2 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -32,6 +32,7 @@ __author__ = ('Ka-Ping Yee <ping@lfw.org>',
'Yury Selivanov <yselivanov@sprymix.com>')
import ast
+import dis
import enum
import importlib.machinery
import itertools
@@ -49,18 +50,10 @@ from operator import attrgetter
from collections import namedtuple, OrderedDict
# Create constants for the compiler flags in Include/code.h
-# We try to get them from dis to avoid duplication, but fall
-# back to hard-coding so the dependency is optional
-try:
- from dis import COMPILER_FLAG_NAMES as _flag_names
-except ImportError:
- CO_OPTIMIZED, CO_NEWLOCALS = 0x1, 0x2
- CO_VARARGS, CO_VARKEYWORDS = 0x4, 0x8
- CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40
-else:
- mod_dict = globals()
- for k, v in _flag_names.items():
- mod_dict["CO_" + v] = k
+# We try to get them from dis to avoid duplication
+mod_dict = globals()
+for k, v in dis.COMPILER_FLAG_NAMES.items():
+ mod_dict["CO_" + v] = k
# See Include/object.h
TPFLAGS_IS_ABSTRACT = 1 << 20
@@ -888,6 +881,14 @@ def getblock(lines):
pass
return lines[:blockfinder.last]
+def _line_number_helper(code_obj, lines, lnum):
+ """Return a list of source lines and starting line number for a code object.
+
+ The arguments must be a code object with lines and lnum from findsource.
+ """
+ _, end_line = list(dis.findlinestarts(code_obj))[-1]
+ return lines[lnum:end_line], lnum + 1
+
def getsourcelines(object):
"""Return a list of source lines and starting line number for an object.
@@ -899,8 +900,16 @@ def getsourcelines(object):
object = unwrap(object)
lines, lnum = findsource(object)
- if ismodule(object): return lines, 0
- else: return getblock(lines[lnum:]), lnum + 1
+ if ismodule(object):
+ return lines, 0
+ elif iscode(object):
+ return _line_number_helper(object, lines, lnum)
+ elif isfunction(object):
+ return _line_number_helper(object.__code__, lines, lnum)
+ elif ismethod(object):
+ return _line_number_helper(object.__func__.__code__, lines, lnum)
+ else:
+ return getblock(lines[lnum:]), lnum + 1
def getsource(object):
"""Return the text of the source code for an object.