Pylance-release: Better handle imports in scripts

Created on 17 Aug 2020  ·  10Comments  ·  Source: microsoft/pylance-release

Invocations of scripts (python path/to/script.py) treat import paths differently than running code as modules. Specifically, invoking a script adds that script's directory to the front of sys.path, which means that its import resolution is different. This is problematic, as there's no way to know if any given file is supposed to be run as a script or not.

This issue tracks better supporting this condition. Splitting this off of https://github.com/microsoft/pylance-release/issues/52#issuecomment-674851297. See also microsoft/python-language-server#1602.

Perhaps there's some configuration that can be done in pyrightconfig/mspythonconfig to mark certain files as scripts.

enhancement needs investigation

Most helpful comment

can you try setting this hidden option, in setting.json, "python.analysis.useImportHeuristic": true, and see whether it helps to resolve local imports? and whether it causes something to break? or whether it behaves differently than what you would expect?

All 10 comments

My specific case is as follows. I'm doing a course. It's organized by weeks, each week covering a given data structure or algorithm. Each week contains from 2 to 6 problems with a folder for each one. What I typically do is open a vscode in the week's folder and work on each problem. Sometimes I need to borrow code from a previous problem, that's why it is so handy to have the root on the week I'm working on. For each problem I create a test file (for pytest) and import the problem's code intro it to test it.

A possible dumb suggestion: what about being able to add the . folder to the root, like a config includeFileDirAsRoot, that for each file to be processed, includes the directory of the file as extra path for that file?

This may be not a perfect solution but would allow some people to work with this issue, setting this in the global / workspace / folder settings to allow and disallow it in the places it needed. For example, enabling this in specific folders and workspaces, while keeping the rest as is.

I also have a project where there the main python package is in a subdirectory.
In my workspace file there is a setting:

"settings": {
        "python.envFile": "${workspaceFolder}/.vscode/.env",
...

and the .env file looks like:

PYTHONPATH=C:\Users\eric\code\my_project\ui

Everything works like a charm except for the Unresolved import reports unless I manually add this like
"python.analysis.extraPaths": ["ui"] but:

• Shouldn't Pylance take note of that python.envFile setting?
• Or would it be feasible to resolve these issues with a Quick fix from this popup offering to add this folder to the extraPaths?

I've seen Pylance actually offers some things like auto imports through these and thats awesome already 👍👍👍 but this one of course shows "No quick fixes available" ... there should be more like these!
image

@ewerybody That would be covered by #275. env files are a detail of the Python extension, and has no idea how to process this format (let alone the Python extension's template-syntax config items...).

I'm still having this error, so I filed a question on StackOverflow. Thanks in advance for your consideration.

Perhaps some heuristics on when to decide whether or not a file is a script could be easily implemented?

  • Detect if __name__ == '__main__' pattern
  • Alternatively, provide some GUI to easily mark file as 'runnable as script', in which case PyLance appends the path of that script's folder into the import resolution list just for the files in the same directory?
  • Since this is a MS extension, is it possible to have knowledge of the currently active launch.json task and change imports based on that? ( Perhaps an ugly solution ...)

I am aware that the FAQ recommends appending the script's folder to the extraPaths variable or using multi-root environments, but I think this is detrimental in a few ways:

  • New users need to understand why this is done and will default to something that just works like Jedi
  • It's cumbersome if no GUI is provided to easily add them for multiple scripts. (perhaps an edge-case)
  • Multi-root environments are more advanced than what simple users need.

Since Python is often picked up by beginners I'm afraid the current import behavior is an issue for newcomers.

can you try setting this hidden option, in setting.json, "python.analysis.useImportHeuristic": true, and see whether it helps to resolve local imports? and whether it causes something to break? or whether it behaves differently than what you would expect?

can you try setting this hidden option, in setting.json, "python.analysis.useImportHeuristic": true, and see whether it helps to resolve local imports? and whether it causes something to break? or whether it behaves differently than what you would expect?

Almost complete beginner here (4 months of learning python; 2 months of experience with VSCode). I repeatedly had these warnings: Import "some_module" could not be resolved. I've just added "python.analysis.useImportHeuristic": true to two of my projects. This removed the warnings. So far, it works fine for me. I'll get back to you if I run into some bugs. Thank you :).

one folder for each chapter, one file for each question, and some shared libraries in the same directory as the question file

This is curious, given the heuristic is supposed to be effectively resolving imports via the directory each file lives in. Is this repo available somewhere?

A glob like ** didn't seem to work.

See #973 (and the reason why that's not simple in https://github.com/microsoft/pyright/issues/1684#issuecomment-806089804).

@jakebailey Sorry, I typoed a lowercase i in useImportHeuristic. I have deleted my comment to avoid misleading others.

The heuristic works fine and correctly detects imports in the same directory as the script.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

savannahostrowski picture savannahostrowski  ·  4Comments

ynouri picture ynouri  ·  3Comments

PedroMDuarte picture PedroMDuarte  ·  5Comments

DannyNemer picture DannyNemer  ·  3Comments

flaree picture flaree  ·  4Comments