Skip to content

Native work - #215

Merged
KotlinIsland merged 13 commits into
mainfrom
native-work
Oct 23, 2026
Merged

KotlinIsland merged 13 commits into
mainfrom
native-work

Conversation

@KotlinIsland

Copy link
Copy Markdown
Owner

No description provided.

… function standing in for an asserting one to assert the same about the same arguments, and report an unresolved keyword-pack default once
…ass's 3.14 `__annotate__`, refuse a read of a class the module does not emit, keep a slotted decorated chain without a dict, keep a write through `globals()`, and move frozen instances and dict keys onto the compiled class
…e protocols in one walk, fold symbolic types inside callable arrows and synthesized classes, and read `super`, `float` and `ty_extensions` names as what they mean where the module rebinds them
…e bindings that reach it, type a refused read as Unknown, bind an override's `_` wherever ty sees the body refer to it, and give a write to a repeated `_` a fresh local with no declared type
…it through, and run the checker-clean blocks of every mdtest file under the divergence harness, with the type alias variance and block fixes that run found
…er share, warn when an async generator's awaitable is dropped unawaited, name a compiled class bare in python's messages, and count published entries on 3.11 as python does
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

by ecosystem round-trip

base: 84c6b992634671519ab7ed4c90995a048cbfbff5 (merge base) → head: 215/merge

regressions: 0, changed: 2685, improvements: 0, error changes: 0 (across 27836 files in 144 projects)

⚠️ 7 project(s) fail to round-trip on both base and head, so this check says nothing about them.

ℹ️ changed round-trip output

DateType — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -14,5 +14,5 @@
 DIGESTS = {
     "/tmp/tmp8o3mfrem/DateType/build/docs/conf.py": {"by": "sha256:79307623df6ce61884512e0bdc1b32491e4c2aff4efcfa0c5e45d2976010bcf9", "py": "sha256:06ca40142aa11aa9b37898e59bce635d09cda0789cd6c625cf61aaf8bd01e31d"},
-    "/tmp/tmp8o3mfrem/DateType/build/datetype/__init__.py": {"by": "sha256:1b21bf028f7ed005dad9351d3944413b3a030a446bf92fd4217290cf2009c148", "py": "sha256:b0453dd6e2195e86020d00947c9b941394fae96a71ae6f6f1d57dc7cb86db9e2"},
+    "/tmp/tmp8o3mfrem/DateType/build/datetype/__init__.py": {"by": "sha256:1b21bf028f7ed005dad9351d3944413b3a030a446bf92fd4217290cf2009c148", "py": "sha256:59370925c3d4a6674fe08135cc4f43fc139b29053899bc0929c3d384376e6149"},
     "/tmp/tmp8o3mfrem/DateType/build/datetype/test/__init__.py": {"by": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "py": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
     "/tmp/tmp8o3mfrem/DateType/build/datetype/test/test_datetype.py": {"by": "sha256:61da5c59dcb92e423e8e5d7e45a646b3f76cf0d130642183aada96412a295dc4", "py": "sha256:680edea67d64782206eddb0866a5e9dae975afe0aa947b7e3d4de420218eea3c"},
DateType — datetype/__init__.py
--- base/datetype/__init__.py
+++ head/datetype/__init__.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, overload
 from datetype._by_runtime import _by_default
DateType — datetype/_by_runtime.py
--- base/datetype/_by_runtime.py
+++ head/datetype/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — README.py
--- base/README.py
+++ head/README.py
@@ -15,5 +15,5 @@
 > Pragmatic functional programming
 """
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Callable, Literal
 def _soundness_check(_v, _t):
@@ -109,5 +109,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -2,22 +2,22 @@
 # the two tables share their keys: the generated path, spelled as it is here
 SOURCEMAP = {
... 52609 characters elided ...
     "/tmp/tmp2wcmegjs/Expression/build/tests/test_typing.py": {"by": "sha256:9ff606f2ff8f1f56236a67c22f0ecba579dcb4e854a595144bd690fae8089d14", "py": "sha256:d81726a709971ef16c9e6e4cb317ede9c6a7243d5e4ac5e82304db205692cc12"},
Expression — docs/guides/choosing-a-type.py
--- base/docs/guides/choosing-a-type.py
+++ head/docs/guides/choosing-a-type.py
@@ -98,5 +98,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/guides/collection-types.py
--- base/docs/guides/collection-types.py
+++ head/docs/guides/collection-types.py
@@ -87,5 +87,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/guides/effects.py
--- base/docs/guides/effects.py
+++ head/docs/guides/effects.py
@@ -89,5 +89,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/guides/error-handling.py
--- base/docs/guides/error-handling.py
+++ head/docs/guides/error-handling.py
@@ -75,5 +75,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/guides/getting-started.py
--- base/docs/guides/getting-started.py
+++ head/docs/guides/getting-started.py
@@ -89,5 +89,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/guides/optional-values.py
--- base/docs/guides/optional-values.py
+++ head/docs/guides/optional-values.py
@@ -86,5 +86,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/tutorial/containers.py
--- base/docs/tutorial/containers.py
+++ head/docs/tutorial/containers.py
@@ -79,5 +79,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/tutorial/lambda_calculus.py
--- base/docs/tutorial/lambda_calculus.py
+++ head/docs/tutorial/lambda_calculus.py
@@ -7,5 +7,5 @@
 return functions, and small functions compose well.
 """
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Callable
 def _soundness_check(_v, _t):
Expression — docs/tutorial/optional_values.py
--- base/docs/tutorial/optional_values.py
+++ head/docs/tutorial/optional_values.py
@@ -86,5 +86,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — docs/tutorial/railway.py
--- base/docs/tutorial/railway.py
+++ head/docs/tutorial/railway.py
@@ -76,5 +76,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — expression/_by_runtime.py
--- base/expression/_by_runtime.py
+++ head/expression/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — expression/collections/array.py
--- base/expression/collections/array.py
+++ head/expression/collections/array.py
@@ -7,5 +7,5 @@
 
 """
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any as Any2, Callable
 from expression._by_runtime import Optional, _soundness_check, _soundness_once_bound, _soundness_parametric
Expression — expression/extra/parser.py
--- base/expression/extra/parser.py
+++ head/expression/extra/parser.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from expression._by_runtime import Optional, _soundness_check, _soundness_once_bound, _soundness_parametric
Expression — tests/_by_runtime.py
--- base/tests/_by_runtime.py
+++ head/tests/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Expression — tests/test_block.py
--- base/tests/test_block.py
+++ head/tests/test_block.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from tests._by_runtime import Optional, _soundness_check, _soundness_iter, _soundness_parametric
 lazy import functools
Expression — tests/test_option.py
--- base/tests/test_option.py
+++ head/tests/test_option.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tests._by_runtime import Optional, _soundness_check, _soundness_iter, _soundness_parametric
Expression — tests/test_result.py
--- base/tests/test_result.py
+++ head/tests/test_result.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from tests._by_runtime import Optional, _soundness_check, _soundness_iter, _soundness_parametric
 lazy from dataclasses import dataclass
Expression — tests/test_tagged_union.py
--- base/tests/test_tagged_union.py
+++ head/tests/test_tagged_union.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from tests._by_runtime import _soundness_check
PyGithub — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -368,5 +368,5 @@
     "/tmp/tmpsnbcaxvh/PyGithub/build/github/CodeSecurityConfig.py": {"by": "sha256:30075dd6b0b3e89975fa48212a291fc74fa1a81f7a230cf1a1fe54fe244ff9a8", "py": "sha256:588b782c6effa1d19afd61fa774fb1d31ca050f7c2b33865e95db0fd6590b212"},
     "/tmp/tmpsnbcaxvh/PyGithub/build/github/CodeSecurityConfigRepository.py": {"by": "sha256:cd22d6f9d579e873938e8fd9cd2c5872d6f0fcd4eca6fe96953f14da09ae9256", "py": "sha256:c76e50d93677a26c06fa00a9dd67c593bac1af6642ec2170ab2c65c5dd07849e"},
-    "/tmp/tmpsnbcaxvh/PyGithub/build/github/Commit.py": {"by": "sha256:ccb4f6bad3b5883de401ceffacba72e2aa16b733856d03b02433646cda0aca56", "py": "sha256:338c80679feb329767545b3f2b21e08cf9e437b6e73af09c597b9acaaa5aef73"},
+    "/tmp/tmpsnbcaxvh/PyGithub/build/github/Commit.py": {"by": "sha256:ccb4f6bad3b5883de401ceffacba72e2aa16b733856d03b02433646cda0aca56", "py": "sha256:692827775982959b7fdf9d9273228a04546a20e7ea3ce2547818af1c0a145a9a"},
... 13817 characters elided ...
     "/tmp/tmpsnbcaxvh/PyGithub/build/tests/GistComment.py": {"by": "sha256:799d7d599a4e8b038ca73b0f155213ac95efb4d575ff5f3a8aefbb3cef06c735", "py": "sha256:d469e867889ea076b790a94a13faa900d40c7eb3d96aff6a0a5fb0376aab9959"},
PyGithub — github/Commit.py
--- base/github/Commit.py
+++ head/github/Commit.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _by_default, _soundness_check
PyGithub — github/ContentFile.py
--- base/github/ContentFile.py
+++ head/github/ContentFile.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from github._by_runtime import _soundness_check
 ############################ Copyrights and license ############################
PyGithub — github/GithubException.py
--- base/github/GithubException.py
+++ head/github/GithubException.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 ############################ Copyrights and license ############################
PyGithub — github/GithubIntegration.py
--- base/github/GithubIntegration.py
+++ head/github/GithubIntegration.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _by_default
PyGithub — github/GithubObject.py
--- base/github/GithubObject.py
+++ head/github/GithubObject.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from github._by_runtime import _soundness_check, _soundness_iter, generic
 ############################ Copyrights and license ############################
PyGithub — github/GithubRetry.py
--- base/github/GithubRetry.py
+++ head/github/GithubRetry.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _by_default, _soundness_check
PyGithub — github/HookDelivery.py
--- base/github/HookDelivery.py
+++ head/github/HookDelivery.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _soundness_check
PyGithub — github/Issue.py
--- base/github/Issue.py
+++ head/github/Issue.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _by_default, _soundness_check
PyGithub — github/NamedUser.py
--- base/github/NamedUser.py
+++ head/github/NamedUser.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _by_default, _soundness_check
PyGithub — github/Repository.py
--- base/github/Repository.py
+++ head/github/Repository.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _by_default, _soundness_check, _soundness_iter
PyGithub — github/Requester.py
--- base/github/Requester.py
+++ head/github/Requester.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from github._by_runtime import _soundness_check, _soundness_iter
 ############################ Copyrights and license ############################
PyGithub — github/Topic.py
--- base/github/Topic.py
+++ head/github/Topic.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from github._by_runtime import _soundness_check
PyGithub — github/_by_runtime.py
--- base/github/_by_runtime.py
+++ head/github/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
PyGithub — openapi/_by_runtime.py
--- base/openapi/_by_runtime.py
+++ head/openapi/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
PyGithub — tests/Framework.py
--- base/tests/Framework.py
+++ head/tests/Framework.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tests._by_runtime import _by_default, _soundness_check
PyGithub — tests/_by_runtime.py
--- base/tests/_by_runtime.py
+++ head/tests/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
PyWinCtl — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -24,7 +24,7 @@
 DIGESTS = {
     "/tmp/tmp38474llv/PyWinCtl/build/pywinctl/__init__.py": {"by": "sha256:9167cb7e304b7689d2ba08ad30fc0c7e7a3c6b5bfb5a0e84116ba6b158083462", "py": "sha256:e05fee61d9bcbecf0cb8d6ddf164fb1218311bd06d3358a486b7122a40ec8768"},
-    "/tmp/tmp38474llv/PyWinCtl/build/pywinctl/_main.py": {"by": "sha256:35d9965aa48aa07fb0588d236205afb09e1f12827bbbec2d24cbfaa75548fbf4", "py": "sha256:56caef75215ee0223c7cab904462b1bbf1854d92f33b0312c557ac39534f1441"},
-    "/tmp/tmp38474llv/PyWinCtl/build/pywinctl/_pywinctl_macos.py": {"by": "sha256:8c0048967b65138caf18099932874f7ec203dfb7d75a399e35e11b9535887ef6", "py": "sha256:b308aec4ae175614bb3786ed67b8d3dfbeb473111f7e442bdf6d4f791bf47484"},
-    "/tmp/tmp38474llv/PyWinCtl/build/tests/test_pywinctl.py": {"by": "sha256:67b142b215d2bb36c2b035d40d13689b09a38218ffe21432291b186b379719bb", "py": "sha256:ff8ddc44754d596c04a8378b9a6dc04ae98a1e1ae063eea2ca33dc3f2592bf46"},
... 905 characters elided ...
     "/tmp/tmp38474llv/PyWinCtl/build/typings/Quartz/CoreGraphics/__init__.pyi": {"by": "sha256:d2b2f6f8c1fcbf3859da386e551fa53c1377840322312dff5a3642288ba831fa", "py": "sha256:3a4d20a31c3e8cbc508c373c1a586ff42334be9846e0741e73cf85ab1d46f5ee"},
PyWinCtl — pywinctl/_by_runtime.py
--- base/pywinctl/_by_runtime.py
+++ head/pywinctl/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
PyWinCtl — pywinctl/_main.py
--- base/pywinctl/_main.py
+++ head/pywinctl/_main.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from pywinctl._by_runtime import _soundness_check
 #!/usr/bin/python
PyWinCtl — pywinctl/_pywinctl_macos.py
--- base/pywinctl/_pywinctl_macos.py
+++ head/pywinctl/_pywinctl_macos.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from pywinctl._by_runtime import _by_default, _soundness_check, _soundness_iter
PyWinCtl — tests/test_pywinctl.py
--- base/tests/test_pywinctl.py
+++ head/tests/test_pywinctl.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 def _soundness_check(_v, _t):
     if not isinstance(_v, _t):
Tanjun — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -24,5 +24,5 @@
... 132549 characters elided ...
     "/tmp/tmpd70n0bjv/Tanjun/build/tests/test_utilities.py": {"by": "sha256:77bbddada1803c358aa6a20c89e455a374df73e8621ee90315c3ab077cca62dd", "py": "sha256:90b7de842db371c4f16353419b40466ab81749193701d9e26edb6b48a3eb194e"},
 }
Tanjun — examples/_by_runtime.py
--- base/examples/_by_runtime.py
+++ head/examples/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Tanjun — tanjun/_by_runtime.py
--- base/tanjun/_by_runtime.py
+++ head/tanjun/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Tanjun — tanjun/abc.py
--- base/tanjun/abc.py
+++ head/tanjun/abc.py
@@ -29,5 +29,6 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Interfaces of the objects and clients used within Tanjun."""
-lazy from ty_extensions import JustFloat
+from builtins import float as float2
+JustFloat = float2
 lazy from typing import Any, Callable, Literal
 from tanjun._by_runtime import _by_default
Tanjun — tanjun/annotations.py
--- base/tanjun/annotations.py
+++ head/tanjun/annotations.py
@@ -199,5 +199,5 @@
   <https://github.com/FasterSpeeding/Tan-chan>.
 """
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, Literal
 from tanjun._by_runtime import _by_default, _soundness_check
Tanjun — tanjun/clients.py
--- base/tanjun/clients.py
+++ head/tanjun/clients.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Standard Tanjun client."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, Literal
 from tanjun._by_runtime import _by_default, _soundness_check, _soundness_iter, _soundness_once_bound
Tanjun — tanjun/commands/slash.py
--- base/tanjun/commands/slash.py
+++ head/tanjun/commands/slash.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Slash command implementations."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, Literal
 from tanjun._by_runtime import _by_default, _soundness_check, _soundness_iter, _soundness_once_bound
@@ -1136,5 +1136,5 @@
     def copy(self, *, parent: tanjun.SlashCommandGroup | None = None) -> Self:
         # <<inherited docstring from tanjun.abc.ExecutableCommand>>.
-        inst = _soundness_once_bound(("BaseSlashCommand",), super().copy(), _soundness_check, lambda: BaseSlashCommand)
+        inst = super().copy()
         inst._parent = parent  # noqa: SLF001
         return inst
@@ -1244,5 +1244,5 @@
     def bind_client(self, client: tanjun.Client, /) -> Self:
         # <<inherited docstring from tanjun.abc.ExecutableCommand>>.
-        _soundness_once_bound(("SlashCommandGroup",), super().bind_client(client), _soundness_check, lambda: SlashCommandGroup)
+        super().bind_client(client)
... 700 characters elided ...
-        inst = _soundness_once_bound(("SlashCommandGroup",), super().copy(parent=parent), _soundness_check, lambda: SlashCommandGroup)
+        inst = super().copy(parent=parent)
         inst._commands = {name: command.copy(parent=inst) for name, command in self._commands.items()}  # noqa: SLF001
         return inst
Tanjun — tanjun/context/autocomplete.py
--- base/tanjun/context/autocomplete.py
+++ head/tanjun/context/autocomplete.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Autocomplete context implementation."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from tanjun._by_runtime import _by_default, _soundness_check
Tanjun — tanjun/context/message.py
--- base/tanjun/context/message.py
+++ head/tanjun/context/message.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Message command implementation."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tanjun._by_runtime import _by_default
Tanjun — tanjun/context/slash.py
--- base/tanjun/context/slash.py
+++ head/tanjun/context/slash.py
@@ -29,5 +29,6 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Slash command implementation."""
-lazy from ty_extensions import JustFloat
+from builtins import float as float2
+JustFloat = float2
 lazy from typing import Any, Callable, Literal
 from tanjun._by_runtime import _by_default, _soundness_check
Tanjun — tanjun/dependencies/data.py
--- base/tanjun/dependencies/data.py
+++ head/tanjun/dependencies/data.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Dependency utilities used for managing data."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tanjun._by_runtime import _by_default, _soundness_check
Tanjun — tanjun/dependencies/limiters.py
--- base/tanjun/dependencies/limiters.py
+++ head/tanjun/dependencies/limiters.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Command cooldown and concurrency limiters."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tanjun._by_runtime import _by_default, _soundness_check, _soundness_iter, _soundness_iter_p, _soundness_parametric
Tanjun — tanjun/dependencies/owners.py
--- base/tanjun/dependencies/owners.py
+++ head/tanjun/dependencies/owners.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Dependency used for managing owner checks."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tanjun._by_runtime import _by_default
Tanjun — tanjun/dependencies/reloaders.py
--- base/tanjun/dependencies/reloaders.py
+++ head/tanjun/dependencies/reloaders.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Implementation of a hot reloader for Tanjun."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tanjun._by_runtime import _by_default, _soundness_check, _soundness_iter
Tanjun — tanjun/errors.py
--- base/tanjun/errors.py
+++ head/tanjun/errors.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """The errors and warnings raised within and by Tanjun."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Literal
 from tanjun._by_runtime import _by_default
Tanjun — tanjun/schedules.py
--- base/tanjun/schedules.py
+++ head/tanjun/schedules.py
@@ -29,5 +29,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """Interface and interval implementation for a Tanjun based callback scheduler."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from tanjun._by_runtime import _by_default, _soundness_check, _soundness_iter
Tanjun — tests/_by_runtime.py
--- base/tests/_by_runtime.py
+++ head/tests/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
Tanjun — tests/context/test_message.py
--- base/tests/context/test_message.py
+++ head/tests/context/test_message.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from tests._by_runtime import _by_default, _soundness_check
Tanjun — tests/context/test_slash.py
--- base/tests/context/test_slash.py
+++ head/tests/context/test_slash.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from tests._by_runtime import _by_default, _soundness_check
Tanjun — tests/dependencies/test_data.py
--- base/tests/dependencies/test_data.py
+++ head/tests/dependencies/test_data.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from tests._by_runtime import _soundness_check
Tanjun — tests/dependencies/test_limiters.py
--- base/tests/dependencies/test_limiters.py
+++ head/tests/dependencies/test_limiters.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from tests._by_runtime import _soundness_check
Tanjun — tests/dependencies/test_owners.py
--- base/tests/dependencies/test_owners.py
+++ head/tests/dependencies/test_owners.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from tests._by_runtime import _soundness_check, _soundness_iter
 # BSD 3-Clause License
Tanjun — tests/test_schedules.py
--- base/tests/test_schedules.py
+++ head/tests/test_schedules.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from tests._by_runtime import _soundness_check
aiohttp — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -107,5 +107,5 @@
     "/tmp/tmpp50akvu0/aiohttp/build/tests/test_benchmarks_web_response.py": ("/tmp/tmpp50akvu0/aiohttp/tests/test_benchmarks_web_response.by", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104]),
... 239391 characters elided ...
     "/tmp/tmpp50akvu0/aiohttp/build/tests/test_web_sendfile_functional.py": {"by": "sha256:71f2b75d7a8a8171dc3ad810a92528dc1b834b8692563240b1f35a3195d1337b", "py": "sha256:01a9401805ebbc0726f0138af59b6d177fdd1ba4182e3c3fc1daeb991c55ac71"},
aiohttp — aiohttp/_by_runtime.py
--- base/aiohttp/_by_runtime.py
+++ head/aiohttp/_by_runtime.py
@@ -398,4 +398,20 @@
 
 
+# a t-string field's source text, as the interpreter running it reports one
+#
+# a lowered field's text keeps the whitespace before the `=`, conversion, format spec
+# or `}` that ends the field, which is what python reports from 3.14.8 on. 3.14.0 to
+# 3.14.7 dropped it (python/cpython#154719), so there it is dropped here too, or a
+# lowered field would report different text from an untouched field beside it. an
+# interpreter older than 3.14 has no t-strings and so no form of its own, and keeps
+# the newer one
+def _by_field_text(_text):
+    from sys import version_info
+
+    if (3, 14) <= version_info < (3, 14, 8):
+        return _text.rstrip()
+    return _text
+
+
 # PEP 750 `Template` / `Interpolation` polyfill for runtimes before 3.14
 #
@@ -405,8 +421,11 @@
 # is their evaluated values. iterating a `Template` yields the segments and
 # interpolations interleaved in source order, the same as the stdlib type
+#
+# the lowering builds every `_Interpolation` with its field's source text in the form
... 2000 characters elided ...
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
aiohttp — aiohttp/abc.py
--- base/aiohttp/abc.py
+++ head/aiohttp/abc.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable as Callable2
 from aiohttp._by_runtime import _by_default
aiohttp — aiohttp/client.py
--- base/aiohttp/client.py
+++ head/aiohttp/client.py
@@ -1,4 +1,4 @@
 """HTTP Client for asyncio."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable as Callable2, Literal, final, overload
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter, _soundness_iter_p, _soundness_parametric
aiohttp — aiohttp/client_proto.py
--- base/aiohttp/client_proto.py
+++ head/aiohttp/client_proto.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from aiohttp._by_runtime import _by_default
aiohttp — aiohttp/client_ws.py
--- base/aiohttp/client_ws.py
+++ head/aiohttp/client_ws.py
@@ -1,4 +1,4 @@
 """WebSocket client for asyncio."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, Literal, overload
 from aiohttp._by_runtime import _by_default, _soundness_check
aiohttp — aiohttp/connector.py
--- base/aiohttp/connector.py
+++ head/aiohttp/connector.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, Literal
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter, _soundness_iter_p, _soundness_parametric
aiohttp — aiohttp/cookiejar.py
--- base/aiohttp/cookiejar.py
+++ head/aiohttp/cookiejar.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter, _soundness_parametric
aiohttp — aiohttp/helpers.py
--- base/aiohttp/helpers.py
+++ head/aiohttp/helpers.py
@@ -1,4 +1,4 @@
 """Various helper functions"""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, final, overload
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter
aiohttp — aiohttp/web.py
--- base/aiohttp/web.py
+++ head/aiohttp/web.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter
aiohttp — aiohttp/web_fileresponse.py
--- base/aiohttp/web_fileresponse.py
+++ head/aiohttp/web_fileresponse.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter
aiohttp — aiohttp/web_log.py
--- base/aiohttp/web_log.py
+++ head/aiohttp/web_log.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter
aiohttp — aiohttp/web_protocol.py
--- base/aiohttp/web_protocol.py
+++ head/aiohttp/web_protocol.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable as Callable2
 from aiohttp._by_runtime import _by_default, _soundness_check
aiohttp — aiohttp/web_response.py
--- base/aiohttp/web_response.py
+++ head/aiohttp/web_response.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, overload
 from aiohttp._by_runtime import _by_default, _soundness_check
aiohttp — aiohttp/web_runner.py
--- base/aiohttp/web_runner.py
+++ head/aiohttp/web_runner.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter
aiohttp — aiohttp/web_server.py
--- base/aiohttp/web_server.py
+++ head/aiohttp/web_server.py
@@ -1,4 +1,4 @@
 """Low level HTTP server."""
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from aiohttp._by_runtime import _soundness_check, _soundness_iter
aiohttp — aiohttp/web_ws.py
--- base/aiohttp/web_ws.py
+++ head/aiohttp/web_ws.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, Literal, overload
 from aiohttp._by_runtime import _by_default, _soundness_check, _soundness_iter
aiohttp — examples/combined_middleware.py
--- base/examples/combined_middleware.py
+++ head/examples/combined_middleware.py
@@ -12,5 +12,5 @@
 3. Retry (innermost) - retries requests on failure
 """
-lazy from ty_extensions import JustFloat
+JustFloat = float
 
 lazy import asyncio
aiohttp — examples/retry_middleware.py
--- base/examples/retry_middleware.py
+++ head/examples/retry_middleware.py
@@ -10,5 +10,5 @@
 and can return different status codes on sequential requests.
 """
-lazy from ty_extensions import JustFloat
+JustFloat = float
 def _soundness_check(_v, _t):
     if not isinstance(_v, _t):
aiohttp — examples/token_refresh_middleware.py
--- base/examples/token_refresh_middleware.py
+++ head/examples/token_refresh_middleware.py
@@ -14,5 +14,5 @@
 In production, use proper JWT libraries and secure token storage.
 """
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any
 def _soundness_check(_v, _t):
aiohttp — tests/autobahn/test_autobahn.py
--- base/tests/autobahn/test_autobahn.py
+++ head/tests/autobahn/test_autobahn.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 def _soundness_check(_v, _t):
     if not isinstance(_v, _t):
aiohttp — tests/test_circular_imports.py
--- base/tests/test_circular_imports.py
+++ head/tests/test_circular_imports.py
@@ -82,5 +82,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
aiohttp — tests/test_client_session.py
--- base/tests/test_client_session.py
+++ head/tests/test_client_session.py
@@ -83,5 +83,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
aiohttp — tests/test_connector.py
--- base/tests/test_connector.py
+++ head/tests/test_connector.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable, Literal
 def _soundness_check(_v, _t):
@@ -88,5 +88,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
aiohttp — tests/test_cookie_helpers.py
--- base/tests/test_cookie_helpers.py
+++ head/tests/test_cookie_helpers.py
@@ -73,5 +73,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
aiohttp — tests/test_cookiejar.py
--- base/tests/test_cookiejar.py
+++ head/tests/test_cookiejar.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 def _soundness_check(_v, _t):
     if not isinstance(_v, _t):
@@ -73,5 +73,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
aiohttp — tests/test_run_app.py
--- base/tests/test_run_app.py
+++ head/tests/test_run_app.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy from typing import Any, Callable
 def _soundness_check(_v, _t):
aiohttp — tests/test_web_log.py
--- base/tests/test_web_log.py
+++ head/tests/test_web_log.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 def _soundness_check(_v, _t):
     if not isinstance(_v, _t):
aiohttp — tests/test_web_protocol.py
--- base/tests/test_web_protocol.py
+++ head/tests/test_web_protocol.py
@@ -68,5 +68,8 @@
         return None
     args = getattr(alias, "__args__", ())
-    params = getattr(klass, "__type_params__", ())
+    # a class the pep 695 polyfill wrote declares its parameters through
+    # `Generic[...]`, which records them in `__parameters__` and leaves
+    # `__type_params__` empty, or absent before 3.12
+    params = getattr(klass, "__type_params__", ()) or getattr(klass, "__parameters__", ())
     if not args:
         defaulted = _by_type_param_defaults(params)
aiohttp — tests/test_web_runner.py
--- base/tests/test_web_runner.py
+++ head/tests/test_web_runner.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy import asyncio
 lazy import platform
aiohttp-devtools — aiohttp_devtools/runserver/log_handlers.py
--- base/aiohttp_devtools/runserver/log_handlers.py
+++ head/aiohttp_devtools/runserver/log_handlers.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 from aiohttp_devtools._by_runtime import _soundness_check
 lazy import json
aiohttp-devtools — aiohttp_devtools/runserver/main.py
--- base/aiohttp_devtools/runserver/main.py
+++ head/aiohttp_devtools/runserver/main.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy import asyncio
 lazy import os
aioredis — aioredis/lock.py
--- base/aioredis/lock.py
+++ head/aioredis/lock.py
@@ -1,3 +1,3 @@
-lazy from ty_extensions import JustFloat
+JustFloat = float
 lazy import asyncio
 lazy import threading

2607 finding(s) omitted to fit GitHub's 65536-character comment limit. Every finding, with nothing elided, is in the roundtrip-report.md artifact of this run.

…n ci, transpile each runtime test for the interpreter it runs on, and fix what those runs found: polyfilled generic parameters, `global` type variables, starred aliases, `literal str` in written types and bounds, renames in compound statements, and a t-string field's text on each 3.14
…e version they target, and answer class and `__new__` docstrings, `object.__new__`'s refusals, `__init__` frame counts, `__closure__` and set members as python does
…odule's class that reads a binding of the module, take `super`'s receiver from the function or lambda it is written in, read type modifiers in typed-dict literals, let a checked cast write an inline protocol or `literal str` target's lowering itself, and give runtime tests their own directories
…ral type as closed or open to its `**: T` items, refuse a store through `super`, and report the `super` keyword in a `NamedTuple` method
…t` lower below the python that added them, report `super[T]` outside the MRO, and run the conformance programs on the interpreter they target
…ing, delete fields and clear an instance dict as python does, document `__class__` reassignment, spell C symbols injectively, and stand a module down over an orphaned base
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

ecosystem check

Linter (stable)

ℹ️ ecosystem check encountered linter errors. (no lint changes; 1 project error)

apache/airflow (error)

ruff check --no-cache --exit-zero --no-fix --output-format concise --no-preview --select ALL

warning: `incorrect-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `incorrect-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
ruff failed
  Cause: Failed to parse /home/runner/work/_temp/ruff-ecosystem-checkouts/apache:airflow/task-sdk/pyproject.toml
  Cause: TOML parse error at line 200, column 37
    |
200 | [tool.ruff.lint.flake8-tidy-imports.extend-banned-api]
    |                                     ^^^^^^^^^^^^^^^^^
unknown field `extend-banned-api`, expected one of `ban-relative-imports`, `banned-api`, `banned-module-level-imports`, `require-lazy`, `ban-lazy`

Linter (preview)

ℹ️ ecosystem check encountered linter errors. (no lint changes; 1 project error)

apache/airflow (error)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL

warning: `incorrect-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `incorrect-blank-line-before-class`.
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
ruff failed
  Cause: Failed to parse /home/runner/work/_temp/ruff-ecosystem-checkouts/apache:airflow/task-sdk/pyproject.toml
  Cause: TOML parse error at line 200, column 37
    |
200 | [tool.ruff.lint.flake8-tidy-imports.extend-banned-api]
    |                                     ^^^^^^^^^^^^^^^^^
unknown field `extend-banned-api`, expected one of `ban-relative-imports`, `banned-api`, `banned-module-level-imports`, `require-lazy`, `ban-lazy`

Formatter (stable)

ℹ️ ecosystem check encountered format errors. (no format changes; 1 project error)

apache/airflow (error)

ruff failed
  Cause: Failed to parse /home/runner/work/_temp/ruff-ecosystem-checkouts/apache:airflow/task-sdk/pyproject.toml
  Cause: TOML parse error at line 200, column 37
    |
200 | [tool.ruff.lint.flake8-tidy-imports.extend-banned-api]
    |                                     ^^^^^^^^^^^^^^^^^
unknown field `extend-banned-api`, expected one of `ban-relative-imports`, `banned-api`, `banned-module-level-imports`, `require-lazy`, `ban-lazy`

Formatter (preview)

ℹ️ ecosystem check encountered format errors. (no format changes; 1 project error)

apache/airflow (error)

ruff format --preview

ruff failed
  Cause: Failed to parse /home/runner/work/_temp/ruff-ecosystem-checkouts/apache:airflow/task-sdk/pyproject.toml
  Cause: TOML parse error at line 200, column 37
    |
200 | [tool.ruff.lint.flake8-tidy-imports.extend-banned-api]
    |                                     ^^^^^^^^^^^^^^^^^
unknown field `extend-banned-api`, expected one of `ban-relative-imports`, `banned-api`, `banned-module-level-imports`, `require-lazy`, `ban-lazy`

@KotlinIsland
KotlinIsland merged commit 8471642 into main Oct 23, 2026
63 of 70 checks passed
@KotlinIsland
KotlinIsland deleted the native-work branch October 23, 2026 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant