使用subprocess.STARTUPINFO时mypy报错,咨询原因及解决办法
Yep, you’re exactly right—this mypy error is directly tied to the issue you referenced, and it boils down to a simple problem: mypy’s standard library type definitions don’t include Windows-only subprocess attributes like STARTUPINFO, STARTF_USESHOWWINDOW, and SW_HIDE by default. Since mypy runs cross-platform type checks, it assumes these attributes don’t exist unless you explicitly tell it otherwise.
Here are four practical fixes you can use, depending on your project’s needs:
1. Platform Checks + Targeted Type Ignores
Wrap your Windows-specific code in a platform check, and use precise type ignore comments to suppress only the "attribute not defined" errors. This keeps your type checks strict everywhere else:
import subprocess import sys if sys.platform == "win32": startupinfo = subprocess.STARTUPINFO() # type: ignore[attr-defined] startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW # type: ignore[attr-defined] startupinfo.wShowWindow = subprocess.SW_HIDE # type: ignore[attr-defined] proc = subprocess.Popen(["my_command.exe"], startupinfo=startupinfo) else: # Handle non-Windows execution proc = subprocess.Popen(["my_command"])
Using type: ignore[attr-defined] is better than a generic # type: ignore because it only silences the specific error you’re dealing with, not other type issues in the same line.
2. Conditional Imports with TYPE_CHECKING
Use the typing.TYPE_CHECKING constant to declare these attributes during type checks, while safely fetching them at runtime. This lets mypy recognize the attributes without breaking cross-platform execution:
import subprocess import sys from typing import TYPE_CHECKING if TYPE_CHECKING and sys.platform == "win32": # Only visible to mypy during type checks from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW, SW_HIDE else: # Fetch attributes at runtime (or fall back to safe defaults) STARTUPINFO = getattr(subprocess, "STARTUPINFO", None) STARTF_USESHOWWINDOW = getattr(subprocess, "STARTF_USESHOWWINDOW", 0) SW_HIDE = getattr(subprocess, "SW_HIDE", 0) if sys.platform == "win32" and STARTUPINFO is not None: startupinfo = STARTUPINFO() startupinfo.dwFlags |= STARTF_USESHOWWINDOW startupinfo.wShowWindow = SW_HIDE proc = subprocess.Popen(["my_command.exe"], startupinfo=startupinfo) else: proc = subprocess.Popen(["my_command"])
3. Update mypy and Typeshed
Sometimes these missing type definitions get fixed in newer versions of mypy or typeshed (the repository of standard library type hints mypy uses). Try upgrading both:
pip install --upgrade mypy typeshed
Even after updating, you’ll still need platform checks if your code runs cross-platform—this just ensures the type definitions are as complete as possible for Windows.
4. Configure mypy for Windows-Only Checks
If your project only targets Windows, you can tell mypy to use Windows-specific type definitions in your config file. For example, add this to your pyproject.toml:
[tool.mypy] platform = "win32"
This makes mypy recognize all Windows-only subprocess attributes without extra work, but note that it won’t validate your code for non-Windows platforms anymore.
内容的提问来源于stack exchange,提问作者Peter

