Repository navigation
Conditional import of a class follows imports of all branches #19009
Description
Activity
Thanks for putting this together, and sorry I didn't notice the below looking at previous iterations of it.
The
sys.platformchecks works as expected, the mismatch with your expectations is that mypy still type checks every file in the directory, even if it's not imported on that platform. To fix this you'll have to (I believe) wrap the whole body ofunix.pyin anotherif sys.platformblock.Thanks for the quick response! Your answer perplexes me. Are you saying that Mypy doesn't check what code is actually executed based on conditionals and missing attributes like this don't often occur in the wild because libraries typically set to
Nonerather than not assigning a symbol at all? And if they did, we would see this more frequently? What about standard library modules that only exist on certain platforms?No, Jelle says that invoking
mypy pkgchecks all files inpkg. So it will checkpkg/_pty/windows.pyon linux and vice versa. You can either exclude these files depending on the platform (no built-in way to do that AFAIC, write a bash wrapper), wrap the whole file withif sys.platform == ...guard or use a file-level assertion (see #5308).If there are no related regressions, just
assert sys.platform == 'win32'
after imports in
pkg/_pty/windows.pyand equivalent assert inpkg/_pty/unix.pyshould do the trick.- addedtopic-reachabilityDetecting unreachable codeDetecting unreachable codependingIssues that may be closedIssues that may be closed
on May 1, 2025 (note that you'll need to actually run
mypyin CI on different platforms and/or with different--platformflags separately to check all that code, otherwise errors in files intended for other platforms will pass unnoticed)The file-level assertion worked! Is it possible to achieve this with a comment instead so that one doesn't have to potentially unnecessarily
import sysand immediately assert, often messing up the import blocks?None that I'm aware of, but you don't have to mess up the imports - unless some of your imports are only available on certain platforms, you can
assertright after all imports.Oh, and you may also try
--always-trueand--always-falsefeature to avoid importingsysaltogether, but that might be less trivial to implement - you still have to define/import names you intend to use that way.I tried inline configuration but it looks like this has no effect:
# mypy: platform=linuxYes, the manual section for the
platformflags says:This option may only be set in the global section ([mypy]).
All such global flags cannot be set inline. And it really makes little sense to set a platform per-file: you can't guarantee that no other file (or even external users, underscores don't prevent me from importing that file) imports it on another platform or without such guard.
Thanks for the help! I'm going to close this since there is nothing to be done (I think?) and will be watching the feature request that I just opened: #19013
Bug Report
When you have the following provider module:
and attempt importing this symbol from somewhere else, Mypy does not respect the platform condition.
For example, if you call
pty.openpty()insidemy_pkg._pty.unixand run Mypy on Windows it will show:To Reproduce
Create the following structure:
with the following contents (
__init__.pyfiles are empty):pyproject.tomlpkg/main.pypkg/_pty/interface.pypkg/_pty/session.pypkg/_pty/unix.pypkg/_pty/windows.pyFinally, enter the
mypy-issuedirectory and runmypy pkgon Windows:Expected Behavior
I would expect that Mypy respects the platform condition like it does in other circumstances I've experienced and is documented.
Your Environment