88from bisect import bisect_right
99from types import CodeType
1010from types import FrameType
11+ from typing import Any
1112from typing import Iterator
1213from typing import List
1314from typing import Optional
1718
1819import py
1920
21+ from _pytest .compat import get_real_func
2022from _pytest .compat import overload
2123from _pytest .compat import TYPE_CHECKING
2224
@@ -282,14 +284,21 @@ def compile_( # noqa: F811
282284 return s .compile (filename , mode , flags , _genframe = _genframe )
283285
284286
285- def getfslineno (obj ) -> Tuple [Optional [ Union ["Literal['']" , py .path .local ] ], int ]:
287+ def getfslineno (obj : Any ) -> Tuple [Union [str , py .path .local ], int ]:
286288 """ Return source location (path, lineno) for the given object.
287289 If the source cannot be determined return ("", -1).
288290
289291 The line number is 0-based.
290292 """
291293 from .code import Code
292294
295+ # xxx let decorators etc specify a sane ordering
296+ # NOTE: this used to be done in _pytest.compat.getfslineno, initially added
297+ # in 6ec13a2b9. It ("place_as") appears to be something very custom.
298+ obj = get_real_func (obj )
299+ if hasattr (obj , "place_as" ):
300+ obj = obj .place_as
301+
293302 try :
294303 code = Code (obj )
295304 except TypeError :
@@ -298,18 +307,16 @@ def getfslineno(obj) -> Tuple[Optional[Union["Literal['']", py.path.local]], int
298307 except TypeError :
299308 return "" , - 1
300309
301- fspath = fn and py .path .local (fn ) or None
310+ fspath = fn and py .path .local (fn ) or ""
302311 lineno = - 1
303312 if fspath :
304313 try :
305314 _ , lineno = findsource (obj )
306315 except IOError :
307316 pass
317+ return fspath , lineno
308318 else :
309- fspath = code .path
310- lineno = code .firstlineno
311- assert isinstance (lineno , int )
312- return fspath , lineno
319+ return code .path , code .firstlineno
313320
314321
315322#
0 commit comments