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)
| 948 | |
| 949 | |
| 950 | def findsource(object): |
| 951 | """Return the entire source file and starting line number for an object. |
| 952 | |
| 953 | The argument may be a module, class, method, function, traceback, frame, |
| 954 | or code object. The source code is returned as a list of all the lines |
| 955 | in the file and the line number indexes a line in that list. An OSError |
| 956 | is raised if the source code cannot be retrieved.""" |
| 957 | |
| 958 | file = getsourcefile(object) |
| 959 | if file: |
| 960 | # Invalidate cache if needed. |
| 961 | linecache.checkcache(file) |
| 962 | else: |
| 963 | file = getfile(object) |
| 964 | # Allow filenames in form of "<something>" to pass through. |
| 965 | # `doctest` monkeypatches `linecache` module to enable |
| 966 | # inspection, so let `linecache.getlines` to be called. |
| 967 | if (not (file.startswith('<') and file.endswith('>'))) or file.endswith('.fwork'): |
| 968 | raise OSError('source code not available') |
| 969 | |
| 970 | module = getmodule(object, file) |
| 971 | if module: |
| 972 | lines = linecache.getlines(file, module.__dict__) |
| 973 | if not lines and file.startswith('<') and hasattr(object, "__code__"): |
| 974 | lines = linecache._getlines_from_code(object.__code__) |
| 975 | else: |
| 976 | lines = linecache.getlines(file) |
| 977 | if not lines: |
| 978 | raise OSError('could not get source code') |
| 979 | |
| 980 | if ismodule(object): |
| 981 | return lines, 0 |
| 982 | |
| 983 | if isclass(object): |
| 984 | try: |
| 985 | lnum = vars(object)['__firstlineno__'] - 1 |
| 986 | except (TypeError, KeyError): |
| 987 | raise OSError('source code not available') |
| 988 | if lnum >= len(lines): |
| 989 | raise OSError('lineno is out of bounds') |
| 990 | return lines, lnum |
| 991 | |
| 992 | if ismethod(object): |
| 993 | object = object.__func__ |
| 994 | if isfunction(object): |
| 995 | object = object.__code__ |
| 996 | if istraceback(object): |
| 997 | object = object.tb_frame |
| 998 | if isframe(object): |
| 999 | object = object.f_code |
| 1000 | if iscode(object): |
| 1001 | if not hasattr(object, 'co_firstlineno'): |
| 1002 | raise OSError('could not find function definition') |
| 1003 | lnum = object.co_firstlineno - 1 |
| 1004 | if lnum >= len(lines): |
| 1005 | raise OSError('lineno is out of bounds') |
| 1006 | return lines, lnum |
| 1007 | raise OSError('could not find code object') |
no test coverage detected