Skip to content

Update specification for directives for sys.implementation and sys.platform checks. - #2173

Open
Josverl wants to merge 3 commits into
python:mainfrom
Josverl:specs/sys.implementation.name
Open

Update specification for directives for sys.implementation and sys.platform checks.#2173
Josverl wants to merge 3 commits into
python:mainfrom
Josverl:specs/sys.implementation.name

Conversation

@Josverl

@JosverlJosverl commented Feb 12, 2026

Copy link
Copy Markdown

This PR adds additional detail to the specification for Version and Platform checking.
Specificially it aims to add support for typechers to add support for :

  • checks on sys.implementation.name
  • membership checks (in tuple)
  • negative membership checks ( not in tuple)

References :

@python-cla-bot

python-cla-botBot commented Feb 12, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated

* Equality: ``sys.platform == "linux"``
* Inequality: ``sys.platform != "win32"``
* Membership: ``sys.platform in ("linux", "darwin")``

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'm not convinced that containment should be supported here. There's already a way to express this in a way that all tools today support. I understand the argument that this is less verbose, but it's not that common for checks to include more than one platform, so I don't think there's a compelling argument to force all tools to support this additional form.

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.

For deciding on issues like this it would be helpful to have a little summary of what type checkers currently support (like what I did in https://discuss.python.org/t/spec-change-clarify-that-tuple-should-not-be-prohibited-as-an-argument-to-type/105590/7). I'll gather a few variants and summarize it.

I think part of this change will be codifying what is already supported universally, and another part will be adding support for more features. The first group should be uncontroversial, and in the second group we should only force work on type checker authors if there's a clear use case.

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.

If possible this would really help with creating readable and maintainable type stubs for MicroPython.
even with the proposed sys.implementation.name check we still see significant API differences due the underlying MCU vendor SDKs being significantly different.
Though MicroPython tries to abstract much of these differences away that is not entirly possible as the underlying SDK or hardware is simply different. This is a common source of errors when code is ported from one MCU architecture to another.
For instance Timers are available on all platforms, but with many different default values.

While the below would work

# machine.pyi classTimer():
""""Timer object"""ifsys.implementation.name=="micropython"and (sys.platform=="esp32"orsys.platform=="mimxrt"orsys.platform=="rp2"orsys.platform=="samd"orsys.platform=="stm32"orsys.platform=="alif"orsys.platform=="webassembly"): @overloaddef__init__(
self,
id: int,
/,
*,
mode: int=PERIODIC,
period: int|None=None,
callback: Callable[[Timer], None] |None=None,
hard: bool|None=None,
):...
elifsys.implementation.name=="micropython"and (sys.platform=="esp8266"orsys.platform=="unix"orsys.platform=="windows"orsys.platform=="zephyr"): @overloaddef__init__(
self,
id: int=-1,
/,
*,
mode: int=PERIODIC,
period: int|None=None,
callback: Callable[[Timer], None] |None=None,
):...

the below is much simpler to understand and maintain.

classTimer():
""""Timer object"""ifsys.implementation.name=="micropython"and (sys.platformin ("esp32", "mimxrt", "rp2", "samd", "stm32", "alif", "webassembly")): @overloaddef__init__(
self,
id: int,
/,
*,
mode: int=PERIODIC,
period: int|None=None,
callback: Callable[[Timer], None] |None=None,
hard: bool|None=None,
):...
elifsys.implementation.name=="micropython"and (sys.platformin ("esp8266", "unix", "windows", "zephyr")): @overloaddef__init__(
self,
id: int=-1,
/,
*,
mode: int=PERIODIC,
period: int|None=None,
callback: Callable[[Timer], None] |None=None,
):...

I think it would be reasonable to explicitly restrict this to "a tuple of literal strings",assuming that simplies the implementation.
Negative membership option could also be omitted , I think that would still be sufficient.

@AlexWaygoodAlexWaygoodFeb 22, 2026

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 fully agree with Eric here FWIW. Adding support for this will add significant complexity to type checkers, and this is the first time I've seen it requested. If we want to ask type checkers to add support for in/not in comparisons with sys.platform and sys.implementation.name, I think it should be a wholly separate proposal to the proposal that asks type checkers to add initial support for comparisons against sys.implementation.version and sys.implementation.name in the same way that they already do for sys.version_info and sys.platform.

Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated

* Equality: ``sys.implementation.name == "cpython"``
* Inequality: ``sys.implementation.name != "cpython"``
* Membership: ``sys.implementation.name in ("pypy", "graalpy")``

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.

Here again, I don't think there's good justification for supporting a containment operator.

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 addedd this for consistency, but I'm OK to remove sys.implementation.name in ("pypy", "graalpy") from the spec to simplify the implementation.

@srittausrittau added the topic: typing spec For improving the typing spec label Feb 20, 2026
@Josverl
Josverlforce-pushed the specs/sys.implementation.name branch 2 times, most recently from 4151e84 to d7fbb9eCompareFebruary 21, 2026 17:09
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated
Comment threaddocs/spec/directives.rst Outdated

Supported patterns:
* ``sys.platform <comparison> <string literal>``
* ``sys.platform in <tuple 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.

Or not in?

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.

the not / and / or are described further down to avoid neededing to repeat then for every possible clause, although !=is repeated.
I could move that section to the top if that is clearer.


Multiple comparisons can be combined with:
* A not unary operator
* An and or or binary operator

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 different, it would allow not (sys.platform in ("a", "b")), not sys.platform not in ("a", "b").

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 see your point, then I think it is clearer to just enumerate all option directly,

Supported patterns:
* ``sys.platform == <string literal>``
* ``sys.platform != <string literal>``
* ``sys.platform in <tuple of string literals>``
* ``sys.platform not in <tuple of string literals>``

Comment threaddocs/spec/directives.rst Outdated
@Josverl
Josverlforce-pushed the specs/sys.implementation.name branch from d7fbb9e to 62d90dcCompareFebruary 22, 2026 12:56
@Josverl

Josverl commented Feb 22, 2026

Copy link
Copy Markdown
Author

I have updated the text to better clarify the exact comparisons for each of the supported attributes,
excluded the use of named attributes,
and did some more word-smithing to reduce unneeded verbosity.
I have also added highlighting to the examples, as a raiding aide.

@Josverl
Josverlforce-pushed the specs/sys.implementation.name branch from 62d90dc to ff338e3CompareFebruary 22, 2026 13:08
Comment threaddocs/spec/directives.rst Outdated
* ``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.

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
Use of named attributes is not supported.
Use of named attributes is not mandated.

@JosverlJosverlFeb 22, 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.

IIRC @carljm requested that addition.
Agree that not mandated is clearer for the metadata.

< Same on line 238>

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 "not mandated" is clearer that type checkers are permitted to support something additionally if they wish to, but that they are not required to do so. So in general I prefer "not mandated".

The one exception for me might be comparisons against length-3-or-greater tuples for sys.version_info or sys.implementation.version. I think it's usually actually incorrect for a type checker to support those unless the type checker actually either infers the micro version of the Python install the user has locally or offers a configuration knob for the micro version to be specified. To my knowledge, no type checker currently does. So for comparisons between sys.version_info or sys.implementation.version and tuples of >=3 length, I think the stronger language of "not supported" (or maybe even stronger than that) is probably still appropriate

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.

Reworded to

Comparisons checks are only supported against the first two elements of the version tuple.
Use of named attributes is not mandated.

Comment threaddocs/spec/directives.rst Outdated
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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.

@JosverlJosverlFeb 22, 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.

@erictraut , @AlexWaygood

Alex proposed elsewhere to change not supported to not mandated

as this section also uses that, I wanted to check if there is a need to change the wording here as well.

Also on the light of Jelle's functionality scan

@Josverl

Josverl commented Mar 30, 2026

Copy link
Copy Markdown
Author

Dear TC,
Is there a decision on this PR yet, or have I missed a step in the process?

If so kindly let me know how to proceed.

@JelleZijlstraJelleZijlstra left a comment

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'm generally supportive but I think this change needs some more editing, and I'd like support in at least some type checkers (at least an open PR) before we start mandating this pattern.

Comment threaddocs/spec/directives.rst Outdated
Josverland others added 3 commits April 3, 2026 21:21
…atform checks.
Signed-off-by: Jos Verlinde <Jos.Verlinde@Microsoft.com>
Formatting improvements.
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
…sion comparisons.
Signed-off-by: Jos Verlinde <Jos_Verlinde@hotmail.com>
@Josverl
Josverlforce-pushed the specs/sys.implementation.name branch from c575c15 to c951b00CompareApril 3, 2026 19:21
@Josverl
Josverl requested review from carljm and erictrautApril 3, 2026 19:23
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: typing specFor improving the typing spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@Josverl@carljm@JelleZijlstra@erictraut@AlexWaygood@srittau