diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-14 22:41:29 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-14 22:41:29 (GMT) |
commit | a8723a02ea109beabe2dfe1bbe18958afc5b7af9 (patch) | |
tree | bea4acb5ca96a4fd4387461f365f477eb77d5ced /Lib/inspect.py | |
parent | 97100c0e3d0e2bd907b41e5583b1f9cb6d9c1a36 (diff) | |
download | cpython-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.py | 37 |
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. |