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:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we haven't really discussed the conformance suite in this PR yet, but I think we should add conformance tests for whatever new requirements we decide on in this PR.

conformance/tests/directives_version_platform.py currently covers basic version and platform comparisons, but none of the implementation checks, membership checks, startswith, or boolean combinations added here.

I would expect coverage of both reachable and unreachable branches, including combinations using not, and, and or. It would also be useful to distinguish required tuple membership from optional set membership and three-element version comparisons, so the tests pin down the intended minimum support.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I think we should add conformance tests for whatever new requirements we decide on in this PR.

Makes sense to me, but TBH I personally would need to study how to define these, And happy to do that either in this PR or as a follow-up , but perhaps agree on the 'rules' first

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This leaves the meaning of <2-tuple> ambiguous in some critical ways. Does a variable which is earlier bound to a 2-tuple count? What about (major, get_minor())?

I think the intent here is that it must be an actual tuple literal containing two integer literals. We should make that explicit.

@Josverl Josverl Sep 21, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your point, but in not quite sure what notation works best for this ,

Is it suffient to say sys.version_info >= <2-tuple of int literals>

or would this be clearer :

  • sys.version_info >= <tuple[int, int]>
  • sys.version_info >= <tuple[Literal[int], Literal[int]]>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably just append ", where <2-tuple> is a literal tuple of two literal integers"

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ruff (PLR6201) will report an error for this tuple membership check, and I tend to agree with ruff that a set literal would be more idiomatic here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the wild I've seen things like sys.platform.startswith("freebsd") a couple of times, because in this case there's also a version number in the platform string (e.g. "freebsd8"). So how about we also allow sys.platform.startswith(<string literal>)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ty already supports sys.platform.startswith; I don't have any objection there.

Supporting set literals will be a little tricky in ty, but should be doable, and I'm not opposed to requiring support for it. I don't think the performance motivation of PLR6201 typically applies much to sys.version_info comparisons, but it is awkward if this rule is generally being applied in a codebase and has to be specifically ignored for sys.version_info checks.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to set and added sys.platform.startswith(<string literal>)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, I think that both tuple and set literals should be specified as supported -- it would be surprising IMO if sets work and tuples don't.

This is perhaps an argument against supporting sets -- it opens a bit of a slippery slope: why not lists? etc

@Josverl Josverl Aug 15, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my original proposal was tuples, as that is one of the core building blocks of Python.
I don't think that for this scale sets have a real benefit over tuples.

I'd like it to be straight and narrow though ,
requiring tuple + set = is still ok , though I notice that ruff mentions 'This rule is unstable and in preview.'
adding lists would start to 🛝

Pausing edits until there is consensus

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After considering it more, I think we should just leave sets out entirely. I wouldn't even mention them as optional: there's no point, since type checkers are always free to support anything they want beyond the spec.

I don't believe there is any actual performance benefit at this scale, and it's not necessary to add complexity to the spec or to type checkers when comparing to a tuple is perfectly usable and functional. The ruff rule is unstable and I think if this spec change is merged, the ruff rule should just be updated to specifically exclude these typing-supported comparisons, so there is no conflict. I don't think the ruff rule should motivate adding sets to the spec.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be updated for consistency with the decision about sets vs tuples.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So can I consider the tuple/set discussion decided in favor of (literal) tuples ony?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carljm You wrote:

I think we should just leave sets out entirely

What is your reasoning about that? Why not support sets/lists as well? To me that would have been the most natural way. I understand that type checkers may support more constructs, but I think it's generally preferable for type checkers to have the same behavior.

My intuition is that normal users would not see a difference between sets / tuples / lists and just use the one they feel most comfortable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidhalter This same logic could be used to expand the required support in various other ways, too. It's not very intuitive to support import sys; sys.platform but not from sys import platform or from sys import platform as plat, for example. IMO if we are looking to improve intuitive consistency, that's a more obvious change than adding containment support for more types.

Ultimately we are talking about special casing sufficient patterns to allow expressing what needs to be expressed; we have to draw the line somewhere, so why require support for extra things that don't add expressive utility? If sets and lists, why not dictionary keys? Why not variables that have been assigned a list or set or tuple? All of these are also intuitive extensions from a user perspective.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If sets and lists, why not dictionary keys?

Because nobody in their right mind would use sys.platform in {...}.keys(), while a normal user would probably like to use sys.platform in [...] or sys.platform in {...}.

I just don't really understand why we should omit this. Do you have reservations because of inference of sets/lists where you would do something like sys.platform in CONSTANT?

Jelle implemented it for Mypy already and it looks pretty straightforward: python/mypy#21913

It's not very intuitive to support import sys; sys.platform but not from sys import platform or from sys import platform as plat, for example. [...] that's a more obvious change than adding containment support for more types.

I'm open to that as well. I probably disagree that it's more obvious, but I do agree that it's unintuitive.

@davidhalter davidhalter Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you support sys.platform in CONSTANT, your reasoning of only supporting tuples makes much more sense. If a type checker chooses to not support that it feels inconsistent to not support lists/sets.

I still lean towards supporting lists/sets, but I'm totally fine if people disagree and we go the tuple-only way. Maybe @jorenham, @JelleZijlstra or @rchen152 can quickly weigh in here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer also supporting lists and sets. That way, users will be more likely to have code work the way they expect regardless of arbitrary choices, and that's generally a good thing. The cost is that type checkers will need to implement some more complicated support, but that cost seems low enough here that it's worth choosing the user-friendlier version.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sets also have my preference, because for containment checks sets are the idiomatic choice, for which there's also a ruff rule: https://docs.astral.sh/ruff/rules/literal-membership/

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand correctly that there is consensus to support tuple , set and list of literals ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All typing council members have now commented in this thread in favor of (or fine with) going ahead with tuple/list/set support, except for @rchen152. Given pyrefly already supports all three, I would not expect @rchen152 to object. So I think it's safe to consider this consensus now.


.. 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"):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a tuple, not a set, and the current text says only sets are supported. My instinct would be to support both, but I wouldn't mind narrowing it down if that's the consensus.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it is no longer consistent due to other changes.
I prefer to revert to only tuple, as that seems to be best supportable by all, with only ruff issuing a warning currently.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recently learned that a set in this case will br optimized using the peephole optimizer, so the performance benefits are real.

@Josverl Josverl Aug 29, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But ty cannot support it, so the disadvantages are even more real.
If both of the Astral tools could work with a common type, that would be helpful.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recently learned that a set in this case will be optimized using the peephole optimizer, so the performance benefits are real.

I don't not what the peephole optimizer optimizes here, but unless I see actual numbers I would not be surprised if small tuples are as fast.

But ty cannot support it, so the disadvantages are even more real.

Please do not argue like that. There are good arguments above why we should or should not support sets. It is possible for Ty to support it and Carl even argued that it likely should be supported (and then argued against it for another reason). Even if Ty doesn't support it, it still might be helpful to have it in the spec, because other people use other type checkers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed this section to:
I hope that is acceptable to all , if not i would really appreceate clear recomendation on how to improve this.

Type checkers must support the following comparison patterns:
   <snip> 
    * ``sys.platform in <tuple of string literals>``
    * ``sys.platform not in <tuple of string literals>``
Type checkers may also support the following comparison patterns:
    * ``sys.platform in <set of string literals>``
    * ``sys.platform not in <set of string literals>``

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Type checkers should support comparison patterns:
Type checkers should support these comparison patterns with `sys.implementation.name`:

* ``sys.implementation.name == <string literal>``
* ``sys.implementation.name != <string literal>``
* ``sys.implementation.name in <set of string literals>``

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also be updated for consistency with the sets vs tuples discussion above.

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


sys.implementation.version checks

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, I think we should probably be explicit here that when a type checker has no "implementation" information, it should assume "CPython, and implementation version matches sys.version_info".

It's less clear to me what should happen if a type-checker is told that the implementation is not CPython, but is not given any specific version information. I guess this could be an error? Otherwise I'm not sure how type-checkers should guess at the implementation version.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair point. there should be no guessing involved, And defaulting to CPyton would be the most logical thing to do.

As an example a device that happens to be connected:

MicroPython v1.28.0 on 2026-04-06; Wio Terminal D51R with SAMD51P19A
Type "help()" for more information.
>>> import sys
>>> sys.version
'3.4.0; MicroPython v1.28.0 on 2026-04-06'
>>> sys.implementation
(name='micropython', version=(1, 28, 0, ''), _machine='Wio Terminal D51R with SAMD51P19A', _mpy=7942, _build='SEEED_WIO_TERMINAL')

If I want to typecheck an app for this device and firmware I would need to supply the typechecker with:

  • sys.implementation.name="micropython"
  • sys.implementation.version=(1,28)
  • sys.version = (3,9) *

using the relevant configuration options for that checker

  • MicroPython uses a subset of features from 3.5-3.11, generally 3.9/3.10 make a good base fit.
    BUt that is just one implementation.

If not provided explicit information through: typechecker config, environment or switches, or detected python runtime sys.implementation.version should fall-back to sys.version.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a table in the config section to add clarity.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is defaulting to sys.version_info really the right call here? On MicroPython that's apparently meaningless, since the version is 1.x instead of 3.x.

@Josverl Josverl Sep 6, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not think of anything other than a cross implementation lookup table, that would come with its own maintenance and distribution chalenges, to solve this for all or even most Python implementations.
The proposed default is intened to make things simpler to understand for humans on CPython,
on other platforms I think is is acceptable to require this to be specified in a .toml or .json

And as I mentioned before - it is quite similar to type checking for Windows+ Python 3.10 from 3.14 venv on Linux

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented on the table below, but I agree with @JelleZijlstra that "fallback to sys.version_info" is only acceptable if the implementation is CPython. If a non-CPython implementation is specified, and no implementation version is specified or inferable from the runtime environment, that must be a configuration error. (I don't love specifying type checker configuration errors, but we cannot specify that type checkers must fall back to a known-wrong sys.implementation.version in this scenario.

@Josverl Josverl Sep 21, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be a misunderstanding;
IIRC I never mentioned a cross platform fallback to CPython, and I can't find the word fallback in the prose either
nonetheless I have updated the table entry for sys.implementation.version to :

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.

I hope that sufficiently clarifies this , if not; I would welcome a text suggestion to improve.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
running interpreter conforms. For CPython (``sys.implementation.name == "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``.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be word-wrapped to around 80 columns -- it doesn't look like we've specified that anywhere, but that's the existing de facto convention in almost all spec files.


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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be more careful with the wording here. "Complex" is not clearly defined, so it's not clear what this heading is saying. Not all unsupported forms can be reasonably called "complex". And "no support" also implies forbidding type checkers from supporting something, which we are not ever doing.

Suggested change
No support for complex expressions
Type checkers are not required to support any forms not explicitly listed as required

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reworded the sub-section heading and prose and example comments based on the above feedback.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My previous comment here was marked resolved but was not addressed. Not all of the patterns below are "obfuscations" and we should not describe them pejoratively.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My previous comment here was marked resolved but was not addressed.

Aplogies for that.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above : I have tried to improve.
Please let me know if this is better


.. code-block:: python
:caption: Examples of unsupported or overly complex version/platform checks

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:caption: Examples of unsupported or overly complex version/platform checks
:caption: Examples of checks that type checkers are not required to support

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reworded the sub-section heading and prose and example comments based on the above feedback.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be sys.version_info, not sys.version.

Also word-wrap to 80 columns (throughout).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected to version_info

In order to blanace width with readability, I have wrapped the table at 110 columns, which is still slightly narrower than the HTML render.
Wrapping to 80 would leave less than 1 word per line for the 4th column


================================ ========================== ============== ===========================================================================
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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
``sys.version`` string ``"major.minor"`` ``"3.11"`` The version of the Python interpreter used to run the type checker.
``sys.version_info`` string ``"major.minor"`` ``"3.11"`` The version of the Python interpreter used to run the type checker.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, corrected.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the fallback to sys.version_info must apply only when the implementation is cpython. If a non-CPython implementation is specified, then it should be an error not to also specify an implementation version (unless the type checker can derive it from the runtime environment.)

It's simply wrong to fall back to sys.version_info for sys.implementation.version if a non-CPython implementation has been specified.

Suggested change
``sys.implementation.version`` string ``"major.minor"`` ``"3.14"`` The value used for ``sys.version`` unless configured otherwise.
``sys.implementation.version`` string ``"major.minor"`` ``"3.14"`` The value used for ``sys.version_info`` unless configured otherwise.

@Josverl Josverl Sep 21, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was never my intent and I do not think I ever mentioned that in the spec.
Either way I have now tried to explicitly stated that for non-cpython : sys.implementation.version should be explicitly provided to the type-checker and that is should raise an error or warning if it is used and no value is provided.

================================ ========================== ============== ===========================================================================

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