internal: clean up getfslineno (#6656)

This commit is contained in:
Daniel Hahler 2020-02-04 22:46:00 +01:00 committed by GitHub
commit 632800add5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 27 additions and 21 deletions

View File

@ -72,6 +72,8 @@ class Code:
""" return a path object pointing to source code (or a str in case """ return a path object pointing to source code (or a str in case
of OSError / non-existing file). of OSError / non-existing file).
""" """
if not self.raw.co_filename:
return ""
try: try:
p = py.path.local(self.raw.co_filename) p = py.path.local(self.raw.co_filename)
# maybe don't try this checking # maybe don't try this checking

View File

@ -8,6 +8,7 @@ import warnings
from bisect import bisect_right from bisect import bisect_right
from types import CodeType from types import CodeType
from types import FrameType from types import FrameType
from typing import Any
from typing import Iterator from typing import Iterator
from typing import List from typing import List
from typing import Optional from typing import Optional
@ -17,6 +18,7 @@ from typing import Union
import py import py
from _pytest.compat import get_real_func
from _pytest.compat import overload from _pytest.compat import overload
from _pytest.compat import TYPE_CHECKING from _pytest.compat import TYPE_CHECKING
@ -282,7 +284,7 @@ def compile_( # noqa: F811
return s.compile(filename, mode, flags, _genframe=_genframe) return s.compile(filename, mode, flags, _genframe=_genframe)
def getfslineno(obj) -> Tuple[Optional[Union["Literal['']", py.path.local]], int]: def getfslineno(obj: Any) -> Tuple[Union[str, py.path.local], int]:
""" Return source location (path, lineno) for the given object. """ Return source location (path, lineno) for the given object.
If the source cannot be determined return ("", -1). If the source cannot be determined return ("", -1).
@ -290,6 +292,13 @@ def getfslineno(obj) -> Tuple[Optional[Union["Literal['']", py.path.local]], int
""" """
from .code import Code from .code import Code
# xxx let decorators etc specify a sane ordering
# NOTE: this used to be done in _pytest.compat.getfslineno, initially added
# in 6ec13a2b9. It ("place_as") appears to be something very custom.
obj = get_real_func(obj)
if hasattr(obj, "place_as"):
obj = obj.place_as
try: try:
code = Code(obj) code = Code(obj)
except TypeError: except TypeError:
@ -298,18 +307,16 @@ def getfslineno(obj) -> Tuple[Optional[Union["Literal['']", py.path.local]], int
except TypeError: except TypeError:
return "", -1 return "", -1
fspath = fn and py.path.local(fn) or None fspath = fn and py.path.local(fn) or ""
lineno = -1 lineno = -1
if fspath: if fspath:
try: try:
_, lineno = findsource(obj) _, lineno = findsource(obj)
except IOError: except IOError:
pass pass
return fspath, lineno
else: else:
fspath = code.path return code.path, code.firstlineno
lineno = code.firstlineno
assert isinstance(lineno, int)
return fspath, lineno
# #

View File

@ -22,7 +22,6 @@ from typing import Union
import attr import attr
import py import py
import _pytest
from _pytest._io.saferepr import saferepr from _pytest._io.saferepr import saferepr
from _pytest.outcomes import fail from _pytest.outcomes import fail
from _pytest.outcomes import TEST_OUTCOME from _pytest.outcomes import TEST_OUTCOME
@ -307,16 +306,6 @@ def get_real_method(obj, holder):
return obj return obj
def getfslineno(obj) -> Tuple[Union[str, py.path.local], int]:
# xxx let decorators etc specify a sane ordering
obj = get_real_func(obj)
if hasattr(obj, "place_as"):
obj = obj.place_as
fslineno = _pytest._code.getfslineno(obj)
assert isinstance(fslineno[1], int), obj
return fslineno
def getimfunc(func): def getimfunc(func):
try: try:
return func.__func__ return func.__func__

View File

@ -16,12 +16,12 @@ import py
import _pytest import _pytest
from _pytest._code.code import FormattedExcinfo from _pytest._code.code import FormattedExcinfo
from _pytest._code.code import TerminalRepr from _pytest._code.code import TerminalRepr
from _pytest._code.source import getfslineno
from _pytest._io import TerminalWriter from _pytest._io import TerminalWriter
from _pytest.compat import _format_args from _pytest.compat import _format_args
from _pytest.compat import _PytestWrapper from _pytest.compat import _PytestWrapper
from _pytest.compat import get_real_func from _pytest.compat import get_real_func
from _pytest.compat import get_real_method from _pytest.compat import get_real_method
from _pytest.compat import getfslineno
from _pytest.compat import getfuncargnames from _pytest.compat import getfuncargnames
from _pytest.compat import getimfunc from _pytest.compat import getimfunc
from _pytest.compat import getlocation from _pytest.compat import getlocation

View File

@ -6,9 +6,9 @@ from typing import Set
import attr import attr
from .._code.source import getfslineno
from ..compat import ascii_escaped from ..compat import ascii_escaped
from ..compat import ATTRS_EQ_FIELD from ..compat import ATTRS_EQ_FIELD
from ..compat import getfslineno
from ..compat import NOTSET from ..compat import NOTSET
from _pytest.outcomes import fail from _pytest.outcomes import fail
from _pytest.warning_types import PytestUnknownMarkWarning from _pytest.warning_types import PytestUnknownMarkWarning

View File

@ -15,8 +15,8 @@ import _pytest._code
from _pytest._code.code import ExceptionChainRepr from _pytest._code.code import ExceptionChainRepr
from _pytest._code.code import ExceptionInfo from _pytest._code.code import ExceptionInfo
from _pytest._code.code import ReprExceptionInfo from _pytest._code.code import ReprExceptionInfo
from _pytest._code.source import getfslineno
from _pytest.compat import cached_property from _pytest.compat import cached_property
from _pytest.compat import getfslineno
from _pytest.compat import TYPE_CHECKING from _pytest.compat import TYPE_CHECKING
from _pytest.config import Config from _pytest.config import Config
from _pytest.config import PytestPluginManager from _pytest.config import PytestPluginManager

View File

@ -20,10 +20,10 @@ import _pytest
from _pytest import fixtures from _pytest import fixtures
from _pytest import nodes from _pytest import nodes
from _pytest._code import filter_traceback from _pytest._code import filter_traceback
from _pytest._code.source import getfslineno
from _pytest.compat import ascii_escaped from _pytest.compat import ascii_escaped
from _pytest.compat import get_default_arg_names from _pytest.compat import get_default_arg_names
from _pytest.compat import get_real_func from _pytest.compat import get_real_func
from _pytest.compat import getfslineno
from _pytest.compat import getimfunc from _pytest.compat import getimfunc
from _pytest.compat import getlocation from _pytest.compat import getlocation
from _pytest.compat import is_generator from _pytest.compat import is_generator

View File

@ -524,6 +524,14 @@ def test_getfslineno() -> None:
B.__name__ = "B2" B.__name__ = "B2"
assert getfslineno(B)[1] == -1 assert getfslineno(B)[1] == -1
co = compile("...", "", "eval")
assert co.co_filename == ""
if hasattr(sys, "pypy_version_info"):
assert getfslineno(co) == ("", -1)
else:
assert getfslineno(co) == ("", 0)
def test_code_of_object_instance_with_call() -> None: def test_code_of_object_instance_with_call() -> None:
class A: class A: