From 0e777a6ef5ef28ac830116a16fbc047af202c86a Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 28 Jan 2020 00:20:22 +0100 Subject: [PATCH 1/5] typing: fix _pytest._code.source.getfslineno: returns str; assignment Fixes: > src/_pytest/_code/source.py:309: error: Incompatible types in > assignment (expression has type "Union[local, str]", variable has type > "Optional[local]") [assignment] --- src/_pytest/_code/source.py | 10 ++++------ testing/code/test_source.py | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index 379393b10cd..99b6c785034 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -8,6 +8,7 @@ from bisect import bisect_right from types import CodeType from types import FrameType +from typing import Any from typing import Iterator from typing import List from typing import Optional @@ -282,7 +283,7 @@ def compile_( # noqa: F811 return s.compile(filename, mode, flags, _genframe=_genframe) -def getfslineno(obj) -> Tuple[Optional[Union["Literal['']", py.path.local]], int]: +def getfslineno(obj: Any) -> Tuple[Optional[Union[str, py.path.local]], int]: """ Return source location (path, lineno) for the given object. If the source cannot be determined return ("", -1). @@ -292,6 +293,7 @@ def getfslineno(obj) -> Tuple[Optional[Union["Literal['']", py.path.local]], int try: code = Code(obj) + return code.path, code.firstlineno except TypeError: try: fn = inspect.getsourcefile(obj) or inspect.getfile(obj) @@ -305,11 +307,7 @@ def getfslineno(obj) -> Tuple[Optional[Union["Literal['']", py.path.local]], int _, lineno = findsource(obj) except IOError: pass - else: - fspath = code.path - lineno = code.firstlineno - assert isinstance(lineno, int) - return fspath, lineno + return fspath, lineno # diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 030e6067625..de4fde3a3f1 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -513,6 +513,7 @@ class A: fspath, lineno = getfslineno(A) _, A_lineno = inspect.findsource(A) + assert isinstance(fspath, py.path.local) assert fspath.basename == "test_source.py" assert lineno == A_lineno From fe8ac079af2d21139c63bb2c9a952162c82071f1 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 28 Jan 2020 15:09:07 +0100 Subject: [PATCH 2/5] fixup! typing: fix _pytest._code.source.getfslineno: returns str; assignment --- src/_pytest/_code/source.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index 99b6c785034..840ec1d99a2 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -293,7 +293,6 @@ def getfslineno(obj: Any) -> Tuple[Optional[Union[str, py.path.local]], int]: try: code = Code(obj) - return code.path, code.firstlineno except TypeError: try: fn = inspect.getsourcefile(obj) or inspect.getfile(obj) @@ -308,6 +307,7 @@ def getfslineno(obj: Any) -> Tuple[Optional[Union[str, py.path.local]], int]: except IOError: pass return fspath, lineno + return code.path, code.firstlineno # From 110b0f736a0432a52f1f60ac3e45f003b6774d81 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 28 Jan 2020 16:11:04 +0100 Subject: [PATCH 3/5] getfslineno(obj: object) --- src/_pytest/_code/source.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index 840ec1d99a2..9f6a6d0cd0e 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -8,7 +8,6 @@ from bisect import bisect_right from types import CodeType from types import FrameType -from typing import Any from typing import Iterator from typing import List from typing import Optional @@ -283,7 +282,7 @@ def compile_( # noqa: F811 return s.compile(filename, mode, flags, _genframe=_genframe) -def getfslineno(obj: Any) -> Tuple[Optional[Union[str, py.path.local]], int]: +def getfslineno(obj: object) -> Tuple[Optional[Union[str, py.path.local]], int]: """ Return source location (path, lineno) for the given object. If the source cannot be determined return ("", -1). @@ -295,7 +294,7 @@ def getfslineno(obj: Any) -> Tuple[Optional[Union[str, py.path.local]], int]: code = Code(obj) except TypeError: try: - fn = inspect.getsourcefile(obj) or inspect.getfile(obj) + fn = inspect.getsourcefile(obj) or inspect.getfile(obj) # type: ignore[arg-type] # noqa: F821 except TypeError: return "", -1 From dcd70a7a26041c7b8101014cebb2ead83753e380 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 28 Jan 2020 16:11:18 +0100 Subject: [PATCH 4/5] TEST: assert fn --- src/_pytest/_code/source.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index 9f6a6d0cd0e..03a28bd4faa 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -298,6 +298,8 @@ def getfslineno(obj: object) -> Tuple[Optional[Union[str, py.path.local]], int]: except TypeError: return "", -1 + assert fn, repr(fn) + fspath = fn and py.path.local(fn) or None lineno = -1 if fspath: From 5bd79f1279fe018f411832bd2718783da661888f Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 29 Jan 2020 00:53:20 +0100 Subject: [PATCH 5/5] getfslineno: skip trying Code --- src/_pytest/_code/source.py | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index 03a28bd4faa..8dc247a067f 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -288,27 +288,21 @@ def getfslineno(obj: object) -> Tuple[Optional[Union[str, py.path.local]], int]: The line number is 0-based. """ - from .code import Code - try: - code = Code(obj) + fn = inspect.getsourcefile(obj) or inspect.getfile(obj) # type: ignore[arg-type] # noqa: F821 except TypeError: + return "", -1 + + assert fn, repr(fn) + + fspath = fn and py.path.local(fn) or None + lineno = -1 + if fspath: try: - fn = inspect.getsourcefile(obj) or inspect.getfile(obj) # type: ignore[arg-type] # noqa: F821 - except TypeError: - return "", -1 - - assert fn, repr(fn) - - fspath = fn and py.path.local(fn) or None - lineno = -1 - if fspath: - try: - _, lineno = findsource(obj) - except IOError: - pass - return fspath, lineno - return code.path, code.firstlineno + _, lineno = findsource(obj) + except IOError: + pass + return fspath, lineno #