Skip to content

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

Merged
ikrommyd merged 9 commits into
mainfrom
henryiii/fix-core-misc
Jul 12, 2026
Merged

fix: categorical hashing, delayed-backend detection, and pretty-printing#4106
ikrommyd merged 9 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

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.92%. Comparing base (a792746) to head (99d2567).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
Files with missing lines Coverage Δ
src/awkward/_categorical.py 96.66% <100.00%> (+36.66%) ⬆️
src/awkward/_do.py 84.14% <ø> (ø)
src/awkward/_errors.py 84.64% <100.00%> (ø)
src/awkward/prettyprint.py 85.35% <100.00%> (+0.08%) ⬆️

... and 7 files with indirect coverage changes

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
@ikrommyd
ikrommyd enabled auto-merge (squash) July 12, 2026 04:27
@ikrommyd
ikrommyd merged commit f71e4b3 into main Jul 12, 2026
38 checks passed
@ikrommyd
ikrommyd deleted the henryiii/fix-core-misc branch July 12, 2026 08:13
@github-actions

Copy link
Copy Markdown

The documentation preview is ready to be viewed at http://preview.awkward-array.org.s3-website.us-east-1.amazonaws.com/PR4106

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.

3 participants