[svn r60141] refactor things such that all fallbacks to inspect.get/findsource happen in helpers in source.py
--HG-- branch : trunk
This commit is contained in:
parent
5c8b04dacb
commit
1a150e9050
|
@ -1,4 +1,5 @@
|
||||||
import py
|
import py
|
||||||
|
from py.__.code import source
|
||||||
|
|
||||||
class Code(object):
|
class Code(object):
|
||||||
""" wrapper around Python code objects """
|
""" wrapper around Python code objects """
|
||||||
|
@ -75,14 +76,8 @@ class Code(object):
|
||||||
def fullsource(self):
|
def fullsource(self):
|
||||||
""" return a py.code.Source object for the full source file of the code
|
""" return a py.code.Source object for the full source file of the code
|
||||||
"""
|
"""
|
||||||
fn = self.raw.co_filename
|
full, _ = source.findsource(self.raw)
|
||||||
try:
|
return full
|
||||||
return fn.__source__
|
|
||||||
except AttributeError:
|
|
||||||
path = self.path
|
|
||||||
if not isinstance(path, py.path.local):
|
|
||||||
return None
|
|
||||||
return py.code.Source(self.path.read(mode="rU"))
|
|
||||||
fullsource = property(fullsource, None, None,
|
fullsource = property(fullsource, None, None,
|
||||||
"full source containing this code object")
|
"full source containing this code object")
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,28 @@ def compile_(source, filename=None, mode='exec', flags=
|
||||||
class MyStr(str):
|
class MyStr(str):
|
||||||
""" custom string which allows to add attributes. """
|
""" custom string which allows to add attributes. """
|
||||||
|
|
||||||
|
def findsource(obj):
|
||||||
|
if hasattr(obj, 'func_code'):
|
||||||
|
obj = obj.func_code
|
||||||
|
elif hasattr(obj, 'f_code'):
|
||||||
|
obj = obj.f_code
|
||||||
|
try:
|
||||||
|
fullsource = obj.co_filename.__source__
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
sourcelines, lineno = py.std.inspect.findsource(obj)
|
||||||
|
except (KeyboardInterrupt, SystemExit):
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
return None, None
|
||||||
|
source = Source()
|
||||||
|
source.lines = map(str.rstrip, sourcelines)
|
||||||
|
return source, lineno
|
||||||
|
else:
|
||||||
|
lineno = obj.co_firstlineno - 1
|
||||||
|
return fullsource, lineno
|
||||||
|
|
||||||
|
|
||||||
def getsource(obj, **kwargs):
|
def getsource(obj, **kwargs):
|
||||||
if hasattr(obj, 'func_code'):
|
if hasattr(obj, 'func_code'):
|
||||||
obj = obj.func_code
|
obj = obj.func_code
|
||||||
|
@ -240,7 +262,7 @@ def getsource(obj, **kwargs):
|
||||||
else:
|
else:
|
||||||
lineno = obj.co_firstlineno - 1
|
lineno = obj.co_firstlineno - 1
|
||||||
end = fullsource.getblockend(lineno)
|
end = fullsource.getblockend(lineno)
|
||||||
return fullsource[lineno:end+1]
|
return Source(fullsource[lineno:end+1], deident=True)
|
||||||
|
|
||||||
|
|
||||||
def deindent(lines, offset=None):
|
def deindent(lines, offset=None):
|
||||||
|
|
|
@ -329,7 +329,7 @@ raise ValueError()
|
||||||
firstlineno = 5
|
firstlineno = 5
|
||||||
|
|
||||||
def fullsource(self):
|
def fullsource(self):
|
||||||
raise fail
|
return None
|
||||||
fullsource = property(fullsource)
|
fullsource = property(fullsource)
|
||||||
|
|
||||||
class FakeFrame(object):
|
class FakeFrame(object):
|
||||||
|
|
|
@ -314,3 +314,43 @@ def test_source_of_class_at_eof_without_newline():
|
||||||
path.write(source)
|
path.write(source)
|
||||||
s2 = py.code.Source(tmpdir.join("a.py").pyimport().A)
|
s2 = py.code.Source(tmpdir.join("a.py").pyimport().A)
|
||||||
assert str(source).strip() == str(s2).strip()
|
assert str(source).strip() == str(s2).strip()
|
||||||
|
|
||||||
|
if True:
|
||||||
|
def x():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_getsource_fallback():
|
||||||
|
from py.__.code.source import getsource
|
||||||
|
expected = """def x():
|
||||||
|
pass"""
|
||||||
|
src = getsource(x)
|
||||||
|
assert src == expected
|
||||||
|
|
||||||
|
def test_getsource___source__():
|
||||||
|
from py.__.code.source import getsource
|
||||||
|
x = py.code.compile("""if 1:
|
||||||
|
def x():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
|
||||||
|
expected = """def x():
|
||||||
|
pass"""
|
||||||
|
src = getsource(x)
|
||||||
|
assert src == expected
|
||||||
|
|
||||||
|
def test_findsource_fallback():
|
||||||
|
from py.__.code.source import findsource
|
||||||
|
src, lineno = findsource(x)
|
||||||
|
assert 'test_findsource_simple' in str(src)
|
||||||
|
assert src[lineno] == ' def x():'
|
||||||
|
|
||||||
|
def test_findsource___source__():
|
||||||
|
from py.__.code.source import findsource
|
||||||
|
x = py.code.compile("""if 1:
|
||||||
|
def x():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
|
||||||
|
src, lineno = findsource(x)
|
||||||
|
assert 'if 1:' in str(src)
|
||||||
|
assert src[lineno] == ' def x():'
|
||||||
|
|
|
@ -51,19 +51,9 @@ class TracebackEntry(object):
|
||||||
|
|
||||||
def getsource(self):
|
def getsource(self):
|
||||||
""" return failing source code. """
|
""" return failing source code. """
|
||||||
try:
|
|
||||||
source = self.frame.code.fullsource
|
source = self.frame.code.fullsource
|
||||||
except (IOError, py.error.ENOENT):
|
|
||||||
return None
|
|
||||||
if source is None:
|
if source is None:
|
||||||
try:
|
|
||||||
sourcelines, lineno = py.std.inspect.findsource(self.frame.code.raw)
|
|
||||||
except (KeyboardInterrupt, SystemExit):
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
return None
|
return None
|
||||||
source = py.code.Source()
|
|
||||||
source.lines = map(str.rstrip, sourcelines)
|
|
||||||
start = self.getfirstlinesource()
|
start = self.getfirstlinesource()
|
||||||
end = self.lineno
|
end = self.lineno
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -18,6 +18,7 @@ a tree of collectors and test items that this modules provides::
|
||||||
"""
|
"""
|
||||||
import py
|
import py
|
||||||
from py.__.test.collect import configproperty, warnoldcollect
|
from py.__.test.collect import configproperty, warnoldcollect
|
||||||
|
from py.__.code.source import findsource
|
||||||
|
|
||||||
class PyobjMixin(object):
|
class PyobjMixin(object):
|
||||||
def obj():
|
def obj():
|
||||||
|
@ -68,7 +69,7 @@ class PyobjMixin(object):
|
||||||
fspath = fn and py.path.local(fn) or None
|
fspath = fn and py.path.local(fn) or None
|
||||||
if fspath:
|
if fspath:
|
||||||
try:
|
try:
|
||||||
lines, lineno = py.std.inspect.findsource(self.obj)
|
_, lineno = findsource(self.obj)
|
||||||
except IOError:
|
except IOError:
|
||||||
lineno = None
|
lineno = None
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue