Jonathan
Jonathan

Reputation: 2845

VSCode settings for Pylance

I am running Vscode with the following components:

Version: 1.51.1 (user setup)
Commit: e5a624b788d92b8d34d1392e4c4d9789406efe8f
Date: 2020-11-10T23:34:32.027Z
Electron: 9.3.3
Chrome: 83.0.4103.122
Node.js: 12.14.1
V8: 8.3.110.13-electron.0
OS: Windows_NT x64 10.0.20270
Pylance 2.6

I have the following directory structure:

src
    m1.py
    .vscode
        settings.json
    lib
        m2.py
        .vscode
        settings.json

I use several linters with this environment when developing Python code. Mypy does not have a problem but pylance is unable to resolve imports.

I am trying to import the module m2.py from m1.py when pylance fails. My settings.json file under the src directory is:

{
    "python.autoComplete.extraPaths": [
        "*.lib"
    ]
}

Can anyone see how to resolve this problem?

Upvotes: 6

Views: 30964

Answers (4)

LightCC
LightCC

Reputation: 11659

Set the sub-folders up as proper Python Packages

This method provides conformance with standard Python project packaging guidelines

I recommend a setup that makes the subfolders all proper python packages. To do that, add a blank __init__.py file to each sub-folder with Python modules (i.e. files) in it.

With your original setup, ignoring the .vscode folders:

src/
  __init__.py
  m1.py
  lib/
    __init__.py
    m2.py

In this case, the imports would need to be from the src folder (it would be considered a package itself, since it has a __init__.py file in it):

import src.m1
import src.lib.m2

Make a proper scripts packages

However, I recommend putting your scripts into their own package, not directly in the src folder:

src/
  scripts/
    __init__.py
    m1.py
  lib/
    __init__.py
    m2.py

This allows all your packages to be referenced with a proper package name rather than src like import scripts.m1 and import lib.m2.

Side Notes

  • If you want these packages to be "sub-packages", you can keep an __init__.py in the src folder to make it the root folder for everything.
  • With that change, imports would be import src.scripts.m1 and import src.lib.m2.
  • Python will go up in the parent folders until it finds a folder without an __init__.py file and then start the import statements in a chain from any sub-folders that are packages (i.e. have an __init__.py file).
  • Any folders chained together as packages after this process can be accessed locally without being added to the System or Python path.

How to import modules from the packages

Under this scheme, the m1.py script should be able to import the m2.py with something like the following. Since src is not a package, it is the root from Python's perspective, and not included in import statements.

# In scripts.m1
import lib.m2 as m2

m2.function_1()
a = m2.function_2(m2.symbol_1)

or

from lib.m2 import function_1, function_2, symbol_1

function_1()
a = function_2(symbol_1)

If you add test files in this setup (say within a tests directory inside of scripts), then you can import the script functions as import scripts.m1 as m1 or from script.m1 import *.

This setup makes the package conform to the standard for python packages and so if you want to make it installable or upload it to PyPi (or otherwise distribute it privately with zip files or through a git repo), you can define and build the project using the setuptools package using a standard setup.py file. See Packaging Python Projects

Upvotes: 0

Dibyasom
Dibyasom

Reputation: 1

Your file structure seems to be the problem, why PyLance can't resolve the imports. The best way out: create a python virtual env and activate it.

Linux

python -m venv env
source env/bin/activate

Windows powershell

py -3.6 -m venv env
.\env\Scripts\Activate

Final Step

Having activated your virtual environment,

  • Just hit ctrl+shift+p
  • search for "python" and hit "restart language server"

That should resolve all imports, thanks to the virtual environemnt.

Upvotes: -1

hamzahik
hamzahik

Reputation: 714

If your VSCode workspace folder is the parent of the src folder it is normal to have Pylance complain because by default the root of your project is your workspace folder. You can see that if I import src.lib.m2 Pylance doesn't complain but it does if I use lib.m2:

enter image description here

Since you don't have a runtime error when running your code I would say you are inside the src folder when you run m1.py.

If my assumptions are not true, you'll need to add more details (code sample, how do you run the m1.py file)

Upvotes: 3

Savannah Ostrowski
Savannah Ostrowski

Reputation: 171

Pylance uses python.analysis.extraPaths as opposed to python.autoComplete.extraPaths.

{
    "python.analysis.extraPaths": [
        "*.lib"
    ]
}

Have you tried that?

Upvotes: 17

Related Questions