@@ -1035,79 +1035,6 @@ class ClassFoundException(Exception):
1035
1035
pass
1036
1036
1037
1037
1038
- class _ClassFinder (ast .NodeVisitor ):
1039
-
1040
- def __init__ (self , cls , tree , lines , qualname ):
1041
- self .stack = []
1042
- self .cls = cls
1043
- self .tree = tree
1044
- self .lines = lines
1045
- self .qualname = qualname
1046
- self .lineno_found = []
1047
-
1048
- def visit_FunctionDef (self , node ):
1049
- self .stack .append (node .name )
1050
- self .stack .append ('<locals>' )
1051
- self .generic_visit (node )
1052
- self .stack .pop ()
1053
- self .stack .pop ()
1054
-
1055
- visit_AsyncFunctionDef = visit_FunctionDef
1056
-
1057
- def visit_ClassDef (self , node ):
1058
- self .stack .append (node .name )
1059
- if self .qualname == '.' .join (self .stack ):
1060
- # Return the decorator for the class if present
1061
- if node .decorator_list :
1062
- line_number = node .decorator_list [0 ].lineno
1063
- else :
1064
- line_number = node .lineno
1065
-
1066
- # decrement by one since lines starts with indexing by zero
1067
- self .lineno_found .append ((line_number - 1 , node .end_lineno ))
1068
- self .generic_visit (node )
1069
- self .stack .pop ()
1070
-
1071
- def get_lineno (self ):
1072
- self .visit (self .tree )
1073
- lineno_found_number = len (self .lineno_found )
1074
- if lineno_found_number == 0 :
1075
- raise OSError ('could not find class definition' )
1076
- elif lineno_found_number == 1 :
1077
- return self .lineno_found [0 ][0 ]
1078
- else :
1079
- # We have multiple candidates for the class definition.
1080
- # Now we have to guess.
1081
-
1082
- # First, let's see if there are any method definitions
1083
- for member in self .cls .__dict__ .values ():
1084
- if (isinstance (member , types .FunctionType ) and
1085
- member .__module__ == self .cls .__module__ ):
1086
- for lineno , end_lineno in self .lineno_found :
1087
- if lineno <= member .__code__ .co_firstlineno <= end_lineno :
1088
- return lineno
1089
-
1090
- class_strings = [('' .join (self .lines [lineno : end_lineno ]), lineno )
1091
- for lineno , end_lineno in self .lineno_found ]
1092
-
1093
- # Maybe the class has a docstring and it's unique?
1094
- if self .cls .__doc__ :
1095
- ret = None
1096
- for candidate , lineno in class_strings :
1097
- if self .cls .__doc__ .strip () in candidate :
1098
- if ret is None :
1099
- ret = lineno
1100
- else :
1101
- break
1102
- else :
1103
- if ret is not None :
1104
- return ret
1105
-
1106
- # We are out of ideas, just return the last one found, which is
1107
- # slightly better than previous ones
1108
- return self .lineno_found [- 1 ][0 ]
1109
-
1110
-
1111
1038
def findsource (object ):
1112
1039
"""Return the entire source file and starting line number for an object.
1113
1040
@@ -1140,11 +1067,11 @@ def findsource(object):
1140
1067
return lines , 0
1141
1068
1142
1069
if isclass (object ):
1143
- qualname = object . __qualname__
1144
- source = '' . join ( lines )
1145
- tree = ast . parse ( source )
1146
- class_finder = _ClassFinder ( object , tree , lines , qualname )
1147
- return lines , class_finder . get_lineno ()
1070
+ try :
1071
+ firstlineno = object . __firstlineno__
1072
+ except AttributeError :
1073
+ raise OSError ( 'source code not available' )
1074
+ return lines , object . __firstlineno__ - 1
1148
1075
1149
1076
if ismethod (object ):
1150
1077
object = object .__func__
0 commit comments