| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -154,23 +154,157 @@ 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: | ||
| * ``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>`` | ||
| * ``sys.version_info < <2-tuple>`` | ||
|
|
||
| Comparison checks are only supported against the first two elements of the version tuple. | ||
| It should be noted that 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 <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. | ||
|
|
||
| .. 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"): | ||
| # Platform-specific stubs for Linux and macOS | ||
| ... | ||
|
|
||
|
|
||
| sys.implementation.name checks | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| Type checkers should support comparison patterns: | ||
| * ``sys.implementation.name == <string literal>`` | ||
| * ``sys.implementation.name != <string literal>`` | ||
| * ``sys.implementation.name in <set of string literals>`` | ||
| * ``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
Comment on lines
+224
to
+242
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThis raises similar questions as the three-tuple sys.version_info feature request above. Type checkers may commonly not have any source of information as to the Python implementation the checked code is expected to run under. What should be their behavior in this case? I think for sys.implementation.name a reasonable choice would be "assume cpython unless known otherwise". Is that just a choice that is up to the individual type checker, or should it be standardized? It seems like if libraries begin to use these comparisons under the assumption type checkers will understand it, it can become a compatibility concern how type checkers behave here.
Sorry, something went wrong.
jorenham reacted with thumbs up emoji
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI guess an alternative behavior to specify here would be that Python type checkers should not assume any particular implemention -- that is, should not treat these checks in any special way -- unless a particular known implementation has been configured.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIn my mind it was clear that the default is the current behaviour: CPython. I do not think it should be the reposinsibility of the type checker to determine what the runtime runtime environment is.
Sorry, something went wrong.
carljm reacted with thumbs up emoji
All reactions
|
||
|
|
||
|
|
||
| sys.implementation.version checks | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualitySame 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.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualityfair 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:
using the relevant configuration options for that checker
If not provided explicit information through: typechecker config, environment or switches, or detected python runtime sys.implementation.version should fall-back to sys.version.
Sorry, something went wrong.
carljm reacted with thumbs up emoji
All reactions
Copy link
Copy Markdown
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAdded a table in the config section to add clarity.
Sorry, something went wrong.
All reactions
|
||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| ``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. For CPython this is the same as `sys.version_info`. | ||
|
|
||
| Type checkers should support the following comparison patterns: | ||
| * ``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 | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| 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.
|
||
|
|
||
| .. code-block:: python | ||
| :caption: Examples of unsupported or overly complex version/platform checks | ||
| :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 provide configuration or CLI options to specify target ``sys.version``, ``sys.platform``, ``sys.implementation.name`` and ``sys.implementation.version``. | ||
|
|
||
| ================================ ========================== ============== =========================================================================== | ||
| 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. | ||
| ``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. | ||
| ================================ ========================== ============== =========================================================================== | ||
|
|
||
| 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 | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.