Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better handle imports in scripts #253

Closed
jakebailey opened this issue Aug 17, 2020 · 11 comments
Closed

Better handle imports in scripts #253

jakebailey opened this issue Aug 17, 2020 · 11 comments
Labels
enhancement New feature or request needs investigation Could be an issue - needs investigation

Comments

@jakebailey
Copy link
Member

jakebailey commented Aug 17, 2020

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 #52 (comment). 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.

@judej judej added enhancement New feature or request needs investigation Could be an issue - needs investigation labels Aug 17, 2020
@github-actions github-actions bot removed the triage label Aug 17, 2020
@Ed1123
Copy link

Ed1123 commented Aug 17, 2020

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.

@AllanDaemon
Copy link

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.

@ewerybody
Copy link

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

@jakebailey
Copy link
Member Author

@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...).

@AndreasLuckert
Copy link

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

@danganea
Copy link

danganea commented Feb 17, 2021

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.

@heejaechang
Copy link
Contributor

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?

@DerrickDDInAI
Copy link

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 :).

@jakebailey
Copy link
Member Author

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 microsoft/pyright#1684 (comment)).

@richardjharris
Copy link

richardjharris commented Apr 13, 2021

@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.

@jakebailey
Copy link
Member Author

I'm going to close this in favor of #68; we're going to be able to close that issue soon, as the useImportHeuristic is poised to become a default behavior of our import resolution. The heuristic effectively resolves imports relative to each file (if we don't resolve the import the normal way), which is what this issue was intending to add.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs investigation Could be an issue - needs investigation
Projects
None yet
Development

No branches or pull requests