diff --git a/docs/spec/directives.rst b/docs/spec/directives.rst index 6ed7016a..e5eaa32f 100644 --- a/docs/spec/directives.rst +++ b/docs/spec/directives.rst @@ -145,8 +145,27 @@ 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`` + +The `` patterns for these variables are described in more detail in the following paragraphs. + +sys.version_info checks +^^^^^^^^^^^^^^^^^^^^^^^^ + +Type checkers should support the following ``sys.version_info`` comparison patterns: + * ``sys.version_info <2-tuple>`` + + `` can be one of the following: + * Greater or equal: ``>=`` + * Less than: ``<`` + +Comparisons checks are only supported against the first two elements of a tuple. + +Example:: import sys @@ -155,13 +174,117 @@ checks, e.g.:: else: # Python 3.11 and lower + + +sys.platform checks +^^^^^^^^^^^^^^^^^^^ + +Type checkers should support ``sys.platform`` comparisons: + + Supported patterns: + * ``sys.platform `` + * ``sys.platform in `` + + `` can be one of the following: + * Equality: ``==`` + * Inequality: ``!=`` + * Membership: ``in`` + +Example:: + + import sys + if sys.platform == 'win32': # Windows specific definitions - else: - # Posix specific definitions -Don't expect a checker to understand obfuscations like -``"".join(reversed(sys.platform)) == "xunil"``. + if sys.platform in ("linux", "darwin"): + # Platform-specific stubs for Linux and macOS + ... + + +.. note:: + + Type checkers are only required to support the above patterns. + + 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. + The membership check ``sys.platform in ("linux", "darwin")`` only supports simple containment testing to a tuple of literal strings. + +sys.implementation.name checks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Type checkers should support ``sys.implementation.name`` comparisons: + +Supported patterns: + * ``sys.implementation.name `` + * ``sys.implementation.name in `` + + `` can be one of the following: + * Equality: ``==`` + * Inequality: ``!=`` + * Membership: ``in`` + + Common values: ``"cpython"``, ``"pypy"``, ``"micropython"``, ``"graalpy"``, ``"jython"``, ``"ironpython"`` + +Example:: + + 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 ``sys.implementation.version`` comparison patterns: + * ``sys.implementation.version <2-tuple>`` + + `` can be one of the following: + * Greater or equal: ``>=`` + * Less than: ``<`` + +Example:: + + 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:: + + Comparisons checks are only supported against the first two elements of a tuple. + + ``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. + + +Combining checks +^^^^^^^^^^^^^^^^ + +Multiple comparisons can be combined with: + * A ``not`` unary operator + * An ``and`` or ``or`` binary operator + +No support for complex expressions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Type checkers are not required to evaluate complex expressions involving these variables. +Therefore do not expect a checker to understand obfuscations such as:: + + import sys + if "".join(reversed(sys.platform)) == "xunil": + # Linux specific code + + +Configuration +^^^^^^^^^^^^^ + +Type checkers should provide configuration to specify target version, platform, and implementation. The exact mechanism is implementation-defined. + .. _`deprecated`: