Open apparebit opened 1 month ago
The reportMissingModuleSource
check arguably doesn't belong in a type checker. It was added by the pylance team for the benefit of their users. It makes more sense when pyright is being used to power a language server.
That said, I agree that this is a bogus error. The check for reportMissingModuleSource
should be smart enough to ignore cases where the import statement is referencing a submodule of a native module.
@debonte, @rchiodo could someone from the pylance team please take ownership of this issue since you're the most familiar with the code that implements the reportMissingModuleSource
check?
BTW, I was initially unable to repro this bug because I thought it was talking about code that imports the prettypretty
library. The bug report is actually talking about type checking the prettypretty
code itself. Here are the repro steps:
style_extras.py
file and delete the # pyright: ignore [reportMissingModuleSource]
comment.BTW, I was initially unable to repro this bug because I thought it was talking about code that imports the
prettypretty
library. The bug report is actually talking about type checking theprettypretty
code itself.
Oops, good point. Thanks for the new and improved repro steps!
The Bug
Pyright emits
reportMissingModuleSource
warnings for submodules implemented by the same native extension, even though:The Python sources for prettypretty include typing stubs for
prettypretty.color
(the primary native module) and submodules such asprettypretty.color.gamut
andprettypretty.color.style
They also include symbolic links for each of the submodules, which follow native library naming convention and point to the actual native library. E.g.,
prettypretty/color/gamut.abi3.so
points toprettypretty/color.abi3.so
.import prettypretty.color
orimport prettypretty.color.style
as the first statement in a fresh interactive session.Typing stubs, native library, and symbolic library links really should be enough to appease the type checker. If we really want two independent sources of truth for accepting native code, I suggest loading the native library and inspecting that. I must admit I'm not a fan of the symbolic links. I also don't know what to do about Windows. My understanding is that Windows finally does support symbolic links even for files (yay!), but that most Windows users leave that feature disabled because symbolic links might turn into a vector for exploits (oops!).
The Details
Prettypretty uses PyO3 for FFI. AFAIK, it doesn't currently use the multiphase extension initialization of PEP 489 but simply instantiates all module objects during initial loading.
PyO3's level of integration between Rust and Python is impressive. But its module wrangling is disappointing:
__name__
(which is the simple name of the submodule, not the fully qualified name it should be) and__package__
(which is empty).sys.modules
registry and are only accessible through attributes of the main module.__name__
and__package__
attributes as well as registering submodules insys.modules
.VS Code or the command line as well as Pyright versions seem to make no difference. The warnings happen in:
All other software is of similarly recent yet stable vintage:
The one thing I noticed in Pyright's verbose output is that it repeatedly tries to find the same source files. I assume it doesn't cache failures then. Otherwise, I couldn't glean anything else from the trace. It is attached below.
If you want to try for yourself, you can just:
./rr.sh install
to install necessary tools./rr.sh
to build the Python extension module./rr.sh check
to check project, including with PyrightWhile prettypretty does build and run on Windows for CI, the above steps only work with (macOS + Homebrew) or (Linux + APT) for now.
The Gory Details
Verbose command line output
Prettypretty uses `# pyright: ignore [reportMissingModuleSource]` comments to avoid useless warnings. I did enable one of them for this run. ``` (.venv) rgrimm@Precious prettypretty % npm run pyright -- --verbose --pythonpath ./.venv/bin/python > pyright > pyright --verbose --pythonpath ./.venv/bin/python Setting pythonPath for service "