Skip to content

Fixes - #213

Merged
KotlinIsland merged 47 commits into
mainfrom
fixes
Oct 23, 2026
Merged

Fixes#213
KotlinIsland merged 47 commits into
mainfrom
fixes

Conversation

@KotlinIsland

Copy link
Copy Markdown
Owner

No description provided.

…wherever a lowering writes a type out from the checker's spelling of it — a soundness check's target, an `is` test, a checked cast, a reified specialization, a `raises` guard and an inferred annotation — instead of the name the source declares, which the emitted module does not bind, so `for x in kept` over a `list[Kept]` no longer raises `NameError` and `x is Kept` / `x cast! Kept` no longer fail to transpile
…ring moves it into a statement it writes — the operand of `or return` / `?? raise` / `if … else raise`, a re-evaluated default, an `if let` subject or condition, a `let` subject, a conjunction `match` subject and its case guard — so its second line no longer fails to parse ("Unexpected indentation") or runs as a statement of its own (`xs = [1]` then `+ [2]`)
…nother — `(a ?? {}).get(k) ?? []`, an argument, a subscript, an f-string — is no longer left in the output; parenthesize the lowered conditional where python would read it as something else (an operand of `and` / `or`, the test or value of a conditional expression, a comprehension iterable or condition, what `*` / `**` unpacks); bind the left operand as a comprehension variable instead of with `:=` where python refuses one (a comprehension iterable, a class-body comprehension), so `[x for x in d.get(k) ?? []]` no longer raises `SyntaxError` at import; and bind a unary left operand once instead of evaluating it twice
….me()?.v`), instead of leaving it in the output; bind a chain's receivers as comprehension variables instead of with `:=` where python refuses one (a comprehension iterable, a class-body comprehension); and refuse a chain whose call or subscript reads a class body's name from a class-body comprehension's first iterable, which that comprehension would no longer see
…ariable instead of with `:=` where python refuses one, and name its temporary like every other lowering's instead of `_s`, which overwrote a module's own `_s` and was an ordinary name in a class body
… `^` lowers to evaluates it into a temporary, so its second line no longer fails to parse
… version from its floor on, and refuse one python would not compile — an assignment expression in a comprehension iterable or a class-body comprehension, a `return` outside a function, a parameter named twice — instead of writing out a module that raises `SyntaxError` at import; the two `match` checks phase 3 already ran are among them
…name

`init(let cast: int)`, `let match`, `let type`, `let lazy` and `local type` did not
parse ("Expected `,`, found `cast`"), and recovery then made a parameter named `let`.
a soft keyword lexes as its own token kind, and the three modifier guards in
`parse_parameter` — the binding / visibility chain, `context`, and `local` / `once` —
took the keyword for a modifier only when a `Name` token followed it. they now go
through `declares_a_name`, the test the statement-level declarations already use, so
any of `match`, `case`, `type`, `lazy` and `cast` names the parameter. nothing can
follow a parameter's name but `:`, `=`, `,` or `)`, so a keyword followed by one of
those is still the parameter itself (`def f(let, match)`)
…` as the type it borrows

`(local type[int]) -> None` did not parse: like the parameter modifiers, the callable-type
modifier was taken only when a `Name` token followed it. a soft keyword now counts too,
except a `cast` that is the infix cast operator, so `(local cast int)` still casts a value
named `local`. the parser decides that from the token after `cast` exactly as it does when
it reads the operator, through one shared `infix_cast_kind`
…ents` and `enum class` as the name it introduces

`protocol match:`, `extension type:`, `newtype lazy = int`, `implements type` and
`enum class case:` did not parse, for the reason a parameter modifier could not take
one: each introducer was recognised only when a `Name` token followed it. they now
take a soft keyword too, through `introduces_a_name`, which leaves a `cast` that the
expression parser reads as the infix cast operator alone, so `protocol cast int` still
casts a value named `protocol`.

`@d` over `private protocol type:` panicked the parser ("left: Name, right: Class"):
the decorated chain already took a soft keyword as a protocol's name, and then
`parse_with_modifier`, which did not, fell through to `parse_class_definition` with
`protocol` as its current token. every site that decides a protocol is being
declared now asks the same question
… the name test the introducers use

`list[some type[int]]` reported "Expected `:`, found `type`" instead of the one
"`some` is only allowed at the top of a parameter annotation" error, because the
recovery arm took `some` for the keyword only when a `Name` token followed it. the test
for "a name follows this keyword" now lives once, as `Parser::peek_is_name` beside the
other token-kind predicates in `expression.rs`, and the misplaced `some`, the
callable-type `local` / `once` and every declaration introducer ask it. `some cast int`
still casts a variable named `some`
…arts no definition in a `.py` file

`@d` over `final x`, `private x = 1` or `private protocol cast int` in a `.py` file panicked
the parser ("left: Name, right: Class"), so the formatter and linter crashed on a
half-typed file. after a decorator, a modifier word went to `parse_with_modifier`, which
reads only a definition, and only a `.by` file first asked
`modifier_chain_ends_at_definition` whether one followed. both now ask, so a `.py` file
gets python's own "Expected class, function definition or async function definition after
decorator" recovery there, as it does over any other statement
…he checker writes a type out for the transpiler — a type test's or checked cast's probe, a reified call's specialization, a covariant class's construction — instead of python's `int | float`, so `x is L` with `type L = list[float]` now holds for a `list[float]` subclass and `argument(y)` with `y: float` reifies `T` as `float` (an invariant class constructed from a `float` variable is still specialized `A[int | float]`, because the checker solves it that way); and split promotion into three independent settings — whether literals widen, whether `float` / `complex` widen, and whether a function widens to its callable type — so the strict numeric model of a `.by` or `strict-float` module widens everything regular promotion does but `float` and `complex` (`self.a = A()` now declares the attribute `A` rather than `final A`, and `self.b = B(1)` keeps `B[Literal[1]]` for a covariant `B` as python does), while a `.by` module keeps a function's own type, whose reified type parameters, `context` parameters, `local` parameters and `raises` clause no callable type carries
… rewrites where it is written — `float`, `int?`, a literal, a tuple type, `typeof`, a callable type, `dynamic`, a template literal, an inline typed dict or named tuple, a symbolic type operation — instead of refusing it as a transform conflict: the check is built from the checker's reading of the target, or settled without it where the operand cannot hold the target, so `def f(x: int) -> float: return x cast! float` now builds and raises at runtime
…g every pair of them: methods that differ only in a receiver holding one value (`"a".lower`, `"a".startswith`, an int or enum member's method) are grouped by receiver like the literals themselves, so calling a method on a large enum's `name` (`kind.name.lower()` over 2000 members) is checked and transpiled in linear time instead of quadratic, with a union of the same members as before, possibly listed in a different order
… relied on: an extension member read as an attribute or as a bare name in a receiver block, an operator an extension supplies, a conversion whose route an extension or a conformance supplies, a protocol extension member reached through a conformance, a type test answered from the conformance registry, and a protocol extension default a conformance's witness table takes; each module is kept with the diagnostics of the inference that relied on it
…extensions applicable, with the module it grants: `import a.b` grants `a.b` and `a`, `from a import x` grants `a`
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

by ecosystem round-trip

base: d7eb92aad359889a3d42877d5d43f9d1f9d42cb0 (merge base) → head: 213/merge

regressions: 0, changed: 4262, improvements: 8, error changes: 1 (across 27816 files in 144 projects)

⚠️ 6 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
@@ -3,5 +3,5 @@
 SOURCEMAP = {
     "/tmp/tmphuf9gouo/DateType/build/docs/conf.py": ("/tmp/tmphuf9gouo/DateType/docs/conf.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]),
... 8183 characters elided ...
     "/tmp/tmphuf9gouo/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,5 +1,6 @@
 lazy from ty_extensions import JustFloat
-lazy from typing import Any, Literal, overload
-_MISSING: Any = object()
+lazy from typing import Any, overload
+from datetype._by_runtime import _by_default
+_MISSING: Any = _by_default("_missing", __name__, "_MISSING")
 
 lazy import sys
@@ -20,5 +21,5 @@
     from typing_extensions import Protocol, runtime_checkable  # type: ignore[assignment]
 
-_D = TypeVar("_D", bound=Literal["Date"])
+_D = TypeVar("_D", bound="Date")
 _GMaybeTZT = TypeVar("_GMaybeTZT", bound=Optional[_tzinfo], covariant=True)
 _GMaybeTZDT = TypeVar("_GMaybeTZDT", bound=Optional[_tzinfo], covariant=True)
@@ -28,6 +29,6 @@
 
 Self = TypeVar("Self")
-AnyDateTime = TypeVar("AnyDateTime", bound=Literal["DateTime[Optional[_tzinfo]]"])
-AnyTime = TypeVar("AnyTime", bound=Literal["Time[Optional[_tzinfo]]"])
+AnyDateTime = TypeVar("AnyDateTime", bound="DateTime[Optional[_tzinfo]]")
+AnyTime = TypeVar("AnyTime", bound="Time[Optional[_tzinfo]]")
 
 _missing = object()
@@ -305,5 +306,5 @@
 
 
-DTSelf = TypeVar("DTSelf", bound=Literal["DateTime"])
+DTSelf = TypeVar("DTSelf", bound="DateTime")
DateType — datetype/_by_runtime.py
--- base/datetype/_by_runtime.py
+++ head/datetype/_by_runtime.py
@@ -31,4 +31,24 @@
     async for _x in _it:
         yield _soundness_check(_x, _t)
+
+
+# a check in a function on a class the module binds further down, or only on some
+# paths. every binding the module makes of each of `_names` binds the class the check
+# names, so once they are all bound `_target` builds the target the checker named, and
+# `_check` is made against it; before then the value passes unchecked. the names are
+# looked up in the globals of the module the check is written in, which the lambda
+# `_target` carries
+def _soundness_once_bound(_names, _v, _check, _target, *_rest):
+    _globals = _target.__globals__
+    # a deferred `from` import is bound once its statement has run, which its
+    # module's `_LazyFrom` knows, and is in the namespace only once something has
+    # read it. the `_LazyFrom` is the module's `__getattr__`'s receiver, asked by
+    # what it holds rather than by its class: this check is often pasted in by
+    # another pass than the import's, and each paste has a class of its own
... 17937 characters elided ...
+def _lazy_from(lazy, mod, names, package=None):
     if package is not None:
         mod = _by_iu.resolve_name(mod, package)
-    return _LazyAttr(mod, attr)
+    for bound, attr in names.items():
+        lazy.__dict__.pop(bound, None)
+        lazy.__by_from__[bound] = (mod, attr)
Expression — README.py
--- base/README.py
+++ head/README.py
@@ -24,4 +24,17 @@
         )
     return _v
+
+def _soundness_once_bound(_names, _v, _check, _target, *_rest):
+    _globals = _target.__globals__
+    # a deferred `from` import is bound once its statement has run, which its
+    # module's `_LazyFrom` knows, and is in the namespace only once something has
+    # read it. the `_LazyFrom` is the module's `__getattr__`'s receiver, asked by
+    # what it holds rather than by its class: this check is often pasted in by
+    # another pass than the import's, and each paste has a class of its own
+    _deferred = getattr(getattr(_globals.get("__getattr__"), "__self__", None), "__by_from__", {})
+    for _name in _names:
+        if _name not in _globals and _deferred.get(_name) is None:
+            return _v
+    return _check(_v, _target(), *_rest)
 
 class Optional:
@@ -386,9 +399,9 @@
 
 
-v = _soundness_parametric(Optional(1), Option[int], (1,))
-fn2: Callable[[Option[int]], Option[int]] = lambda x: _soundness_parametric(x.map(lambda y: y + 1), Option[int], (1,))
... 2127 characters elided ...
 
     return x + y
@@ -581,5 +594,5 @@
 
     # -- The rest of the function will never be executed --
-    y = yield from _soundness_parametric(Optional(43), Option[int], (1,))
+    y = yield from _soundness_once_bound(("Option",), Optional(43), _soundness_parametric, lambda: Option[int], (1,))
 
     return x + y
Expression — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -2,5 +2,5 @@
 # the two tables share their keys: the generated path, spelled as it is here
 SOURCEMAP = {
... 27429 characters elided ...
     "/tmp/tmpyzurbxe8/Expression/build/expression/extra/result/catch.py": {"by": "sha256:210c10273bd427f0248d81b535a28d98a5311dce0143e7c8350993cc0cd2bf50", "py": "sha256:926cb2f461b1d33e700460ebceda411718900aba8bbec1ee1715aebf8364102c"},
Expression — expression/_by_runtime.py
--- base/expression/_by_runtime.py
+++ head/expression/_by_runtime.py
@@ -31,4 +31,24 @@
     async for _x in _it:
         yield _soundness_check(_x, _t)
+
+
+# a check in a function on a class the module binds further down, or only on some
+# paths. every binding the module makes of each of `_names` binds the class the check
+# names, so once they are all bound `_target` builds the target the checker named, and
+# `_check` is made against it; before then the value passes unchecked. the names are
+# looked up in the globals of the module the check is written in, which the lambda
+# `_target` carries
+def _soundness_once_bound(_names, _v, _check, _target, *_rest):
+    _globals = _target.__globals__
+    # a deferred `from` import is bound once its statement has run, which its
+    # module's `_LazyFrom` knows, and is in the namespace only once something has
+    # read it. the `_LazyFrom` is the module's `__getattr__`'s receiver, asked by
+    # what it holds rather than by its class: this check is often pasted in by
+    # another pass than the import's, and each paste has a class of its own
... 17937 characters elided ...
+def _lazy_from(lazy, mod, names, package=None):
     if package is not None:
         mod = _by_iu.resolve_name(mod, package)
-    return _LazyAttr(mod, attr)
+    for bound, attr in names.items():
+        lazy.__dict__.pop(bound, None)
+        lazy.__by_from__[bound] = (mod, attr)
Expression — expression/collections/array.py
--- base/expression/collections/array.py
+++ head/expression/collections/array.py
@@ -8,6 +8,6 @@
 """
 lazy from ty_extensions import JustFloat
-lazy from typing import Any as Any2, Callable, Literal
-from expression._by_runtime import Optional, _soundness_check, _soundness_parametric
+lazy from typing import Any as Any2, Callable
+from expression._by_runtime import Optional, _soundness_check, _soundness_once_bound, _soundness_parametric
 
 
@@ -209,5 +209,5 @@
             return TypedArray(chooser(x).to_seq())
 
-        return _soundness_check(self.collect(mapper), TypedArray)
+        return _soundness_once_bound(("TypedArray",), self.collect(mapper), _soundness_check, lambda: TypedArray)
 
     def collect(self, mapping: Callable[[_TSource], TypedArray[_TResult]]) -> TypedArray[_TResult]:
@@ -308,5 +308,5 @@
             The list of indexed elements.
         """
-        return _soundness_check(of_seq(enumerate(self)), TypedArray)
+        return _soundness_once_bound(("TypedArray",), of_seq(enumerate(self)), _soundness_check, lambda: TypedArray)
 
     def item(self, index: int) -> _TSource:
... 565 characters elided ...
@@ -469,5 +469,5 @@
 
     def __str__(self) -> str:
-        return f"[|{', '.join(_soundness_parametric(self.map(str), TypedArray[str], (0,)))}|]"
+        return f"[|{', '.join(_soundness_once_bound(("TypedArray",), self.map(str), _soundness_parametric, lambda: TypedArray[str], (0,)))}|]"
 
     def __repr__(self) -> str:
Expression — expression/collections/block.py
--- base/expression/collections/block.py
+++ head/expression/collections/block.py
@@ -19,6 +19,6 @@
 """
 lazy from typing import Any, Callable, Literal, overload
-from expression._by_runtime import Optional, _soundness_check, _soundness_parametric
-_MISSING: Any = object()
+from expression._by_runtime import Optional, _by_default, _soundness_check, _soundness_once_bound, _soundness_parametric
+_MISSING: Any = _by_default("()", __name__, "_MISSING")
 
 
@@ -115,5 +115,5 @@
             return Block(chooser(x).to_seq())
 
-        return _soundness_check(self.collect(mapper), Block)
+        return _soundness_once_bound(("Block",), self.collect(mapper), _soundness_check, lambda: Block)
 
     def collect(self, mapping: Callable[[_TSource], Block[_TResult]]) -> Block[_TResult]:
@@ -224,5 +224,5 @@
             The list of indexed elements.
         """
-        return _soundness_check(of_seq(enumerate(self)), Block)
+        return _soundness_once_bound(("Block",), of_seq(enumerate(self)), _soundness_check, lambda: Block)
 
     def item(self, index: int) -> _TSource:
@@ -307,5 +307,5 @@
     @staticmethod
... 1323 characters elided ...
@@ -535,5 +535,5 @@
 
     def __str__(self) -> str:
-        return f"[{', '.join(_soundness_parametric(self.map(str), Block[str], (0,)))}]"
+        return f"[{', '.join(_soundness_once_bound(("Block",), self.map(str), _soundness_parametric, lambda: Block[str], (0,)))}]"
 
     def __repr__(self) -> str:
Expression — expression/collections/map.py
--- base/expression/collections/map.py
+++ head/expression/collections/map.py
@@ -1,3 +1,3 @@
-from expression._by_runtime import _soundness_check, _soundness_iter
+from expression._by_runtime import _soundness_check, _soundness_iter, _soundness_once_bound
 # Attribution to original authors of this code
 # --------------------------------------------
@@ -52,5 +52,5 @@
     @staticmethod
     def create(ie: Iterable[tuple[_Key, _Value]]) -> Map[_Key, _Value]:
-        return _soundness_check(create(ie), Map)
+        return _soundness_once_bound(("Map",), create(ie), _soundness_check, lambda: Map)
 
     def contains_key(self, key: _Key) -> bool:
@@ -176,5 +176,5 @@
             The new map.
         """
-        return _soundness_check(of_block(lst), Map)
+        return _soundness_once_bound(("Map",), of_block(lst), _soundness_check, lambda: Map)
 
     @staticmethod
@@ -185,5 +185,5 @@
             The new map.
         """
-        return _soundness_check(of_list(lst), Map)
+        return _soundness_once_bound(("Map",), of_list(lst), _soundness_check, lambda: Map)
 
     @staticmethod
... 213 characters elided ...
 
     def __hash__(self) -> int:
@@ -227,5 +227,5 @@
             return False
 
-        other = _soundness_check(cast(Map[Any, Any], o), Map)
+        other = _soundness_once_bound(("Map",), cast(Map[Any, Any], o), _soundness_check, lambda: Map)
         iterator: Iterator[tuple[Any, Any]] = iter(other.to_seq())
Expression — expression/collections/seq.py
--- base/expression/collections/seq.py
+++ head/expression/collections/seq.py
@@ -23,6 +23,6 @@
 """
 lazy from typing import Any, Callable as Callable2, overload
-from expression._by_runtime import Optional, _soundness_check, _soundness_parametric
-_MISSING: Any = object()
+from expression._by_runtime import Optional, _by_default, _soundness_check, _soundness_once_bound, _soundness_parametric
+_MISSING: Any = _by_default("()", __name__, "_MISSING")
 
 
@@ -138,5 +138,5 @@
             function.
         """
-        return _soundness_check(_soundness_check(self.map(mapping), Seq).concat(), Seq)
+        return _soundness_once_bound(("Seq",), _soundness_once_bound(("Seq",), self.map(mapping), _soundness_check, lambda: Seq).concat(), _soundness_check, lambda: Seq)
 
     @staticmethod
@@ -316,5 +316,5 @@
         sequence.
         """
-        return _soundness_check(self.skip(1), Seq)
+        return _soundness_once_bound(("Seq",), self.skip(1), _soundness_check, lambda: Seq)
 
     def take(self, count: int) -> Seq[_TSource]:
@@ -340,5 +340,5 @@
 
     def to_list(self) -> Block[_TSource]:
-        return _soundness_check(to_list(self), Block)
+        return to_list(self)
 
     def try_find_index(self, predicate: Callable2[[_TSource], bool]) -> Option[int]:
@@ -993,5 +993,5 @@
     from .block import Block
 
-    return _soundness_check(Block.of_seq(source), Block)
+    return Block.of_seq(source)
Expression — expression/core/async_builder.py
--- base/expression/core/async_builder.py
+++ head/expression/core/async_builder.py
@@ -4,5 +4,4 @@
 create computational expressions for async operations.
 """
-from expression._by_runtime import _soundness_check
 
 lazy import inspect
@@ -10,5 +9,5 @@
 lazy from collections.abc import AsyncGenerator, Awaitable, Callable
 lazy from functools import wraps
-lazy from typing import Any, Generic, TypeVar, cast, Callable as Callable2, Literal
+lazy from typing import Any, Generic, TypeVar, cast, Callable as Callable2
 
 lazy from typing_extensions import ParamSpec
@@ -84,5 +83,5 @@
             # Effect errors (Nothing, Error, etc) short circuits
             state.is_done = True
-            return await self.return_from(_soundness_check(cast(Literal["_M"], error.args[0]), str))
+            return await self.return_from(cast(_M, error.args[0]))
         except StopAsyncIteration:
             state.is_done = True
@@ -118,12 +117,12 @@
                 result_value: _T | None
                 if inspect.iscoroutine(body):
... 521 characters elided ...
 
-            gen = _soundness_check(cast(Literal["AsyncGenerator[_T, Any]"], body), str)
+            gen = cast(AsyncGenerator[_T, Any], body)
             state = AsyncBuilderState[_T]()  # Initialize AsyncBuilderState
             result: _M = await self.zero()  # Initialize result
Expression — expression/core/builder.py
--- base/expression/core/builder.py
+++ head/expression/core/builder.py
@@ -1,8 +1,7 @@
-from expression._by_runtime import _soundness_check
 lazy import inspect
 lazy from abc import ABC
 lazy from collections.abc import Callable, Generator
 lazy from functools import wraps
-lazy from typing import Any, Generic, TypeVar, cast, Callable as Callable2, Literal
+lazy from typing import Any, Generic, TypeVar, cast, Callable as Callable2
 
 lazy from typing_extensions import ParamSpec
@@ -76,5 +75,5 @@
             # Effect errors (Nothing, Error, etc) short circuits
             state.is_done = True
-            return self.return_from(_soundness_check(cast(Literal["_M"], error.args[0]), str))
+            return self.return_from(cast(_M, error.args[0]))
         except StopIteration as ex:
             state.is_done = True
@@ -108,10 +107,10 @@
                 # Treat its return value like a `return` statement: a value
                 # maps to return_(value), a None return value maps to zero().
-                result_value = _soundness_check(cast(Literal["_T | None"], body), str)
... 208 characters elided ...
 
-            gen = _soundness_check(cast(Literal["Generator[Any, Any, Any]"], body), str)
+            gen = cast(Generator[Any, Any, Any], body)
             state = BuilderState[_T]()  # Initialize BuilderState
             result: _M = self.zero()  # Initialize result
Expression — expression/core/option.py
--- base/expression/core/option.py
+++ head/expression/core/option.py
@@ -7,5 +7,5 @@
 """
 lazy from typing import Any, Callable, Literal, Protocol
-from expression._by_runtime import Optional, _soundness_check
+from expression._by_runtime import Optional, _soundness_check, _soundness_once_bound
 class _Callable_3fc10be8(Protocol):
     def __call__(self, *args: "*_P") -> "_TResult": ...
@@ -99,5 +99,5 @@
         match self:
             case Option(tag="some", some=some):
-                return _soundness_check(Optional(mapper(some)), Option)
+                return _soundness_once_bound(("Option",), Optional(mapper(some)), _soundness_check, lambda: Option)
             case _:
                 return Nothing
@@ -111,5 +111,5 @@
         match self, other:
             case Option(tag="some", some=some), Option(tag="some", some=other_value):
-                return _soundness_check(Optional(mapper(some, other_value)), Option)
+                return _soundness_once_bound(("Option",), Optional(mapper(some, other_value)), _soundness_check, lambda: Option)
             case _:
... 2576 characters elided ...
-    return _soundness_check(value.to_result(error), Result)
+    return value.to_result(error)
 
 
 def to_result_with(value: Option[_TSource], error: Callable[[], _TError]) -> Result[_TSource, _TError]:
-    return _soundness_check(value.to_result_with(error), Result)
+    return value.to_result_with(error)
Expression — expression/core/result.py
--- base/expression/core/result.py
+++ head/expression/core/result.py
@@ -9,5 +9,5 @@
 the Result type to Exception.
 """
-from expression._by_runtime import Optional, _soundness_check
+from expression._by_runtime import Optional, _soundness_check, _soundness_once_bound
 
 
@@ -93,7 +93,7 @@
         match self:
             case Result(tag="ok", ok=value):
-                return _soundness_check(Result[_TResult, _TErrorOut].Ok(mapper(value)), Result)
-            case Result(error=error):
-                return _soundness_check(Result[_TResult, _TErrorOut].Error(error), Result)
+                return _soundness_once_bound(("Result",), Result[_TResult, _TErrorOut].Ok(mapper(value)), _soundness_check, lambda: Result)
+            case Result(error=error):
+                return _soundness_once_bound(("Result",), Result[_TResult, _TErrorOut].Error(error), _soundness_check, lambda: Result)
 
     def map2(
@@ -109,5 +109,5 @@
         match self:
             case Result(tag="ok", ok=value):
-                return _soundness_check(other.map(lambda value_: mapper(value, value_)), Result)
... 3591 characters elided ...
 
     def __iter__(self) -> Generator[_TSourceOut, _TSourceOut, _TSourceOut]:
@@ -494,5 +494,5 @@
     match result:
         case Result(tag="ok", ok=value):
-            return _soundness_check(Optional(value), Option)
+            return Optional(value)
         case _:
             return Nothing
Expression — expression/extra/parser.py
--- base/expression/extra/parser.py
+++ head/expression/extra/parser.py
@@ -1,4 +1,4 @@
 lazy from ty_extensions import JustFloat
-from expression._by_runtime import Optional, _soundness_check, _soundness_parametric
+from expression._by_runtime import Optional, _soundness_check, _soundness_once_bound, _soundness_parametric
 
 lazy import string
@@ -49,11 +49,11 @@
 
     def and_then(self, p2: Parser[_B]) -> Parser[tuple[_A, _B]]:
-        return _soundness_check(pipe(self, and_then(p2)), Parser)
+        return _soundness_once_bound(("Parser",), pipe(self, and_then(p2)), _soundness_check, lambda: Parser)
 
     def ignore_then(self, p2: Parser[_B]) -> Parser[_B]:
-        return _soundness_check(pipe(self, ignore_then(p2)), Parser)
+        return _soundness_once_bound(("Parser",), pipe(self, ignore_then(p2)), _soundness_check, lambda: Parser)
 
     def then_ignore(self, p2: Parser[Any]) -> Parser[_A]:
-        return _soundness_check(pipe(self, then_ignore(p2)), Parser)
+        return _soundness_once_bound(("Parser",), pipe(self, then_ignore(p2)), _soundness_check, lambda: Parser)
 
... 959 characters elided ...
         bound = bind(binder)
-        return _soundness_check(pipe(self, bound), Parser)
+        return _soundness_once_bound(("Parser",), pipe(self, bound), _soundness_check, lambda: Parser)
 
     def between(self, p2: Parser[_A], p3: Parser[Any]) -> Parser[_A]:
Expression — tests/_by_runtime.py
--- base/tests/_by_runtime.py
+++ head/tests/_by_runtime.py
@@ -31,4 +31,24 @@
     async for _x in _it:
         yield _soundness_check(_x, _t)
+
+
+# a check in a function on a class the module binds further down, or only on some
+# paths. every binding the module makes of each of `_names` binds the class the check
+# names, so once they are all bound `_target` builds the target the checker named, and
+# `_check` is made against it; before then the value passes unchecked. the names are
+# looked up in the globals of the module the check is written in, which the lambda
+# `_target` carries
+def _soundness_once_bound(_names, _v, _check, _target, *_rest):
+    _globals = _target.__globals__
+    # a deferred `from` import is bound once its statement has run, which its
+    # module's `_LazyFrom` knows, and is in the namespace only once something has
+    # read it. the `_LazyFrom` is the module's `__getattr__`'s receiver, asked by
+    # what it holds rather than by its class: this check is often pasted in by
+    # another pass than the import's, and each paste has a class of its own
... 17937 characters elided ...
+def _lazy_from(lazy, mod, names, package=None):
     if package is not None:
         mod = _by_iu.resolve_name(mod, package)
-    return _LazyAttr(mod, attr)
+    for bound, attr in names.items():
+        lazy.__dict__.pop(bound, None)
+        lazy.__by_from__[bound] = (mod, attr)
PyGithub — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -13,17 +13,17 @@
     "/tmp/tmp7p_o3ln5/PyGithub/build/github/ApplicationOAuth.py": ("/tmp/tmp7p_o3ln5/PyGithub/github/ApplicationOAuth.by", [None, 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, 48, 48, 48, 48, 48, 48, 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, 97, 97, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 116, 116, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 157, 157, 157, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196]),
... 363760 characters elided ...
     "/tmp/tmp7p_o3ln5/PyGithub/build/tests/GistComment.py": {"by": "sha256:799d7d599a4e8b038ca73b0f155213ac95efb4d575ff5f3a8aefbb3cef06c735", "py": "sha256:d469e867889ea076b790a94a13faa900d40c7eb3d96aff6a0a5fb0376aab9959"},
PyGithub — github/AdvisoryCredit.py
--- base/github/AdvisoryCredit.py
+++ head/github/AdvisoryCredit.py
@@ -99,6 +99,6 @@
             assert "login" in credit, credit
             assert "type" in credit, credit
-            assert isinstance(_soundness_check(credit["login"], (str, NamedUser)), (str, github.NamedUser.NamedUser)), credit["login"]
-            assert isinstance(_soundness_check(credit["type"], str), str), credit["type"]
+            assert isinstance(credit["login"], (str, github.NamedUser.NamedUser)), credit["login"]
+            assert isinstance(credit["type"], str), credit["type"]
         else:
             assert isinstance(credit.login, str), credit.login
@@ -111,11 +111,11 @@
             assert "login" in credit, credit
             assert "type" in credit, credit
-            assert isinstance(_soundness_check(credit["login"], (str, NamedUser)), (str, github.NamedUser.NamedUser)), credit["login"]
-            login = _soundness_check(credit["login"], (str, NamedUser))
+            assert isinstance(credit["login"], (str, github.NamedUser.NamedUser)), credit["login"]
+            login = credit["login"]
             if isinstance(login, github.NamedUser.NamedUser):
                 login = login.login
             return {
                 "login": login,
-                "type": _soundness_check(credit["type"], str),
+                "type": credit["type"],
             }
         else:
PyGithub — github/AdvisoryVulnerability.py
--- base/github/AdvisoryVulnerability.py
+++ head/github/AdvisoryVulnerability.py
@@ -1,3 +1,3 @@
-from github._by_runtime import _soundness_check, _soundness_iter
+from github._by_runtime import _soundness_check
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -134,15 +134,15 @@
             assert isinstance(_soundness_check(package["name"], (str, type(None))), (str, type(None))), package
             assert "patched_versions" in vulnerability, vulnerability
-            assert isinstance(_soundness_check(vulnerability["patched_versions"], (str, type(None))), (str, type(None))), vulnerability
+            assert isinstance(vulnerability["patched_versions"], (str, type(None))), vulnerability
             assert "vulnerable_functions" in vulnerability, vulnerability
-            assert isinstance(_soundness_check(vulnerability["vulnerable_functions"], (list, type(None))), (list, type(None))), vulnerability
... 1502 characters elided ...
+                "patched_versions": vulnerability["patched_versions"],
+                "vulnerable_functions": vulnerability["vulnerable_functions"],
+                "vulnerable_version_range": vulnerability["vulnerable_version_range"],
             }
         return {
PyGithub — github/Auth.py
--- base/github/Auth.py
+++ head/github/Auth.py
@@ -1,5 +1,6 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("Consts.DEFAULT_JWT_ISSUED_AT", __name__, "_MISSING2")
+_MISSING: Any = _by_default("Consts.DEFAULT_JWT_EXPIRY", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -227,9 +228,9 @@
         sign_func: DictSignFunction | None = None,
         jwt_expiry: int = _MISSING,
-        jwt_issued_at: int = _MISSING,
+        jwt_issued_at: int = _MISSING2,
     ):
         if jwt_expiry is _MISSING:
             jwt_expiry = Consts.DEFAULT_JWT_EXPIRY
-        if jwt_issued_at is _MISSING:
+        if jwt_issued_at is _MISSING2:
             jwt_issued_at = Consts.DEFAULT_JWT_ISSUED_AT
         assert isinstance(app_id, (int, str)), app_id
PyGithub — github/AuthenticatedUser.py
--- base/github/AuthenticatedUser.py
+++ head/github/AuthenticatedUser.py
@@ -1,5 +1,62 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check, _soundness_iter
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check, _soundness_iter
+_MISSING10: Any = _by_default("NotSet", __name__, "_MISSING10")
+_MISSING11: Any = _by_default("NotSet", __name__, "_MISSING11")
+_MISSING12: Any = _by_default("NotSet", __name__, "_MISSING12")
+_MISSING13: Any = _by_default("NotSet", __name__, "_MISSING13")
+_MISSING14: Any = _by_default("NotSet", __name__, "_MISSING14")
+_MISSING15: Any = _by_default("NotSet", __name__, "_MISSING15")
+_MISSING16: Any = _by_default("NotSet", __name__, "_MISSING16")
+_MISSING17: Any = _by_default("NotSet", __name__, "_MISSING17")
+_MISSING18: Any = _by_default("NotSet", __name__, "_MISSING18")
+_MISSING19: Any = _by_default("NotSet", __name__, "_MISSING19")
+_MISSING20: Any = _by_default("NotSet", __name__, "_MISSING20")
+_MISSING21: Any = _by_default("NotSet", __name__, "_MISSING21")
... 25195 characters elided ...
@@ -1240,5 +1297,5 @@
 :calls: `GET /user/memberships/orgs <https://docs.github.com/en/rest/orgs/members#list-organization-memberships-for-the-authenticated-user>`_\
 """
-        return PaginatedList[Membership](
+        return PaginatedList(
             github.Membership.Membership,
             self._requester,
PyGithub — github/Authorization.py
--- base/github/Authorization.py
+++ head/github/Authorization.py
@@ -1,5 +1,9 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING5: Any = _by_default("NotSet", __name__, "_MISSING5")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -133,8 +137,8 @@
         self,
         scopes: Opt[list[str]] = _MISSING,
-        add_scopes: Opt[list[str]] = _MISSING,
-        remove_scopes: Opt[list[str]] = _MISSING,
-        note: Opt[str] = _MISSING,
-        note_url: Opt[str] = _MISSING,
+        add_scopes: Opt[list[str]] = _MISSING2,
+        remove_scopes: Opt[list[str]] = _MISSING3,
+        note: Opt[str] = _MISSING4,
... 376 characters elided ...
-        if note is _MISSING:
+        if note is _MISSING4:
             note = NotSet
-        if note_url is _MISSING:
+        if note_url is _MISSING5:
             note_url = NotSet
         assert isinstance(scopes, _NotSetType) or all(isinstance(element, str) for element in scopes), scopes
PyGithub — github/Branch.py
--- base/github/Branch.py
+++ head/github/Branch.py
@@ -1,5 +1,38 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check, _soundness_iter
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check, _soundness_iter
+_MISSING10: Any = _by_default("NotSet", __name__, "_MISSING10")
+_MISSING11: Any = _by_default("NotSet", __name__, "_MISSING11")
+_MISSING12: Any = _by_default("NotSet", __name__, "_MISSING12")
+_MISSING13: Any = _by_default("NotSet", __name__, "_MISSING13")
+_MISSING14: Any = _by_default("NotSet", __name__, "_MISSING14")
+_MISSING15: Any = _by_default("NotSet", __name__, "_MISSING15")
+_MISSING16: Any = _by_default("NotSet", __name__, "_MISSING16")
+_MISSING17: Any = _by_default("NotSet", __name__, "_MISSING17")
+_MISSING18: Any = _by_default("NotSet", __name__, "_MISSING18")
+_MISSING19: Any = _by_default("NotSet", __name__, "_MISSING19")
+_MISSING20: Any = _by_default("NotSet", __name__, "_MISSING20")
+_MISSING21: Any = _by_default("NotSet", __name__, "_MISSING21")
+_MISSING22: Any = _by_default("NotSet", __name__, "_MISSING22")
... 10415 characters elided ...
             required_approving_review_count = NotSet
-        if require_last_push_approval is _MISSING:
+        if require_last_push_approval is _MISSING34:
             require_last_push_approval = NotSet
         assert is_optional_list(dismissal_users, str), dismissal_users
PyGithub — github/BranchProtection.py
--- base/github/BranchProtection.py
+++ head/github/BranchProtection.py
@@ -164,5 +164,5 @@
         if not _soundness_check(is_defined(self._user_push_restrictions), bool):
             return None
-        return PaginatedList[NamedUser](
+        return PaginatedList(
             github.NamedUser.NamedUser,
             self._requester,
PyGithub — github/CheckRun.py
--- base/github/CheckRun.py
+++ head/github/CheckRun.py
@@ -1,5 +1,14 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING10: Any = _by_default("NotSet", __name__, "_MISSING10")
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING5: Any = _by_default("NotSet", __name__, "_MISSING5")
+_MISSING6: Any = _by_default("NotSet", __name__, "_MISSING6")
+_MISSING7: Any = _by_default("NotSet", __name__, "_MISSING7")
+_MISSING8: Any = _by_default("NotSet", __name__, "_MISSING8")
+_MISSING9: Any = _by_default("NotSet", __name__, "_MISSING9")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -207,5 +216,5 @@
... 1960 characters elided ...
+        if completed_at is _MISSING8:
             completed_at = NotSet
-        if output is _MISSING:
+        if output is _MISSING9:
             output = NotSet
-        if actions is _MISSING:
+        if actions is _MISSING10:
             actions = NotSet
         assert is_optional(name, str), name
PyGithub — github/CheckSuite.py
--- base/github/CheckSuite.py
+++ head/github/CheckSuite.py
@@ -1,5 +1,7 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -245,6 +247,6 @@
         self,
         check_name: Opt[str] = _MISSING,
-        status: Opt[str] = _MISSING,
-        filter: Opt[str] = _MISSING,
+        status: Opt[str] = _MISSING2,
+        filter: Opt[str] = _MISSING3,
     ) -> PaginatedList[CheckRun]:
         """\
@@ -253,7 +255,7 @@
         if check_name is _MISSING:
             check_name = NotSet
-        if status is _MISSING:
+        if status is _MISSING2:
             status = NotSet
-        if filter is _MISSING:
+        if filter is _MISSING3:
             filter = NotSet
         assert is_optional(check_name, str), check_name
@@ -267,5 +269,5 @@
         if _soundness_check(is_defined(filter), bool):
             url_parameters["filter"] = filter
-        return PaginatedList[CheckRun](
+        return PaginatedList(
             github.CheckRun.CheckRun,
             self._requester,
PyGithub — github/CodeScanAlert.py
--- base/github/CodeScanAlert.py
+++ head/github/CodeScanAlert.py
@@ -160,5 +160,5 @@
 :calls: `GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances <https://docs.github.com/en/rest/code-scanning/code-scanning#list-instances-of-a-code-scanning-alert>`_\
 """
-        return PaginatedList[CodeScanAlertInstance](
+        return PaginatedList(
             github.CodeScanAlertInstance.CodeScanAlertInstance,
             self._requester,
PyGithub — github/Commit.py
--- base/github/Commit.py
+++ head/github/Commit.py
@@ -1,6 +1,16 @@
 lazy from ty_extensions import JustFloat
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING10: Any = _by_default("NotSet", __name__, "_MISSING10")
+_MISSING11: Any = _by_default("NotSet", __name__, "_MISSING11")
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING5: Any = _by_default("NotSet", __name__, "_MISSING5")
+_MISSING6: Any = _by_default("NotSet", __name__, "_MISSING6")
+_MISSING7: Any = _by_default("NotSet", __name__, "_MISSING7")
+_MISSING8: Any = _by_default("NotSet", __name__, "_MISSING8")
+_MISSING9: Any = _by_default("NotSet", __name__, "_MISSING9")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
... 4579 characters elided ...
             check_name = NotSet
         assert is_optional(app_id, int), app_id
@@ -379,5 +389,5 @@
 
         request_headers = {"Accept": "application/vnd.github.v3+json"}
-        return PaginatedList[CheckSuite](
+        return PaginatedList(
             github.CheckSuite.CheckSuite,
             self._requester,
PyGithub — github/CommitComment.py
--- base/github/CommitComment.py
+++ head/github/CommitComment.py
@@ -188,5 +188,5 @@
 :return: :class: :class:`github.PaginatedList.PaginatedList` of :class:`github.Reaction.Reaction`\
 """
-        return PaginatedList[Reaction](
+        return PaginatedList(
             github.Reaction.Reaction,
             self._requester,
PyGithub — github/Comparison.py
--- base/github/Comparison.py
+++ head/github/Comparison.py
@@ -114,5 +114,5 @@
 At most 10000 commits can be retrieved.\
 """
-        return PaginatedList[Commit](
+        return PaginatedList(
             github.Commit.Commit,
             self._requester,
@@ -180,5 +180,5 @@
        At most 10000 commits can be retrieved.\
 """
-        return PaginatedList[Commit](
+        return PaginatedList(
             github.Commit.Commit,
             self._requester,
PyGithub — github/ContentFile.py
--- base/github/ContentFile.py
+++ head/github/ContentFile.py
@@ -187,5 +187,5 @@
             # The repository was not set automatically, so it must be looked up by url.
             repo_url = "/".join(_soundness_check(self.url.split("/")[:6], list))  # pragma no cover (Should be covered)
-            self._repository = _ValuedAttribute[Repository](
+            self._repository = _ValuedAttribute(
                 github.Repository.Repository(self._requester, self._headers, {"url": repo_url}, completed=False)
             )  # pragma no cover (Should be covered)
PyGithub — github/Copilot.py
--- base/github/Copilot.py
+++ head/github/Copilot.py
@@ -54,5 +54,5 @@
 """
         url = f"/orgs/{self._org_name.value}/copilot/billing/seats"
-        return PaginatedList[CopilotSeat](
+        return PaginatedList(
             github.CopilotSeat.CopilotSeat,
             self._requester,
PyGithub — github/Deployment.py
--- base/github/Deployment.py
+++ head/github/Deployment.py
@@ -1,5 +1,9 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING5: Any = _by_default("NotSet", __name__, "_MISSING5")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -198,5 +202,5 @@
 :calls: `GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses <https://docs.github.com/en/rest/reference/repos#list-deployments>`_\
 """
-        return PaginatedList[DeploymentStatus](
+        return PaginatedList(
             github.DeploymentStatus.DeploymentStatus,
             self._requester,
@@ -222,8 +226,8 @@
         state: str,
... 722 characters elided ...
             environment = NotSet
-        if environment_url is _MISSING:
+        if environment_url is _MISSING4:
             environment_url = NotSet
-        if auto_inactive is _MISSING:
+        if auto_inactive is _MISSING5:
             auto_inactive = NotSet
         assert isinstance(state, str), state
PyGithub — github/EnterpriseConsumedLicenses.py
--- base/github/EnterpriseConsumedLicenses.py
+++ head/github/EnterpriseConsumedLicenses.py
@@ -97,5 +97,5 @@
 If no ``per_page`` is given, the default page size is 30. The maximum is 100.\
 """
-        return PaginatedList[NamedEnterpriseUser](
+        return PaginatedList(
             github.NamedEnterpriseUser.NamedEnterpriseUser,
             self._requester,
@@ -119,5 +119,5 @@
        Iterating over the users will fetch pages of this size. The default page size is 30, the maximum is 100.\
 """
-        return PaginatedList[NamedEnterpriseUser](
+        return PaginatedList(
             github.NamedEnterpriseUser.NamedEnterpriseUser,
             self._requester,
PyGithub — github/Environment.py
--- base/github/Environment.py
+++ head/github/Environment.py
@@ -191,5 +191,5 @@
 \
 """
-        return PaginatedList[Secret](
+        return PaginatedList(
             github.Secret.Secret,
             self._requester,
@@ -236,5 +236,5 @@
 Gets all repository variables :rtype: :class:`PaginatedList` of :class:`Variable`\
 """
-        return PaginatedList[Variable](
+        return PaginatedList(
             github.Variable.Variable,
             self._requester,
PyGithub — github/Gist.py
--- base/github/Gist.py
+++ head/github/Gist.py
@@ -1,5 +1,6 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -249,5 +250,5 @@
         headers, data = self._requester.requestJsonAndCheck("DELETE", self.url)
 
-    def edit(self, description: Opt[str] = _MISSING, files: Opt[dict[str, InputFileContent | None]] = _MISSING) -> None:
+    def edit(self, description: Opt[str] = _MISSING, files: Opt[dict[str, InputFileContent | None]] = _MISSING2) -> None:
         """\
 :calls: `PATCH /gists/{gist_id} <https://docs.github.com/en/rest/reference/gists>`_\
@@ -255,5 +256,5 @@
         if description is _MISSING:
             description = NotSet
-        if files is _MISSING:
+        if files is _MISSING2:
             files = NotSet
         assert is_optional(description, str), description
@@ -284,5 +285,5 @@
 :calls: `GET /gists/{gist_id}/comments <https://docs.github.com/en/rest/reference/gists#comments>`_\
 """
-        return PaginatedList[GistComment](
+        return PaginatedList(
             github.GistComment.GistComment,
             self._requester,
PyGithub — github/GitRef.py
--- base/github/GitRef.py
+++ head/github/GitRef.py
@@ -1,6 +1,5 @@
-lazy from builtins import object as object2
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object2()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
PyGithub — github/GitRelease.py
--- base/github/GitRelease.py
+++ head/github/GitRelease.py
@@ -1,5 +1,11 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING5: Any = _by_default("NotSet", __name__, "_MISSING5")
+_MISSING6: Any = _by_default("NotSet", __name__, "_MISSING6")
+_MISSING7: Any = _by_default("NotSet", __name__, "_MISSING7")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -289,7 +295,7 @@
         prerelease: bool = False,
         tag_name: Opt[str] = _MISSING,
-        target_commitish: Opt[str] = _MISSING,
-        make_latest: Opt[str] = _MISSING,
-        discussion_category_name: Opt[str] = _MISSING,
... 1475 characters elided ...
-        content_type: Opt[str] = _MISSING,
+        content_type: Opt[str] = _MISSING7,
         label: str = "",
     ) -> GitReleaseAsset:
@@ -382,5 +388,5 @@
 \
 """
-        if content_type is _MISSING:
+        if content_type is _MISSING7:
             content_type = NotSet
         assert isinstance(name, str), name
PyGithub — github/GithubIntegration.py
--- base/github/GithubIntegration.py
+++ head/github/GithubIntegration.py
@@ -1,5 +1,14 @@
 lazy from ty_extensions import JustFloat
 lazy from typing import Any
-_MISSING: Any = object()
+from github._by_runtime import _by_default
+_MISSING2: Any = _by_default("Consts.DEFAULT_TIMEOUT", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("Consts.DEFAULT_USER_AGENT", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("Consts.DEFAULT_PER_PAGE", __name__, "_MISSING4")
+_MISSING5: Any = _by_default("Consts.DEFAULT_SECONDS_BETWEEN_REQUESTS", __name__, "_MISSING5")
+_MISSING6: Any = _by_default("Consts.DEFAULT_SECONDS_BETWEEN_WRITES", __name__, "_MISSING6")
+_MISSING7: Any = _by_default("Consts.DEFAULT_JWT_EXPIRY", __name__, "_MISSING7")
+_MISSING8: Any = _by_default("Consts.DEFAULT_JWT_ISSUED_AT", __name__, "_MISSING8")
+_MISSING9: Any = _by_default("Consts.DEFAULT_JWT_ALGORITHM", __name__, "_MISSING9")
+_MISSING: Any = _by_default("Consts.DEFAULT_BASE_URL", __name__, "_MISSING")
 ############################ Copyrights and license ############################
... 1996 characters elided ...
-        if jwt_issued_at is _MISSING:
+        if jwt_issued_at is _MISSING8:
             jwt_issued_at = Consts.DEFAULT_JWT_ISSUED_AT
-        if jwt_algorithm is _MISSING:
+        if jwt_algorithm is _MISSING9:
             jwt_algorithm = Consts.DEFAULT_JWT_ALGORITHM
         if integration_id is not None:
PyGithub — github/GithubObject.py
--- base/github/GithubObject.py
+++ head/github/GithubObject.py
@@ -63,5 +63,5 @@
 lazy from decimal import Decimal
 lazy from operator import itemgetter
-from typing import TYPE_CHECKING, Any, TypeGuard, Callable as Callable2, Literal, overload
+from typing import TYPE_CHECKING, Any, TypeGuard, Callable as Callable2, overload
 
 lazy from typing import Self
@@ -77,5 +77,5 @@
 K = typing.TypeVar("K")
 T_co = typing.TypeVar("T_co", covariant=True)
-T_gh = typing.TypeVar("T_gh", bound=Literal["GithubObject"])
+T_gh = typing.TypeVar("T_gh", bound="GithubObject")
PyGithub — github/GithubRetry.py
--- base/github/GithubRetry.py
+++ head/github/GithubRetry.py
@@ -1,6 +1,6 @@
 lazy from ty_extensions import JustFloat
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING: Any = _by_default("DEFAULT_SECONDARY_RATE_WAIT", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
PyGithub — github/Hook.py
--- base/github/Hook.py
+++ head/github/Hook.py
@@ -1,5 +1,8 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -165,7 +168,7 @@
         config: dict,
         events: Opt[list[str]] = _MISSING,
-        add_events: Opt[list[str]] = _MISSING,
-        remove_events: Opt[list[str]] = _MISSING,
-        active: Opt[bool] = _MISSING,
+        add_events: Opt[list[str]] = _MISSING2,
+        remove_events: Opt[list[str]] = _MISSING3,
+        active: Opt[bool] = _MISSING4,
     ) -> None:
         """\
@@ -174,9 +177,9 @@
         if events is _MISSING:
             events = NotSet
-        if add_events is _MISSING:
+        if add_events is _MISSING2:
             add_events = NotSet
-        if remove_events is _MISSING:
+        if remove_events is _MISSING3:
             remove_events = NotSet
-        if active is _MISSING:
+        if active is _MISSING4:
             active = NotSet
         assert isinstance(name, str), name
PyGithub — github/InputFileContent.py
--- base/github/InputFileContent.py
+++ head/github/InputFileContent.py
@@ -1,5 +1,5 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
PyGithub — github/InputGitAuthor.py
--- base/github/InputGitAuthor.py
+++ head/github/InputGitAuthor.py
@@ -1,5 +1,5 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
PyGithub — github/InputGitTreeElement.py
--- base/github/InputGitTreeElement.py
+++ head/github/InputGitTreeElement.py
@@ -1,5 +1,6 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -53,9 +54,9 @@
         type: str,
         content: Opt[str] = _MISSING,
-        sha: Opt[str | None] = _MISSING,
+        sha: Opt[str | None] = _MISSING2,
     ):
         if content is _MISSING:
             content = NotSet
-        if sha is _MISSING:
+        if sha is _MISSING2:
             sha = NotSet
         assert isinstance(path, str), path
PyGithub — github/Installation.py
--- base/github/Installation.py
+++ head/github/Installation.py
@@ -233,5 +233,5 @@
         url_parameters: dict[str, Any] = {}
 
-        return PaginatedList[Repository](
+        return PaginatedList(
             contentClass=github.Repository.Repository,
             requester=self._requester,
PyGithub — github/Issue.py
--- base/github/Issue.py
+++ head/github/Issue.py
@@ -1,6 +1,14 @@
 lazy from ty_extensions import JustFloat
 lazy from typing import Any
-from github._by_runtime import _soundness_check, _soundness_iter
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING5: Any = _by_default("NotSet", __name__, "_MISSING5")
+_MISSING6: Any = _by_default("NotSet", __name__, "_MISSING6")
+_MISSING7: Any = _by_default("NotSet", __name__, "_MISSING7")
+_MISSING8: Any = _by_default("NotSet", __name__, "_MISSING8")
+_MISSING9: Any = _by_default("NotSet", __name__, "_MISSING9")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -323,5 +331,5 @@
... 7553 characters elided ...
+        return PaginatedList(
             Issue,
             self._requester,
@@ -754,5 +762,5 @@
 :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Issue.Issue`\
 """
-        return PaginatedList[Issue](
+        return PaginatedList(
             Issue,
             self._requester,
PyGithub — github/IssueComment.py
--- base/github/IssueComment.py
+++ head/github/IssueComment.py
@@ -193,5 +193,5 @@
         <https://docs.github.com/en/rest/reference/reactions#list-reactions-for-an-issue-comment>`_\
 """
-        return PaginatedList[Reaction](
+        return PaginatedList(
             github.Reaction.Reaction,
             self._requester,
PyGithub — github/Label.py
--- base/github/Label.py
+++ head/github/Label.py
@@ -1,5 +1,5 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
PyGithub — github/Milestone.py
--- base/github/Milestone.py
+++ head/github/Milestone.py
@@ -1,5 +1,7 @@
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -189,5 +191,5 @@
 
     def edit(
-        self, title: str, state: Opt[str] = _MISSING, description: Opt[str] = _MISSING, due_on: Opt[date] = _MISSING
+        self, title: str, state: Opt[str] = _MISSING, description: Opt[str] = _MISSING2, due_on: Opt[date] = _MISSING3
     ) -> None:
         """\
@@ -196,7 +198,7 @@
         if state is _MISSING:
             state = NotSet
-        if description is _MISSING:
+        if description is _MISSING2:
             description = NotSet
-        if due_on is _MISSING:
... 263 characters elided ...
 """
-        return PaginatedList[Label](github.Label.Label, self._requester, f"{self.url}/labels", None)
+        return PaginatedList(github.Label.Label, self._requester, f"{self.url}/labels", None)
 
     def _useAttributes(self, attributes: dict[str, Any]) -> None:
PyGithub — github/NamedUser.py
--- base/github/NamedUser.py
+++ head/github/NamedUser.py
@@ -1,6 +1,9 @@
 lazy from ty_extensions import JustFloat
 lazy from typing import Any
-from github._by_runtime import _soundness_check
-_MISSING: Any = object()
+from github._by_runtime import _by_default, _soundness_check
+_MISSING2: Any = _by_default("NotSet", __name__, "_MISSING2")
+_MISSING3: Any = _by_default("NotSet", __name__, "_MISSING3")
+_MISSING4: Any = _by_default("NotSet", __name__, "_MISSING4")
+_MISSING: Any = _by_default("NotSet", __name__, "_MISSING")
 ############################ Copyrights and license ############################
 #                                                                              #
@@ -440,5 +443,5 @@
 :calls: `GET /users/{username}/events <https://docs.github.com/en/rest/reference/activity#events>`_\
 """
-        return github.PaginatedList.PaginatedList[Event](github.Event.Event, self._requester, f"{self.url}/events", None)
+        return github.PaginatedList.PaginatedList(github.Event.Event, self._requester, f"{self.url}/events", None)
 
     def get_followers(self) -> PaginatedList[NamedUser]:
... 5077 characters elided ...
 :calls: `GET /users/{username}/watched <https://docs.github.com/en/rest/reference/activity#starring>`_\
 """
-        return github.PaginatedList.PaginatedList[Repository](
+        return github.PaginatedList.PaginatedList(
             github.Repository.Repository, self._requester, f"{self.url}/watched", None
         )
PyGithub — github/OrganizationVariable.py
--- base/github/OrganizationVariable.py
+++ head/github/OrganizationVariable.py
@@ -60,5 +60,5 @@
     @property
     def selected_repositories(self) -> PaginatedList[Repository]:
-        return PaginatedList[Repository](
+        return PaginatedList(
             github.Repository.Repository,
             self._requester,
beartype — beartype/_util/hint/pep/proposal/pep484585/generic/pep484585genfind.py
(only produced on base)

✅ improvements (failed on base, now builds)

  • apprise <build>

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

…pe makes, which the semantic index has no record of: a receiver callable read as a method (`x.fn()`), a name in a lazily evaluated annotation, a name read through `global`, the enum a context-sensitive name or case name is lowered to qualify with, and the module bindings the runtime spelling of a type test, a checked cast or a `raises` guard reads
…an import also counts as used when the module it names declares an extension or a conformance that inference relied on
…only its unused aliases, writing `pass` where a block would be left empty; an import in a package's `__init__.by` or one testing for a module's availability gets no fix
… import kept for its module's extensions is used; regenerate the rule docs and schema
…, as one query the transpiler and the native backend both ask; the emitted python is unchanged
… as used: a soundness check's target, at every position a build can enable, a reified call's or construction's specialization, and the arms a union parameter's reified type parameter is bounded by
…moved by `by check --fix`, and fail when it then checks or behaves differently, every soundness check on
…ker reads it as, wherever one is expected — an argument, a keyword argument, an element of `*args`, a default, a `yield`, a method call such as `items.append((1, 2))`, a collection literal at any depth, a write to an attribute, an `init(let p: ...)` parameter — instead of only under an annotated assignment, a `return` or a list or set literal, where everything else stayed a plain tuple and field access raised `AttributeError` with `by check` clean

the transpiler now finds the literals by their inferred type rather than by syntactic hooks, and builds the class the checker identified: the one a type form of the same type declares, or one declared from the checker's field types for a class from another module, refusing a field type the module cannot spell. in a `.by` file an attribute write records its value as it was checked against the declaration; a write through a union receiver is still checked against each member's own declaration, and is rejected only where the members would build different anonymous named tuples from one literal. an anonymous named tuple is built only where its fields accept the literal, which is otherwise inferred against the rest of the expected type; a literal more than one accepts is `ambiguous-conversion` instead of becoming the first; a `.py` file no longer reads a plain tuple as a named tuple
…t has a plain tuple literal the checker reads as an anonymous named tuple, which the native lowering built as a plain tuple, so the callee's field access raised `AttributeError`
…amed tuple expected wherever it stands, how a union chooses one, and that a `.py` file keeps a plain tuple a tuple
…where it holds there the binding the checker resolved: every binding of it is made above the module statement the code is in, which for a function or a method is the `def` or `class` statement holding it, since the function may be called as soon as that runs; none is made only for the checker; and either the module binds it on every path to its end, with no `del` and no binding made in one branch of a conditional expression unbinding it, or every binding of it is one a statement at the top of the module always makes once it completes, which a module the checker finds never ends (one that stops with `sys.exit()`) needs. a binding is made only for the checker when a condition deciding whether it is made reads `typing.TYPE_CHECKING` — the test of an `if`, `elif` or `while`, the subject, patterns and guards of a `match` case, an expression around a walrus — or when its value reads it (`Foo = _F if TYPE_CHECKING else None`), whichever way the condition goes (`if not TYPE_CHECKING:` and `if TYPE_CHECKING and ready:` count), with the constant found by resolving each name: imported under any name, read off the `typing` module, held by an assignment, a walrus or an augmented assignment, or a module's own `TYPE_CHECKING`, which the checker reads as `True` too; a name imported from another module is made only for the checker when the binding it imports is. a specialization the checker solved that only refines a construction is left out where its names do not hold (`self.entries = set()` with `entries: set[Decimal]` stays `set()` rather than raising `NameError`), a soundness check against such a class is left out, a plain `cast`'s type is written as a string, and a reified type argument, an `is` test and a checked cast that would need it are errors at check time (`unspecialized-reified-generic`, `erased-type-check`); where the program binds the name some other way, in the `else:` of a `TYPE_CHECKING` block, the error says the class it binds need not be the one the checker resolved. `redundant-condition` no longer reports a test of `typing.TYPE_CHECKING` imported under another name
…her down, or only on some paths, once the class is bound, by looking the name up as the check runs (`for cut in _soundness_once_bound(("Cut",), self.cuts, _soundness_iter, lambda: Cut):`), where every binding the module makes of the name binds that one class, none only for the checker, and nothing unbinds or rebinds it through `global`; such a check was left out. the lookup is keyed by the name the class is emitted under (`"_Kept"` for a `private class Kept`), a check at the module's own level keeps the rule that the class is bound above it, and `by compile` leaves a function making such a check to its interpreted definition
…ose `repr` is the default as written, so `inspect.signature` reports `geysers: int = <default: EARLY>` rather than one anonymous `object()` shared by every such parameter; a required parameter after a defaulted one shows as `<required>`. the guard tests the marker's class (`if type(geysers) is _MISSING:`), and a marker handed back as an argument, as `BoundArguments.apply_defaults` hands it, is still the argument not given. a structural protocol test against a method whose unannotated parameter has such a default raises rather than read the marker's type as the parameter's, and no longer reads a required parameter after a default as optional
…en an argument is the very object that definition holds as the parameter's default, as it already did when the argument was left out. in `.by` that object is the marker `inspect.signature` reports for a default re-evaluated per call, or for a required parameter after a defaulted one, so a call bound with `BoundArguments.apply_defaults` and made through `by compile` output evaluates the default (`def f(xs: list[int] = [])`) or raises the missing-argument `TypeError`, instead of the native body taking the marker as the argument (`AttributeError: '_by_default' object has no attribute 'append'`, or a soundness `TypeError` for `x: int = LIMIT`)
… imports whose binding is the only definition its name has in the module (no other assignment, `def`, `class`, loop/`with`/`except`/walrus target, second import, declaration, `del`, or `global` write from a nested scope), with every name node that reads it. a read resolves as python resolves it, so a class body that binds the name reads the module's binding until it has made its own, never a function's around it, and a class-body read that may find either disqualifies the import. a module with a star import or its own `__getattr__`/`__dir__` defers nothing
… it registers its names with one `_LazyFrom` per module whose `__dict__` is the module's own namespace (`_lazy_from(_by_lazy, "json", {"dumps": "dumps"})`), and every read of a name that `deferrable_from_imports` reports is written as `_by_lazy.dumps`. the first read resolves the name off its module, with the same submodule fallback and `ImportError` wording as before, and stores the object in the namespace, so the name is the object itself: identity, `type()`, `json.dumps`, `pytest.approx` and `=== None` all answer as for an ordinary import, which the `_LazyAttr` proxy could not. a patch of the name in the importing module (`mock.patch`, `monkeypatch.setattr`) reaches its reads, a read before the statement has run raises python's `NameError`, and the module's `__getattr__`/`__dir__` serve the names to other modules. a name with a read that cannot be rewritten, or a name read in an `f"{x=}"` or a t-string, or beginning with two underscores, keeps an ordinary import, as do exception classes, special forms and names an annotation or a decorator reads. `_soundness_once_bound` counts a registered deferred name as bound. the interpreted fallback of a `by compile` module keeps its `from` imports ordinary (`Config::defer_from_imports`), since compiled functions read the module's globals by name. `_LazyAttr`, `_lazy_attr` and `_by_forward_operators` are removed

a relative `from . import helper` reads `helper` off the package and imports it as a submodule only when the package has none, as python does, rather than importing the submodule `pkg.helper` unconditionally where the statement stood

a name read inside a forward reference the transpiler writes as a string, such as a type variable's bound written ahead of the class it names (`TypeVar("T", bound="dict[Thing, C.Inner]")`), keeps an ordinary import, since whatever evaluates that string looks the name up in the module's namespace
…e checker reads it as wherever it stands, a generic's type argument included: `list["a"]`, `dict[str, "k"]`, `Callable[["p"], "r"]`, an alias's value and a `type` statement's become `list[Literal["a"]]` and so on, where they were left bare and python read them as forward references to names that do not exist (`typing.get_type_hints` raised `NameError`). a union with no literal arm is now searched for one inside its arms (`list[1] | int`). a forward reference the transpiler quotes itself is still a string, with the literal types inside it lowered
…own in `.by`, and quote it in the output

in a `.by` file the checker now reads the type arguments of a specialization written as a value (`list[F]()`, `Alias = dict[str, F]`, the `Foo[F]` of a base) and the type-expression arguments of a typing construct assigned to a name (`T = TypeVar("T", bound=F)`, `NewType`, the functional `NamedTuple` and `TypedDict`) as deferred, as it reads an annotation, and records which ones it read that way (`TypeExpressionFlags::READ_DEFERRED`, `SemanticModel::is_read_deferred`). the transpiler quotes a forward reference in exactly those (`a = list[F](); class F` → `a = list["F"]()`), and keeps the names a quote reads out of the lazy `from` import polyfill, since a quote is evaluated against the module's namespace. this replaces the rule that quoted only a class's own name in its bases and class body

the positions python reads as an object rather than a type are read where they are written, and a name not yet bound there is `unresolved-reference`: a base itself, which was read as deferred before, so `class A(A)` and `class Bar(F)` above `class F` are now `unresolved-reference` where `class A(A)` was silent (a cycle across modules, or in a stub, is still `cyclic-class-definition`); a reified class's type arguments; the bases of `type()` and `types.new_class`; the type an `is`, `cast!`, `cast?` or `cast` reads; and a value inside a type, the arguments of `Literal[...]` and the metadata of `Annotated[...]`, even inside a deferred specialization
…he module binds

the class an anonymous named tuple lowers to is written ahead of everything the module binds,
so a field naming one of those (`x: list[(a: F, b: int)]` with `class F` further down, or a
`typeof y` of a module variable) raised `NameError` as the module was imported. such a field
type is now written as a string, as a renamed type variable's already was, with the lowered type
inside it (`a: "F"`), in an annotation and in a type written as a value alike
…, and keep the names it reads ordinary imports

below python 3.15 the lazy-import polyfill defers a `from` import's names, but python evaluates a string type (`list["F | JSONDecoder"]`) against the module's namespace, where a deferred name is not bound yet: `typing.get_type_hints` raised `NameError` for a name read only inside such a string

a quote can now only be written through `WrittenQuotes` (`transforms/quotes.rs`): `quote(text)` writes a lowered type as a string and records it, and `quote_span(range)` gives a `Fragment::Quote` the driver writes as a string, recording what it lowered to. every producer holds the registry: the forward-reference quoting, a `cast` target, the fields of a hoisted anonymous named tuple, typed dict and inline or callable protocol, and a type variable's bound read through its classes. code that only picks names never sees it. the lazy-import phase keeps every name the recorded quotes read an ordinary import
… a project's files in parallel. each rayon job gets its own handle on the project db without attaching it for the whole job: the `Cannot change database mid-query` panic came from `map_with_db` attaching the job's handle across the closure, not from a database built inside a salsa query, so a type-aware pass's own single-file and rebuilt databases attach normally. modules are handed to the caller in source order, so a build reports every module it could not emit in that order, and under the `run` gate the hand-over stops at the first failure in source order and no module after it is started. a panic in one module's transpile is reported as that module's `panic` diagnostic through `ty_project::catch_panic`, the helper a check uses (now public, and naming what was being done through `PanicError::to_diagnostic_message`), so a cancellation goes back to the caller unchanged and a panic propagated from a query another thread was running is reported. `by build`, `by run`, `by compile` and `by transpile <dir>` exit 101 when a check or a transpile panicked, as `by check` does. on neuromorph (213 files, interleaved, 4 rounds) the build goes from 24.3–27.2s wall / 29.4–30.9s cpu / 1.66 GB to 5.6–6.1s wall / 35.5–36.5s cpu / 2.06–2.18 GB, with byte-identical output
…by restage` read a project through is set up the way `by check` sets up its own: parsed-module lru disabled, open files frozen and the project and file inputs frozen, before the sources are indexed so the freeze reaches every file. without the freeze salsa recorded a dependency on each file input, and the check inside a build cost more than a standalone `by check`. on neuromorph (213 files, ABBA, 4 rounds) the build's check phase goes from 7.9–8.7s cpu / 1.04–1.11 GB to 5.2–5.8s cpu / 312–317 MB, and the whole build from 36.3–40.2s cpu / 2.02–2.19 GB peak to 33.5–36.2s cpu / 1.20–1.38 GB, with byte-identical output and diagnostics
…dic is parsed as an anonymous named tuple wherever the named field comes, as `(int, name: T)` already was: `(int, str, name: T)` and `(int, local b: T)` used to parse as parameter lists, which the checker read as anonymous named tuples while the transpiler wrote them as plain `tuple[...]` annotations. the checker now makes an anonymous named tuple class only from a tuple the parser flagged as one, and a keyword variadic (`**kw: T`, `**: T`, `**P`) in a tuple type is `invalid-type-form`: it collects keyword arguments, which a tuple has no place for, so it belongs only in a callable's parameter list. before, `(int, **kw: T)` was read as an anonymous named tuple and `(int, /, **kw: T)` as `tuple[int, T]`, while the transpiler wrote both as `tuple[int]`
…DynamicNamedTupleAnchor::Anonymous`, which only an anonymous named tuple form makes, instead of by a `_AnonNamedTuple_` prefix on the class's name. a `NamedTuple(...)` or `namedtuple(...)` call the program makes is an ordinary named tuple whatever it names its class: it displays under its own name, is not structurally assignable to an anonymous named tuple, and a plain tuple is no longer read as an instance of it, which the transpiler used to construct as a class of its own
…y operator `===` is not valid in .py files", as every other basedpython-only form does. the python-mode parser used to accept both silently, so `buff check` and `by check` reported nothing for a `.py` file python itself rejects, and a `===` left in transpiled output passed phase 3. the parser fixture that pinned their shape in python mode moves from `valid` to `invalid`
…output parses it first and returns it untouched when it spells no anonymous named tuple, as a type or as a value, and no inline protocol, instead of building a single-file db and inferring the whole output to ask which plain tuple literals the checker reads as an anonymous named tuple. those two are the only syntax the cleanup lowers, and the checker makes an anonymous named tuple type only from a form the parser flags, marked by its `DynamicNamedTupleAnchor::Anonymous` anchor; the cleanup's db reads nothing but the output and the vendored stubs, and a test checks that no vendored stub spells one. phase 3 no longer scans its parse of the output for leftover basedpython syntax: a parse as python rejects every basedpython-only form, so that parse is the check. `VendoredFileSystem::read_directory` lists the archive's root. on neuromorph (213 files, ABBA, 4 rounds) `by build` goes from 34.3–36.7s cpu / 1.26–1.35 GB peak to 16.3–17.4s cpu / 0.71–0.82 GB, with byte-identical output, and a differential `by transpile` of the 6821 distinct sandpit files at `requires-python >=3.10`, with and without the early return, gives identical output, diagnostics and exit codes
…re the binding the checker resolved once the file is inferred, never from inside inference. inference plans a type test, a checked cast and a bare reified call or construction without asking, since the question needs an `InferredInCheckOrder` for the file, which only the check-order inference makes, and the methods that ask it live on `LoweringModel`, which inference never builds. it reports what does not depend on the answer, and records the site (`RuntimeReadSite`, by node index, in the diagnostics it already carries). `runtime_read_checks`, a query per scope that `check_types` runs after every scope is inferred, infers the scopes around the site first, asks the question with the same plans the transpiler uses, and reports `erased-type-check` and `unspecialized-reified-generic` for a name that does not hold, with the messages inference used to give. the module-level names a type test or a checked cast is written with reach `unused-import` from that query instead of from inference. asked inside the module's inference, the end-of-module question inferred every module-level condition after a type test, each inside the inference of the next: 37 levels of `analyze_predicate` in `parametric_protocol_checks_run_correctly`, which overflowed a 2 MiB test thread at opt-level 0. a reason that does not depend on the bindings (an unspellable argument, a protocol target) is now the one reported where both apply, and an erroneous test against a class the program does not bind narrows on its negative branch as an otherwise checkable one does
@github-actions

github-actions Bot commented Oct 22, 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/airflow-core/pyproject.toml
  Cause: TOML parse error at line 352, column 37
    |
352 | [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 920c8f0 into main Oct 23, 2026
61 of 68 checks passed
@KotlinIsland
KotlinIsland deleted the fixes branch October 23, 2026 01:20
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