diff --git a/CHANGELOG b/CHANGELOG index 620f90880..391897561 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ Bug fixes / Maintenance - fix pyimport() to work with directories - streamline py.path.local.mkdtemp implementation and usage - don't print empty lines when showing junitxml-filename +- fix py.code.compile(source) to generate unique filenames Changes between 1.3.0 and 1.3.1 ================================================== diff --git a/py/_code/source.py b/py/_code/source.py index 1eb4dcc86..87e61d4d1 100644 --- a/py/_code/source.py +++ b/py/_code/source.py @@ -17,6 +17,7 @@ class Source(object): """ a immutable object holding a source code fragment, possibly deindenting it. """ + _compilecounter = 0 def __init__(self, *parts, **kwargs): self.lines = lines = [] de = kwargs.get('deindent', True) @@ -195,10 +196,12 @@ class Source(object): if _genframe is None: _genframe = sys._getframe(1) # the caller fn,lineno = _genframe.f_code.co_filename, _genframe.f_lineno + base = "<%d-codegen " % self._compilecounter + self.__class__._compilecounter += 1 if not filename: - filename = '' % (fn, lineno) + filename = base + '%s:%d>' % (fn, lineno) else: - filename = '' % (filename, fn, lineno) + filename = base + '%r %s:%d>' % (filename, fn, lineno) source = "\n".join(self.lines) + '\n' try: co = cpy_compile(source, filename, mode, flag) diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 978915550..e333c2d7b 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -151,6 +151,22 @@ class TestSourceParsingAndCompiling: source = py.code.Source(co) assert str(source) == "x=3" + def test_compile_and_getsource_through_same_function(self): + def gensource(source): + return py.code.compile(source) + co1 = gensource(""" + def f(): + raise KeyError() + """) + co2 = gensource(""" + def f(): + raise ValueError() + """) + source1 = py.std.inspect.getsource(co1) + assert 'KeyError' in source1 + source2 = py.std.inspect.getsource(co2) + assert 'ValueError' in source2 + def test_getstatement(self): #print str(self.source) ass = str(self.source[1:]) @@ -229,11 +245,11 @@ class TestSourceParsingAndCompiling: def check(comp, name): co = comp(self.source, name) if not name: - expected = "" %(mypath, mylineno+2+1) + expected = "codegen %s:%d>" %(mypath, mylineno+2+1) else: - expected = "" % (name, mypath, mylineno+2+1) + expected = "codegen %r %s:%d>" % (name, mypath, mylineno+2+1) fn = co.co_filename - assert fn == expected + assert fn.endswith(expected) mycode = py.code.Code(self.test_compilefuncs_and_path_sanity) mylineno = mycode.firstlineno