Originally reported by: Chris Rebert (BitBucket: cvrebert, GitHub: @cvrebert?)
Testcase:
#!python
#!/usr/bin/env python2.7
import distutils.version
Output:
#!txt
************* Module foo
foo.py:1: [C0111(missing-docstring), ] Missing module docstring
foo.py:2: [F0401(import-error), ] Unable to import 'distutils.version'
foo.py:2: [E0611(no-name-in-module), ] No name 'version' in module 'distutils'
foo.py:2: [W0611(unused-import), ] Unused import distutils
Which doesn't agree with Python itself:
#!python
$ python
Python 2.7.3 (default, Apr 10 2013, 06:20:15)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import distutils.version
>>> # no error
_Original comment by_ BitBucket: notsqrt, GitHub: @notsqrt?:
Came across this issue with the following config:
#!text
No config file found, using default configuration
pylint 1.0.0,
astroid 1.0.0, common 0.60.0
Python 2.7.3 (default, Apr 10 2013, 06:20:15)
[GCC 4.6.3]
_Original comment by_ Sylvain Thénault (BitBucket: sthenault, GitHub: @sthenault?):
PYTHONPATH pb ?
#!python
[syt@host pylint]$ cat x.py
import distutils.version
print distutils.version
[syt@host pylint]$ pylint -rn x.py
************* Module pylint.x
C: 1, 0: Missing module docstring (missing-docstring)
[syt@host pylint]$ pylint --version
pylint 1.0.0,
astroid 1.0.0, common 0.60.0
Python 2.7.4 (default, Apr 19 2013, 18:28:01)
[GCC 4.7.3]
_Original comment by_ Sylvain Thénault (BitBucket: sthenault, GitHub: @sthenault?):
can't reproduce
_Original comment by_ BitBucket: notsqrt, GitHub: @notsqrt?:
Seems to be messed up by virtualenvs.
Steps to reproduce :
mktmpenv)pip install pylintpylint x.py(with the same x.py as above)
Fails with version:
pylint 1.0.0,
astroid 1.0.1, common 0.60.0
Python 2.7.5+ (default, Sep 19 2013, 13:48:49)
[GCC 4.8.1]
_Original comment by_ Jan Vermaete (BitBucket: jan.vermaete):
I confirm it's related to virtualenv (python -m venv env).
-> it's not 'invalid', IMHO
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (In
tel)] on win32
Astroid: Changeset: 1073 (4b0a497acee0) Merged in AndroWiiid/astroid/dev (pull request #12) …
common: Changeset:1589 (e9fc9f452231) merge default heads
pylint: Changeset:1149 (656d711815bc) fix tests broken due to Windows line ending or by output format change introduced in ed904ee30bc5
_Original comment by_ BitBucket: fbretel, GitHub: @fbretel?:
Confirmed on Ubuntu 13.10, Python 2.7.5+, pylint 0.26.0 or 1.0.0, astng 0.24.3, common 0.60.0, virtualenv 1.10.1.
May be related to http://stackoverflow.com/a/14293787/421846
_Original comment by_ BitBucket: elmirjagudin, GitHub: @elmirjagudin?:
This is caused by the monkey-patched distutils package which virtualenv creates.
The virtualenv script only creates distutils/__init__.py inside it's sandbox, it does not create the distutils/versions.py file. When you do 'import distutils.version', the distutils module will be loaded from the sandbox, but the version module will be loaded from the global location. For example, this is run from inside of "~boris/tst" sandbox:
#!python
$ python
>>> import distutils.version
>>> distutils.__file__
'/home/boris/tst/lib/python2.7/distutils/__init__.pyc'
>>> distutils.version.__file__
'/usr/lib/python2.7/distutils/version.pyc'
However, due to how modules look-up is implemented in logilab.common.modutils, pylint can't locate distutils.version. Pylint will only look for version module in the same directory where it have found it's parent module distutils.
IMHO, the problem lies in logilab.common.modutils._module_file() function. It calls find_module() to locate the module. For any child modules it specifies only parent's directory as the search path.
_Original comment by_ Sylvain Thénault (BitBucket: sthenault, GitHub: @sthenault?):
Removing version: 1.0 (automated comment)
_Original comment by_ Buck Evan (BitBucket: bukzor, GitHub: @bukzor?):
@elmirjagudin What is your proposed change? From what I can see, the distutils.__init__ does a fair bit of work to make the namespace work as it does, and the only way pylint could know what's done there is to execute it, which would break the contract of "pylint is a static analysis tool".
_Original comment by_ Buck Evan (BitBucket: bukzor, GitHub: @bukzor?):
Is there any conceivable way this will be fixed?
_Original comment by_ Claudiu Popa (BitBucket: PCManticore, GitHub: @PCManticore):
Probably, it just needs someone to write the patch. We'll look into it after finishing with pylint 1.5.0, that's the main priority for now.
I still get this 4 years old bug when pylint is installed in a virtual environment... any fix planned?
any work around?
@p00j4 yeah, just add comment to your code, like this:
from distutils.version import LooseVersion # pylint: disable=no-name-in-module,import-error
and this way pylint will ignore two specific errors for that specific line.
This issue is still (!) here:
python3 --version # Python 3.4.3
python3 -m virtualenv .venv
source .venv/bin/activate
which python3 # python3 is .venv/bin/python3
python3 -m pip install pylint==1.8.3 # Successfully installed astroid-1.6.2 isort-4.3.4 lazy-object-proxy-1.3.1 mccabe-0.6.1 pylint-1.8.3 six-1.11.0 wrapt-1.10.11
echo 'import distutils.version' > dummy.py
python3 -m pylint dummy.py
*** Module dummy
C: 1, 0: Missing module docstring (missing-docstring)
E: 1, 0: No name 'version' in module 'distutils' (no-name-in-module)
E: 1, 0: Unable to import 'distutils.version' (import-error)
W: 1, 0: Unused import distutils.version (unused-import)
Your code has been rated at -110.00/10
Yes, @florent-vial this issue is still (!) here! No one worked on it and no one volunteered to do it, as far as I know. Have you seen how distutils looks in a virtualenv? Something like this if you never saw it https://github.com/pypa/virtualenv/blob/master/virtualenv_embedded/distutils-init.py. From the point of view of pylint, this version module is simply not there. The only way we could potentially understand this is if we could somehow manage to write an astroid brain for distutils that patches version to be the module outside of the virtualenv, but this sounds hacky, I'm not even sure it's going to work and to be honest I don't even have time to do it.
Hey thanks for the feedback. I have little insight into the virtualenv internals to say the least, so i am not ready either to dig into this one.
I used the inline # pylint: disable=no-name-in-module,import-error wherever i am using distutils.version, which is an ok workaround after all since i execute code anyway somewhere else.
@florent-vial you can set ignored-modules = distutils in .pylintrc file so there will be no need to add directives on every line.
@kapsh thank you for the hint. For others wanting the same workaround, this is the needed pylintrc config:
[TYPECHECK]
ignored-modules = distutils
@PCManticore how about teaching pylint (maybe via extension) to ignore import errors for distutils (if we are inside a virtualenv) ?
Looking at the history of this issue I am the person with the most commits/references flooding the history. I may as well try to write a patch for it.
Some anecdata on this: I ran into this issue again recently and updating to Python 3.7 (from 3.6) made it go away.
Despite the comment from @mattsb42-aws , I'm encountering this problem with Python 3.7.2.
When's the next pylint release? We are waiting for this fix :)
https://github.com/PyCQA/pylint/releases
Most helpful comment
I still get this 4 years old bug when pylint is installed in a virtual environment... any fix planned?