Return source location (path, lineno) for the given object. If the source cannot be determined return ("", -1). The line number is 0-based.
(obj: object)
| 1200 | |
| 1201 | |
| 1202 | def getfslineno(obj: object) -> Tuple[Union[str, Path], int]: |
| 1203 | """Return source location (path, lineno) for the given object. |
| 1204 | |
| 1205 | If the source cannot be determined return ("", -1). |
| 1206 | |
| 1207 | The line number is 0-based. |
| 1208 | """ |
| 1209 | # xxx let decorators etc specify a sane ordering |
| 1210 | # NOTE: this used to be done in _pytest.compat.getfslineno, initially added |
| 1211 | # in 6ec13a2b9. It ("place_as") appears to be something very custom. |
| 1212 | obj = get_real_func(obj) |
| 1213 | if hasattr(obj, "place_as"): |
| 1214 | obj = obj.place_as # type: ignore[attr-defined] |
| 1215 | |
| 1216 | try: |
| 1217 | code = Code.from_function(obj) |
| 1218 | except TypeError: |
| 1219 | try: |
| 1220 | fn = inspect.getsourcefile(obj) or inspect.getfile(obj) # type: ignore[arg-type] |
| 1221 | except TypeError: |
| 1222 | return "", -1 |
| 1223 | |
| 1224 | fspath = fn and absolutepath(fn) or "" |
| 1225 | lineno = -1 |
| 1226 | if fspath: |
| 1227 | try: |
| 1228 | _, lineno = findsource(obj) |
| 1229 | except OSError: |
| 1230 | pass |
| 1231 | return fspath, lineno |
| 1232 | |
| 1233 | return code.path, code.firstlineno |
| 1234 | |
| 1235 | |
| 1236 | # Relative paths that we use to filter traceback entries from appearing to the user; |