microsoft / pylance-release

Documentation and issues for Pylance
Creative Commons Attribution 4.0 International
1.7k stars 769 forks source link

Local imports don't resolve when single files are open (not open folder/workspace mode) #1114

Closed codingatty closed 3 years ago

codingatty commented 3 years ago

Environment data

Expected behaviour

Statement importing from current directory should not be flagged as error

Actual behaviour

Error message: Import "bar" could not be resolvedPylance (reportMissingImports)

Logs

No logs; I've added "python.analysis.logLevel": "Trace" to settings.json, but see no log.

Code Snippet / Additional information

Two python files, foo.py and bar.py, both in C:\test\PylanceError:

foo.py:

import os
import bar   # <--- problem import
mycd = os.getcwd()
print(f"foo says: current directory is {mycd}")

bar.py:

import os
mycd = os.getcwd()
print(f"bar says: current directory is {mycd}")

In VSCode, Pylance flags the statement labeled "problem import" as:

'Import "bar" could not be resolved Pylance (reportMissingImports)'

But the module is clearly there.

When foo.py is executed (whether from the command line or using Run / Run without debugging in VSCode) , it runs as expected, finding and importing bar.py with no issues:

PS C:\test\PylanceError>  c:; cd 'c:\test\PylanceError'; & 'python' 'c:\Users\carro\.vscode\extensions\ms-python.python-2021.3.680753044\pythonFiles\lib\python\debugpy\l3044\pythonFiles\lib\python\debugpy\launcher' '51534' '--' 'c:\test\PylanceError\foo.py'
bar says: current directory is C:\test\PylanceError
foo says: current directory is C:\test\PylanceError
PS C:\test\PylanceError>

I am aware of issue no. #236, but part of the discussion there says "Pylance automatically includes the root path of your workspace"; but the issue here is that Pylance seems not to be including the root path else it would be able to locate the imported module bar.py.

Hard-coding the root path of the workspace directory in settings.json

    "python.analysis.extraPaths": ["C:/test/PylanceError"],

circumvents the issue, but of course only for programs in this directory, i.e., it fixes only this demo illustration, but not the problem itself.

jakebailey commented 3 years ago

Can you please provide the trace logs? If you have opened the folder PylanceError, this should work, so I would be interested in what root we report. https://github.com/microsoft/pylance-release/blob/main/TROUBLESHOOTING.md#filing-an-issue

codingatty commented 3 years ago

@jakebailey, I've added "python.analysis.logLevel": "Trace" to settings.json, but see no log. The only content in the folder are the two files foo.py and bar.py, and the __pycache__ subdir containing bar.cpython-38.pyc, the compiled version of bar.py that is created by the import.

My settings.json (including the "extrapaths" workaround mentioned above):

{
    "editor.suggestSelection": "first",
    "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
    "breadcrumbs.enabled": true,
    "editor.minimap.enabled": false,
    "python.jediEnabled": false,
    "[python]": {

    },
    "python.languageServer": "Pylance",
    "python.showStartPage": false,
    "python.analysis.logLevel": "Trace",
    "python.analysis.extraPaths": ["C:/test/PylanceError"],
    "workbench.editorAssociations": [
        {
            "viewType": "jupyter.notebook.ipynb",
            "filenamePattern": "*.ipynb"
        }
    ]
}
jakebailey commented 3 years ago

Where are you looking for the logs? They should be in the output panel if you select "python language server":

image

codingatty commented 3 years ago

Thanks; I didn't know about the drop-down.

Log (this is without the .extraPaths workaround):

[Info  - 4:45:02 PM] Pylance language server 2021.3.4 (pyright ba71f257) starting
[Info  - 4:45:02 PM] Server root directory: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist
Search paths found for configured python interpreter:
  C:\Program Files\Python38\DLLs
  C:\Program Files\Python38\lib
  C:\Program Files\Python38
  C:\Users\carro\AppData\Roaming\Python\Python38\site-packages
  C:\Program Files\Python38\lib\site-packages
  C:\Program Files\Python38\lib\site-packages\win32
  C:\Program Files\Python38\lib\site-packages\win32\lib
  C:\Program Files\Python38\lib\site-packages\Pythonwin
[Warn  - 4:45:03 PM] stubPath typings is not a valid directory.
[Info  - 4:45:03 PM] Assuming Python platform Windows
[Info  - 4:45:03 PM] Searching for source files
[Info  - 4:45:03 PM] No source files found.
[FG] parsing: c:\test\PylanceError\bar.py (51ms)
[FG] parsing: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\builtins.pyi [fs read 2ms] (98ms)
[FG] binding: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\builtins.pyi (34ms)
[FG] binding: c:\test\PylanceError\bar.py (0ms)
[Info  - 4:45:03 PM] Background analysis(1) root directory: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist
[Info  - 4:45:03 PM] Background analysis(1) started
Background analysis message: setConfigOptions
Background analysis message: ensurePartialStubPackages
Background analysis message: setTrackedFiles
Background analysis message: markAllFilesDirty
Background analysis message: setFileOpened
Background analysis message: getDiagnosticsForRange
Background analysis message: getSemanticTokens full
IntelliCode model c:\Users\carro\.vscode\extensions\visualstudioexptteam.vscodeintellicode-1.2.12\cache\E61945A9A512ED5E1A3EE3F1A2365B88F8FE_E4E9EADA96734F01970E616FAB2FAC19
Loading ONNX runtime...
Loaded ONNX runtime. Creating IntelliCode session...
2021-04-01 15:45:03.8176658 [I:onnxruntime:, inference_session.cc:226 onnxruntime::InferenceSession::ConstructorCommon::<lambda_4a97af1a1c2108607fadd351fab1ba99>::operator ()] Flush-to-zero and denormal-as-zero are off
2021-04-01 15:45:03.8177372 [I:onnxruntime:, inference_session.cc:233 onnxruntime::InferenceSession::ConstructorCommon] Creating and using per session threadpools since use_per_session_threads_ is true
2021-04-01 15:45:03.8366400 [I:onnxruntime:, inference_session.cc:1107 onnxruntime::InferenceSession::Initialize] Initializing session.
2021-04-01 15:45:03.8366641 [I:onnxruntime:, inference_session.cc:1132 onnxruntime::InferenceSession::Initialize] Adding default CPU execution provider.
2021-04-01 15:45:03.8392935 [I:onnxruntime:, reshape_fusion.cc:37 onnxruntime::ReshapeFusion::ApplyImpl] Total fused reshape node count: 0
2021-04-01 15:45:03.8396786 [I:onnxruntime:, reshape_fusion.cc:37 onnxruntime::ReshapeFusion::ApplyImpl] Total fused reshape node count: 0
2021-04-01 15:45:03.8440229 [V:onnxruntime:, inference_session.cc:893 onnxruntime::InferenceSession::TransformGraph] Node placements
2021-04-01 15:45:03.8440390 [V:onnxruntime:, inference_session.cc:895 onnxruntime::InferenceSession::TransformGraph] All nodes have been placed on [CPUExecutionProvider].
2021-04-01 15:45:03.8441876 [V:onnxruntime:, session_state.cc:76 onnxruntime::SessionState::CreateGraphInfo] SaveMLValueNameIndexMapping
2021-04-01 15:45:03.8442455 [V:onnxruntime:, session_state.cc:122 onnxruntime::SessionState::CreateGraphInfo] Done saving OrtValue mappings.
2021-04-01 15:45:03.8444623 [I:onnxruntime:, session_state_utils.cc:103 onnxruntime::session_state_utils::SaveInitializedTensors] Saving initialized tensors.
2021-04-01 15:45:03.8445172 [I:onnxruntime:, session_state_utils.cc:177 onnxruntime::session_state_utils::SaveInitializedTensors] [Memory] SessionStateInitializer statically allocates 35748096 bytes for Cpu

2021-04-01 15:45:03.8530759 [I:onnxruntime:, session_state_utils.cc:219 onnxruntime::session_state_utils::SaveInitializedTensors] Done saving initialized tensors
2021-04-01 15:45:03.8558941 [I:onnxruntime:, inference_session.cc:1282 onnxruntime::InferenceSession::Initialize] Session successfully initialized.
Created IntelliCode session.
[BG(1)] getSemanticTokens full at c:\test\PylanceError\bar.py ...
[BG(1)]   parsing: c:\test\PylanceError\bar.py (29ms)
[BG(1)]   parsing: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\builtins.pyi [fs read 2ms] (100ms)
[BG(1)]   binding: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\builtins.pyi (57ms)
[BG(1)]   binding: c:\test\PylanceError\bar.py (0ms)
[BG(1)]   parsing: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\os\__init__.pyi [fs read 1ms] (35ms)
[BG(1)]   binding: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\os\__init__.pyi (7ms)
[BG(1)]   parsing: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\_typeshed\__init__.pyi [fs read 1ms] (14ms)
[BG(1)]   binding: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\_typeshed\__init__.pyi (2ms)
[BG(1)]   parsing: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\typing.pyi [fs read 1ms] (31ms)
[BG(1)]   binding: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stdlib\typing.pyi (10ms)
[BG(1)]   parsing: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stubs\typing-extensions\typing_extensions.pyi [fs read 0ms] (3ms)
[BG(1)]   binding: c:\Users\carro\.vscode\extensions\ms-python.vscode-pylance-2021.3.4\dist\typeshed-fallback\stubs\typing-extensions\typing_extensions.pyi (1ms)
[BG(1)] getSemanticTokens full at c:\test\PylanceError\bar.py (314ms)
Background analysis message: analyze
[BG(1)] analyzing: c:\test\PylanceError\bar.py ...
[BG(1)]   checking: c:\test\PylanceError\bar.py (2ms)
[BG(1)] analyzing: c:\test\PylanceError\bar.py (2ms)
Background analysis message: getSemanticTokens range
[BG(1)] getSemanticTokens range 0:0 - 2:47 at c:\test\PylanceError\bar.py (1ms)
Background analysis message: getDiagnosticsForRange
Background analysis message: resumeAnalysis
[FG] parsing: c:\test\PylanceError\foo.py (8ms)
[FG] binding: c:\test\PylanceError\foo.py (1ms)
Background analysis message: setFileOpened
Background analysis message: getDiagnosticsForRange
Background analysis message: getSemanticTokens full
[BG(1)] getSemanticTokens full at c:\test\PylanceError\foo.py ...
[BG(1)]   parsing: c:\test\PylanceError\foo.py (30ms)
[BG(1)]   binding: c:\test\PylanceError\foo.py (1ms)
[BG(1)] getSemanticTokens full at c:\test\PylanceError\foo.py (33ms)
Background analysis message: getDiagnosticsForRange
Background analysis message: analyze
[BG(1)] analyzing: c:\test\PylanceError\foo.py ...
[BG(1)]   checking: c:\test\PylanceError\foo.py (1ms)
[BG(1)] analyzing: c:\test\PylanceError\foo.py (1ms)
Background analysis message: resumeAnalysis
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
jakebailey commented 3 years ago

Hm, apparently we don't log the workspace root; we should do that.

The log lines:

[Info  - 4:45:03 PM] Searching for source files
[Info  - 4:45:03 PM] No source files found.

Are very strange, as there should definitely be source files in the workspace.

The log line:

[Warn  - 4:45:03 PM] stubPath typings is not a valid directory.

Concerns me, as "typings" should instead be an absolute path by the time it's been logged. For example, in a scratch project:

[Info  - 5:04:10 PM] Pylance language server 2021.3.4-pr.706576750 (pyright ba71f257) starting
[Info  - 5:04:10 PM] Server root directory: c:\Users\jabaile\.vscode\extensions\ms-python.vscode-pylance-2021.3.4-pr.706576750\dist
[Info  - 5:04:10 PM] Loading configuration file at e:\work\scratch\pyrightconfig.json
[Info  - 5:04:10 PM] Assuming Python platform Windows
[Info  - 5:04:10 PM] No include entries specified; assuming e:\work\scratch
[Info  - 5:04:10 PM] Auto-excluding **/node_modules
[Info  - 5:04:10 PM] Auto-excluding **/__pycache__
[Info  - 5:04:10 PM] Auto-excluding .git
[Info  - 5:04:10 PM] Setting pythonPath for service "scratch": "e:\work\scratch\.venv\Scripts\python.exe"
Search paths found for configured python interpreter:
  C:\Users\jabaile\scoop\apps\python38\current\DLLs
  C:\Users\jabaile\scoop\apps\python38\current\lib
  C:\Users\jabaile\scoop\apps\python38\current
  e:\work\scratch\.venv
  e:\work\scratch\.venv\lib\site-packages
[Warn  - 5:04:11 PM] stubPath e:\work\scratch\typings is not a valid directory.
[Info  - 5:04:11 PM] Searching for source files
[Info  - 5:04:11 PM] Auto-excluding e:\work\scratch\.venv
[Info  - 5:04:11 PM] Found 2 source files

It seems like for some reason, your workspace root is not being set.

To confirm, you're opening a folder in VS Code, and not just opening each file individually from a blank editor, correct?

codingatty commented 3 years ago

"To confirm, you're opening a folder in VS Code, and not just opening each file individually from a blank editor, correct?"

I open each of the python source files individually; typically from Windows Explorer by right clicking and selecting "Open with / Visual Studio Code".

jakebailey commented 3 years ago

That's the problem. You have to open a directory, not individual files. Without a workspace root, we don't know where to root absolute imports other than those that come from libraries.

codingatty commented 3 years ago

So Pylance does not know to use the directory in which a file is located when editing a file?

There are a few usability issues with opening a directory, so it's not my preferred way of working.

You need to go through a potentially long navigation sequence, particularly if you edit programs in differing locations, since each open process starts from the prior one.

Opening a directory requires going to additional steps to get the particular file you want to edit, and is noisy, it starts with a listing of all files and subdirectories, whether of interest or not, instead of the efficient way of getting to the actual file you want to edit.

Most seriously, opening a directory loses all tabs of other files already being edited.

Shouldn't Pylance recognized the directory in which the file being edited resides as the workspace root?

jakebailey commented 3 years ago

I rarely see users using the open file mode. From my experience, most users work on specific projects at once, switching between folders (and tabs are preserved). Note that you can hit Ctrl+P to jump to any file in the workspace, if finding the file is the trouble.

I can see a potential enhancement for this mode; if no workspace root (which means open file only), then for each opened file, treat it's containing folder as its import root. But, that only works for very simple and flat projects; any nested folders would break it.

More info about how your code is typically laid out would be useful.

codingatty commented 3 years ago

Jake, no objection to treating this as an enhancement request, then. In the meantime, I'll just suppress the diagnostic. (I've lived with it a long time, it's not that big a deal, but a recent update to either VSCode or Pylance, not sure which, made the diagnostic more prominent, prompting me to report.) I do think that if VSCode allows you to open a file, Pylance should work with a file that is opened.

The typical layout is as described in the toy example I opened with: one or more Python programs that import a module that resides in the same directory as the program(s) doing the import. I find myself doing this pretty frequently for my own programs that are essentially scripts akin to shell scripts or batch files, which is a common use for Python; or to explore an idea.

Elypha commented 3 years ago

Hey, just got the same difficulty as the OP and want to say that the 'open file mode' is actually not that less used especially for people who are not full-time professional developers when working with their tiny simple projects with about or less than 10 files in total. I think being able to support simple project root is good enough for such a use case, and I really appreciate it that you would like to take this request and make an enhancement in the future.

rangan2510 commented 3 years ago

Hey, I am getting the same issue. Doing a PyTorch project where I am keeping some files in the "layers" folder under cwd. So, when I write "from layers.[filename] import [classname], I get this PyLance issue. The code works fine, but there's yellow squiggly lines.

jakebailey commented 3 years ago

@rangan2510 Are you using open file mode? If you open the directory that contains "layers", does it work as expected?

rangan2510 commented 3 years ago

@jakebailey I get the issue when I open vs code from the directory that contains layers. However, if I open from the root folder, it works fine.

jakebailey commented 3 years ago

Your issue is unrelated and is #68. You probably want to be setting extraPaths to ["./layers"] or trying out the import heuristic noted in that thread.

Samtsirhc commented 3 years ago

I agree all your opinions,and we actually need it. When I work with a tiny project, I would use "open file".

jakebailey commented 3 years ago

This should have been closed a while ago; 2021.6.3 enables the heuristic from https://github.com/microsoft/pylance-release/issues/68#issuecomment-811618343 when in open-file mode.

See: https://github.com/microsoft/pylance-release/blob/main/CHANGELOG.md#202163-23-june-2021