From e34cbc78499ba9ab60e01ca5bcd9ded87a9cffd1 Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Sat, 15 Aug 2026 22:15:33 +0200 Subject: [PATCH 1/6] Update specification for directives for sys.implementation and sys.platform checks. Signed-off-by: Jos Verlinde --- docs/spec/directives.rst | 144 +++++++++++++++++++++++++++++++++++---- 1 file changed, 131 insertions(+), 13 deletions(-) diff --git a/docs/spec/directives.rst b/docs/spec/directives.rst index 488d71a26..fe6aa102a 100644 --- a/docs/spec/directives.rst +++ b/docs/spec/directives.rst @@ -154,23 +154,141 @@ left undefined by the typing spec at this time. Version and platform checking ----------------------------- -Type checkers are expected to understand simple version and platform -checks, e.g.:: +Type checkers should support narrowing based on: + * ``sys.version_info`` + * ``sys.platform`` + * ``sys.implementation.version`` + * ``sys.implementation.name`` - import sys +Type checkers should support combining these checks with: + * A ``not`` unary operator + * An ``and`` or ``or`` binary operator - if sys.version_info >= (3, 12): - # Python 3.12+ - else: - # Python 3.11 and lower +Type checkers are only required to support the fully-qualified form (e.g., ``sys.platform``). +Support for aliases or import variants (e.g., ``from sys import platform``) is not required, though type checkers may choose to support them. - if sys.platform == 'win32': - # Windows specific definitions - else: - # Posix specific definitions +The comparison patterns for these variables are described in more detail in the following paragraphs. -Don't expect a checker to understand obfuscations like -``"".join(reversed(sys.platform)) == "xunil"``. +sys.version_info checks +^^^^^^^^^^^^^^^^^^^^^^^^ + +Type checkers should support the following comparison patterns: + * ``sys.version_info >= <2-tuple>`` + * ``sys.version_info < <2-tuple>`` + +Comparisons checks are only supported against the first two elements of the version tuple. +Use of named attributes is not supported. + +.. code-block:: python + :caption: Example `sys.version_info` + :emphasize-lines: 2 + + import sys + if sys.version_info >= (3, 12): + # Python 3.12+ + else: + # Python 3.11 and lower + +sys.platform checks +^^^^^^^^^^^^^^^^^^^ + +Type checkers should support the following comparison patterns: + * ``sys.platform == `` + * ``sys.platform != `` + * ``sys.platform in `` + * ``sys.platform not in `` + + Common values: ``"linux"``, ``"darwin"``, ``"win32"``, ``"emscripten"``, ``"wasi"`` + +The membership checks ``in`` and ``not in``, only support simple containment testing to a tuple of literal strings. + +.. code-block:: python + :caption: Example `sys.platform` + :emphasize-lines: 2,4 + + import sys + if sys.platform == 'win32': + # Windows specific definitions + if sys.platform in ("linux", "darwin"): + # Platform-specific stubs for Linux and macOS + ... + + +sys.implementation.name checks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Type checkers should support comparison patterns: + * ``sys.implementation.name == `` + * ``sys.implementation.name != `` + * ``sys.implementation.name in `` + * ``sys.implementation.name not in `` + + Common values: ``"cpython"``, ``"pypy"``, ``"micropython"``, ``"graalpy"``, ``"jython"``, ``"ironpython"`` + +.. code-block:: python + :caption: Example `sys.implementation.name` + :emphasize-lines: 2,4 + + import sys + if sys.implementation.name == "cpython": + # CPython-specific stub + if sys.implementation.name == "micropython": + # MicroPython-specific stub + + +sys.implementation.version checks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Type checkers should support the following comparison patterns: + * ``sys.implementation.version >= <2-tuple>`` + * ``sys.implementation.version < <2-tuple>`` + +Comparisons checks are only supported against the first two elements of the implementation version tuple. +Use of named attributes is not supported. + +.. code-block:: python + :caption: Example `sys.implementation.version` + :emphasize-lines: 2,4 + + import sys + if sys.implementation.name == "pypy" and sys.implementation.version >= (7, 3): + # PyPy version 7.3 and above + if sys.implementation.name == "micropython" and sys.implementation.version >= (1, 24): + # MicroPython version 1.24 and above + +.. note:: + + ``sys.implementation.version`` is a tuple, in the same format as sys.version_info. However it represents the version of the Python implementation rather than the version of the Python language. + This has a distinct meaning from the specific version of the Python language to which the currently running interpreter conforms. For CPython this is the same as `sys.version_info`. + + +No support for complex expressions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Type checkers are only required to support the above patterns, and are not required to evaluate complex expressions involving these variables. +For example, the pattern ``sys.platform == "linux"`` is supported but other syntax variants such as ``platform == "linux"`` and ``"win" not in sys.platform`` are not supported. + +Therefore checkers are **not required** to understand obfuscations such as: + +.. code-block:: python + :caption: Examples of unsupported or overly complex version/platform checks + :emphasize-lines: 3,5,7 + + import sys + from sys import platform + if "".join(reversed(sys.platform)) == "xunil": + # Linux specific code + if platform == "linux": + # Linux specific code + if "win" not in sys.platform: + # Non-Windows specific code + + +Configuration +^^^^^^^^^^^^^ + +Type checkers should provide configuration or CLI options to specify target sys.version, sys.platform, sys.implementation.name and sys.implementation.version. +The exact mechanism for this is implementation-defined by the type checker. .. _`deprecated`: From 33c447706217fe86becdba2568fabf5b9e22266e Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Sat, 15 Aug 2026 22:15:33 +0200 Subject: [PATCH 2/6] Update docs/spec/directives.rst Formatting improvements. Co-authored-by: Jelle Zijlstra --- docs/spec/directives.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/spec/directives.rst b/docs/spec/directives.rst index fe6aa102a..b70bca048 100644 --- a/docs/spec/directives.rst +++ b/docs/spec/directives.rst @@ -200,7 +200,7 @@ Type checkers should support the following comparison patterns: Common values: ``"linux"``, ``"darwin"``, ``"win32"``, ``"emscripten"``, ``"wasi"`` -The membership checks ``in`` and ``not in``, only support simple containment testing to a tuple of literal strings. +The membership checks ``in`` and ``not in`` only support simple containment testing with a tuple of literal strings. .. code-block:: python :caption: Example `sys.platform` From 2c4e700bb39cd7697c52e3aa8369d9849eaec19a Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Sat, 15 Aug 2026 22:15:33 +0200 Subject: [PATCH 3/6] Clarify language in directives regarding named attribute usage in version comparisons. Signed-off-by: Jos Verlinde --- docs/spec/directives.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/spec/directives.rst b/docs/spec/directives.rst index b70bca048..8ecc6624a 100644 --- a/docs/spec/directives.rst +++ b/docs/spec/directives.rst @@ -177,7 +177,7 @@ Type checkers should support the following comparison patterns: * ``sys.version_info < <2-tuple>`` Comparisons checks are only supported against the first two elements of the version tuple. -Use of named attributes is not supported. +Use of named attributes is not mandated. .. code-block:: python :caption: Example `sys.version_info` @@ -244,7 +244,7 @@ Type checkers should support the following comparison patterns: * ``sys.implementation.version < <2-tuple>`` Comparisons checks are only supported against the first two elements of the implementation version tuple. -Use of named attributes is not supported. +Use of named attributes is not mandated. .. code-block:: python :caption: Example `sys.implementation.version` @@ -266,7 +266,7 @@ No support for complex expressions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type checkers are only required to support the above patterns, and are not required to evaluate complex expressions involving these variables. -For example, the pattern ``sys.platform == "linux"`` is supported but other syntax variants such as ``platform == "linux"`` and ``"win" not in sys.platform`` are not supported. +For example, the pattern ``sys.platform == "linux"`` is supported but other syntax variants such as ``platform == "linux"`` and ``"win" not in sys.platform`` are not mandated. Therefore checkers are **not required** to understand obfuscations such as: From 98e3697d27b8ff617aa5b7b6aa978c2bb1e351c3 Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Sat, 15 Aug 2026 22:15:34 +0200 Subject: [PATCH 4/6] spec/directives: Process review comments. Signed-off-by: Jos Verlinde --- docs/spec/directives.rst | 64 +++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/docs/spec/directives.rst b/docs/spec/directives.rst index 8ecc6624a..eae15d291 100644 --- a/docs/spec/directives.rst +++ b/docs/spec/directives.rst @@ -154,7 +154,7 @@ left undefined by the typing spec at this time. Version and platform checking ----------------------------- -Type checkers should support narrowing based on: +Type checkers should understand code paths as definitely reachable or not reachable due to comparison tests against these symbols: * ``sys.version_info`` * ``sys.platform`` * ``sys.implementation.version`` @@ -176,8 +176,9 @@ Type checkers should support the following comparison patterns: * ``sys.version_info >= <2-tuple>`` * ``sys.version_info < <2-tuple>`` -Comparisons checks are only supported against the first two elements of the version tuple. -Use of named attributes is not mandated. +Comparison checks are only supported against the first two elements of the version tuple. +It should be noted that type checkers may choose to also support the 3-tuple ``sys.version_info >= <3-tuple>``. +Type checkers are not expected to support comparisons with named attributes of `sys.version_info`. .. code-block:: python :caption: Example `sys.version_info` @@ -186,8 +187,10 @@ Use of named attributes is not mandated. import sys if sys.version_info >= (3, 12): # Python 3.12+ + elif sys.version_info >= (3, 11): + # Python 3.11 else: - # Python 3.11 and lower + # Python 3.10 and lower sys.platform checks ^^^^^^^^^^^^^^^^^^^ @@ -195,12 +198,13 @@ sys.platform checks Type checkers should support the following comparison patterns: * ``sys.platform == `` * ``sys.platform != `` - * ``sys.platform in `` - * ``sys.platform not in `` + * ``sys.platform.startswith()`` + * ``sys.platform in `` + * ``sys.platform not in `` Common values: ``"linux"``, ``"darwin"``, ``"win32"``, ``"emscripten"``, ``"wasi"`` -The membership checks ``in`` and ``not in`` only support simple containment testing with a tuple of literal strings. +The membership checks ``in`` and ``not in`` only support simple containment testing with a set of literal strings. .. code-block:: python :caption: Example `sys.platform` @@ -220,11 +224,13 @@ sys.implementation.name checks Type checkers should support comparison patterns: * ``sys.implementation.name == `` * ``sys.implementation.name != `` - * ``sys.implementation.name in `` - * ``sys.implementation.name not in `` + * ``sys.implementation.name in `` + * ``sys.implementation.name not in `` + Default value: ``"cpython"``, unless configured otherwise. Common values: ``"cpython"``, ``"pypy"``, ``"micropython"``, ``"graalpy"``, ``"jython"``, ``"ironpython"`` + .. code-block:: python :caption: Example `sys.implementation.name` :emphasize-lines: 2,4 @@ -239,12 +245,16 @@ Type checkers should support comparison patterns: sys.implementation.version checks ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``sys.implementation.version`` is a tuple, in the same format as sys.version_info. However it represents the version of the Python implementation +rather than the version of the Python language. This has a distinct meaning from the specific version of the Python language to which the currently +running interpreter conforms. For CPython this is the same as `sys.version_info`. + Type checkers should support the following comparison patterns: * ``sys.implementation.version >= <2-tuple>`` * ``sys.implementation.version < <2-tuple>`` -Comparisons checks are only supported against the first two elements of the implementation version tuple. -Use of named attributes is not mandated. +Comparison checks are only supported against the first two elements of the implementation version tuple. +Type checkers are not required to support comparisons against named attributes of `sys.implementation.version`. .. code-block:: python :caption: Example `sys.implementation.version` @@ -256,39 +266,45 @@ Use of named attributes is not mandated. if sys.implementation.name == "micropython" and sys.implementation.version >= (1, 24): # MicroPython version 1.24 and above -.. note:: - - ``sys.implementation.version`` is a tuple, in the same format as sys.version_info. However it represents the version of the Python implementation rather than the version of the Python language. - This has a distinct meaning from the specific version of the Python language to which the currently running interpreter conforms. For CPython this is the same as `sys.version_info`. - No support for complex expressions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Type checkers are only required to support the above patterns, and are not required to evaluate complex expressions involving these variables. -For example, the pattern ``sys.platform == "linux"`` is supported but other syntax variants such as ``platform == "linux"`` and ``"win" not in sys.platform`` are not mandated. +Type checkers are required to support the above patterns, and are not required to evaluate other comparisons or other syntax variants. Therefore checkers are **not required** to understand obfuscations such as: .. code-block:: python :caption: Examples of unsupported or overly complex version/platform checks - :emphasize-lines: 3,5,7 + :emphasize-lines: 4,6,8 import sys from sys import platform + if "".join(reversed(sys.platform)) == "xunil": - # Linux specific code + # Typecheckers will not be required to understand this obfuscated check if platform == "linux": - # Linux specific code + # Typecheckers will not be required to understand this import alias for sys.platform if "win" not in sys.platform: - # Non-Windows specific code + # Typecheckers will not be required to understand this reversed membership check Configuration ^^^^^^^^^^^^^ -Type checkers should provide configuration or CLI options to specify target sys.version, sys.platform, sys.implementation.name and sys.implementation.version. -The exact mechanism for this is implementation-defined by the type checker. +Type checkers must provide configuration or CLI options to specify target ``sys.version``, ``sys.platform``, ``sys.implementation.name`` and ``sys.implementation.version``. + +================================ ========================== ============== =========================================================================== + Symbol Suggested Format Example Suggested Default +================================ ========================== ============== =========================================================================== +``sys.version`` string ``"major.minor"`` ``"3.11"`` The version of the Python interpreter used to run the type checker. +``sys.platform`` lowercase string ``"linux"`` The platform of the Python interpreter used to run the type checker. +``sys.implementation.name`` lowercase string ``"cpython"`` ``"cpython"`` unless configured otherwise. +``sys.implementation.version`` string ``"major.minor"`` ``"3.14"`` The value used for ``sys.version`` unless configured otherwise. +================================ ========================== ============== =========================================================================== + +The configuration options should allow users to specify the target values for these symbols, so that type checkers can evaluate the version and platform checks correctly. +The exact mechanism and name for these configuration options is implementation-specific, and defined by each type checker. .. _`deprecated`: From 4ca8fd6399cde04dcd7996dcbdc8605b71ebdd39 Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Tue, 8 Sep 2026 19:24:55 +0200 Subject: [PATCH 5/6] spec/directives: Process additional review comments. --- docs/spec/directives.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/spec/directives.rst b/docs/spec/directives.rst index eae15d291..201b99dcc 100644 --- a/docs/spec/directives.rst +++ b/docs/spec/directives.rst @@ -177,7 +177,7 @@ Type checkers should support the following comparison patterns: * ``sys.version_info < <2-tuple>`` Comparison checks are only supported against the first two elements of the version tuple. -It should be noted that type checkers may choose to also support the 3-tuple ``sys.version_info >= <3-tuple>``. +Type checkers may choose to also support the 3-tuple ``sys.version_info >= <3-tuple>``. Type checkers are not expected to support comparisons with named attributes of `sys.version_info`. .. code-block:: python @@ -199,6 +199,9 @@ Type checkers should support the following comparison patterns: * ``sys.platform == `` * ``sys.platform != `` * ``sys.platform.startswith()`` + * ``sys.platform in `` + * ``sys.platform not in `` +Type checkers may also support the following comparison patterns: * ``sys.platform in `` * ``sys.platform not in `` @@ -247,7 +250,7 @@ sys.implementation.version checks ``sys.implementation.version`` is a tuple, in the same format as sys.version_info. However it represents the version of the Python implementation rather than the version of the Python language. This has a distinct meaning from the specific version of the Python language to which the currently -running interpreter conforms. For CPython this is the same as `sys.version_info`. +running interpreter conforms. For CPython (``sys.implementation.name == "cpython"``) this is the same as `sys.version_info`. Type checkers should support the following comparison patterns: * ``sys.implementation.version >= <2-tuple>`` @@ -292,7 +295,7 @@ Therefore checkers are **not required** to understand obfuscations such as: Configuration ^^^^^^^^^^^^^ -Type checkers must provide configuration or CLI options to specify target ``sys.version``, ``sys.platform``, ``sys.implementation.name`` and ``sys.implementation.version``. +Type checkers must be able to retrieve the information from the python implementation's runtime environment, or provide configuration or CLI options to specify target ``sys.version``, ``sys.platform``, ``sys.implementation.name`` and ``sys.implementation.version``. ================================ ========================== ============== =========================================================================== Symbol Suggested Format Example Suggested Default From c0639ddd3076e1c0217c6c0fe6a03a0e279a15ac Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Mon, 21 Sep 2026 23:33:45 +0200 Subject: [PATCH 6/6] spec/directives: Process additional review comments. Also : - wrapped lines to ~85 characters - tables to 110 characters - Improved .rst formatting and markup The Intent is for these commits allow tracability of review comments, but to be squashed to a single commit during merge. Signed-off-by: Jos Verlinde --- docs/spec/directives.rst | 210 ++++++++++++++++++++++++--------------- 1 file changed, 128 insertions(+), 82 deletions(-) diff --git a/docs/spec/directives.rst b/docs/spec/directives.rst index 201b99dcc..0582ccfa9 100644 --- a/docs/spec/directives.rst +++ b/docs/spec/directives.rst @@ -154,88 +154,111 @@ left undefined by the typing spec at this time. Version and platform checking ----------------------------- -Type checkers should understand code paths as definitely reachable or not reachable due to comparison tests against these symbols: - * ``sys.version_info`` - * ``sys.platform`` - * ``sys.implementation.version`` - * ``sys.implementation.name`` +Type checkers should understand code paths as definitely reachable or not reachable +due to comparison tests against these symbols: + +* ``sys.version_info`` +* ``sys.platform`` +* ``sys.implementation.version`` +* ``sys.implementation.name`` Type checkers should support combining these checks with: - * A ``not`` unary operator - * An ``and`` or ``or`` binary operator -Type checkers are only required to support the fully-qualified form (e.g., ``sys.platform``). -Support for aliases or import variants (e.g., ``from sys import platform``) is not required, though type checkers may choose to support them. +* A ``not`` unary operator +* An ``and`` or ``or`` binary operator + +Type checkers are only required to support the fully-qualified form +(e.g., ``sys.platform``). Support for aliases or import variants +(e.g., ``from sys import platform``) is not required, though type checkers may +choose to support them. -The comparison patterns for these variables are described in more detail in the following paragraphs. +The comparison patterns for these variables are described in more detail in the +following paragraphs. sys.version_info checks ^^^^^^^^^^^^^^^^^^^^^^^^ Type checkers should support the following comparison patterns: - * ``sys.version_info >= <2-tuple>`` - * ``sys.version_info < <2-tuple>`` -Comparison checks are only supported against the first two elements of the version tuple. -Type checkers may choose to also support the 3-tuple ``sys.version_info >= <3-tuple>``. -Type checkers are not expected to support comparisons with named attributes of `sys.version_info`. +* ``sys.version_info >= <2-tuple>`` +* ``sys.version_info < <2-tuple>`` + +where ``<2-tuple>`` is a literal tuple of two literal integers. + +Comparison checks are only supported against the first two elements of the version +tuple. Type checkers may choose to also support the 3-tuple +``sys.version_info >= <3-tuple>``. Type checkers are not expected to support +comparisons with named attributes of ``sys.version_info``. .. code-block:: python - :caption: Example `sys.version_info` - :emphasize-lines: 2 + :caption: Examples of ``sys.version_info`` checks + :emphasize-lines: 2,4 import sys - if sys.version_info >= (3, 12): - # Python 3.12+ - elif sys.version_info >= (3, 11): - # Python 3.11 - else: + if sys.version_info >= (3, 13): + # Python 3.13+ + elif sys.version_info < (3, 11): # Python 3.10 and lower + else: + # Python 3.11, 3.12 sys.platform checks ^^^^^^^^^^^^^^^^^^^ Type checkers should support the following comparison patterns: - * ``sys.platform == `` - * ``sys.platform != `` - * ``sys.platform.startswith()`` - * ``sys.platform in `` - * ``sys.platform not in `` -Type checkers may also support the following comparison patterns: - * ``sys.platform in `` - * ``sys.platform not in `` - Common values: ``"linux"``, ``"darwin"``, ``"win32"``, ``"emscripten"``, ``"wasi"`` +* ``sys.platform == `` +* ``sys.platform != `` +* ``sys.platform.startswith()`` +* ``sys.platform in `` +* ``sys.platform in `` +* ``sys.platform in `` +* ``sys.platform not in `` +* ``sys.platform not in `` +* ``sys.platform not in `` + +Common values: ``"linux"``, ``"darwin"``, ``"win32"``, ``"emscripten"``, +``"wasi"`` -The membership checks ``in`` and ``not in`` only support simple containment testing with a set of literal strings. +The membership checks ``in`` and ``not in`` only support simple containment +testing with a tuple, set, or list of literal strings. .. code-block:: python - :caption: Example `sys.platform` - :emphasize-lines: 2,4 + :caption: Examples of ``sys.platform`` checks + :emphasize-lines: 2,4,6,8 import sys - if sys.platform == 'win32': - # Windows specific definitions - if sys.platform in ("linux", "darwin"): + if sys.platform == "win32": + # Windows-specific definitions + elif sys.platform in ("linux", "darwin"): # Platform-specific stubs for Linux and macOS - ... + elif sys.platform.startswith("freebsd"): + # FreeBSD-specific stubs, including versions such as "freebsd8" + if sys.platform not in ["wasi", "emscripten"]: + # Stubs for platforms other than WASI and Emscripten sys.implementation.name checks ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type checkers should support comparison patterns: - * ``sys.implementation.name == `` - * ``sys.implementation.name != `` - * ``sys.implementation.name in `` - * ``sys.implementation.name not in `` - Default value: ``"cpython"``, unless configured otherwise. - Common values: ``"cpython"``, ``"pypy"``, ``"micropython"``, ``"graalpy"``, ``"jython"``, ``"ironpython"`` +* ``sys.implementation.name == `` +* ``sys.implementation.name != `` +* ``sys.implementation.name in `` +* ``sys.implementation.name in `` +* ``sys.implementation.name in `` +* ``sys.implementation.name not in `` +* ``sys.implementation.name not in `` +* ``sys.implementation.name not in `` + +Default value: ``"cpython"``, unless configured otherwise. +Common values: ``"cpython"``, ``"pypy"``, ``"micropython"``, ``"graalpy"``, +``"jython"``, ``"ironpython"`` .. code-block:: python - :caption: Example `sys.implementation.name` + :caption: Examples of ``sys.implementation.name`` checks :emphasize-lines: 2,4 import sys @@ -248,66 +271,89 @@ Type checkers should support comparison patterns: sys.implementation.version checks ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``sys.implementation.version`` is a tuple, in the same format as sys.version_info. However it represents the version of the Python implementation -rather than the version of the Python language. This has a distinct meaning from the specific version of the Python language to which the currently -running interpreter conforms. For CPython (``sys.implementation.name == "cpython"``) this is the same as `sys.version_info`. +The value of ``sys.implementation.version`` is a tuple, in the same format as +``sys.version_info``. However, it represents the version of the +*Python implementation* rather than the version of the *Python language*. This has +a distinct meaning from the specific version of the Python language to which the +currently running interpreter conforms. + +For CPython (``sys.implementation.name == "cpython"``) this is the same as +``sys.version_info``. +For other Python implementations the value of ``sys.implementation.version`` may +differ and must be specified according to the type checkers' +configuration options. If it is not specified, type checkers should issue a warning +or error if it is used in a type-checking context. Type checkers should support the following comparison patterns: - * ``sys.implementation.version >= <2-tuple>`` - * ``sys.implementation.version < <2-tuple>`` -Comparison checks are only supported against the first two elements of the implementation version tuple. -Type checkers are not required to support comparisons against named attributes of `sys.implementation.version`. +* ``sys.implementation.version >= <2-tuple>`` +* ``sys.implementation.version < <2-tuple>`` + +Comparison checks are only supported against the first two elements of the +implementation version tuple. Type checkers are not required to support comparisons +against named attributes of ``sys.implementation.version``. .. code-block:: python - :caption: Example `sys.implementation.version` + :caption: Examples of ``sys.implementation.version`` checks :emphasize-lines: 2,4 import sys if sys.implementation.name == "pypy" and sys.implementation.version >= (7, 3): # PyPy version 7.3 and above - if sys.implementation.name == "micropython" and sys.implementation.version >= (1, 24): + elif sys.implementation.name == "micropython" and sys.implementation.version >= (1, 24): # MicroPython version 1.24 and above -No support for complex expressions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Required forms and optional extensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Type checkers are required to support the above patterns, and are not required to evaluate other comparisons or other syntax variants. - -Therefore checkers are **not required** to understand obfuscations such as: +Type checkers must support the forms described above. They may support additional +comparisons and syntax forms, but are not required to recognize them. For example, +type checkers are not required to support the following forms: .. code-block:: python - :caption: Examples of unsupported or overly complex version/platform checks - :emphasize-lines: 4,6,8 + :caption: Examples of forms that type checkers are not required to support + :emphasize-lines: 4,6,8 - import sys - from sys import platform + import sys + from sys import platform - if "".join(reversed(sys.platform)) == "xunil": - # Typecheckers will not be required to understand this obfuscated check - if platform == "linux": - # Typecheckers will not be required to understand this import alias for sys.platform - if "win" not in sys.platform: - # Typecheckers will not be required to understand this reversed membership check + if "".join(reversed(sys.platform)) == "xunil": + # Comparison using a computed value + if platform == "linux": + # Comparison using an imported alias + if "win" not in sys.platform: + # Substring membership test against sys.platform Configuration ^^^^^^^^^^^^^ -Type checkers must be able to retrieve the information from the python implementation's runtime environment, or provide configuration or CLI options to specify target ``sys.version``, ``sys.platform``, ``sys.implementation.name`` and ``sys.implementation.version``. - -================================ ========================== ============== =========================================================================== - Symbol Suggested Format Example Suggested Default -================================ ========================== ============== =========================================================================== -``sys.version`` string ``"major.minor"`` ``"3.11"`` The version of the Python interpreter used to run the type checker. -``sys.platform`` lowercase string ``"linux"`` The platform of the Python interpreter used to run the type checker. -``sys.implementation.name`` lowercase string ``"cpython"`` ``"cpython"`` unless configured otherwise. -``sys.implementation.version`` string ``"major.minor"`` ``"3.14"`` The value used for ``sys.version`` unless configured otherwise. -================================ ========================== ============== =========================================================================== - -The configuration options should allow users to specify the target values for these symbols, so that type checkers can evaluate the version and platform checks correctly. -The exact mechanism and name for these configuration options is implementation-specific, and defined by each type checker. +Type checkers must be able to retrieve the information from the Python +implementation's runtime environment, or provide configuration or CLI options +to specify target ``sys.version``, ``sys.platform``, +``sys.implementation.name`` and ``sys.implementation.version``. + +============================== ======================== ============= ===================================== +Symbol Suggested Format Example Suggested Default +============================== ======================== ============= ===================================== +``sys.version_info`` string ``"major.minor"`` ``"3.11"`` The version of the Python interpreter + used to run the type checker. +``sys.platform`` lowercase string ``"linux"`` The platform of the Python interpreter + used to run the type checker. +``sys.implementation.name`` lowercase string ``"cpython"`` ``"cpython"`` unless configured + otherwise. +``sys.implementation.version`` string ``"major.minor"`` ``"3.14"`` On CPython, default to the value used + for ``sys.version``. On other + implementations, the value must be + provided according to the type + checker's configuration options. +============================== ======================== ============= ===================================== + +The configuration options should allow users to specify the target values for these +symbols, so that type checkers can evaluate the version and platform checks +correctly. The exact mechanism and names for these configuration options are +implementation-specific and defined by each type checker. .. _`deprecated`: