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

Spurious no-member errors with modules named builtins on py3 #3327

Open
AdamG opened this issue Jan 2, 2020 · 2 comments
Open

Spurious no-member errors with modules named builtins on py3 #3327

AdamG opened this issue Jan 2, 2020 · 2 comments
Assignees
Labels
False Positive 🦟 A message is emitted but nothing is wrong with the code Needs PR This issue is accepted, sufficiently specified and now needs an implementation

Comments

@AdamG
Copy link

AdamG commented Jan 2, 2020

pylint gives incorrect no-member errors when checking a file that does a from-import of a module named "builtins" in python3 and then accesses any name that are not attributes of dict types. (My guess is that this also would have happened in python2 with modules named __builtin__, but that's much less likely to happen in IRL code than a module called foopkg.builtins.)

This does not occur when doing import foopkg.builtins as builtins, only when doing from foopkg import builtins. It does not matter whether the module is aliased to some other name (eg, ... as builtins_mod).

Steps to reproduce

Commands to set up a test case:

mkdir subpkg
touch subpkg/__init__.py
echo "foo = object()" > subpkg/builtins.py
echo "foo = object()" > subpkg/any_other_module_name.py
cat << EOF > no_error_any_other_module.py
from subpkg import any_other_module_name as builtins_mod
bar = builtins_mod.foo
EOF
cat << EOF > no_error_import_as.py
import subpkg.builtins as builtins_mod
bar = builtins_mod.foo
EOF
cat << EOF > gives_error_from_import.py
from subpkg import builtins as builtins_mod
bar = builtins_mod.foo # will have incorrect no-member
baz = builtins_mod.pop # this *should* be a no-member error, but doesn't get noticed.
EOF

Pylint run & output:

$ pylint --version
pylint 2.4.4
astroid 2.3.3
Python 3.7.6 (default, Jan  2 2020, 11:24:00)
[GCC 8.3.0]
$ pylint -E --rcfile=/dev/null gives_error_from_import.py no_error_any_other_module.py no_error_import_as.py
************* Module gives_error_from_import
gives_error_from_import.py:2:6: E1101: Instance of 'dict' has no 'foo' member (no-member)

This does not occur with pylint 1.6.5, but does occur with 1.7.6 (with python3.6, 1.7.6 does not work with python3.7 (#2241)). This makes it similar to #1606, but I don't think this is a duplicate of that issue - this occurs with any (even trivial, as shown above) modules named builtins, and is unrelated to anything weird that future.builtins is doing, so the fix suggested in that issue wouldn't resolve this.

I have set up a test case in AdamG@f2e7019 that is currently failing, but should work as a regression test once the underlying issue is fixed.

Current behavior

When doing a from-import, gives an error on access of builtins_mod.foo, even though it exists in that module.

The error message always indicates that pylint thinks that the builtins object is a dict, which points to checkers.utils.is_builtin() being somehow involved. I tried a few things in VariablesChecker and TypeChecker, but nothing seemed to make a difference; i'm not familiar enough with this codebase/astroid to get much further.

Expected behavior

It should not give the incorrect no-member error. It certainly shouldn't conditionally occur based on the name of the imported module.

pylint --version output

see above

@AWhetter AWhetter self-assigned this Jan 6, 2020
@AWhetter
Copy link
Contributor

AWhetter commented Jan 6, 2020

When the ImportFrom is being inferred, a getattr() is done on the module (https://github.com/PyCQA/astroid/blob/631539e8ca8cbdb73b1c8655214de10bdd51e466/astroid/inference.py#L276). We have builtins listed as an attribute that's inherent on every module (https://github.com/PyCQA/astroid/blob/631539e8ca8cbdb73b1c8655214de10bdd51e466/astroid/interpreter/objectmodel.py#L125), which is incorrect. __builtins__ used to be on every module in Python 2, but builtins isn't on every module in Python 3.
Removing that attribute fixes this test case. I've run the tests and nothing fails, but I want to do a bit of manual checking before I go ahead and commit the fix for this.

@Pierre-Sassoulas Pierre-Sassoulas added Needs investigation 🔬 A bug or crash where it's not immediately obvious what is happenning False Positive 🦟 A message is emitted but nothing is wrong with the code Needs reproduction 🔍 Need a way to reproduce it locally on a maintainer's machine and removed Bug 🪲 labels Jun 30, 2022
@clavedeluna
Copy link
Contributor

I'm able to reproduce this exactly as stated. @AWhetter if you have a fix commit, it would be worth PR-ing!

@clavedeluna clavedeluna added Needs PR This issue is accepted, sufficiently specified and now needs an implementation and removed Needs reproduction 🔍 Need a way to reproduce it locally on a maintainer's machine Needs investigation 🔬 A bug or crash where it's not immediately obvious what is happenning labels Nov 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
False Positive 🦟 A message is emitted but nothing is wrong with the code Needs PR This issue is accepted, sufficiently specified and now needs an implementation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants