6

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?

Jonathan
  • 2,635
  • 3
  • 30
  • 49
  • what is the reason of the `*.`, mention paths relative to the workspace root of `m1.py` – rioV8 Dec 08 '20 at 16:12
  • @rioV8 Must my files be contained in a Vscode workspace? – Jonathan Dec 08 '20 at 18:07
  • they only mention relative paths so you can try to see if they can be anywhere, otherwise try to add the `lib` to `PYTHONPATH` – rioV8 Dec 08 '20 at 20:27
  • @rioV8 `Pythonpath` will be good at runtime, but it seems that `pylance` has a different idea about `package` location than `Python`. – Jonathan Dec 08 '20 at 21:26
  • PyLance needs to use `PYTHONPATH` for it to find standard packages if you work with an environment. Set `PYTHONPATH` in the shell before starting VSC – rioV8 Dec 08 '20 at 22:06
  • @Jonathan what is the folder of your workspace, `src` or the parent of `src` ? – hamzahik Dec 10 '20 at 13:20
  • @hamzahik The parent of `src`. – Jonathan Dec 10 '20 at 16:38
  • Why do you have a src/.vscode folder with settings.json file? The .vscode folder should be in the parent folder of src, that is the root folder of your workspace. – Jason Harrison Jan 30 '21 at 02:38

4 Answers4

13

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

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

Have you tried that?

  • 4
    An update here is that we've recently added a quick fix/code action to let you easily add extraPaths without fiddling with the UI. You can learn more about that via https://devblogs.microsoft.com/python/python-in-visual-studio-code-july-2021-release/#a-faster-way-to-configure-project-roots – Savannah Ostrowski Aug 27 '21 at 21:41
3

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)

hamzahik
  • 714
  • 4
  • 7
0

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

LightCC
  • 9,804
  • 5
  • 52
  • 92
-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.