Skip to content

Walk NestedTree nesting levels with loops instead of recursion - #106

Merged
pazz merged 1 commit into
mainfrom
fix-nested-nesting-recursion
Oct 25, 2026
Merged

pazz merged 1 commit into
mainfrom
fix-nested-nesting-recursion

Conversation

@pazz

@pazz pazz commented Oct 25, 2026

Copy link
Copy Markdown
Owner

Closes #101.

NestedTree.__getitem__ (through _lookup_entry) and parent_position (through _parent_position) called themselves once per nesting level, that is per Tree held as a node of another Tree. About a thousand nested Tree objects raised RecursionError. These were the last recursive walks in nested.py.

Both are now loops. __getitem__ steps into the nested trees and, as before, stops at an entry that is not a Tree. parent_position looks up the trees along the position once with _trees and works outwards from the innermost level until one has a parent, as the sibling moves already do; the old code looked the trees up again at every level. The two private helpers are deleted. No public behaviour changes.

test_deep_nesting nests 1100 SimpleTree objects and checks the walk in both directions, parents, siblings and depth. It checks against expected values directly, because the flatten helper of the invariant tests itself recurses per nesting level. Without the fix it raises RecursionError, and it still fails if either of the two functions is restored on its own.

Known limit, outside this change: if every one of about a thousand nesting levels is decorated (for example each wrapped in ArrowTree), rendering still raises RecursionError inside urwid, because the decorated line becomes as many nested urwid.Columns. Navigation and get_decorated work on such a tree.

Review findings and resolution

review-correctness

  • Two blank lines left inside the class where _lookup_entry was: fixed.
  • Rendering fails at about a thousand nesting levels when every level is decorated, with the recursion inside urwid's Columns: left, as it lies outside urwidtrees' navigation and this issue; recorded above as a known limit.
  • Checked without findings: the test fails without either half of the fix; the full suite passes on urwid 3.0.4 and 2.1.2; 1100 nesting levels with plain, ArrowTree and CollapsibleArrowTree subtrees, with and without interpret_covered; deep chains, 10000 children and 10000 subtrees run as fast as on main.

review-design

  • The same extra blank line: fixed.
  • Otherwise no changes: the diff is the smallest clean one, reuses _trees and follows the inside-out loop used elsewhere in the module; the public API is unchanged.

🤖 Generated with Claude Code

NestedTree.__getitem__ (through _lookup_entry) and parent_position
(through _parent_position) called themselves once per nesting level, so
about a thousand Tree objects nested inside each other raised
RecursionError. Both are now loops; parent_position looks up the trees
along the position once instead of once per level.

Closes #101.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@pazz
pazz merged commit 7946b8f into main Oct 25, 2026
4 checks passed
@pazz
pazz deleted the fix-nested-nesting-recursion branch October 25, 2026 06:13
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.

NestedTree recurses once per nesting level

1 participant