-
Notifications
You must be signed in to change notification settings - Fork 11
Open
Labels
bugSomething isn't workingSomething isn't working
Description
The behavior of inspect.getsourcelines is incorrect for different classes with the same name (defined in different scopes). Observe the following excerpt from inspect.findsource (used by getsourcelines internally):
if isclass(object):
name = object.__name__
pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
# make some effort to find the best matching class definition:
# use the one with the least indentation, which is the one
# that's most probably not inside a function definition.
candidates = []
for i in range(len(lines)):
match = pat.match(lines[i])
if match:
# if it's at toplevel, it's already the best one
if lines[i][0] == 'c':
return lines, i
# else add whitespace to candidate list
candidates.append((match.group(1), i))
if candidates:
# this will sort by whitespace, and by line number,
# less whitespace first
candidates.sort()
return lines, candidates[0][1]
In other words, it returns the source for the "best" matching class definition instead of the correct class definition. So, code like this would break:
def foo():
class Baz: ...
ast = synr.to_ast(Baz)
def bar():
class Baz: ... # something different
ast = synr.to_ast(Baz) # this will parse the first Baz in foo
Not sure there's an easy solution. We could do our own check that there aren't multiple classes with the same name in a source file and error out if there is (to be conservative). inspect should really have a disclaimer somewhere in the visible documentation for this, or implement a correct solution (perhaps using the __qualname__ field of the class).
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working