diff options
author | Sebastian Ramacher <sramacher@debian.org> | 2015-07-03 09:34:00 +0200 |
---|---|---|
committer | Sebastian Ramacher <sramacher@debian.org> | 2015-07-03 09:34:00 +0200 |
commit | 847d91b8791cff253103c657a7cb9ac4caa4e234 (patch) | |
tree | 6f42cd6c6e21ac2cbcb15ae6636310141f0f0e37 | |
parent | 32bb6286b46da35dab1e29fc83f8ffe8fcb36e3f (diff) |
Imported Upstream version 1.4.30
-rw-r--r-- | CHANGELOG | 7 | ||||
-rw-r--r-- | PKG-INFO | 2 | ||||
-rw-r--r-- | conftest.py | 20 | ||||
-rw-r--r-- | py.egg-info/PKG-INFO | 2 | ||||
-rw-r--r-- | py/__init__.py | 2 | ||||
-rw-r--r-- | py/_code/source.py | 74 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | testing/code/test_source.py | 13 |
8 files changed, 52 insertions, 70 deletions
@@ -1,3 +1,10 @@ +1.4.30 +================================================== + +- fix issue68 an assert with a multiline list comprehension + was not reported correctly. Thanks Henrik Heibuerger. + + 1.4.29 ================================================== @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: py -Version: 1.4.29 +Version: 1.4.30 Summary: library with cross-python path, ini-parsing, io, code, log facilities Home-page: http://pylib.readthedocs.org/ Author: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others diff --git a/conftest.py b/conftest.py index a2d8760..11c2d44 100644 --- a/conftest.py +++ b/conftest.py @@ -14,26 +14,6 @@ def pytest_addoption(parser): group.addoption('--runslowtests', action="store_true", dest="runslowtests", default=False, help=("run slow tests")) - group.addoption('--lsof', - action="store_true", dest="lsof", default=False, - help=("run FD checks if lsof is available")) - -def pytest_configure(config): - if config.getvalue("lsof"): - try: - out = py.process.cmdexec("lsof -p %d" % pid) - except py.process.cmdexec.Error: - pass - else: - config._numfiles = len([x for x in out.split("\n") if "REG" in x]) - -def pytest_unconfigure(config, __multicall__): - if not hasattr(config, '_numfiles'): - return - __multicall__.execute() - out2 = py.process.cmdexec("lsof -p %d" % pid) - len2 = len([x for x in out2.split("\n") if "REG" in x]) - assert len2 < config._numfiles + 7, out2 def pytest_funcarg__sshhost(request): val = request.config.getvalue("sshhost") diff --git a/py.egg-info/PKG-INFO b/py.egg-info/PKG-INFO index 6ff86ca..a0324b4 100644 --- a/py.egg-info/PKG-INFO +++ b/py.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: py -Version: 1.4.29 +Version: 1.4.30 Summary: library with cross-python path, ini-parsing, io, code, log facilities Home-page: http://pylib.readthedocs.org/ Author: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others diff --git a/py/__init__.py b/py/__init__.py index fec8803..ba5ef6c 100644 --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ dictionary or an import path. (c) Holger Krekel and others, 2004-2014 """ -__version__ = '1.4.29' +__version__ = '1.4.30' from py import _apipkg diff --git a/py/_code/source.py b/py/_code/source.py index 18709af..3a648e6 100644 --- a/py/_code/source.py +++ b/py/_code/source.py @@ -1,4 +1,6 @@ from __future__ import generators + +from bisect import bisect_right import sys import inspect, tokenize import py @@ -314,45 +316,28 @@ def deindent(lines, offset=None): return newlines -def get_statement_startend(lineno, nodelist): - from bisect import bisect_right - # lineno starts at 0 - nextlineno = None - while 1: - lineno_list = [x.lineno-1 for x in nodelist] # ast indexes start at 1 - #print lineno_list, [vars(x) for x in nodelist] - insert_index = bisect_right(lineno_list, lineno) - if insert_index >= len(nodelist): - insert_index -= 1 - elif lineno < (nodelist[insert_index].lineno - 1) and insert_index > 0: - insert_index -= 1 - assert lineno >= (nodelist[insert_index].lineno - 1) - nextnode = nodelist[insert_index] - - try: - nextlineno = nodelist[insert_index+1].lineno - 1 - except IndexError: - pass - lastnodelist = nodelist - nodelist = getnodelist(nextnode) - if not nodelist: - start, end = nextnode.lineno-1, nextlineno - start = min(lineno, start) - assert start <= lineno and (end is None or lineno < end) - return start, end - -def getnodelist(node): - import _ast +def get_statement_startend2(lineno, node): + import ast + # flatten all statements and except handlers into one lineno-list + # AST's line numbers start indexing at 1 l = [] - #print "node", node, "fields", node._fields, "lineno", getattr(node, "lineno", 0) - 1 - for subname in "test", "type", "body", "handlers", "orelse", "finalbody": - attr = getattr(node, subname, None) - if attr is not None: - if isinstance(attr, list): - l.extend(attr) - elif hasattr(attr, "lineno"): - l.append(attr) - return l + for x in ast.walk(node): + if isinstance(x, _ast.stmt) or isinstance(x, _ast.ExceptHandler): + l.append(x.lineno - 1) + for name in "finalbody", "orelse": + val = getattr(x, name, None) + if val: + # treat the finally/orelse part as its own statement + l.append(val[0].lineno - 1 - 1) + l.sort() + insert_index = bisect_right(l, lineno) + start = l[insert_index - 1] + if insert_index >= len(l): + end = None + else: + end = l[insert_index] + return start, end + def getstatementrange_ast(lineno, source, assertion=False, astnode=None): if astnode is None: @@ -364,10 +349,9 @@ def getstatementrange_ast(lineno, source, assertion=False, astnode=None): except ValueError: start, end = getstatementrange_old(lineno, source, assertion) return None, start, end - start, end = get_statement_startend(lineno, getnodelist(astnode)) + start, end = get_statement_startend2(lineno, astnode) # we need to correct the end: # - ast-parsing strips comments - # - else statements do not have a separate lineno # - there might be empty lines # - we might have lesser indented code blocks at the end if end is None: @@ -383,15 +367,15 @@ def getstatementrange_ast(lineno, source, assertion=False, astnode=None): try: for tok in tokenize.generate_tokens(lambda: next(it)): block_finder.tokeneater(*tok) - except (inspect.EndOfBlock, IndentationError) as e: + except (inspect.EndOfBlock, IndentationError): end = block_finder.last + start - #except Exception: - # pass + except Exception: + pass - # the end might still point to a comment, correct it + # the end might still point to a comment or empty line, correct it while end: line = source.lines[end - 1].lstrip() - if line.startswith("#"): + if line.startswith("#") or not line: end -= 1 else: break @@ -7,7 +7,7 @@ def main(): name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.29', + version='1.4.30', url='http://pylib.readthedocs.org/', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 53095bc..830de2c 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -224,7 +224,6 @@ class TestSourceParsingAndCompiling: assert len(source) == 6 assert source.getstatementrange(2) == (1, 4) - @py.test.mark.xfail def test_getstatementrange_bug2(self): source = Source("""\ assert ( @@ -240,6 +239,18 @@ class TestSourceParsingAndCompiling: assert len(source) == 9 assert source.getstatementrange(5) == (0, 9) + def test_getstatementrange_ast_issue58(self): + source = Source("""\ + + def test_some(): + for a in [a for a in + CAUSE_ERROR]: pass + + x = 3 + """) + assert getstatement(2, source).lines == source.lines[2:3] + assert getstatement(3, source).lines == source.lines[3:4] + @py.test.mark.skipif("sys.version_info < (2,6)") def test_getstatementrange_out_of_bounds_py3(self): source = Source("if xxx:\n from .collections import something") |