Return the entire source file and starting line number for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An OSError
(object)
| 972 | |
| 973 | |
| 974 | def findsource(object): |
| 975 | """Return the entire source file and starting line number for an object. |
| 976 | |
| 977 | The argument may be a module, class, method, function, traceback, frame, |
| 978 | or code object. The source code is returned as a list of all the lines |
| 979 | in the file and the line number indexes a line in that list. An OSError |
| 980 | is raised if the source code cannot be retrieved.""" |
| 981 | |
| 982 | file = getsourcefile(object) |
| 983 | if file: |
| 984 | # Invalidate cache if needed. |
| 985 | linecache.checkcache(file) |
| 986 | else: |
| 987 | file = getfile(object) |
| 988 | # Allow filenames in form of "<something>" to pass through. |
| 989 | # `doctest` monkeypatches `linecache` module to enable |
| 990 | # inspection, so let `linecache.getlines` to be called. |
| 991 | if (not (file.startswith('<') and file.endswith('>'))) or file.endswith('.fwork'): |
| 992 | raise OSError('source code not available') |
| 993 | |
| 994 | module = getmodule(object, file) |
| 995 | if module: |
| 996 | lines = linecache.getlines(file, module.__dict__) |
| 997 | if not lines and file.startswith('<') and hasattr(object, "__code__"): |
| 998 | lines = linecache._getlines_from_code(object.__code__) |
| 999 | else: |
| 1000 | lines = linecache.getlines(file) |
| 1001 | if not lines: |
| 1002 | raise OSError('could not get source code') |
| 1003 | |
| 1004 | if ismodule(object): |
| 1005 | return lines, 0 |
| 1006 | |
| 1007 | if isclass(object): |
| 1008 | try: |
| 1009 | lnum = vars(object)['__firstlineno__'] - 1 |
| 1010 | except (TypeError, KeyError): |
| 1011 | raise OSError('source code not available') |
| 1012 | if lnum >= len(lines): |
| 1013 | raise OSError('lineno is out of bounds') |
| 1014 | return lines, lnum |
| 1015 | |
| 1016 | if ismethod(object): |
| 1017 | object = object.__func__ |
| 1018 | if isfunction(object): |
| 1019 | object = object.__code__ |
| 1020 | if istraceback(object): |
| 1021 | object = object.tb_frame |
| 1022 | if isframe(object): |
| 1023 | object = object.f_code |
| 1024 | if iscode(object): |
| 1025 | if not hasattr(object, 'co_firstlineno'): |
| 1026 | raise OSError('could not find function definition') |
| 1027 | lnum = object.co_firstlineno - 1 |
| 1028 | if lnum >= len(lines): |
| 1029 | raise OSError('lineno is out of bounds') |
| 1030 | return lines, lnum |
| 1031 | raise OSError('could not find code object') |
no test coverage detected
searching dependent graphs…