From 0402e4e5a67e314cedc953d4380e83a3a15333ae Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Mon, 5 Oct 2026 01:19:59 -0400 Subject: [PATCH 1/6] docs: scope immutable subtree window acquisition --- .../SCOPE.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md diff --git a/evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md b/evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md new file mode 100644 index 0000000000..efb8e46681 --- /dev/null +++ b/evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md @@ -0,0 +1,23 @@ +# Immutable subtree window acquisition + +Base: published frozen combined Text63/64 08e3dd6b3c7839baafcac6ff9ea61eb510ff9573. +The qualified source controls and 487b standalone wheel remain unchanged. + +The existing immutable SubtreeGeometry owns source placement, membership, clip +scope and source order. Its viewport projection still scans every stored entry +before rejecting offscreen rectangles; restore also flattens complete native +membership on each use. Preserve complete capture, full-map queries, explicit +reader paths, overlay/screen-dependent fallback and bounded resource retirement. + +Reuse the existing native spatial acquisition mechanism only as a derived index +of the original immutable resource, not a second scene or mutable geometry +registry. Migrate Placed and Intrinsic capture/publication together. Investigate +membership consumers before changing the published considered-widget contract. + +Claim: native _compositor.py subtree capture/projection/restore and necessary +original membership consumers. No Toad, installed prefix, SDK, keeper, App or +recording lease. Heis owns the Toad workflow and original453 qualification. + +Source ownership reasoning and implementation precede the final proportional +native App source controls. No CPU, frame latency or smoothness claim follows +from source deletion or a spatial-query operation count. From d94fe553c677c97808ab301644f2e65c96f18044 Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Mon, 5 Oct 2026 01:21:31 -0400 Subject: [PATCH 2/6] perf: acquire ordered viewport entries from immutable subtree geometry --- src/textual/_compositor.py | 39 ++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index 039ffd722d..1a8b6e132d 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -40,7 +40,8 @@ from textual import errors from textual._context import visible_screen_stack from textual._loop import loop_last -from textual.geometry import NULL_SPACING, Offset, Region, Size, Spacing +from textual._spatial_map import SpatialMap +from textual.geometry import NULL_OFFSET, NULL_SPACING, Offset, Region, Size, Spacing from textual.map_geometry import MapGeometry from textual.strip import Strip, StripRenderable from textual.widget import Widget @@ -198,7 +199,8 @@ class SubtreeGeometry(ABC, Generic[GeometryEntry]): """One immutable native arrangement resource in the compositor's cache.""" key: SubtreeGeometryKey - geometry: Mapping[Widget, GeometryEntry] + geometry: Mapping[Widget, tuple[int, GeometryEntry]] + """Original source ordinals and placements, indexed by their native widget.""" widgets: frozenset[Widget] invisible_widgets: frozenset[Widget] @@ -208,7 +210,20 @@ def complete_arrangement(cls, enclosing_complete: bool) -> bool: @classmethod def capture(cls, key, geometry, widgets, invisible_widgets, clips, clip, screen_coordinates): - return cls(key, MappingProxyType(geometry), widgets, invisible_widgets) + return cls(key, MappingProxyType({ + node: (ordinal, entry) + for ordinal, (node, entry) in enumerate(geometry.items()) + }), widgets, invisible_widgets) + + @cached_property + def spatial_map(self) -> SpatialMap[tuple[int, Widget]]: + """Derive spatial admission from this immutable arrangement, once.""" + spatial_map: SpatialMap[tuple[int, Widget]] = SpatialMap() + spatial_map.insert( + (entry.region, NULL_OFFSET, False, False, (ordinal, node)) + for node, (ordinal, entry) in self.geometry.items() + ) + return spatial_map @abstractmethod def matches(self, key: SubtreeGeometryKey) -> bool: @@ -234,7 +249,16 @@ def project_into(self, geometry: CompositorMap, key: SubtreeGeometryKey, entry. Both newly captured and reused resources publish through here. """ source_bounds = bounds - (key.region.offset - self.key.region.offset) - for node, entry in self.geometry.items(): + if visible_only: + candidates = dict(self.spatial_map.get_values_in_region(source_bounds)) + for node in (root, *retained): + if (indexed := self.geometry.get(node)) is not None: + candidates[indexed[0]] = node + entries = ((node, self.geometry[node][1]) + for _, node in sorted(candidates.items())) + else: + entries = ((node, entry) for node, (_, entry) in self.geometry.items()) + for node, entry in entries: required = not visible_only or node is root or node in retained # Clip intersection can only reduce these original rectangle bounds. # Reject an offscreen, unrequired entry before resolving its clip @@ -252,7 +276,9 @@ def _project_entry(self, entry: GeometryEntry, key: SubtreeGeometryKey, ... def references_retired(self, owner: Widget, retired: set[Widget]) -> bool: - return not retired.isdisjoint((owner, *self.geometry, *self.widgets, *self.invisible_widgets)) + return (owner in retired or not self.geometry.keys().isdisjoint(retired) + or not self.widgets.isdisjoint(retired) + or not self.invisible_widgets.isdisjoint(retired)) @dataclass(frozen=True) @@ -288,7 +314,8 @@ def capture(cls, key, geometry, widgets, invisible_widgets, clips, clip, screen_ return PlacedSubtreeGeometry.capture( key, geometry, widgets, invisible_widgets, clips, clip, screen_coordinates) intrinsic[node] = SubtreeMapGeometry(entry, bounds) - return cls(key, MappingProxyType(intrinsic), widgets, invisible_widgets) + return super().capture(key, intrinsic, widgets, invisible_widgets, + clips, clip, screen_coordinates) def matches(self, key: SubtreeGeometryKey) -> bool: return self.key.intrinsic() == key.intrinsic() From 5a569464bcc567b5f8e85120a1983f52db1cf82e Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Mon, 5 Oct 2026 01:27:05 -0400 Subject: [PATCH 3/6] test: bind subtree window acquisition to native source and overlay lifetimes --- src/textual/_compositor.py | 4 +- tests/test_viewport_geometry_targets.py | 74 ++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index 1a8b6e132d..f7073d7b1a 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -216,7 +216,7 @@ def capture(cls, key, geometry, widgets, invisible_widgets, clips, clip, screen_ }), widgets, invisible_widgets) @cached_property - def spatial_map(self) -> SpatialMap[tuple[int, Widget]]: + def _spatial_map(self) -> SpatialMap[tuple[int, Widget]]: """Derive spatial admission from this immutable arrangement, once.""" spatial_map: SpatialMap[tuple[int, Widget]] = SpatialMap() spatial_map.insert( @@ -250,7 +250,7 @@ def project_into(self, geometry: CompositorMap, key: SubtreeGeometryKey, """ source_bounds = bounds - (key.region.offset - self.key.region.offset) if visible_only: - candidates = dict(self.spatial_map.get_values_in_region(source_bounds)) + candidates = dict(self._spatial_map.get_values_in_region(source_bounds)) for node in (root, *retained): if (indexed := self.geometry.get(node)) is not None: candidates[indexed[0]] = node diff --git a/tests/test_viewport_geometry_targets.py b/tests/test_viewport_geometry_targets.py index e4fcf33364..c763d4f292 100644 --- a/tests/test_viewport_geometry_targets.py +++ b/tests/test_viewport_geometry_targets.py @@ -25,12 +25,62 @@ def compose(self): yield Static("second line " * 5) +async def test_cached_overlay_and_fixed_children_match_the_original_scene(): + from textual._compositor import Compositor, PlacedSubtreeGeometry + + class CachedBody(VerticalGroup): + CACHE_SUBTREE_GEOMETRY = True + + body = CachedBody( + Static("Fixed heading", id="fixed-heading"), + Static("Screen overlay", id="screen-overlay"), + *(Static(f"Source row {index}") for index in range(80)), + id="cached-body", + ) + + class OverlayScreen(TargetedScreen): + CSS = """ + #fixed-heading { dock: top; height: 1; } + #screen-overlay { overlay: screen; width: 15; height: 1; offset: 5 3; } + """ + + def compose(self): + with VerticalScroll(id="history"): + yield body + + app = App() + async with app.run_test(size=(40, 10)) as pilot: + screen = OverlayScreen() + screen.targets = (body,) + await app.push_screen(screen) + await pilot.pause() + history = screen.query_one("#history", VerticalScroll) + compositor = screen._compositor + for position in (0, 30, 0): + history.scroll_to(y=position, immediate=True, animate=False) + screen._refresh_layout(app.size, scroll=True) + # The overlay's clip reaches the outer screen, so this resource + # keeps placed geometry rather than manufacturing an intrinsic clip. + assert isinstance(compositor._subtree_geometry[body], PlacedSubtreeGeometry) + expected, _ = Compositor(max_subtree_geometry_entries=0)._arrange_root( + screen, app.size, visible_only=False, + ) + admitted = [(node, entry) for node, entry in expected.items() + if node is body or entry.visible_region.overlaps(app.size.region)] + assert all(compositor._visible_map[node] == entry for node, entry in admitted) + actual_layers = compositor._ordered_geometry(compositor._visible_map) + expected_layers = compositor._ordered_geometry(expected) + assert [(node, entry) for node, entry in actual_layers if node in dict(admitted)] == [ + (node, entry) for node, entry in expected_layers if node in dict(admitted) + ] + + async def test_complete_cached_body_keeps_capture_and_explicit_reader_geometry(): class CachedBody(VerticalGroup): CACHE_SUBTREE_GEOMETRY = True rows = [Static(f"Original row {index}", id=f"cached-row-{index}") - for index in range(40)] + for index in range(240)] body = CachedBody(*rows, id="cached-body") class CachedScreen(TargetedScreen): @@ -41,7 +91,7 @@ def compose(self): app = App() async with app.run_test(size=(40, 10)) as pilot: screen = CachedScreen() - screen.targets = (body, rows[35]) + screen.targets = (body, rows[235]) await app.push_screen(screen) await pilot.pause() history = screen.query_one("#history", VerticalScroll) @@ -49,18 +99,26 @@ def compose(self): resource = compositor._subtree_geometry[body] assert all(row in resource.geometry for row in rows) - for position in (0, 20, 0): + for position in (0, 200, 0): history.scroll_to(y=position, immediate=True, animate=False) screen._refresh_layout(app.size, scroll=True) viewport = compositor._visible_map - assert body in viewport and rows[35] in viewport - omitted = rows[20] if position == 0 else rows[0] + assert body in viewport and rows[235] in viewport + omitted = rows[200] if position == 0 else rows[0] assert omitted not in viewport assert all(row in resource.geometry for row in rows) - # Capture remains complete without replacing the published viewport. + assert all(row in compositor.widgets for row in rows) _, placement = next(compositor.published_geometry((body,))) + source_bounds = app.size.region - (placement.region.offset - resource.key.region.offset) + candidates = resource._spatial_map.get_values_in_region(source_bounds) + # The immutable source stays complete; spatial admission and the + # explicit offscreen reader path remain different original facts. + assert omitted not in {node for _, node in candidates} + assert rows[235] not in {node for _, node in candidates} + assert len(candidates) < len(resource.geometry) + # Capture remains complete without replacing the published viewport. size, strips = compositor.render_subtree_strips(body, placement) - assert size.height == 40 + assert size.height == 240 assert all(f"Original row {index}" in strip.text for index, strip in enumerate(strips)) assert compositor._visible_map is viewport @@ -72,7 +130,7 @@ def compose(self): await pilot.pause() screen._refresh_layout(app.size, scroll=True) assert rows[5] not in compositor._subtree_geometry[body].geometry - assert rows[35] in compositor._visible_map + assert rows[235] in compositor._visible_map async def test_offscreen_targets_match_full_geometry_without_full_tree_traversal(): From 0ab59a0466cff6fd2bd8c3747b1be7e2fd660586 Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Mon, 5 Oct 2026 01:30:57 -0400 Subject: [PATCH 4/6] test: compare cached overlays against original native paint admission --- tests/test_viewport_geometry_targets.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/test_viewport_geometry_targets.py b/tests/test_viewport_geometry_targets.py index c763d4f292..5780ebc89d 100644 --- a/tests/test_viewport_geometry_targets.py +++ b/tests/test_viewport_geometry_targets.py @@ -34,7 +34,7 @@ class CachedBody(VerticalGroup): body = CachedBody( Static("Fixed heading", id="fixed-heading"), Static("Screen overlay", id="screen-overlay"), - *(Static(f"Source row {index}") for index in range(80)), + *(Static(f"Source row {index}", id=f"source-row-{index}") for index in range(80)), id="cached-body", ) @@ -65,13 +65,16 @@ def compose(self): expected, _ = Compositor(max_subtree_geometry_entries=0)._arrange_root( screen, app.size, visible_only=False, ) - admitted = [(node, entry) for node, entry in expected.items() - if node is body or entry.visible_region.overlaps(app.size.region)] - assert all(compositor._visible_map[node] == entry for node, entry in admitted) + paint = compositor._paint_regions(compositor._ordered_geometry(expected), app.size.region) + admitted = {node: expected[node] for node in paint} + admitted[body] = expected[body] # The original explicit geometry target. + for node, entry in admitted.items(): + assert node in compositor._visible_map, (position, node.id, entry) + assert compositor._visible_map[node] == entry actual_layers = compositor._ordered_geometry(compositor._visible_map) expected_layers = compositor._ordered_geometry(expected) - assert [(node, entry) for node, entry in actual_layers if node in dict(admitted)] == [ - (node, entry) for node, entry in expected_layers if node in dict(admitted) + assert [(node, entry) for node, entry in actual_layers if node in admitted] == [ + (node, entry) for node, entry in expected_layers if node in admitted ] From 230289d89d23195a005aadaa645686cebdcf7c04 Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Mon, 5 Oct 2026 01:35:24 -0400 Subject: [PATCH 5/6] docs: qualify immutable subtree window acquisition at native source scope --- .../SANITY.json | 32 + .../SCOPE.md | 56 + .../owner-consumers.json | 1792 +++++++++++++++++ 3 files changed, 1880 insertions(+) create mode 100644 evidence/immutable-subtree-window-acquisition-20261005/SANITY.json create mode 100644 evidence/immutable-subtree-window-acquisition-20261005/owner-consumers.json diff --git a/evidence/immutable-subtree-window-acquisition-20261005/SANITY.json b/evidence/immutable-subtree-window-acquisition-20261005/SANITY.json new file mode 100644 index 0000000000..a1b5650d77 --- /dev/null +++ b/evidence/immutable-subtree-window-acquisition-20261005/SANITY.json @@ -0,0 +1,32 @@ +{ + "source": "0ab59a0466cff6fd2bd8c3747b1be7e2fd660586", + "production_byte_equal_native_batch": "5a569464bcc567b5f8e85120a1983f52db1cf82e", + "native_source_batch": { + "passed": 32, + "failed": 1, + "seconds": 5.195401245029643, + "original_log": "/home/ts/wt/textual-native-subtree-strips-20261002/.artifacts/immutable-subtree-window-acquisition-20261005/negative01-native-source-batch.log", + "original_log_sha256": "543bdbdecaa15d6150b4d9c582097a33d013432e21a3aeca9a8c0d48200528f9" + }, + "corrected_overlay_source_control": { + "source": "0ab59a0466cff6fd2bd8c3747b1be7e2fd660586", + "argv": [ + "python", + "-m", + "pytest", + "-q", + "tests/test_viewport_geometry_targets.py::test_cached_overlay_and_fixed_children_match_the_original_scene" + ], + "exit_code": 0, + "seconds": 1.4935176220024005, + "assessment": "Original negative01: 32 qualified controls and one incorrect overlay oracle. Diagnostic identified source-row-9 at y10 outside10row viewport; visible_region had zeroheight but Region.overlaps(wholeviewport) reportedtrue. Oracle now consumes original Compositor._paint_regions, exactly terminal paint admission plus original explicit bodytarget. Native production unchanged from source batch5a569; passed32 source cases not repeated.", + "qualification": "Actual native App source only; no installed Toad/frame performance." + }, + "interpretation": "32 original qualified controls plus corrected affected overlay control PASS on byte-equal native production. Original 1-failure receipt retained. No repeated unchanged controls. Source-App scope only, no installed or frame gain qualification.", + "remaining_cost": "Complete widgets/invisible membership unions remain O(n); spatial grid construction is O(source extent/entries) once per immutable resource; coarse query false positives still need exact clipping. No CPU/smoothness proof.", + "no_new_env": true, + "no_installed_access": true, + "no_build": true, + "no_provider": true, + "no_film": true +} diff --git a/evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md b/evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md index efb8e46681..9a77e3e3dd 100644 --- a/evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md +++ b/evidence/immutable-subtree-window-acquisition-20261005/SCOPE.md @@ -21,3 +21,59 @@ recording lease. Heis owns the Toad workflow and original453 qualification. Source ownership reasoning and implementation precede the final proportional native App source controls. No CPU, frame latency or smoothness claim follows from source deletion or a spatial-query operation count. + +## Frozen implementation and source qualification + +Production source: 0ab59a0466cff6fd2bd8c3747b1be7e2fd660586 (native product +byte-equal to the actual 5a569464 source batch). One production file: 33 added, +6 deleted lines compared with frozen08e3; no other native production changes. + +`SubtreeGeometry.capture` now binds the original source ordinal alongside each +entry in its one immutable geometry mapping. Placed capture and Intrinsic capture +both consume this shared algorithm. Its private cached spatial resource uses +EXISTING SpatialMap and contains widget/ordinal references derived only from that +mapping. No second geometry map, ordinal registry, mutable update path or extra +lifetime owner was introduced. The original cache capacity, source key and +retirement own the index's lifetime. + +Viewport publication queries that resource in original source coordinates, adds +root/explicit retained paths by direct lookup, and projects candidates in original +insertion order. This replaces the every-entry viewport scan. Complete full-map +and body capture consume all original entries and do not require the spatial +index. Screen-dependent/overlay clips still select Placed geometry at capture; +the index uses those actual absolute rectangles, not layout's fixed/overlay flags. +Exact region and clip admission remains unchanged after the candidate query. + +Retirement now uses original geometry-key and membership-set disjointness rather +than allocating an expanded tuple of every referenced widget. Complete widget and +invisible-widget membership remain their original immutable sets, and restore +still unions them: this O(n) work is a required current contract, not claimed gone. +Index construction is source-size/extent work once per retained resource; coarse +spatial candidates still require exact clipping. No asymptotic/time claim applies +to the complete rendering workflow. + +One final native App/source batch yielded 32 PASS and one failed NEW overlay +expectation. The original log and negative receipt are retained. Its expected set +used an empty intersection rectangle as painted (row9 y10 outside a ten-row +viewport); original Region.overlaps can return true for that zero-height shape. +The control now consumes the existing Compositor._paint_regions owner plus the +original explicit target. Only that changed control was re-run: PASS, 0.35s +pytest / 1.49s controller. Native production is byte-equal across both receipts; +the other 32 accepted controls were not repeated. No Region behavior was patched +or timeout/geometry oracle relaxed. SANITY.json binds these exact limits. + +Actual source-App coverage: 240-row cached body forward/reverse acquisition, +offscreen explicit reader target, complete capture/full-map lookup, considered +membership, authored display invalidation, cache-budget/retirement; fixed child +and screen-overlay fallback/order against the original uncached scene; existing +native paint/layer/point-hit/damage and SpatialMap controls. + +After: native249/tests460/Toad288 parsed without omissions. Before/after complete +root candidate output is in owner-consumers.json; dynamic aliases and external +subclass resolution remain explicit limits. Pattern IMPL-12: original shared +capture/publication behavior replaces the duplicated source-enumeration path. + +No new env, build, keeper, installed prefix, Toad App, provider, physical recording +or CPU/smoothness qualification. Draft source checkpoint; affected installed +qualification belongs to a future meaningful Heis integration purpose. Frozen +Text63/64 08e3/wheel487 and Heis453 operands remain untouched. diff --git a/evidence/immutable-subtree-window-acquisition-20261005/owner-consumers.json b/evidence/immutable-subtree-window-acquisition-20261005/owner-consumers.json new file mode 100644 index 0000000000..775118a996 --- /dev/null +++ b/evidence/immutable-subtree-window-acquisition-20261005/owner-consumers.json @@ -0,0 +1,1792 @@ +{ + "before": { + "source": "08e3dd6b3c7839baafcac6ff9ea61eb510ff9573", + "roots": { + "src/textual": { + "parsed": 249, + "omissions": [] + }, + "tests": { + "parsed": 460, + "omissions": [] + } + }, + "sites": [ + { + "path": "src/textual/_compositor.py", + "line": 166, + "symbol": "SubtreeMapGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 197, + "symbol": "SubtreeGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 259, + "symbol": "PlacedSubtreeGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 271, + "symbol": "IntrinsicSubtreeGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 217, + "symbol": "restore_into", + "kind": "FunctionDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 227, + "symbol": "project_into", + "kind": "FunctionDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 254, + "symbol": "references_retired", + "kind": "FunctionDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 169, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 193, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 201, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 203, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 259, + "symbol": "SubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 271, + "symbol": "SubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 271, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 828, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1140, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1328, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1333, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 175, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 211, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 222, + "symbol": "project_into", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 222, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 225, + "symbol": "invisible_widgets", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 291, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 296, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 735, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 824, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1329, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1330, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1331, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1359, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1363, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1377, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1591, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1607, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 182, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 183, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 186, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 211, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 225, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 237, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 282, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 282, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 285, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 290, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 527, + "symbol": "SubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 570, + "symbol": "references_retired", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 737, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 747, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1114, + "symbol": "restore_into", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 1114, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1343, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1360, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1361, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1364, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1365, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1592, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1610, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1612, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 184, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 185, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 185, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 187, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 246, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 281, + "symbol": "PlacedSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 289, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 289, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 790, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1099, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1100, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1104, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1112, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1347, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 255, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 255, + "symbol": "invisible_widgets", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 280, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 288, + "symbol": "PlacedSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 577, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 744, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 896, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1107, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1593, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 188, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 579, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 740, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 748, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1105, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_spatial_map.py", + "line": 15, + "symbol": "SpatialMap", + "kind": "ClassDef" + }, + { + "path": "src/textual/_spatial_map.py", + "line": 84, + "symbol": "get_values_in_region", + "kind": "FunctionDef" + }, + { + "path": "src/textual/css/styles.py", + "line": 978, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/css/styles.py", + "line": 990, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 153, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 155, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 179, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 169, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 170, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 179, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 184, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 169, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 184, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/layout.py", + "line": 55, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/layout.py", + "line": 34, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/layout.py", + "line": 97, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "src/textual/layout.py", + "line": 58, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/screen.py", + "line": 1502, + "symbol": "references_retired", + "kind": "Attribute" + }, + { + "path": "src/textual/selection.py", + "line": 184, + "symbol": "references_retired", + "kind": "FunctionDef" + }, + { + "path": "src/textual/widget.py", + "line": 336, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 340, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 342, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 763, + "symbol": "PlacedSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 763, + "symbol": "IntrinsicSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 337, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 18, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 29, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 21, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 32, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 204, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 208, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 254, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 218, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 205, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 205, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 209, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 209, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 255, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 255, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 221, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 223, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 224, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 37, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 43, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 43, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 53, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 57, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 58, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 59, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 60, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 74, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 50, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 59, + "symbol": "geometry", + "kind": "Attribute" + } + ], + "limits": "Syntactic declaration/attribute matches; geometry attribute uses include unrelated shapes. Dynamic aliases/external subclasses are unresolved, not counted absent." + }, + "after": { + "source": "0ab59a0466cff6fd2bd8c3747b1be7e2fd660586", + "roots": { + "src/textual": { + "parsed": 249, + "omissions": [] + }, + "tests": { + "parsed": 460, + "omissions": [] + } + }, + "sites": [ + { + "path": "src/textual/_compositor.py", + "line": 167, + "symbol": "SubtreeMapGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 198, + "symbol": "SubtreeGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 285, + "symbol": "PlacedSubtreeGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 297, + "symbol": "IntrinsicSubtreeGeometry", + "kind": "ClassDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 232, + "symbol": "restore_into", + "kind": "FunctionDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 242, + "symbol": "project_into", + "kind": "FunctionDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 278, + "symbol": "references_retired", + "kind": "FunctionDef" + }, + { + "path": "src/textual/_compositor.py", + "line": 170, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 194, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 202, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 205, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 285, + "symbol": "SubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 297, + "symbol": "SubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 297, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 219, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 855, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1167, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1355, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1360, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 176, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 216, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 221, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 221, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 237, + "symbol": "project_into", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 237, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 240, + "symbol": "invisible_widgets", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 317, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 323, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 762, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 851, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1356, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1357, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1358, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1386, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1390, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1404, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1618, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1634, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 183, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 184, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 187, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 240, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 308, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 308, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 311, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 316, + "symbol": "SubtreeMapGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 554, + "symbol": "SubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 597, + "symbol": "references_retired", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 764, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 774, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1141, + "symbol": "restore_into", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 1141, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1370, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1387, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1388, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1391, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1392, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1619, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1637, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1639, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 185, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 186, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 186, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 188, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 253, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 270, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 307, + "symbol": "PlacedSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 315, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 315, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 817, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1126, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1127, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1131, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1139, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1374, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 281, + "symbol": "invisible_widgets", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 306, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 314, + "symbol": "PlacedSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 604, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 771, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 923, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1134, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1620, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 189, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 224, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 257, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 260, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 606, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 767, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 775, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 1132, + "symbol": "invisible_widgets", + "kind": "Name" + }, + { + "path": "src/textual/_compositor.py", + "line": 255, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 279, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "src/textual/_compositor.py", + "line": 215, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/_spatial_map.py", + "line": 15, + "symbol": "SpatialMap", + "kind": "ClassDef" + }, + { + "path": "src/textual/_spatial_map.py", + "line": 84, + "symbol": "get_values_in_region", + "kind": "FunctionDef" + }, + { + "path": "src/textual/css/styles.py", + "line": 978, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/css/styles.py", + "line": 990, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 153, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 155, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 179, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 169, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 170, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 179, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 184, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 169, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/dom.py", + "line": 184, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/layout.py", + "line": 55, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/layout.py", + "line": 34, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/layout.py", + "line": 97, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "src/textual/layout.py", + "line": 58, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "src/textual/screen.py", + "line": 1502, + "symbol": "references_retired", + "kind": "Attribute" + }, + { + "path": "src/textual/selection.py", + "line": 184, + "symbol": "references_retired", + "kind": "FunctionDef" + }, + { + "path": "src/textual/widget.py", + "line": 336, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 340, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 342, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 763, + "symbol": "PlacedSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 763, + "symbol": "IntrinsicSubtreeGeometry", + "kind": "Name" + }, + { + "path": "src/textual/widget.py", + "line": 337, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 18, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 29, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 21, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/css/test_programmatic_style_changes.py", + "line": 32, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 204, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 208, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 254, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 218, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 205, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 205, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 209, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 209, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 255, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 255, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 221, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 223, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_compositor.py", + "line": 224, + "symbol": "geometry", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 37, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 43, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 43, + "symbol": "SpatialMap", + "kind": "Name" + }, + { + "path": "tests/test_spatial_map.py", + "line": 53, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 57, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 58, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 59, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_spatial_map.py", + "line": 60, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 135, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 64, + "symbol": "PlacedSubtreeGeometry", + "kind": "Name" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 116, + "symbol": "get_values_in_region", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 103, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 121, + "symbol": "geometry", + "kind": "Attribute" + }, + { + "path": "tests/test_viewport_geometry_targets.py", + "line": 112, + "symbol": "geometry", + "kind": "Attribute" + } + ], + "limits": "Syntactic declaration/attribute matches; geometry attribute uses include unrelated shapes. Dynamic aliases/external subclasses are unresolved, not counted absent." + }, + "dependent_toad": { + "source": "09147f7d99cd30a75022c56d1b70f679fea7319b", + "parsed": 288, + "omissions": [], + "sites": [ + { + "path": "src/toad/widgets/viewport_body.py", + "line": 653, + "symbol": "render_subtree_strips" + }, + { + "path": "src/toad/widgets/viewport_body.py", + "line": 648, + "symbol": "published_geometry" + } + ] + }, + "ownership": "SubtreeGeometry.capture owns source ordinals and immutable entries once. Existing SpatialMap is private derived spatial resource, indexes ordinal/widget references only. No geometry copy/ordinal registry/independent mutation path. Both leafs use shared capture/projection; original membership fact and O(n) union retained." +} From 2a1fcfb04df86d0c2f7a148efbc332a452d87bc1 Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Mon, 5 Oct 2026 01:43:00 -0400 Subject: [PATCH 6/6] docs: bind normal main union to qualified native65 wheel --- .../NORMAL-MAIN-JOIN.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 evidence/immutable-subtree-window-acquisition-20261005/NORMAL-MAIN-JOIN.json diff --git a/evidence/immutable-subtree-window-acquisition-20261005/NORMAL-MAIN-JOIN.json b/evidence/immutable-subtree-window-acquisition-20261005/NORMAL-MAIN-JOIN.json new file mode 100644 index 0000000000..4863254de7 --- /dev/null +++ b/evidence/immutable-subtree-window-acquisition-20261005/NORMAL-MAIN-JOIN.json @@ -0,0 +1,17 @@ +{ + "qualified_source": "230289d89d23195a005aadaa645686cebdcf7c04", + "normal_main": "fc17c5f6f046d5fadad47da71842a78432731f63", + "merge_head": "f244a641e1aece5ec385c1a81e3908ae5a5eb68e", + "all_textual_assets": 266, + "git_local_frozen_wheel_byte_equal": true, + "build_inputs_byte_equal": [ + "README.md", + "pyproject.toml" + ], + "src_delta": [], + "retained_wheel": "/home/ts/wt/textual-native-subtree-strips-20261002/.artifacts/native65-filewheel-20261005/textual-8.2.8-py3-none-any.whl", + "wheel_sha256": "e253066f005a2d9d67aeae2279ee4852b92f86d13b03acf32b60f16307d79355", + "wheel_metadata_sha256": "fa4831c4001c94a8d8177cccd05099d8fa021575c81a3bd53eae3b995eb22f1e", + "merge_conflicts": false, + "qualification": "Normal current-main integration only. Original native controls and standalone e253 artifact preserved; no new source checks/build/runtime/installed/frame qualification." +}