-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
Stop detecting modules compiled by cffi
as namespace packages
#1777
Conversation
Pull Request Test Coverage Report for Build 3073456457
💛 - Coveralls |
I'm having trouble to reproduce using my usual workflow.
Note that this happens when trying to install to the user site-packages. Virtualenv installations seems to be OK.
|
Could you try installing in a virtualenv with |
@Pierre-Sassoulas I think I've not been clear enough. Within a virtualenv ( All the trouble happens when trying to install in the user site-packages directory:
|
I don't know if I understood correctly what user site package is but wouldn't |
No! That's exactly what is broken (in recent pip releases, the
Note the I install stuff in the user site-packages directory ( |
OK, this is what I did to manually try this PR
After that, I ran However, the issue of installing with pip from a git repo is still there. My git clone is in "/tmp/astroid":
BTW, this issue occurs with the |
OK, thank you for walking me through it. We switched to |
This commit fixes pylint-dev/pylint#7399 Thanks! |
@rjarry I'm using latest pip and setuptools (both installed in the user site-packages directory) with Fedora 36 system Python 3.10.6.
|
@dalcinl I do not install with
|
@rjarry Yes, I know, virtual envs are working fine. It is with the
|
@jacobtylerwalls Do you know if |
I'll have a look if this is fixed by it. If so, this will probably become uncovered on |
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.
Thank you @jacobtylerwalls ! Let's release astroid 2.12.10 and pylint 2.15.3 once this is merged :)
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.
This is not affected by custom import hooks as fixed in #1752.
Thanks for investigating, I appreciate it! |
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From pylint-dev#1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. But if you have imported it as `celery.result`, `sys.modules["celery"].__spec__` is going to be `None`, and hence the function will return True, and but below where we try to load get `submodule_path`/`__path__` for `celery.result` will fail as it is not a package. See https://github.com/PyCQA/astroid/blob/056d8e5fab7a167f73115d524ab92170b3ed5f9f/astroid/interpreter/_import/spec.py#L205-L207 --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `find_spec("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. I still think there's a bug for the `ExplicitNamespacePackageFinder.find_module` for namespace packages, since `modname` might be `namespace.package.module` but since `is_namespace` package goes through components, the successive `sys.modules[modname].__path__` may raise error, since modname could be not a package in a namespaced package. But I am not quite sure about that."
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From pylint-dev#1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. But if you have imported it as `celery.result`, `sys.modules["celery"].__spec__` is going to be `None`, and hence the function will return True, and but below where we try to load get `submodule_path`/`__path__` for `celery.result` will fail as it is not a package. See https://github.com/PyCQA/astroid/blob/056d8e5fab7a167f73115d524ab92170b3ed5f9f/astroid/interpreter/_import/spec.py#L205-L207 --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `find_spec("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. I still think there's a bug for the `ExplicitNamespacePackageFinder.find_module` for namespace packages, since `modname` might be `namespace.package.module` but since `is_namespace` package goes through components, the successive `sys.modules[modname].__path__` may raise error, since modname could be not a package in a namespaced package. But I am not quite sure about that. Fixes #7488.
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From pylint-dev#1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. But if you have imported it as `celery.result`, `sys.modules["celery"].__spec__` is going to be `None`, and hence the function will return True, and but below where we try to load get `submodule_path`/`__path__` for `celery.result` will fail as it is not a package. See https://github.com/PyCQA/astroid/blob/056d8e5fab7a167f73115d524ab92170b3ed5f9f/astroid/interpreter/_import/spec.py#L205-L207 --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `find_spec("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. I still think there's a bug for the `ExplicitNamespacePackageFinder.find_module` for namespace packages, since `modname` might be `namespace.package.module` but since `is_namespace` package goes through components, the successive `sys.modules[modname].__path__` may raise error, since modname could be not a package in a namespaced package. But I am not quite sure about that. Fixes pylint-dev/pylint#7488.
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From pylint-dev#1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. But if you have imported it as `celery.result`, `sys.modules["celery"].__spec__` is going to be `None`, and hence the function will return True, and but below where we try to load get `submodule_path`/`__path__` for `celery.result` will fail as it is not a package. See https://github.com/PyCQA/astroid/blob/056d8e5fab7a167f73115d524ab92170b3ed5f9f/astroid/interpreter/_import/spec.py#L205-L207 --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `find_spec("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. Fixes pylint-dev/pylint#7488.
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From pylint-dev#1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. `celery` is recreating module to make it lazily load. See https://github.com/celery/celery/blob/34533ab44d2a6492004bc3df44dc04ad5c6611e7/celery/__init__.py#L150. This module does not have `__spec__` set. Reading through Python's docs, it seems that `__spec__` can be set to None, so it seems like it's not a thing that we can depend upon for namespace checks. See https://docs.python.org/3/reference/import.html#spec__. --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `importlib.util._find_spec_from_path("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. Fixes pylint-dev/pylint#7488.
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From #1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. `celery` is recreating module to make it lazily load. See https://github.com/celery/celery/blob/34533ab44d2a6492004bc3df44dc04ad5c6611e7/celery/__init__.py#L150. This module does not have `__spec__` set. Reading through Python's docs, it seems that `__spec__` can be set to None, so it seems like it's not a thing that we can depend upon for namespace checks. See https://docs.python.org/3/reference/import.html#spec__. --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `importlib.util._find_spec_from_path("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. Fixes pylint-dev/pylint#7488.
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From #1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. `celery` is recreating module to make it lazily load. See https://github.com/celery/celery/blob/34533ab44d2a6492004bc3df44dc04ad5c6611e7/celery/__init__.py#L150. This module does not have `__spec__` set. Reading through Python's docs, it seems that `__spec__` can be set to None, so it seems like it's not a thing that we can depend upon for namespace checks. See https://docs.python.org/3/reference/import.html#spec__. --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `importlib.util._find_spec_from_path("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. Fixes pylint-dev/pylint#7488.
See https://stackoverflow.com/a/42962529. Let's take the following contents as an example: ```python import celery.result ``` From #1777, astroid started to use `processed_components` for namespace check. In the above case, the `modname` is `celery.result`, it first checks for `celery` and then `celery.result`. Before that PR, it'd always check for `celery.result`. `celery` is recreating module to make it lazily load. See https://github.com/celery/celery/blob/34533ab44d2a6492004bc3df44dc04ad5c6611e7/celery/__init__.py#L150. This module does not have `__spec__` set. Reading through Python's docs, it seems that `__spec__` can be set to None, so it seems like it's not a thing that we can depend upon for namespace checks. See https://docs.python.org/3/reference/import.html#spec__. --- The `celery.result` gets imported for me when pylint-pytest plugin tries to load fixtures, but this could happen anytime if any plugin imports packages. In that case, `importlib.util._find_spec_from_path("celery")` will raise ValueError since it's already in `sys.modules` and does not have a spec. Fixes pylint-dev/pylint#7488.
Steps
Description
The
is_namespace()
changes in 2.12 broke introspection of modules compiled bycffi
, which as quoted in the issue, patchsys.modules
. The only reason we are looking atsys.modules
is to support the edge case of oldpkg_resources
-style namespace packages. The principle of false negatives are better than letting things crash suggests that we should just loosen the check to top level modnames ("pylint" rather than "pylint.lint"), because that allows thecffi
modules to not crash without failing thepkg_resources
tests. (Another way of saying: I'm not aware of any false negatives we're causing withpkg_resources
-style packages, since the tests pass, but I can't rule it out.)No tests--did not want to introduce a test dependency on
cffi
.Type of Changes
Related Issue
Closes #1776
Closes pylint-dev/pylint#7399
@dalcinl, does this resolve your issue?