summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Ramacher <sramacher@debian.org>2015-07-03 09:34:00 +0200
committerSebastian Ramacher <sramacher@debian.org>2015-07-03 09:34:00 +0200
commit847d91b8791cff253103c657a7cb9ac4caa4e234 (patch)
tree6f42cd6c6e21ac2cbcb15ae6636310141f0f0e37
parent32bb6286b46da35dab1e29fc83f8ffe8fcb36e3f (diff)
Imported Upstream version 1.4.30
-rw-r--r--CHANGELOG7
-rw-r--r--PKG-INFO2
-rw-r--r--conftest.py20
-rw-r--r--py.egg-info/PKG-INFO2
-rw-r--r--py/__init__.py2
-rw-r--r--py/_code/source.py74
-rw-r--r--setup.py2
-rw-r--r--testing/code/test_source.py13
8 files changed, 52 insertions, 70 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 23314b4..b38276f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
==================================================
diff --git a/PKG-INFO b/PKG-INFO
index 6ff86ca..a0324b4 100644
--- a/PKG-INFO
+++ b/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/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
diff --git a/setup.py b/setup.py
index e36b55f..cef660e 100644
--- a/setup.py
+++ b/setup.py
@@ -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")