I am learning a Python book, so I created folder for each chapter to storage code. Working directory is as follows:
└─chapter1
├─a.py
└─b.py
b.py
import a
When I "open by code" in "book" folder, the Yellow wavy line is below the code "import a".
Import "a" could not be resolved
However, module "a" is really imported and it works well.
If I delete "python.languageServer": "Pylance" and use Jedi, yellow wavy line won't show up.
In addition, if i "open by code" in "chapter1" folder, yellow wavy line won't show up.
The Yellow wavy line doesn't have any effect, but it's a nuisance. Is this a normal reminder?
If the answer is Yes, please ignore my question.
See: https://github.com/microsoft/pylance-release/blob/master/TROUBLESHOOTING.md#unresolved-import-warnings
The workspace root is an import root, but it appears you are trying to make each chapter its own project where files are imported there. This warning is important and does have an effect, because Pylance is telling you that we can't resolve your imports and won't offer any completion for those modules.
You may want to consider either opening each folder independently (thus making them their own import roots), or trying VS Code's multi-root workspace support if you want to treat every folder as its own individual import root. I'd normally suggest extraPaths, but you're likely to end up with a lot of paths if you're going to make a folder per-chapter of a book.
Jedi can do this because its import resolution system is different and tries its best to find imports which match, in this case it finds a in the local folder and resolves to this. But this method can cause false negatives and not show warnings for code that wouldn't normally execute.
Also related is #68, microsoft/python-language-server#1602
Now I understand. I appreciate your detailed reply. Thank you!
I think that bug is still valid and applies to any python project that is not keeping its modules inside the root of the project. That is really bad because the best practices are to avoid keeping modules in root and use a folder like src or lib to keep them.
Thus we are penalizing anyone that makes use of good practices for layouting python codebases.
This isn't a bug. You need to configure the tool appropriately.
Pylance automatically includes the root path of your workspace. It also automatically adds a subdirectory called ./src. If you want to include other subdirectories as import resolution paths, you can configure those using the python.analysis.extraPaths setting for the workspace.
If it automatically adds a ./src to the lookup path I agree is not effectively a bug. I seen that github also adds the lib folder to its .gitignore default template for new repos, which is bit weird as it conflicts with a common practice of using lib for keeping you code.
Still, I am pleased that one of the two is working naturally without configuration and I already renamed on recent repository folder from lib/ to src/, at least now I have two strong reasons to consider src better than lib. For more popular project this rename could be bit tricky.
To avoid configuration, ideally pylance could look inside setup.cfg for where the project keeps its modules:
# setup.cfg
[options.packages.find]
where = src
Most published projects don't use src or lib, instead using nothing at all, or a folder name at the top level for their package (e.g. numpy has "numpy", pytorch has "torch") which requires no configuration. When I originally analyzed a bunch of user feedback and repos, I found that it was either a free for all, the "name of the top level module" layout, or src, hence why the feature is as limited as it is (since it can actually hurt people's imports if we're adding too many roots).
It would really be interesting to get a survey on which versions are used for where fro all projects that have one and are hosted on github. I am really curious about a top count report. Publishing such a report may motivate others to adopt a more standardized layout. I am not surprised that there is no standard because when this feature was introduced they missed to recommend a specific folder name. While is convenient to store module in root, any senior python developer can tell you what kind of issues you miss to discover. Still, moving code is hard for big projects.
I'm still having this error, so I filed a question on StackOverflow. Thanks in advance for your consideration.
that's not how python behaves with regard to import, so I'd consider this to be a bug.
My layout is:
root\folder
-->__init__.py
-->__main__.py
file.py
My __main__.py has from file import function
And when I have VS Code open on the root, Pylance can't find the module "file", yet calling python folder works just fine.
@Stanzilla See: https://github.com/microsoft/pylance-release/blob/main/TROUBLESHOOTING.md#unresolved-import-warnings
Okay but that seems like a fairly standard setup, any reason why it's not supported by default?
I guess I'm confused; your text layout is compressed so I can't really tell what is nested in what. In general we assume that the workspace root is the root of all imports. We can't really tell what folders are also import roots without configuration, otherwise we'd just be doing lose non-spec imports and/or be unable to tell if an import has failed.
is there any update on this issue? I tried to add "python.analysis.extraPaths": ["path/to/root/dir/"] in .vscode/settings.json but it doesn't solve the issue at all.
This is a closed issue. If extraPaths isn't working for you, please file a new issue; it's very likely not the same.
no se si con este aporte pueda ayudar a alguno de los que empezamo en la programacion. pero a mi me salia el mismo error en un proyecto de practica y lo resolvi agregando from python.car import Car en mi caso.
antes cuando me salia el errro de advertencia (Import "car" could not be resolved)
era por que solo colocaba:
from car import Car luego le agregue Python y me funciono.
from Python.car import Car
if __name__ == "__main__":
print("Hola Mundo")
car = Car()
car.license = "AMS234"
car.driver = "Andres Herrera"
print(vars(car))
car2 = Car()
car2.license = "QWE567"
car2.driver = "Matha"
print(vars(car2))
Aqui mi aporte a los que recien estamos en la programacion. Saludos
Para el problema del import en python a mi lo que me generaba el problema era la extensión Pylance. Lo que hice para solucionarlo: En el settings.json buscar y deshabilitar la línea que dice “python.languageServer”: ‘Pylance’" y listo, espero les funcione.
Nota: Para los novatos como yo en VSCODE, para abrir el settings.json, ingresan a la paleta de comandos Ctrl+Shift+P y buscan Open Settings (JSON)
@alberto301230 You seem to be suggesting that disabling Pylance entirely fixed that issue; we'd of course like to fix it. There's nothing about that code above that shouldn't be working given the right project layout, if you can reproduce this and open a new issue, that would be appreciated.
that's not how python behaves with regard to import, so I'd consider this to be a bug.
@jakebailey I'd consider reopening this issue using @prosenboim's argument. This is not how python searches for modules, which is unexpected behavior, especially when the warning doesn't give a good clue about the python.analysis.extraPaths hack.
I don't really know how to apply that argument alone without any good examples, and none were included for that comment. Python's import resolution is very nuanced; it depends on your $PWD, how you run the code (module versus script), the environment itself (pth files, paths, installed namespace packages), at-runtime sys.path modifications, etc. We're trying our best to handle as many cases as possible for the most people as possible, and know that there are holes (like #253). Even an editor like PyCharm has the notion of "source roots", where the UI exposes some folders as places you can import code from and roots imports from them. You may never see it, but it's there.
It's really difficult to capture everyone's behaviors while actually providing useful error messages, which is what we want to be able to do. If there are more examples of projects or layouts we can try and detect, then that is good information. If you'd find it useful to have some sort of suggestion to configure the project based on us going through files and seeing if an import root _would_ fix things, then maybe we can do that too. Maybe we do have to do something looser like jedi (which will resolve practically anything, even if it will crash) with some suggestions for config updates. Back when I was designing the "autoSearchPaths" feature, we found that the bulk of people with import issues were just using src directly, and that's why we do that.
But "it doesn't work" or "python doesn't behave this way" is really hard to take action on without additional context. It's frustrating to read comments bumping month old threads, us asking for more info or a new issue so we can properly track and put time into solving it, but then the feedback never happens, and the cycle continues.
That's fair. Apologies for not including additional context/info. Hopefully this is more helpful. I think the standard Module Search Path should be sufficient for many projects.
6.1.2. The Module Search Path
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
- The directory containing the input script (or the current directory when no file is specified).
- PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
- The installation-dependent default.
As it stands currently, Pylance won't even find my module file in the same directory as a script/main module unless it is in the root of the workspace or I add an extraPath.
workspace_root/
|-- external
|-- internal
|-- projA/
|-- projB/
|-- pyProj/
|-- module.py
|-- script.py
script.py imports module.py but Pylance doesn't know where module.py is.
edit: to be even more clear, I'm not sure it's possible for you to recreate sys.path but supporting some of the things, like PYTHONPATH and the directory a script resides in could help.
We certainly implement that algorithm in general, the problem is scripts, which is #253 and is difficult to emulate statically.
We don't know for any given file if it's supposed to be a script or not to know that it is supposed to be allowed to import absolutely from the folder in which it is contained (and therefore should not search the workspace root).
There's also the other problem that this then means that any other file that script import also needs to know that script is running it and that imports are resolved differently with an extra root where script lives. This is the problem, it's infectious and means that maybe one module's imports _do_ actually work when some other file imports it after being invoked a specific way, and that's why we have to have some element of config to try and get a consistent state for each file.
It would be interesting to see if we can do some sort of scan to figure out if by modifying extraPaths, imports for a project would be improved, and offer that as a specific suggestion to change the workspace config.
But in essence, this is the feedback we wanted on #253. That issue hasn't gained much traction and we've been working on other features like go-to-def tweaks and docstring fixes (both very upvoted).
looking more through #253 and some of the other issues referenced there, I have a new appreciation for the problem. extraPaths works as a stopgap until a more robust solution is found, so I'll rescind my initial thought that this issue should be re-opened since I think it's covered elsewhere. Apologies for reviving this old duplicate 😁
No worries, I appreciate the feedback. I just wish there were a clean way to solve it! Maybe there will be an epiphany some day...
vscode- root
folder_1
a.py (has a class C)
folder_2
b.py
Inside b.py, I do from folder_1.a import C; however this does not work. Any suggestions?
Can you please file a new issue and fill out the bug template with trace logs? What you've written should work so long as you've opened up the folder containing both.
Is still a problem
Adding this to the .vscode/settings.json file worked for me 💯:
"python.analysis.extraPaths": ["path_to_the_specified_src_folder"]
It'll be difficult to maintain it updated will all the paths, but at least you won't get those linting errors.
If you're still following this thread (versus the linked issues), we have a new hidden option to experiment with a new import resolution mechanism.
https://github.com/microsoft/pylance-release/issues/68#issuecomment-811618343
https://github.com/microsoft/pylance-release/issues/253#issuecomment-811618821
We'd appreciate feedback there.
Most helpful comment
See: https://github.com/microsoft/pylance-release/blob/master/TROUBLESHOOTING.md#unresolved-import-warnings
The workspace root is an import root, but it appears you are trying to make each chapter its own project where files are imported there. This warning is important and does have an effect, because Pylance is telling you that we can't resolve your imports and won't offer any completion for those modules.
You may want to consider either opening each folder independently (thus making them their own import roots), or trying VS Code's multi-root workspace support if you want to treat every folder as its own individual import root. I'd normally suggest
extraPaths, but you're likely to end up with a lot of paths if you're going to make a folder per-chapter of a book.Jedi can do this because its import resolution system is different and tries its best to find imports which match, in this case it finds
ain the local folder and resolves to this. But this method can cause false negatives and not show warnings for code that wouldn't normally execute.Also related is #68, microsoft/python-language-server#1602