Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect MRO inferred with multiple inheritance from module-qualified classes #843

Closed
timmartin opened this issue Oct 7, 2020 · 3 comments · Fixed by #844
Closed

Incorrect MRO inferred with multiple inheritance from module-qualified classes #843

timmartin opened this issue Oct 7, 2020 · 3 comments · Fixed by #844

Comments

@timmartin
Copy link
Contributor

Steps to reproduce

File other.py:

class A:
    pass

class B:
    pass

Then run:

import astroid

class_node = astroid.extract_node("""
import other

class Child(other.A, other.B): #@
    pass
""")

print([cls.name for cls.name in class_node.mro()])

Current behavior

['Child', 'A', 'object']

Expected behavior

['Child', 'A', 'B', 'object']

python -c "from astroid import __pkginfo__; print(__pkginfo__.version)" output

2.5.0

@timmartin
Copy link
Contributor Author

I believe this change will fix this, I just need to write a proper PR.

I think the problem is that when we run multiple inferences in _inferred_bases, the context is reused which means the second and subsequent inferences have bad data. Cloning the context before running the inference seems to address this.

@hippo91
Copy link
Contributor

hippo91 commented Oct 10, 2020

@timmartin thanks for the report. I can reproduce it.
One interesting thing is:

import astroid

class_node = astroid.extract_node("""
from other import A, B

class Child(A, B): #@
    pass
""")

print([cls.name for cls in class_node.mro()])

prints: ['Child', 'A', 'B', 'object']

@timmartin
Copy link
Contributor Author

Yes, that's correct. I believe this is because in the first case, there is non-trivial inference that must be applied to each expression (other.A, other.B) to determine its type, and sharing the context between the two infer calls causes the second to fail. In the second case, the shared context doesn't affect the second infer call, either because the two expressions are so trivial or because there's no overlap between the names in the two expressions. I'm mostly guessing this from context, I don't yet properly understand how the inference works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants