-
-
Notifications
You must be signed in to change notification settings - Fork 278
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
Bug 905 #913
Bug 905 #913
Conversation
… infer the origin class : i.e MutableSet = _alias(collections.MutableSet ...) origin is the class in collections module. Needs to add __getitem method on its metaclass so that is support indexing (MutableSet[T]).
The |
ChangeLog
Outdated
Closes PyCQA/pylint#4093 | ||
Closes PyCQA/pylint#4131 | ||
Closes PyCQA/pylint#4145 | ||
Closes PyCQA/pylint#3247 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closes PyCQA/pylint#4093 | |
Closes PyCQA/pylint#4131 | |
Closes PyCQA/pylint#4145 | |
Closes PyCQA/pylint#3247 | |
Closes PyCQA/pylint#2717 | |
Closes PyCQA/pylint#3247 | |
Closes PyCQA/pylint#4093 | |
Closes PyCQA/pylint#4131 | |
Closes PyCQA/pylint#4145 |
Copied from the PR description + sorted
astroid/brain/brain_typing.py
Outdated
if isinstance(node, nodes.Call) and isinstance(node.func, nodes.Name): | ||
if node.func.name == "_alias" and isinstance(node.args[0], nodes.Attribute): | ||
return True | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if isinstance(node, nodes.Call) and isinstance(node.func, nodes.Name): | |
if node.func.name == "_alias" and isinstance(node.args[0], nodes.Attribute): | |
return True | |
return False | |
return ( | |
isinstance(node, nodes.Call) and | |
isinstance(node.func, nodes.Name) and | |
node.func.name == "_alias" and | |
isinstance(node.args[0], nodes.Attribute) | |
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense to take a look at #908 after that. I updated the pre-commit
config to use a current version of black.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I merged #908, a rebase is probably necessary. There are a lot of pre-commit check that are in pylint and not in astroid, I might update astroid configuration once we release 2.7.2, upgraded black is enough for now.
Good job on fixing false negative in pylint, I think maybe we can disable them as they're unrelated to the functional test they broke ? But it could also be kept and prevent regression? Let's first merge this one in astroid. |
I'm noticing some issues with |
@cdce8p can you give a snippet for the issues you are facing? |
@hippo91 I tried to analyze it a bit more. The following typing symbols seem to cause issue now: typing.Deque
typing.Defaultdict
typing.OrderedDict
typing.Counter Additionally I believe that transform might not be working correctly for: typing.Pattern
typing.Match |
As for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hippo91 That should work for the first for. That leaves typing.Pattern
and typing.Match
.
def __getitem__(cls, value): | ||
return cls | ||
""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ABC_METACLASS_TEMPLATE = """ | |
from abc import ABCMeta | |
ABCMeta | |
""" | |
if res.metaclass(): | ||
res.metaclass().locals["__getitem__"] = [func_to_add] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if res.metaclass(): | |
res.metaclass().locals["__getitem__"] = [func_to_add] | |
if res != astroid.Uninferable: | |
if not res.metaclass(): | |
res._metaclass = extract_node(ABC_METACLASS_TEMPLATE) | |
res.metaclass().locals["__getitem__"] = [func_to_add] | |
else: | |
return |
@hippo91 Some last commons for today: Failing pylint tests collection - getitem import collection
import collection.abc
var1: collections.OrderedDict[str, int]
var2: collections.abc.Iterable[int] Both should be unsubscriptable in Python 3.7 and 3.8.
Additional tests -- All in all, I really like your changes. Thanks for taking the time and working on it. Please let me know if I can help you any further. |
… infer the origin class : i.e MutableSet = _alias(collections.MutableSet ...) origin is the class in collections module. Needs to add __getitem method on its metaclass so that is support indexing (MutableSet[T]).
@cdce8p thanks a lot for all your investigations. I appreciate a lot. @Pierre-Sassoulas it seems there is still a bit of work before getting this merge. |
@hippo91 Could you rebase this branch onto master and then force push it?
I think I already did just now. Will publish my changes after your rebase. |
Tests are now also done: cdce8p@2e15d63 |
Ideally we would release a fix for the crash today so this is available in 2.7.2 for debian (deadline march 1 ) . Will there be a way to release this fix in astroid and then release pylint today ? If not we might want to release what was fixed in pylint anyway and bump this issue to 2.7.3 ? |
@Pierre-Sassoulas I posted a working solution, so it's just a matter of rebasing, force-pushing and integrating. If it would be of any help, I could open a new MR with both the original idea from @hippo91 and my changes. Maybe that would be easier to review then. Let me know if I should do that. |
Yeah, usually we can squash everything and merge without a rebase but this time it does not seems super wise. |
Ok. Give me a few minutes. I'll tag you both so you get notified once I open the MR. |
@cdce8p good idea. I am sorry but i will no longer have time to work for pylunt/astroid this week end. So if this patch is needed fast please do it as you feel. Thanks a lot. PS : as i am not very used to rebase and force push can you give me the commands i would have to type? |
Assuming the PyCQA/astroid remote is git fetch upstream master
git checkout bug_905
git rebase upstream/master
# Resolve all rebase conflicts
# Best done in an editor (like VS Code)
git add .
git rebase --continue
# Repeat until rebase is complete
git push -f # --force-with-lease to not erase code by mistake if it's a shared branch |
Ok, I never realeased astroid, but I can start. This would be 2.5.1, right ? |
Replaced by #916 |
Thanks for those guidelines @cdce8p and for all the hard work! |
Steps
Description
This PR solves "Duplicates found in MROs" false positives.
The bug was not a regression as i first thought. @cdce8p detected that it was as old as #2717. The last
astroid
version just make it more present.The bug is in fact the consequence of types aliasing in the
typing
module.As the
_alias
function of thetyping
module returns_GenericAlias
class, then this last class (and its inheritance tree) ends eventually in the inferred mro of the aliased class.This way
class V(MutableSet[T])
mro is inferred as `V => _GenericAlias => _Final => object.But the correct mro should be "V => MutableSet => Set => Collection => Sized => Iterable => Container => Generic => object"
To mock the correct behavior, the
typing_brain
has been enriched with a new function. This function when receiving the call node corresponding toMutableSet = _alias(...)
infer theMutableSet
node name instead of inferring_alias
call.This way, we obtain the correct class (in this example
MutableSet
) with its correct mro. We just have to add a__getitem__
class method in the inferred class so that subscripting it is not detected as an error byastroid
.The mro obtained is the same as the one obtained by the
python
interpreter except the fact that in the inferred one, there is nottyping.Generic
but i think it is not a problem.I tested
pylint
against this PR and all tests except one are ok. The failing one istry_except_raise_crash.py
. Due to this PR improvment some false negatives are corrected and thus following messages appear and IMHO are correct:Type of Changes
Related Issue
Closes #905
Closes pylint-dev/pylint#4093
Closes pylint-dev/pylint#4131
Closes pylint-dev/pylint#4145
Closes pylint-dev/pylint#3247
Closes pylint-dev/pylint#2717