Skip to content
Open
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 150 additions & 13 deletions docs/spec/directives.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,23 +154,160 @@ 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 understand code paths as definitely reachable or not reachable due to comparison tests against these symbols:
Comment thread
Josverl marked this conversation as resolved.
Outdated
* ``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>``
Comment thread
Josverl marked this conversation as resolved.
Outdated
* ``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`.

.. code-block:: python
:caption: Example `sys.version_info`
:emphasize-lines: 2

import sys
if sys.version_info >= (3, 12):
# Python 3.12+
elif sys.version_info >= (3, 11):
# Python 3.11
else:
# Python 3.10 and lower

sys.platform checks
^^^^^^^^^^^^^^^^^^^

Type checkers should support the following comparison patterns:
* ``sys.platform == <string literal>``
* ``sys.platform != <string literal>``
* ``sys.platform.startswith(<string literal>)``
* ``sys.platform in <tuple of string literals>``
* ``sys.platform not in <tuple of string literals>``
Comment thread
Josverl marked this conversation as resolved.
Outdated
Type checkers may also support the following comparison patterns:
* ``sys.platform in <set of string literals>``
* ``sys.platform not in <set of string literals>``

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.
Comment thread
Josverl marked this conversation as resolved.
Outdated

.. 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"):
Comment thread
Josverl marked this conversation as resolved.
Outdated
# Platform-specific stubs for Linux and macOS
...


sys.implementation.name checks
Comment thread
Josverl marked this conversation as resolved.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Type checkers should support comparison patterns:
Comment thread
Josverl marked this conversation as resolved.
Outdated
* ``sys.implementation.name == <string literal>``
* ``sys.implementation.name != <string literal>``
* ``sys.implementation.name in <set of string literals>``
Comment thread
Josverl marked this conversation as resolved.
Outdated
* ``sys.implementation.name not in <set of string literals>``

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

import sys
if sys.implementation.name == "cpython":
# CPython-specific stub
if sys.implementation.name == "micropython":
# MicroPython-specific stub


sys.implementation.version checks
Comment thread
Josverl marked this conversation as resolved.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``sys.implementation.version`` is a tuple, in the same format as sys.version_info. However it represents the version of the Python implementation
Comment thread
Josverl marked this conversation as resolved.
Outdated
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`.
Comment thread
Josverl marked this conversation as resolved.
Outdated
Comment thread
Josverl marked this conversation as resolved.
Outdated

Type checkers should support the following comparison patterns:
Comment thread
Josverl marked this conversation as resolved.
* ``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`
: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


No support for complex expressions
Comment thread
Josverl marked this conversation as resolved.
Outdated
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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:
Comment thread
Josverl marked this conversation as resolved.
Outdated
Comment thread
Josverl marked this conversation as resolved.
Outdated

.. code-block:: python
:caption: Examples of unsupported or overly complex version/platform checks
Comment thread
Josverl marked this conversation as resolved.
Outdated
:emphasize-lines: 4,6,8

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


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``.
Comment thread
Josverl marked this conversation as resolved.
Outdated

================================ ========================== ============== ===========================================================================
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.
Comment thread
Josverl marked this conversation as resolved.
Outdated
``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.
Comment thread
Josverl marked this conversation as resolved.
Outdated
================================ ========================== ============== ===========================================================================

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`:

Expand Down