pylint false positive E0401 import errors in vscode while using venv
Asked Answered
C

7

39

I created a venv using python3.6 on my mac os in this folder /Users/kim/Documents/Apps/PythonApps/python36-miros-a3

I ran a pip install pylint after I activated the virtual env

My workspace is in /Users/kim/Documents/Apps/WebApps/miros-a3

Inside my vscode workspace, I have the following Workspace settings

{
    "folders": [
        {
            "path": "."
        }
    ],
    "settings": {
        "python.pythonPath": "/Users/kim/Documents/Apps/PythonApps/python36-miros-a3/bin/python3.6",
        "python.venvPath": "/Users/kim/Documents/Apps/PythonApps"
    }
}

I have tried setting a custom path for the pylint and also changing the venvpath.

The pylint kept complaining about the import statement saying it does not exist.

enter image description here

enter image description here

As you can see, they are in the same folder, and I can definitely execute my python files.

What can I do to avoid these kind of false positive import errors?

I have also tried the following:

  1. go to commandline turn on the virtual env and then type code to activate the vscode as recommended here https://code.visualstudio.com/docs/setup/mac
  2. also tried this https://donjayamanne.github.io/pythonVSCodeDocs/docs/troubleshooting_linting/
Cyclopropane answered 29/6, 2018 at 6:21 Comment(0)
R
76

Pylint has some quirks. In this case it doesn't know where to find your module because it's in subdirectory of your venv path. To solve this:

  1. Put this setting in your workspace or folder settings:

    "python.linting.pylintArgs": [
        "--init-hook",
        "import sys; sys.path.append('<path to folder your module is in>')"
    ]
    

    or, maybe better

  2. Generate .pylintrc file. From integrated terminal with venv activated run:

    pylint --generate-rcfile > .pylintrc 
    

    then open the generated file and uncomment the init-hook= part to be:

    init-hook='import sys; sys.path.append("<path to folder you module is in>")'
    

    Read the .pylintrc and tweak settings if you wish. In both cases path should point to your 'database' folder.

  3. After learning about pylint settings, do it the right way:

    from database.database_dispatcher import ...
    

    See this answer by Anthony Sottile.

Reprisal answered 8/7, 2018 at 21:44 Comment(1)
I much prefer the first approach, because it will work on any system by using {workspaceFolder}: "import sys; sys.path.append({workspaceFolder})"Laurinelaurita
A
13

To me, pylint is correct in flagging this error here

the top level module is database (it contains an __init__.py file)

Your import should look like (fully absolute)

from database.database_dispatcher import ...

or (explicit relative) (yes! the . before the module name is intentional)

from .database_dispatcher import ...

My follow-up guess is that you're currently invoking your script as python ./database/main.py ... which is putting ./database at the beginning of sys.path so it would appear that your imports are working correctly -- this is side-stepping your module structure however. You should be invoking your script using python -m database.main ... instead.

Note that implicit relative imports were removed in python 3.x -- though this (imo) wart of script sys.path insertion remains.

Aldin answered 8/7, 2018 at 22:7 Comment(0)
N
7

Just my $0.02 on how I fixed it in my situation.

My problem was totally related to having pylint installed globally, and coding in a venv. vscode was trying to use the globally installed pylint which simply was not aware of dependencies I installed in my Python venv. This answer solved my problem. It points here which explained how to configure vscode to run using the venv for my project. Once i did that vscode immediately threw a warning saying I had no linting tool installed and prompted me to install one. Once that was done my linting false-positives went away.

Nomadic answered 24/7, 2019 at 13:44 Comment(2)
I like this solution, but the only problem is that pylint will be in the requirement file. I'm ok with it tho.Hemihedral
@Hemihedral You can create a separate requirements-dev.txt and put pylint and other development-only packages in there.Brenn
R
4

Expanding on Gatmando's answer, you need to tell vscode to use the pylint in your .env instead of the global pylint:

In your workspace settings file: .vscode/settings.json, add python.linting.pylintPath and point it to pylint package in your virtualenv:

{
    "python.pythonPath": ".env/bin/python",
    "python.linting.pylintPath": ".env/bin/pylint"
}
Runlet answered 15/11, 2020 at 6:23 Comment(0)
B
2

Another option is to create a .env file in the vscode project root dir:

.env file:

PYTHONPATH=.

Some caveats of using the .env file:

  • It will be used for anything that the vscode ide runs (e.g. pylint, pytest), so the PYTHONPATH may clash between different tools.

  • You could specify multiple dirs to PYTHONPATH to accommodate multiple tools by using separators. (Example: PYTHONPATH=src:. ) However, this is not cross-OS because the Windows separator is ; while Linux/Mac is :


If the .env PYTHONPATH solves your issue, then great. But due to the caveats, I ended up using the pylint --init-hook method because it only affects pylint, and it can be cross-OS:

.vscode/settings.json

    "python.linting.pylintArgs": [
        "--init-hook",
        "import sys, os; sys.path.insert(0, os.path.join('src', 'foo'))"
    ]
Brenn answered 12/1, 2022 at 17:11 Comment(0)
R
1

This problem is likely to affect first-time VS Code Pylint extension users. To solve it, check if you have your own pylint package by running:

pip show pylint 

(or conda list pylint).

...and if not, then install your own pylint for the desired Python version (in the conda environment of your choice, etc.), e.g. by:

pip install pylint

(or conda install -c conda-forge pylint).

and now the VS Code Pylint extension will automatically switch to this version of pylint (after Python kernel restart in VS Code) and use this pylint package (and your Python kernel) instead of its own unreachable bundled-in one (and the system Python).


This can happen by default in a fresh environment (such as a data science container) because the Pylint VS Code extension (Marketplace | Open VSX) has pylint bundled in, in a deeply nested, hard-to-find location, and likely matching your Linux system built-in python rather than your desired up-to-date one. So if you choose your desired Python kernel, it will (by default) not contain the pylint package and the bundled-in one will likely be unreachable from your selected Python kernel (conda environment).

Rugg answered 27/6, 2023 at 8:28 Comment(1)
I know what you are thinking Mods, but no, I genuinely wrote it all by myself. But having read it now I am almost sure the now banned AI detectors would give you a false positive here and with great confidence;)Rugg
G
0

add library to PYTHONPATH

When executing pylint from bash you can do this:

PYTHONPATH="${PYTHONPATH}:library_path" pylint project_path
Gavotte answered 2/3, 2023 at 9:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.