I would like to revisit this conversation with a concrete proposal in the hope of gaining additional feedback.
Proposed Specification Text
The following is a concrete proposal for updating the Version and Platform Checking section of the Python typing specification.
This also contains a rewording of the existing text for clarity and completeness.
========================================================================
Version and platform checking
Type checkers should support narrowing based on sys.version_info, sys.platform, and sys.implementation.name checks.
sys.version_info checks
Type checkers should support sys.version_info comparisons:
import sys
if sys.version_info >= (3, 12):
# Python 3.12+
else:
# Python 3.11 and lower
Supported patterns:
- Equality:
sys.version_info == (3, 10) - Inequality:
sys.version_info != (3, 9) - Comparison:
sys.version_info >= (3, 10),sys.version_info < (3, 12) - Tuple slicing:
sys.version_info[:2] >= (3, 10) - Element access:
sys.version_info[0] >= 3
sys.platform checks
Type checkers should support sys.platform comparisons:
import sys
if sys.platform == 'win32':
# Windows specific definitions
if sys.platform in ("linux", "darwin"):
# Platform-specific stubs for Linux and macOS
...
Supported patterns:
- Equality:
sys.platform == "linux" - Inequality:
sys.platform != "win32" - Membership:
sys.platform in ("linux", "darwin") - Negative membership:
sys.platform not in ("win32", "cygwin")
sys.implementation.name checks
Type checkers should support sys.implementation.name comparisons:
import sys
if sys.implementation.name == "cpython":
# CPython-specific stub
if sys.implementation.name == "micropython":
# MicroPython-specific stub
Supported patterns:
- Equality:
sys.implementation.name == "cpython" - Inequality:
sys.implementation.name != "cpython" - Membership:
sys.implementation.name in ("pypy", "graalpy") - Negative membership:
sys.implementation.name not in ("cpython", "pypy")
Common values: "cpython", "pypy", "micropython", "graalpy", "jython", "ironpython"
Configuration
Type checkers should provide configuration to specify target version, platform, and implementation. The exact mechanism is implementation-defined.
========================================================================
Open Questions
-
Scope of
sys.platformcollections:- Should we support any iterable, or limit to tuple or set literals? Recommend: tuple literals; set literals if feasible for type checkers
- Should we support
not inchecks? Recommend: Yes
-
sys.implementationattributes:- Should we support
sys.implementation.versioncomparisons (similar tosys.version_info)?
- Should we support
-
Combining version, platform, and implementation checks:
- Should we explicitly allow combined checks (e.g.,
if sys.platform == "linux" and sys.implementation.name == "pypy":)?
Recommend: Yes, as long as each individual check is supported. This is not explicitly specified in the proposed text, as the implementation complexity for type checkers needs further assessment.
- Should we explicitly allow combined checks (e.g.,
I’d appreciate feedback on:
- Syntax: Are the proposed patterns (especially collection membership) the right approach?
- Use cases: Are there other alternative implementations or patterns that should be considered?
- Implementation concerns: Type checker maintainers - are there technical challenges I haven’t considered?
- Specification wording: What level of detail should be in the typing spec vs. left to implementation?
Related discussions:
- Options for shorthand for sys.platform checks · python/typing · Discussion #1953 · GitHub
- Python Type Annotations: Tooling/Gaps/Pain Points · pyscript/pyscript · Discussion #2316 · GitHub
Thank you for considering this proposal.