Skip to content

Work - #207

Merged
KotlinIsland merged 25 commits into
mainfrom
work
Sep 24, 2026
Merged

Work#207
KotlinIsland merged 25 commits into
mainfrom
work

Conversation

@KotlinIsland

Copy link
Copy Markdown
Owner

No description provided.

…k away from one that has

the main loop takes every event off one queue and, through every `Client` it hands out,
puts events onto it too. that queue was bounded, so the two ends could meet: workers filled
it and blocked, the main loop was by then waiting to hand its next task to those same
workers whose own queue was full, and the one thread that would have drained the events was
the thread that was waiting. a server in that state answers nothing again — not the editor,
not a shutdown, and not a `by check`, which sat on the socket for its full two minutes
before checking the project itself.

the queue is unbounded now. an event is work that has already been done, so holding one back
buys nothing; what paces the work is the pool's own bounded queue, which is untouched. the
`try_send` that one caller used to dodge this is gone with it.

and a caller no longer waits two minutes to find out that nobody is home. the main loop says
it has the request before it re-reads the file system and before it checks anything, so
there is something to wait for, or five seconds and the check the caller could always run.
a member of an enum with a data type is that data type too, and the enum defines no
`__bool__` of its own — so the one `bool()` finds is the data type's, and it reads the value.
`Priority.NONE = 0` in an `IntEnum` is falsy for the same reason `0` is. what ty read instead
was the enum's instance type, which throws the value away: `int.__bool__` returns `bool`, so
every member of every `IntEnum` and `StrEnum` came back ambiguously truthy.

an enum that writes its own `__bool__` or `__len__`, or inherits one from an enum class it
extends, still decides for itself, and a `__new__` that replaces the value leaves nothing to
read off the declaration.

the imprecision was expensive as well as wrong. narrowing against an enum evaluates every
member, and where the narrowed value was already known to be truthy each arm came back as
`Literal[E.MEMBER] & ~AlwaysFalsy` — an intersection, which misses the map the union builder
keeps for enum literals and falls into a pairwise scan instead. on an enum of 2057 members,
two such comparisons cost about four million redundancy queries. with the falsy member
excluded and the rest bare literals, checking sc-neuromorph goes from 11.3s to 5.8s, and the
file that drew the complaint from 19.0s to 9.3s.
@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

by ecosystem round-trip

base: e317fa789b893d13dc76b742f954e5786154ff3b (merge base) → head: 207/merge

regressions: 0, changed: 37, improvements: 0, error changes: 0 (across 25260 files in 148 projects)

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

ℹ️ changed round-trip output

black — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -512,5 +512,5 @@
     "/tmp/tmpha9kgh2h/black/build/tests/data/cases/pattern_matching_with_if_stmt.py": {"by": "sha256:fa6d65664473d84421bcf86d3993390ed45f4b09554a9ecd0532d7d8ca982a1e", "py": "sha256:fa6d65664473d84421bcf86d3993390ed45f4b09554a9ecd0532d7d8ca982a1e"},
     "/tmp/tmpha9kgh2h/black/build/tests/data/cases/pep604_union_types_line_breaks.py": {"by": "sha256:d90a5d3c4e402174077017379cced344bb727a5f4ff5869e576df7c0663e7378", "py": "sha256:27acaa8d4e0cfe3567b12c2f8f2f771967d4cf01bc9f9ed4e07b811ac56bfb6a"},
-    "/tmp/tmpha9kgh2h/black/build/tests/data/cases/pep646_typed_star_arg_type_var_tuple.py": {"by": "sha256:95f2f66b928a80e612aad79ab2fb23e80fd1b07fedc7893a4c398cb2e767c3c4", "py": "sha256:95f2f66b928a80e612aad79ab2fb23e80fd1b07fedc7893a4c398cb2e767c3c4"},
+    "/tmp/tmpha9kgh2h/black/build/tests/data/cases/pep646_typed_star_arg_type_var_tuple.py": {"by": "sha256:95f2f66b928a80e612aad79ab2fb23e80fd1b07fedc7893a4c398cb2e767c3c4", "py": "sha256:f691536e87124d74787096134c774d937cacf2fed8a1098e36335d88e641d653"},
... 230 characters elided ...
     "/tmp/tmpha9kgh2h/black/build/tests/data/cases/pep_572_py310.py": {"by": "sha256:7bcbe1e487d97c7b2596625481cb9776d0aa826ff0db5a8afef23a9908aba007", "py": "sha256:7bcbe1e487d97c7b2596625481cb9776d0aa826ff0db5a8afef23a9908aba007"},
black — tests/data/cases/pep646_typed_star_arg_type_var_tuple.py
--- base/tests/data/cases/pep646_typed_star_arg_type_var_tuple.py
+++ head/tests/data/cases/pep646_typed_star_arg_type_var_tuple.py
@@ -2,5 +2,5 @@
 
 
-def fn(*args: *(*A, B)) -> None:
+def fn(*args: *tuple[*A, B]) -> None:
     pass
hydra-zen — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -121,5 +121,5 @@
     "/tmp/tmpk1jbn0rs/hydra-zen/build/hydra_zen/structured_configs/__init__.py": {"by": "sha256:af55bc610232584965fd4cdf78e7698e563c3a135f2dbf261d3fec218ce472a3", "py": "sha256:b7812173908de28ac155915e813defcc42e3552bfed1f3c14cc95a82e73fbfd1"},
     "/tmp/tmpk1jbn0rs/hydra-zen/build/hydra_zen/structured_configs/_globals.py": {"by": "sha256:b7992c1ed2ea89fab26555d08cf273fafdefb3d00b8b70baa76a24ad34d38114", "py": "sha256:eea00dd37452009ef7646ea8b035c920588673b0b46eb672f89046454b41194a"},
-    "/tmp/tmpk1jbn0rs/hydra-zen/build/hydra_zen/structured_configs/_implementations.py": {"by": "sha256:182dfd2abe689f02441d68109c42b6637e7d866d0ee961c83e5e882203e9dbf9", "py": "sha256:b5ccf417a5c6dfe4154a89c246c24834670fc7a7d73c6d4558b44fdb00b88429"},
+    "/tmp/tmpk1jbn0rs/hydra-zen/build/hydra_zen/structured_configs/_implementations.py": {"by": "sha256:182dfd2abe689f02441d68109c42b6637e7d866d0ee961c83e5e882203e9dbf9", "py": "sha256:5dc1507ee7097b3e4d98e0e35c5d41cf7f452fe95a452bf5c27db0c10937c666"},
... 244 characters elided ...
     "/tmp/tmpk1jbn0rs/hydra-zen/build/hydra_zen/structured_configs/_make_config.py": {"by": "sha256:affe4e58596b29de82d74874c7bbcbc5a7b8f475cde06e9a50044deda193a697", "py": "sha256:e9cd6aa6731deff6bcf3d4197974e0919771ca75b86cb987471200f2815423d6"},
hydra-zen — hydra_zen/structured_configs/_implementations.py
--- base/hydra_zen/structured_configs/_implementations.py
+++ head/hydra_zen/structured_configs/_implementations.py
@@ -910,5 +910,5 @@
                     return tuple[_unique_type, ...]
                 else:
-                    return tuple[tuple[_unique_type] | len(args)]
+                    return tuple[tuple[_unique_type] * len(args)]
 
             return Any
mitmproxy — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -872,5 +872,5 @@
     "/tmp/tmp3xq7h67e/mitmproxy/build/mitmproxy/tools/console/help.py": {"by": "sha256:2fcc236ef3a810b231fd80b302fe72da8fdabf50e5ce11d32a8e29fe60eb939e", "py": "sha256:e2781771fc90764e192d982849246d04494b9ea7d785b42947bfc391949e597b"},
     "/tmp/tmp3xq7h67e/mitmproxy/build/mitmproxy/tools/console/keybindings.py": {"by": "sha256:118933a4c77dcf71801e3d771fcc3b64100ed2b4341c55528378549ac690686a", "py": "sha256:46bd48abb97c6cba73b72f39656376b5e8a4deabd01e84ec998300f91563e427"},
-    "/tmp/tmp3xq7h67e/mitmproxy/build/mitmproxy/tools/console/keymap.py": {"by": "sha256:31e8ef2344ecb5e26634dd2ed22e5988f3cffa377fa772d803b07568e26530b6", "py": "sha256:3aa35efd460670f5d7c87a86eff36f59f1f1205db1604c86dff70a51ce3ce35e"},
+    "/tmp/tmp3xq7h67e/mitmproxy/build/mitmproxy/tools/console/keymap.py": {"by": "sha256:31e8ef2344ecb5e26634dd2ed22e5988f3cffa377fa772d803b07568e26530b6", "py": "sha256:45083c76a0106cab2d7b963355f69750b00bdc7e440068f05dc8828ec32cb656"},
... 246 characters elided ...
     "/tmp/tmp3xq7h67e/mitmproxy/build/mitmproxy/tools/console/master.py": {"by": "sha256:b71f99d0b5f102ce0dbc5c5436e2fde30c84542023cd34b32d694d2f46a843af", "py": "sha256:2f5b07f9e4b857ac1ad528294b79fdb30c41d1118a87a49c6a00035f0dcb8723"},
mitmproxy — mitmproxy/tools/console/keymap.py
--- base/mitmproxy/tools/console/keymap.py
+++ head/mitmproxy/tools/console/keymap.py
@@ -1,3 +1,3 @@
-from mitmproxy._by_runtime import _soundness_check, _soundness_iter
+from mitmproxy._by_runtime import _soundness_check
 lazy import logging
 lazy import os
@@ -113,5 +113,5 @@
 """
         self._check_contexts(contexts)
-        for c in _soundness_iter(contexts, str):
+        for c in contexts:
             b = self.get(c, key)
             if b:
mypy — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -1325,5 +1325,5 @@
     "/tmp/tmp2j428ogw/mypy/build/mypy/checkstrformat.py": {"by": "sha256:d1b06a4f2f3fdbb5cdba4989b3022af6b8a4ac700aa9d0974b92056c680e3ce6", "py": "sha256:5cae5044ac4bfb14f007eca7d78246c42f7da924290abae1af3fa2fc1b5eba76"},
     "/tmp/tmp2j428ogw/mypy/build/mypy/constant_fold.py": {"by": "sha256:0ded5c2e3547ad992db0617efd5b1583c66c93118e019404c1414b60cf9a24f3", "py": "sha256:e1f0b3561375a69de2ddd58d84cb57d45c79e5ed5a3ffbd544564849fc5fcdcd"},
-    "/tmp/tmp2j428ogw/mypy/build/mypy/constraints.py": {"by": "sha256:6312bcec6851309cde2544b73781e7ff04c93c6bc025a2e50ce710bbe2a8920a", "py": "sha256:a74d68dc9f64eb8bc6e58d829e2e5bb85a2c67bc35efd9ef8873e9c0911a651b"},
+    "/tmp/tmp2j428ogw/mypy/build/mypy/constraints.py": {"by": "sha256:6312bcec6851309cde2544b73781e7ff04c93c6bc025a2e50ce710bbe2a8920a", "py": "sha256:1af333efd39aae152679dbad802a72ee5efb25619227eed16192f13dc91ac907"},
... 1727 characters elided ...
     "/tmp/tmp2j428ogw/mypy/build/mypy/typeshed/stdlib/importlib/resources/readers.pyi": {"by": "sha256:f3f5c77e5697233657c3360f77c6508cdeeae00be2ecd9fbdc16c03b1eb8eaef", "py": "sha256:2fd212763ca2571f29a673f66d34a36dd77f773bebd65637fda467e997e2b6c3"},
mypy — mypy/constraints.py
--- base/mypy/constraints.py
+++ head/mypy/constraints.py
@@ -1357,5 +1357,5 @@
                 for i in range(len(template_items)):
                     res.extend(
-                        infer_constraints(template_items[i], actual_items[i], self.direction)
+                        infer_constraints(template_items[i], _soundness_check(actual_items[i], Type), self.direction)
                     )
             res.extend(
operator — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -297,5 +297,5 @@
     "/tmp/tmpha9kgh2h/operator/build/testing/src/scenario/logger.py": {"by": "sha256:8e5f2766b77c55e77cbd66476d02067daf831214018393285065294c3f7af0c3", "py": "sha256:1f4ec956cd57a4980fe9d1c98b6b56632616ab121660161efb3b05637f15fec4"},
     "/tmp/tmpha9kgh2h/operator/build/testing/src/scenario/mocking.py": {"by": "sha256:e4b740eb37569f22128b76fcf3ed60d6203bb622a09a7f4d8d03bb6497b97f22", "py": "sha256:3ac5ffe7b021cf544e9e7441bc8ac280bd5d079c1bc43068e2803df3c15eb058"},
-    "/tmp/tmpha9kgh2h/operator/build/testing/src/scenario/state.py": {"by": "sha256:a2eff5b524b90e1eda9b217274b42669230faef4e670e61158901030a1b50485", "py": "sha256:69ce925c9f05c5272e2bc210324da4e6666726d07b4a20edd95f0a1a3c148c41"},
+    "/tmp/tmpha9kgh2h/operator/build/testing/src/scenario/state.py": {"by": "sha256:a2eff5b524b90e1eda9b217274b42669230faef4e670e61158901030a1b50485", "py": "sha256:e2aaceb8d54ed5d65109cf429a1c4aae25075f525476f59c5d4f83608070ba1a"},
     "/tmp/tmpha9kgh2h/operator/build/testing/tests/__init__.py": {"by": "sha256:24c3d66b39d26b5899cdb9a0b04050aa6c894fe99a8f3e7a199d0e3936beb64f", "py": "sha256:24c3d66b39d26b5899cdb9a0b04050aa6c894fe99a8f3e7a199d0e3936beb64f"},
     "/tmp/tmpha9kgh2h/operator/build/testing/tests/benchmark/__init__.py": {"by": "sha256:24ed7d19d986f3835ed8963ca2df94eef297288ee36cf9d0bfeb33ad95016ffe", "py": "sha256:24ed7d19d986f3835ed8963ca2df94eef297288ee36cf9d0bfeb33ad95016ffe"},
operator — testing/src/scenario/state.py
--- base/testing/src/scenario/state.py
+++ head/testing/src/scenario/state.py
@@ -529,9 +529,9 @@
         if latest_content is not None:
             self._validate_content(latest_content, 'latest_content')
-        object.__setattr__(self, 'tracked_content', dict[str, str](tracked_content))
+        object.__setattr__(self, 'tracked_content', dict(tracked_content))
         object.__setattr__(
             self,
             'latest_content',
-            dict[str, str](latest_content) if latest_content is not None else dict[str, str](tracked_content),
+            dict(latest_content) if latest_content is not None else dict(tracked_content),
         )
         object.__setattr__(self, 'id', id if id is not None else _generate_secret_id())
pip — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -661,5 +661,5 @@
     "/tmp/tmpgy6k_8rz/pip/build/pip/_internal/cli/autocompletion.py": {"by": "sha256:04c3f4fc29975ca08b4d886f4daac464bb6c9614074d86259514c4f8e64de799", "py": "sha256:934a3f45e1be2d2879a862f2f5c36320632c3edbba9be728a4fecc065447ad51"},
     "/tmp/tmpgy6k_8rz/pip/build/pip/_internal/cli/base_command.py": {"by": "sha256:dc65e3e8c7f352a752b7643355403d22f0a0b32c065afbe4cc1c55a9427295d4", "py": "sha256:647a5eda9b52c6b71aa67a64afda026dab60c84b59c6dd477802a8f7b0ebfcff"},
-    "/tmp/tmpgy6k_8rz/pip/build/pip/_internal/cli/cmdoptions.py": {"by": "sha256:67053773e101979a7d97212afab8a12bad3623fb4ff522cf02285291eeedb18d", "py": "sha256:7230fb494bd2c3d8ee3999059f03a6381d1cc4f575179735b997d8944409b3b4"},
+    "/tmp/tmpgy6k_8rz/pip/build/pip/_internal/cli/cmdoptions.py": {"by": "sha256:67053773e101979a7d97212afab8a12bad3623fb4ff522cf02285291eeedb18d", "py": "sha256:8737d4e375bf703d86567432ee2ae74251c4b6ceaba8c7e4a339fad404d4c337"},
     "/tmp/tmpgy6k_8rz/pip/build/pip/_internal/cli/command_context.py": {"by": "sha256:25a091090d2fe502140008da4b10230ef78fbb40b4b8107fc8f3830024d9325b", "py": "sha256:8c0026eeb8b5a05e2dd9e563564ece797eccb3b6a23f5769766b2a36e33672d2"},
     "/tmp/tmpgy6k_8rz/pip/build/pip/_internal/cli/index_command.py": {"by": "sha256:8db446e76f8d511b0a8da3116f78776ea6ed1db5a04be19bf7eec249800ce2ca", "py": "sha256:62350de6388382ef256cb7332892befc59599374b9d9d691ac4edda8ae5e69bd"},
pip — pip/_internal/cli/cmdoptions.py
--- base/pip/_internal/cli/cmdoptions.py
+++ head/pip/_internal/cli/cmdoptions.py
@@ -180,5 +180,5 @@
 
 class PipOption(Option):
-    TYPES: tuple[str, ...] = Option.TYPES + ("path", "package_name")
+    TYPES: tuple[*tuple[str, ...], str, str] = Option.TYPES + ("path", "package_name")
     TYPE_CHECKER = _soundness_check(Option.TYPE_CHECKER.copy(), dict)
     TYPE_CHECKER["package_name"] = _package_name_option_check
pytest-autoprofile — lib/pytest_autoprofile/__init__.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_doctest.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_json.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_multiprocessing.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_patches.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_test_util_capture_warnings.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_test_utils.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_typing.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_warnings.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/_xdoctest.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/importers.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/option_hooks.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/plugin.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/profiler.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/rewriting.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/setup.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/startup_hook.py
(only produced on base)
pytest-autoprofile — lib/pytest_autoprofile/utils.py
(only produced on base)
scipy-stubs — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -1173,5 +1173,5 @@
     "/tmp/tmp3yoy8n02/scipy-stubs/build/scipy-stubs/sparse/_base.pyi": {"by": "sha256:3d14248c97b656df154b2a6d328646a154956e3297b32ad12e26156c4c95c361", "py": "sha256:47f7fbcc0f6f2cfa3e8d03b3156457da4ad38fb6c44dbb8e9294ec0b961ddd92"},
     "/tmp/tmp3yoy8n02/scipy-stubs/build/scipy-stubs/sparse/_bsr.pyi": {"by": "sha256:4fb8387d675152bcdaafc1e7470557284512eb094aa2e9ca2e62d0b4ce461acc", "py": "sha256:1cce76de3764ca8ccac640e894f472d8bd97245aca84d89dde7a81318636840b"},
-    "/tmp/tmp3yoy8n02/scipy-stubs/build/scipy-stubs/sparse/_construct.pyi": {"by": "sha256:93ad527825dc2a9c2a376036f20a5452544db15d8dfcd5671d6d2ff06a675b2d", "py": "sha256:47effbded9348e3f5bdf6b54f11377b44650a6401e7a532512a897bf7a43cca4"},
+    "/tmp/tmp3yoy8n02/scipy-stubs/build/scipy-stubs/sparse/_construct.pyi": {"by": "sha256:c67bc23015dccbaac19d477a0062528987c2e9fb22b74e79d4e38c0d91eb56e1", "py": "sha256:47effbded9348e3f5bdf6b54f11377b44650a6401e7a532512a897bf7a43cca4"},
... 4759 characters elided ...
     "/tmp/tmp3yoy8n02/scipy-stubs/build/scipy-stubs/stats/_finite_differences.pyi": {"by": "sha256:bd3df4a8708a3dc072333125c97d71de4578c9581f6e970779e429b63508099d", "py": "sha256:2e93f4f1241e7d7d4f922635491b495e52b838cbe1858252cd158d3571b27ea0"},
static-frame — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -263,5 +263,5 @@
     "/tmp/tmp3yoy8n02/static-frame/build/static_frame/core/node_fill_value.py": {"by": "sha256:618caf49d118400bc761d86fba3357b2282fc7c6c8e4148bc84261732a0abba3", "py": "sha256:2fb0152bc8734fa1dca67c82185153288ac8cd7797b74a45aef299cc388efb43"},
     "/tmp/tmp3yoy8n02/static-frame/build/static_frame/core/node_hashlib.py": {"by": "sha256:e5b582e7eb551d29e0c4a90a0e4bf9003825feb1b5a49c60776d2c7f005e3fbf", "py": "sha256:d1ed6a9dccab30eda55ca43c81af174898800960f98981b64e0be2f77d5b92c5"},
-    "/tmp/tmp3yoy8n02/static-frame/build/static_frame/core/node_iter.py": {"by": "sha256:91ebe420b1bc5ea2a14c0f02ea2508b694c4bce3fd9be8e71d69e8be94a690ec", "py": "sha256:120a5dc70a16be1db7a77ea30e3df10804da12f80812511018abaaf09015c61d"},
+    "/tmp/tmp3yoy8n02/static-frame/build/static_frame/core/node_iter.py": {"by": "sha256:91ebe420b1bc5ea2a14c0f02ea2508b694c4bce3fd9be8e71d69e8be94a690ec", "py": "sha256:1c7562a3e776f7d3b716c3b602c21694cc098b4745659d3b6baa173cb841044c"},
... 238 characters elided ...
     "/tmp/tmp3yoy8n02/static-frame/build/static_frame/core/node_selector.py": {"by": "sha256:bb5424426acbf0a509c777b716a08c4c2ece872fd63c0a01bdecb7b23bb83636", "py": "sha256:71f64c24e85cdaf4789b2a321097d7b779d165034870a2d5fe9f3fe72cc844ef"},
static-frame — static_frame/core/node_iter.py
--- base/static_frame/core/node_iter.py
+++ head/static_frame/core/node_iter.py
@@ -382,5 +382,5 @@
     __slots__ = ()
 
-    _INTERFACE: tuple[str, ...] = IterNodeDelegate._INTERFACE + ('reduce', 'reduce_pool')
+    _INTERFACE: tuple[*tuple[str, ...], str, str] = IterNodeDelegate._INTERFACE + ('reduce', 'reduce_pool')
 
     def _reduce_dispatch(self, pool: tp.Optional[PoolConfig] = None) -> ReduceDispatch:
@@ -470,5 +470,5 @@
     __slots__ = ()
 
-    _INTERFACE: tuple[str, ...] = IterNodeDelegate._INTERFACE + (
+    _INTERFACE: tuple[*tuple[str, ...], str, str, str, str, str, str, str, str, str] = IterNodeDelegate._INTERFACE + (
         'map_all',
         'map_all_iter',
stone — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -132,5 +132,5 @@
     "/tmp/tmp3xq7h67e/stone/build/stone/frontend/ir_generator.py": {"by": "sha256:55e810d609db348318876c56511831c32d0ca7404d3a2c564f3cefafab78a5e7", "py": "sha256:7f570111d06697bc7c95fa29155922d5855f768ed1e3af899a2a2e8e419df41c"},
     "/tmp/tmp3xq7h67e/stone/build/stone/frontend/lexer.py": {"by": "sha256:6f74ceb3f1cac2d11b0638773dc827ae64829a7da029e3e65bb835654cb26aec", "py": "sha256:4188e0af5cd4c5071698e494750ebdd49ac6e59242652d9ab0c897e53758ff3f"},
-    "/tmp/tmp3xq7h67e/stone/build/stone/frontend/parser.py": {"by": "sha256:4f544a5976738345bff7e061fff6d31433ccff194a176ec8b308dec7e37c0533", "py": "sha256:f34212d0dc877faec312e8fab2324396e1740d4798903dddf915ec5fb2a71490"},
+    "/tmp/tmp3xq7h67e/stone/build/stone/frontend/parser.py": {"by": "sha256:4f544a5976738345bff7e061fff6d31433ccff194a176ec8b308dec7e37c0533", "py": "sha256:0ac231abe136867a50e48f5ab6db682adbd310b116b8baf3f070be7ce2b133be"},
     "/tmp/tmp3xq7h67e/stone/build/stone/ir/__init__.py": {"by": "sha256:481b036e26ed7f3a77f32037fe42127f64c69de98e6ae44b8754663930ca8bcb", "py": "sha256:481b036e26ed7f3a77f32037fe42127f64c69de98e6ae44b8754663930ca8bcb"},
     "/tmp/tmp3xq7h67e/stone/build/stone/ir/api.py": {"by": "sha256:b69502e93c8ba4b2c27756a9d938aa7398f699d42950f78e64a8c116d59ff625", "py": "sha256:8407cf5131c9d03b9b7a283a92c1c5fa17a175781966580c0fef1ea7f4791566"},
stone — stone/frontend/parser.py
--- base/stone/frontend/parser.py
+++ head/stone/frontend/parser.py
@@ -50,5 +50,5 @@
 
     # Ply parser requiment: Tokens must be re-specified in parser
-    tokens: tuple[str, ...] = Lexer.tokens
+    tokens: tuple[str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, *tuple[str, ...]] = Lexer.tokens
 
     # Ply feature: Starting grammar rule
tornado — _by_sourcemap.py
--- base/_by_sourcemap.py
+++ head/_by_sourcemap.py
@@ -189,5 +189,5 @@
     "/tmp/tmp2j428ogw/tornado/build/tornado/test/gettext_translations/extract_me.py": {"by": "sha256:248bf62d9b254570ca77a123ee06da2898921dda401aac8bb3bb7f43dac5a2bd", "py": "sha256:248bf62d9b254570ca77a123ee06da2898921dda401aac8bb3bb7f43dac5a2bd"},
     "/tmp/tmp2j428ogw/tornado/build/tornado/test/http1connection_test.py": {"by": "sha256:900c107d435423fa04b6fe4b030f2f75e7fa032ef3edd66e598c4d4a339aa7f4", "py": "sha256:264b29506982b4b74e8f744de8171e1698fbb572792125a1ab888642d26de24d"},
-    "/tmp/tmp2j428ogw/tornado/build/tornado/test/httpclient_test.py": {"by": "sha256:cf156cfc392734b6ac3c8a307b1eec1189fd1b2c17ea6ec0f957d0fd4c8c5fa9", "py": "sha256:f265749e2e8e5108b92a89814cba5732bc33d601df56335a3704a10d44527232"},
+    "/tmp/tmp2j428ogw/tornado/build/tornado/test/httpclient_test.py": {"by": "sha256:cf156cfc392734b6ac3c8a307b1eec1189fd1b2c17ea6ec0f957d0fd4c8c5fa9", "py": "sha256:89ff7e9d5df718af57c09c139bb16062f40d95267ee1494a6e0ce5ffc0e909a5"},
     "/tmp/tmp2j428ogw/tornado/build/tornado/test/httpserver_test.py": {"by": "sha256:9e40d732d31b76a5362631df72cc8a253b83f3ac96fc48b327b3829266b302b2", "py": "sha256:60f3714000599d69d3899afecd8aed41c451bbcb0ad75844e0c7ee50bc9da040"},
     "/tmp/tmp2j428ogw/tornado/build/tornado/test/import_test.py": {"by": "sha256:43cb8ac18a3fac0ae1f3337288baec420ac6625c0f882556e81bebf8b0cc373f", "py": "sha256:642c026ad5012493b06ba9382d1a5219109cc2e1e1a40b5dd40983f9b7309603"},
tornado — tornado/test/httpclient_test.py
--- base/tornado/test/httpclient_test.py
+++ head/tornado/test/httpclient_test.py
@@ -153,5 +153,5 @@
 
 class AllMethodsHandler(RequestHandler):
-    SUPPORTED_METHODS: tuple[str, ...] = RequestHandler.SUPPORTED_METHODS + ("OTHER",)  # type: ignore
+    SUPPORTED_METHODS: tuple[*tuple[str, ...], str] = RequestHandler.SUPPORTED_METHODS + ("OTHER",)  # type: ignore
 
     def method(self):

💥 fails to round-trip (unchanged from base)

  • alerta: build: killed: timed out after 900s
  • apprise: build: killed: exceeded 11.7365GB memory budget
  • cryptography: build: killed: exceeded 11.7365GB memory budget
  • dedupe: build: killed: timed out after 900s
  • jax: build: killed: timed out after 900s
  • manticore: reverse: killed: exceeded 11.7358GB memory budget
  • meson: build: killed: exceeded 11.7365GB memory budget
  • openlibrary: reverse: killed: timed out after 900s
  • pandas: build: killed: timed out after 900s
  • pandas-stubs: build: killed: timed out after 900s
  • scikit-learn: build: killed: exceeded 11.7358GB memory budget
  • scipy: build: killed: exceeded 11.7365GB memory budget
  • setuptools: build: killed: exceeded 11.7365GB memory budget
  • sympy: reverse: killed: exceeded 11.7358GB memory budget
  • xarray: build: killed: exceeded 11.7358GB memory budget

⏭️ skipped

  • AutoSplit: setup failed: setup_primer_project.py failed for 'AutoSplit': Cloning into '/tmp/tmp3o_4o_us/AutoSplit'... Using CPython 3.12.3 interpreter at: /home/runner/work/_temp/setup-uv-cache/environments-v2/…
  • CPython (Argument Clinic): skipped: 2334 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory
  • CPython (cases_generator): skipped: 2334 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory
  • CPython (peg_generator): skipped: 2334 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory
  • core: skipped: 18900 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory
  • dd-trace-py: skipped: 3042 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory
  • ecosystem-analyzer: setup failed: setup_primer_project.py failed for 'ecosystem-analyzer': Cloning into '/tmp/tmp3xq7h67e/ecosystem-analyzer'... Using CPython 3.12.3 interpreter at: /home/runner/work/_temp/setup-uv-cach…
  • pylint: skipped: 2474 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory
  • rotki: skipped: 2654 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory
  • spack: skipped: known to spike past the runner's memory during by build (faster than the watchdog can react)
  • streamlit: setup failed: setup_primer_project.py failed for 'streamlit': Cloning into '/tmp/tmpspsgvml_/streamlit'... Updating files: 83% (8294/9976) Updating files: 84% (8380/9976) Updating files: 85% (8480/99…
  • zulip: skipped: 2032 .py files exceeds --max-project-py-files (2000); by build would not fit in the runner's memory

…an unknown integer

`(1, "a") * n` used to widen to `tuple[Literal[1, "a"], ...]`, losing the
order of its elements. its type is now `(1, "a") * int`: a tuple variable
segment can repeat a run of several element types, so indexing from either
end, unpacking, sequence patterns, `len` narrowing, reversal and concatenation
keep each element's type, and a length that is not a whole number of
repetitions is rejected

how long the run is belongs to the type, since it decides which lengths the
tuple can have: `(int, str, int, str) * int` is assignable to `(int, str) * int`
but not the other way about. only a run of one element is a homogeneous tuple

assignability between repeated tuples checks the short values one at a time
and every longer value as a front, whole repetitions and a back. a variadic
`*args: *((int, str) * int)` takes whole repetitions of arguments: its
arguments, splatted ones included, are checked against the tuple as a whole,
and two signatures with such a parameter are related through the tuples of
positional arguments they accept, which a parameter list cannot spell. a type
parameter in a run, `(T, U) * int`, is solved from the elements at the same
positions in the argument

concatenating onto a variable-length tuple now keeps the fixed elements on
either side instead of widening, and joining a segment to itself keeps it

python has no spelling for the type, so an annotation lowers to
`tuple[int | str, ...]`, and a python file's inlay hint shows that reduced
form. two lowerings were wrong before this: an operation nested in a tuple or
type argument was rendered as `|`, so `list[(int, str) * 2]` became
`list[tuple[int, str] | Literal[2]]`; and nothing inside a variadic
parameter's unpacked annotation was lowered at all, so `*args: *(int, str)`
emitted `Unpack[(int, str)]`
@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

ecosystem check

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

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

sphinx-doc/sphinx (error)

ruff format --no-preview --exclude tests/roots/test-pycode/cp_1251_coded.py

warning: Selection `DOC` has no effect because preview is not enabled.
warning: Detected debug build without --no-cache.
error: Encountered error: No such file or directory (os error 2)

Formatter (preview)

✅ ecosystem check detected no format changes.

…rscore marks unused

in a `.by` file privacy is spelled `private`/`protected`, so a leading underscore
only means "unused". the lint reports every use of such a name: variables,
parameters, functions, classes, modules of a `.by` package, `from` imports,
keyword arguments naming a parameter or a dataclass field, the target of a `del`,
and members read through `self`, `super()`, an instance, the class, a class
pattern keyword, an `extension`, an inline protocol, a receiver callable or a
trailing lambda block

only names the `.by` source spelled are reported. a name declared in python or a
stub, an override of a python base class member, a member of a class whose bases
can't all be resolved, a name the parser generates (a property's `field` storage,
an enum variant's `_0`, the assignment `init(let _x: int)` stands for), `_` and
dunders are left alone, and so is anything that can't be traced. the parser keeps
a record of the names it writes itself, so the lint can tell those from the ones
the source spelled

mdtests that used underscore names as ordinary names are renamed, and the
visibility test for plain underscore names now expects the warning
…nd report a written `-> asserts` its body does not establish

a `def` that leaves its return type out and returns nothing asserts what its body
establishes, and callers narrow by that. what is asserted is what every way out
of the body agrees on — each `return` it can reach, and the end of the body — so
an early `return` before the assertion, a body that catches its own failure, a
rebound parameter, or an `async def` assert nothing

a written `-> asserts` is held to the same reading: the body has to establish
what it claims wherever it returns, and is reported where it doesn't — ruling out
`None` is not truthiness, since `0` is falsy. a body that assigns to a parameter
establishes nothing about the argument, while assigning to a member does, since
the caller reads that back. an override makes the assertion its base makes,
recovered or written, and has to establish it in its own body

two ways out are left alone rather than checked: a `return` a `finally` suite can
follow, since what the suite leaves behind is not modelled, and a `...` body,
which leaves the claim to whatever implements it
the edits are computed against one revision of the buffer. a client that has
typed since can now see that and throw them away, rather than applying them to
text they no longer describe
`_by_sourcemap.py` is a single file holding an entry per transpiled module, so
answering each file on its own handed back a whole map per file — each the
tree's map plus that one file's entry. whichever the caller wrote last dropped
every other edit's line table. the set now goes in as a set and comes back with
one map carrying all of it, and one file refused refuses the set
@KotlinIsland
KotlinIsland force-pushed the work branch 2 times, most recently from 591b2a4 to 4096923 Compare September 23, 2026 16:11
KotlinIsland and others added 18 commits September 24, 2026 13:48
editors were guessing `out/<path relative to the project>.py`. both halves of
that are wrong: the directory is `build`, and the path inside it follows the
module tree rather than the directory tree. the build is what knows, so it
answers
a run configuration and a test list are questions about the project, and an
editor working them out itself re-derives what the transpiler, the checker and
the project resolver already decided. each is answered from that one reading
instead: `main`'s generated command line from the transpiler, collected tests
from the pytest model, runnable modules from the resolver.

the transpiler's reading of `main` is lifted into an `EntryPoint` type so the
`__main__` guard and the answer here cannot drift apart. pytest collection
learns the `.by` spelling of a test file's name, which it needs when asked
about a path rather than about a transpiled module
an editor typing in an indentation-delimited language needs which line opens a
suite, where a compound statement ends, and what a string literal's escapes and
interpolations are. worked out from the text those come out subtly wrong — a
`match = 1` read as a `match` statement, a `:` inside a string read as the end
of a header — so they are read off the parse tree.

`textDocument/documentHighlight` on a keyword uses the same reading to answer
the keywords that belong with it: the `elif`s and `else` of an `if`, the
`return`s of a `def`
`by build` in `tests/` builds the whole project, and writing that into
`tests/build` put a second tree where nothing looks for it — not
`by/buildOutput`, which names one build directory per project, and not the next
`by build` from the root. an explicit `--out` is still the caller's path,
relative to where they typed it
for a debugger that has to be the process the program runs in. the launcher
goes in front of the interpreter rather than replacing it, so discovery and the
version probe still decide which interpreter that is
counting characters called `名前 = 1` and `abcd = 1` different columns when a
fixed-width editor draws them in the same one. each character now counts for its
unicode width and a tab reaches the next tab stop, and the columns are reported
beside each gap so a client need not measure them again.

`tabSize` is a required parameter: it decides the answer as soon as a tab comes
before an `=`, and it is the client's setting rather than anything the source
says
`by run` runs the program in the directory it was invoked from, which is right
for an application: a relative path on its command line, and anything it reads
or writes beside the project, mean what they meant when they were written. But
the project is python only in the tree this staged, and that tree is reachable
only through `sys.path` — which serves an import and nothing else. So a program
whose arguments *are* the project's own files had no way to name one:
`by run pytest -v tests/test_calc.py` failed with "file or directory not found"
in a src layout and a flat layout alike, and `by run pytest --collect-only`
collected nothing at all, because the only `tests/test_calc` in the caller's
directory is a `.by`.

`--in-build` runs it in the staged tree instead. The whole project is there —
every transpiled module at its place in the module tree, and beside them every
file the build carries over unchanged, `pyproject.toml` included — so a path
target resolves, the tool's own configuration is found where it always was, and
what it reports is relative to a tree laid out like the project:
`tests/test_calc.py::TestGroup::test_add`, whatever the source layout.

The flag is the caller's to set because only the caller knows which of the two
directories it means, and neither can be inferred from the program's name.
the checker asks `should_check_file` inside inference, so a gate that followed
the check mode baked the mode into every memoized result. a file the editor had
closed then could not be checked at all on an unchanged database, because its
diagnostics were never collected; and the same gate, asked about the file some
other callable is defined in, made an open file's diagnostics depend on which
files happened to be open beside it.

the mode now decides only which files a check *reports*, in `is_in_check_set`,
outside any query. a re-stage can therefore check the files it was asked for
whether or not they are open — which it must, since their bytes are about to go
into a tree a program is running out of
each refactoring answers from the semantic index rather than from the text, so
inlining `x` replaces the reads of that variable and never a same-named
parameter, attribute or keyword argument. one that cannot preserve meaning
refuses with the reason, which a client that asked for refactorings shows.

a client that can resolve an action's edit is sent the action without one and
asks for it when the action is chosen, against the document version it was
offered for
a variable is bound directly above the statement, so the expression now runs
before the rest of it — only the same program when it ran exactly once per run
of the statement with nothing observable before it.

a constant is bound at the top of the module, so it runs as the module loads
whether or not the expression would have run at all. that needs more than
literals: `1 / 0` in a branch that is never taken, or an expression under an
`assert` python skips with `-O`, would raise on import. whether an operation
over literals raises is asked of the checker rather than read off its spelling —
ty folds it to the value it produces exactly when it has carried it out
what the statements read from the enclosing function becomes a parameter, and
what they bind that is read afterwards is returned. statements selected in a
method become a method of the same class, called through the receiver.

statements whose meaning depends on being written where they are — control flow
that leaves the selection, `global` and `nonlocal`, a variable that may be
unbound or is assigned on only some paths — are refused
writes the type ty infers for a `def` with no `->`, spelled as the file would
spell it and importing what it names
`data class` lowers to `@dataclass(slots=True)`, so this is a change of meaning
the user asks for rather than a rewrite that preserves one. what is refused is a
class the keyword cannot apply to — an enum, a protocol, a `TypedDict`, a named
tuple — and one that would break under slots: it writes its own `__slots__`, a
method assigns an attribute the body does not declare, or a method calls
`super()` with no arguments, whose `__class__` cell the new class object would
not match.

going back refuses a `field(...)` default, which only the dataclass machinery
reads: a plain class would hold the descriptor itself, on every instance
unsafe: the read then evaluates to `None` where it used to raise, and whatever
uses it has to handle that
`refactors` computed every refactoring's rewrite to decide whether to offer it
and then threw the rewrite away. so a client narrowing a `textDocument/codeAction`
with `only` still paid for all seven, and a client that cannot resolve an action's
edit paid for the chosen one twice — once to be offered, once to be handed over.

it now takes the kinds to consider and hands the edits back with each offer.
there is no cheaper applicability test to put in front of that: a refactoring
applies exactly when a meaning-preserving rewrite can be spelled, and a separate
test for that would be a second implementation of the same reasoning, free to
disagree with the first.

`codeAction/resolve` still spells the rewrite again rather than being handed it,
which is what resolve is for: what it saves is sending seven edits nobody chose,
not working them out. the docs said otherwise and now say this.

`only` also governs the quick fixes, which were sent whatever a client asked for.
`by/entryPoint`, `by/testItems`, `by/runModules`, `by/buildOutput` and
`by/syntaxOutline` arrive over several commits but read as one thing: the
questions an editor used to answer by guessing at a layout the build decides.
`editor.md` already names `by/alignmentGroups` and `by/dataFlowAt`, so they
belong beside those rather than scattered across the commits that added them.
@KotlinIsland
KotlinIsland merged commit f1cd8e5 into main Sep 24, 2026
63 of 67 checks passed
@KotlinIsland
KotlinIsland deleted the work branch September 24, 2026 06:23
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.

2 participants