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 OSE
(object)
| 1049 | |
| 1050 | |
| 1051 | def findsource(object): |
| 1052 | """Return the entire source file and starting line number for an object. |
| 1053 | |
| 1054 | The argument may be a module, class, method, function, traceback, frame, |
| 1055 | or code object. The source code is returned as a list of all the lines |
| 1056 | in the file and the line number indexes a line in that list. An OSError |
| 1057 | is raised if the source code cannot be retrieved.""" |
| 1058 | |
| 1059 | file = getsourcefile(object) |
| 1060 | if file: |
| 1061 | # Invalidate cache if needed. |
| 1062 | linecache.checkcache(file) |
| 1063 | else: |
| 1064 | file = getfile(object) |
| 1065 | # Allow filenames in form of "<something>" to pass through. |
| 1066 | # `doctest` monkeypatches `linecache` module to enable |
| 1067 | # inspection, so let `linecache.getlines` to be called. |
| 1068 | if not (file.startswith('<') and file.endswith('>')): |
| 1069 | raise OSError('source code not available') |
| 1070 | |
| 1071 | module = getmodule(object, file) |
| 1072 | if module: |
| 1073 | lines = linecache.getlines(file, module.__dict__) |
| 1074 | else: |
| 1075 | lines = linecache.getlines(file) |
| 1076 | if not lines: |
| 1077 | raise OSError('could not get source code') |
| 1078 | |
| 1079 | if ismodule(object): |
| 1080 | return lines, 0 |
| 1081 | |
| 1082 | if isclass(object): |
| 1083 | qualname = object.__qualname__ |
| 1084 | source = ''.join(lines) |
| 1085 | tree = ast.parse(source) |
| 1086 | class_finder = _ClassFinder(qualname) |
| 1087 | try: |
| 1088 | class_finder.visit(tree) |
| 1089 | except ClassFoundException as e: |
| 1090 | line_number = e.args[0] |
| 1091 | return lines, line_number |
| 1092 | else: |
| 1093 | raise OSError('could not find class definition') |
| 1094 | |
| 1095 | if ismethod(object): |
| 1096 | object = object.__func__ |
| 1097 | if isfunction(object): |
| 1098 | object = object.__code__ |
| 1099 | if istraceback(object): |
| 1100 | object = object.tb_frame |
| 1101 | if isframe(object): |
| 1102 | object = object.f_code |
| 1103 | if iscode(object): |
| 1104 | if not hasattr(object, 'co_firstlineno'): |
| 1105 | raise OSError('could not find function definition') |
| 1106 | lnum = object.co_firstlineno - 1 |
| 1107 | pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)') |
| 1108 | while lnum > 0: |
no test coverage detected