Skip to content

Commit ff338e3

Browse files
committed
Update specification for directives for sys.implementation and sys.platform checks.
Signed-off-by: Jos Verlinde <Jos.Verlinde@Microsoft.com>
1 parent f98d75e commit ff338e3

File tree

1 file changed

+131
-13
lines changed

1 file changed

+131
-13
lines changed

docs/spec/directives.rst

Lines changed: 131 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -145,23 +145,141 @@ left undefined by the typing spec at this time.
145145
Version and platform checking
146146
-----------------------------
147147

148-
Type checkers are expected to understand simple version and platform
149-
checks, e.g.::
148+
Type checkers should support narrowing based on:
149+
* ``sys.version_info``
150+
* ``sys.platform``
151+
* ``sys.implementation.version``
152+
* ``sys.implementation.name``
150153

151-
import sys
154+
Type checkers should support combining these checks with:
155+
* A ``not`` unary operator
156+
* An ``and`` or ``or`` binary operator
152157

153-
if sys.version_info >= (3, 12):
154-
# Python 3.12+
155-
else:
156-
# Python 3.11 and lower
158+
Type checkers are only required to support the fully-qualified form (e.g., ``sys.platform``).
159+
Support for aliases or import variants (e.g., ``from sys import platform``) is not required, though type checkers may choose to support them.
157160

158-
if sys.platform == 'win32':
159-
# Windows specific definitions
160-
else:
161-
# Posix specific definitions
161+
The comparison patterns for these variables are described in more detail in the following paragraphs.
162162

163-
Don't expect a checker to understand obfuscations like
164-
``"".join(reversed(sys.platform)) == "xunil"``.
163+
sys.version_info checks
164+
^^^^^^^^^^^^^^^^^^^^^^^^
165+
166+
Type checkers should support the following comparison patterns:
167+
* ``sys.version_info >= <2-tuple>``
168+
* ``sys.version_info < <2-tuple>``
169+
170+
Comparisons checks are only supported against the first two elements of the version tuple.
171+
Use of named attributes is not supported.
172+
173+
.. code-block:: python
174+
:caption: Example `sys.version_info`
175+
:emphasize-lines: 2
176+
177+
import sys
178+
if sys.version_info >= (3, 12):
179+
# Python 3.12+
180+
else:
181+
# Python 3.11 and lower
182+
183+
sys.platform checks
184+
^^^^^^^^^^^^^^^^^^^
185+
186+
Type checkers should support the following comparison patterns:
187+
* ``sys.platform == <string literal>``
188+
* ``sys.platform != <string literal>``
189+
* ``sys.platform in <tuple of string literals>``
190+
* ``sys.platform not in <tuple of string literals>``
191+
192+
Common values: ``"linux"``, ``"darwin"``, ``"win32"``, ``"emscripten"``, ``"wasi"``
193+
194+
The membership checks ``in`` and ``not in``, only support simple containment testing to a tuple of literal strings.
195+
196+
.. code-block:: python
197+
:caption: Example `sys.platform`
198+
:emphasize-lines: 2,4
199+
200+
import sys
201+
if sys.platform == 'win32':
202+
# Windows specific definitions
203+
if sys.platform in ("linux", "darwin"):
204+
# Platform-specific stubs for Linux and macOS
205+
...
206+
207+
208+
sys.implementation.name checks
209+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
210+
211+
Type checkers should support comparison patterns:
212+
* ``sys.implementation.name == <string literal>``
213+
* ``sys.implementation.name != <string literal>``
214+
* ``sys.implementation.name in <tuple of string literals>``
215+
* ``sys.implementation.name not in <tuple of string literals>``
216+
217+
Common values: ``"cpython"``, ``"pypy"``, ``"micropython"``, ``"graalpy"``, ``"jython"``, ``"ironpython"``
218+
219+
.. code-block:: python
220+
:caption: Example `sys.implementation.name`
221+
:emphasize-lines: 2,4
222+
223+
import sys
224+
if sys.implementation.name == "cpython":
225+
# CPython-specific stub
226+
if sys.implementation.name == "micropython":
227+
# MicroPython-specific stub
228+
229+
230+
sys.implementation.version checks
231+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
232+
233+
Type checkers should support the following comparison patterns:
234+
* ``sys.implementation.version >= <2-tuple>``
235+
* ``sys.implementation.version < <2-tuple>``
236+
237+
Comparisons checks are only supported against the first two elements of the implementation version tuple.
238+
Use of named attributes is not supported.
239+
240+
.. code-block:: python
241+
:caption: Example `sys.implementation.version`
242+
:emphasize-lines: 2,4
243+
244+
import sys
245+
if sys.implementation.name == "pypy" and sys.implementation.version >= (7, 3):
246+
# PyPy version 7.3 and above
247+
if sys.implementation.name == "micropython" and sys.implementation.version >= (1, 24):
248+
# MicroPython version 1.24 and above
249+
250+
.. note::
251+
252+
``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.
253+
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`.
254+
255+
256+
No support for complex expressions
257+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
258+
259+
Type checkers are only required to support the above patterns, and are not required to evaluate complex expressions involving these variables.
260+
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.
261+
262+
Therefore checkers are **not required** to understand obfuscations such as:
263+
264+
.. code-block:: python
265+
:caption: Examples of unsupported or overly complex version/platform checks
266+
:emphasize-lines: 3,5,7
267+
268+
import sys
269+
from sys import platform
270+
if "".join(reversed(sys.platform)) == "xunil":
271+
# Linux specific code
272+
if platform == "linux":
273+
# Linux specific code
274+
if "win" not in sys.platform:
275+
# Non-Windows specific code
276+
277+
278+
Configuration
279+
^^^^^^^^^^^^^
280+
281+
Type checkers should provide configuration or CLI options to specify target sys.version, sys.platform, sys.implementation.name and sys.implementation.version.
282+
The exact mechanism for this is implementation-defined by the type checker.
165283

166284
.. _`deprecated`:
167285

0 commit comments

Comments
 (0)