mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
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.
This commit is contained in:
parent
97100c0e3d
commit
a8723a02ea
5 changed files with 49 additions and 17 deletions
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue