Skip to content

fix: categorical hashing, delayed-backend detection, and pretty-printing#4106

Open
henryiii wants to merge 4 commits into
mainfrom
henryiii/fix-core-misc
Open

fix: categorical hashing, delayed-backend detection, and pretty-printing#4106
henryiii wants to merge 4 commits into
mainfrom
henryiii/fix-core-misc

Conversation

@henryiii

@henryiii henryiii commented Jun 10, 2026

Copy link
Copy Markdown
Member

🤖 AI text below 🤖

Summary

Four isolated correctness fixes identified in an automated multi-agent review (Claude Code):

  1. src/awkward/_categorical.pyHashableList not recursive (#1)
    HashableList.__init__ was doing tuple(obj) without applying as_hashable to each element, unlike HashableDict which correctly recurses. This caused TypeError: unhashable type: 'dict' when categorical array categories were lists containing dicts (e.g. list-of-record categories). Fixed: tuple(as_hashable(x) for x in obj).

  2. src/awkward/_errors.pyany_backend_is_delayed short-circuits too eagerly (#2)
    Inside the loop, when an object had no recognizable backend, the method returned False unconditionally (or returned the recursive result unchanged), so remaining args were never inspected. This means ([plain_obj, dask_array]) would be classified as not-delayed. Fixed: only return early when the recursive result is True; otherwise continue to the next item.

  3. src/awkward/prettyprint.pycustom_str result spliced character-by-character (#3)
    When custom_str(current) returned a string, strs = custom (a plain str) was passed to front.extend(strs) / back[:0] = strs, which iterates over individual characters. Additionally, cols_taken kept the value from the discarded default rendering rather than the actual custom string length. Fixed: wrap in [custom] and recompute cols_taken = len(custom).

  4. src/awkward/_do.pyrecursively_apply Record branch omits regular_to_jagged (#4)
    The isinstance(layout, Record) branch called recursively_apply positionally and omitted regular_to_jagged, silently resetting it to False for Record inputs. Fixed: forward the missing argument.

Test plan

  • New tests: tests/test_4106_fix_core_misc.py — 8 focused regression tests covering all four fixes
  • Existing categorical tests: test_0401, test_1688, test_0674
  • Existing prettyprint tests: test_2856
  • Existing regular_to_jagged tests: test_2047
  • All pass under PYTHONPATH=$PWD/src /tmp/ak-review-venv/bin/python -m pytest

AI assistance disclosure

This PR was generated by Claude Code (claude-sonnet-4-6) as part of an automated multi-agent review process. All fixes were verified against tests before submission.

🤖 Generated with Claude Code

henryiii added a commit that referenced this pull request Jun 10, 2026
Covers: categorical hashing with nested list/dict categories,
any_backend_is_delayed loop correctness, prettyprint custom_str
token handling, and recursively_apply Record regular_to_jagged
forwarding.

Assisted-by: ClaudeCode:claude-sonnet-4-6
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

henryiii added a commit that referenced this pull request Jun 11, 2026
Covers: categorical hashing with nested list/dict categories,
any_backend_is_delayed loop correctness, prettyprint custom_str
token handling, and recursively_apply Record regular_to_jagged
forwarding.

Assisted-by: ClaudeCode:claude-sonnet-4-6
@henryiii henryiii force-pushed the henryiii/fix-core-misc branch from c1ddfac to 998bb26 Compare June 11, 2026 19:45
@TaiSakuma TaiSakuma added the type/fix PR title type: fix (set automatically) label Jun 12, 2026
henryiii and others added 4 commits July 7, 2026 13:54
- _categorical.py: HashableList.__init__ now recurses via as_hashable for each
  element, matching HashableDict; fixes TypeError on list-of-dict categories
- _errors.py: any_backend_is_delayed only short-circuits on True from recursion,
  not False, so remaining args in a mixed list are always inspected
- prettyprint.py: custom_str result is wrapped in a single-element list and
  cols_taken is recomputed from len(custom), preventing character-by-character
  splicing and width accounting errors
- _do.py: recursively_apply Record branch forwards regular_to_jagged to the
  recursive call instead of silently resetting it to False

Assisted-by: ClaudeCode:claude-sonnet-4-6
Covers: categorical hashing with nested list/dict categories,
any_backend_is_delayed loop correctness, prettyprint custom_str
token handling, and recursively_apply Record regular_to_jagged
forwarding.

Assisted-by: ClaudeCode:claude-sonnet-4-6
Rename test_4106-fix-core-misc.py → test_4106_fix_core_misc.py (underscore
required by validate-test-names.py). Reduce 16 tests to 8: one focused
regression per bug, removing near-duplicate and internal-structure-probing
cases. Merge prettyprint width and splicing checks into one test.

Assisted-by: ClaudeCode:claude-sonnet-4-6
@henryiii henryiii force-pushed the henryiii/fix-core-misc branch from 998bb26 to 5d4b55d Compare July 7, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/fix PR title type: fix (set automatically)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants