Skip to content

refactor(types/collections): share base class, tighten validators, expand docs#778

Merged
tcoratger merged 3 commits into
leanEthereum:mainfrom
tcoratger:refactor/collections-base-class-and-docs
May 26, 2026
Merged

refactor(types/collections): share base class, tighten validators, expand docs#778
tcoratger merged 3 commits into
leanEthereum:mainfrom
tcoratger:refactor/collections-base-class-and-docs

Conversation

@tcoratger
Copy link
Copy Markdown
Collaborator

Summary

  • Extract a private _SSZSequence[T] base that holds the shared scaffolding (init_subclass, JSON serializer, offset-table writer, iteration, indexing).
  • Tighten both validators: vector now rejects str/bytes explicitly, list's broad except Exception is narrowed to domain exceptions with the inner cause chained.
  • Simplify decoders: vector reads its offset table in one comprehension with an upfront scope guard; list uses a star-unpack literal for the offset list plus the trailing scope sentinel.
  • Rewrite documentation in the bitfields.py style — module overview defines fixed-size vs variable-size up front, the __init_subclass__ docstring shows a concrete class declaration, inline comments are glued to each block and explain the why.
  • Replace fragile column-diagrams with byte-range tables that read cleanly in any editor.

Test plan

  • uv run pytest tests/lean_spec/types/test_collections.py (57 passed)
  • uv run pytest tests/lean_spec/types/ (1089 passed)
  • uv run pytest tests/ (2997 passed)
  • just check (ruff, ruff format, ty, codespell, mdformat all clean)

🤖 Generated with Claude Code

tcoratger and others added 3 commits May 26, 2026 11:28
…pand docs

Pull the duplicated scaffolding out of SSZVector and SSZList into a private
_SSZSequence base — __init_subclass__, JSON serializer, offset-table writer,
__len__, __iter__, __getitem__, and elements live there once instead of twice.

Validator changes:

- Vector validator now rejects str/bytes inputs explicitly, matching list
  behavior and avoiding silent character iteration.
- The broad except Exception in the list validator is narrowed to the four
  domain exception types, and the underlying coercion detail is chained into
  the high-level message.

Decoder changes:

- SSZVector.deserialize reads the full offset table in one comprehension and
  adds an upfront scope check, so malformed inputs fail with a clear error
  rather than stream underflow.
- SSZList.deserialize uses a single star-unpack literal for the offset list
  plus the trailing scope sentinel.
- Phase labels renamed to per-case labels since the branches dispatch rather
  than sequence.

Docs follow bitfields.py style throughout:

- Module overview defines fixed-size vs variable-size up front, illustrated
  with a byte-range table instead of a fragile column diagram.
- __init_subclass__ docstring includes a concrete class declaration to show
  what the hook produces.
- Inline comments are glued to each block and explain the why, not the what.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ines

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests now exercise every branch in collections.py through the public API:

- Validator branches for both vector and list: missing-attr cases, str/bytes/
  bytearray rejection, non-iterable scalar, generator coercion, typed pass-
  through, raw-value coercion, chained-cause failure messages, too-few /
  too-many / empty / at-limit / over-limit construction.
- Size-query coverage: is_fixed_size True for fixed-element vectors and False
  for variable-element vectors; get_byte_length returns the correct total for
  fixed-size and raises for variable-size.
- Accessors: explicit integer-index and negative-index tests for both vector
  and list.
- __add__: empty + empty / empty + non-empty / non-empty + empty edge cases
  in addition to the existing happy paths.
- Offset-validation paths now tested via crafted decode_bytes payloads on
  real subclasses rather than through the private _validate_offsets helper:
  scope below table, invalid first offset, non-monotonic offsets, final-
  offset overflow, single-element variable list, misaligned offset, count
  beyond limit.
- JSON serialization covers Boolean preservation (verifies the bool-exclusion
  branch) and Container passthrough (verifies the else branch).

Every error assertion uses pytest.raises(..., match=re.escape(EXACT_MESSAGE))
so the full inner message is checked even when wrapped in ValidationError.

Removed:
- TestCollectionHelpers — the private _validate_offsets is now covered
  indirectly through deserialize, not directly.
- Duplicate over-limit tests on BooleanList4.
- Module-level sig_test_data constants — inlined into the parametrize case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tcoratger tcoratger merged commit 5268716 into leanEthereum:main May 26, 2026
12 of 13 checks passed
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.

1 participant