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

Completely hide certain files or folders from pyright #2013

Closed
dave-mclean opened this issue Jun 21, 2021 · 5 comments
Closed

Completely hide certain files or folders from pyright #2013

dave-mclean opened this issue Jun 21, 2021 · 5 comments
Labels
as designed Not a bug, working as intended

Comments

@dave-mclean
Copy link

Is your feature request related to a problem? Please describe.
Sometimes I want pyright to wholly ignore the existence of a file or files, to act as though the file just wasn't there. Neither excluding files, not ignoring them seem to achieve this behaviour

Describe the solution you'd like
A way to make pyright behave as though certain files or folders do not exist

Additional context
My project has some __init__.pyi stub files to allow mypy to work correctly, which breaks importing of certain projects in pyright (and therefore Pylance).

If I remove the __init__.pyi files, pyright linting (and Pylance click-through) works correctly.
I can't actually remove the files (because we need them for mypy) so I want to be able to tell Pylance to just ignore the __init__.pyi files entirely. You can only configure Pylance using pyrightconfig.json

However neither excluding nor ignoring the files achieves what I want. I assume because of this comment in the config docs

Note that files in the exclude paths may still be included in the analysis if they are referenced (imported) by source files that are not excluded.)

@erictraut
Copy link
Collaborator

What contents are in your __init__.pyi files? Are they empty, or do they contain stub definitions? Are they associated with internal modules or submodules within your project, or are they meant to be stand-ins for external (third-party) libraries that your project imports?

What symptoms do you see with pyright when these __init__.pyi files are present? Does it result in false positive errors of some sort? If so, please provide a concrete example.

I'm not sure what you mean by "pylance click-through". Can you elaborate?

@dave-mclean
Copy link
Author

The __init__.pyi files are empty. They are a work-around (suggested by Guido) for this issue related to mypy and namespace packages: python/mypy#1645 (comment)

If the __init__.pyi files are present, pyright is unable to resolve imports from namespace packages returning:

error: Import "x.y.z" could not be resolved (reportMissingImports) even though the actual code compiles and runs correctly.

If the __init__.pyi files are removed, pyright will correctly resolve these imports and show no errors.

In Addition:
If using the Pylance Python Language Server in VS-Code when the __init__.pyi files are present it is not possible to right-click >> go-to-defintion to of any of the imports that don't resolve.

If the __init__.pyi files are removed, right-click >> go-to-defintion successfully opens the correct modules in the editor.

Based on your comment here I have been trying to get Pylance to exclude these __init__.pyi files by using the pyrightconfig.json but I have not had success.

I have tried running pyright separately from the command line and find that after when the __init__.pyi files are deleted pyright raises no errors

No configuration file found.
pyproject.toml file found at <dir>
Loading pyproject.toml file at <dir>
Assuming Python version 3.9
Assuming Python platform Darwin
stubPath <dir> is not a valid directory.
Searching for source files
Found 1 source file <file>
0 errors, 0 warnings, 0 infos
Completed in 0.962sec

but when the __init__.pyi files exist but are excluded using configuration in my pyproject.toml pyright cannot resolve the imports for namespace packages.

No configuration file found.
pyproject.toml file found at <dir>
Loading pyproject.toml file at <dir>
Assuming Python version 3.9
Assuming Python platform Darwin
stubPath <dir> is not a valid directory.
Searching for source files
Found 1 source file <file>
<file>:7:6 - error: Import "x.y.z" could not be resolved (reportMissingImports)
<file>:8:6 - error: Import "x.y.z" could not be resolved (reportMissingImports)
2 errors, 0 warnings, 0 infos
Completed in 0.869sec

I'm trying to exclude them using this configuration in my pyproject.toml:

[tool.pyright]
include = [".."]
exclude = [
    "relative/path/to/__init__.pyi",
]

@erictraut
Copy link
Collaborator

I see, thanks for the additional context.

I don't think we'd be interested in adding a new configuration option for pyright just to work around a bug / limitation in mypy. Mypy really should have proper support for namespace packages. PEP 420 has been around since Python 3.3. And adding __init__.pyi is a pretty hacky workaround.

Do you need to use namespace packages here? Could you simply replace your __init__.pyi with __init__.py and turn it into a traditional package that mypy is able to cope with?

Alternatively, would you consider switching from mypy to pyright for all your type checking? Is there something missing from pyright that prevents you from switching away from mypy completely?

If you do need to run mypy (e.g. as part of your CI pipeline), perhaps you could write script that creates the required __init__.pyi files prior to running mypy (and deletes them afterward)?

@dave-mclean
Copy link
Author

Thanks for taking the time to respond especially given that as you say the root cause of my issue is a problem in mypy rather than pyright.

I did consider some alternative options but I felt that given that pyright has the promising looking "exclude" feature in it's config the easiest of all them might be to just successfully exclude the offending files rather than switching the entire type system or implementing other work-arounds.

I also figured being able to truly hide certain files and folders from pyright might be useful in other situations. That was a bit speculative though.

Out of curiosity, how come exclude doesn't work here? Why is pyright still affected by these __init__.pyi files even though they've been excluded in the config.

@erictraut
Copy link
Collaborator

The "include" and "exclude" configuration options are used by pyright to define which files are part of your workspace and which are not. If you run the pyright CLI or run pylance with "python.analysis.diagnosticMode" set to "workspace", it will analyze all of the files in your workspace. These files are fully analyzed (i.e. every statement in each file is considered), and diagnostics are reported for these files.

During analysis of one of these workspace files, pyright might encounter an import that refers to a file outside of your workspace. If so, it will resolve that import (following the normal import resolution rules defined by the Python interpreter and PEP 561), read the file, parse it, and do a minimal amount of type analysis as required to evaluate the types of the imported symbols.

In short, "exclude" doesn't mean "pretend this file doesn't exist in the file system even if it's present". It means "don't include this file in my workspace". If a file is excluded from your workspace but is imported by one of the files in your workspace, it will be consulted for type information as needed.

@erictraut erictraut added the as designed Not a bug, working as intended label Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
as designed Not a bug, working as intended
Projects
None yet
Development

No branches or pull requests

2 participants