Skip to content

feat: multi-class FK cascade reach through union / polymorphic-base targets (#262) - #290

Merged
yedidyakfir merged 20 commits into
developfrom
gsd/262-cascade-fk-multi-target-pr
Aug 16, 2026
Merged

feat: multi-class FK cascade reach through union / polymorphic-base targets (#262)#290
yedidyakfir merged 20 commits into
developfrom
gsd/262-cascade-fk-multi-target-pr

Conversation

@yedidyakfir

@yedidyakfir yedidyakfir commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Extends the TTL cascade so a single FK edge referencing a Reference[A | B] union or a polymorphic base class resolves to multiple candidate target classes.

  • Phase 1 (planner): _unwrap_relational_target now enumerates every candidate (union members + registered subclasses); CascadeEdge carries a candidates list alongside target; single-target plan JSON stays byte-identical (golden hash unchanged); validate_cascade_ttl_targets fails fast for every candidate.
  • Phase 2 (traversal + guard): the server-side Lua push_child resolves each reached key's actual class from its {class}:{pk} first-colon prefix, exact-matches it against the edge's candidates, and re-arms each reached child to its own class's Meta.ttl / special-suffix keys / outgoing edges. Non-candidate reaches are tallied via a new third FCALL return element mismatched_class; corrupt/no-colon reaches are silent, uncounted dead-ends. Adds an init-time CascadeKeyInitialsError guard (a cascade participant's class_key_initials() must equal __name__).
  • Changelog: multi-class reach is recorded under ## [1.3.6] → Fixed. The page section that originally accompanied this PR was dropped — this closes a gap in the existing cascade rather than adding a user-facing capability. The same commit backfills every other unreleased changelog entry since v1.3.4 (Milestone: Configurable TTL Cascade #283, Fix init_rapyer connection rebinding order #276, Runtime CPU optimizations: lazy _pk + cheaper __setattr__ type checks #263, v1.3.6: Cascade reach through special-field references (RedisSet/RedisPriorityQueue of ForeignKey) #289), which had been missing.

Single-target cascade behavior is preserved byte-for-byte; the per-child cascading-TTL-refresh apply layer is reused unchanged.

Testing

  • Unit + fakeredis: 840 passed (102 cascade), byte-identity golden hash 0bc1f0e973ecfcf4 unchanged.
  • Re-verified after the comment/docs/changelog pass: 840 unit passed, 64 cascade integration tests passed against real Redis Stack on :6370, ruff check clean (also fixes a pre-existing I001 that CI never caught, because the earlier lint job died on a GitHub Actions outage before running).
  • Real Redis Stack 7.4.7: full multi-class integration matrix (12 tests — union across scalar/list/dict/set/priority-queue shapes, colon-bearing pk, mixed-class diamond, depth-budget truncation through a resolved-class edge, non-candidate drift tally, corrupt dead-end) plus the full integration suite: 1636 passed, 205 skipped, 0 failures.

Closes #262

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Cascade TTL updates now support union and polymorphic references across scalar, collection, and special-field relationships.
    • Referenced records resolve to their concrete class, allowing each class’s TTL settings to be applied.
    • Cascade results now report class mismatches separately from dangling references.
  • Bug Fixes

    • Invalid or malformed cascade targets are safely skipped without interrupting processing.
    • Initialization now detects incompatible cascade key configuration early.
  • Documentation

    • Added guidance and runnable examples for multi-class cascade behavior, TTL requirements, and configuration constraints.

yedidyakfir and others added 15 commits August 6, 2026 18:02
- Add CascadeUnionMemberA/B + CascadeUnionOwner fixtures (union-typed FK)
- Assert edge lists both candidates and single-target edge keeps candidates=None
- RED: union crashes on UnionType.__name__; CascadeEdge has no candidates field

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- _unwrap_relational_target returns an accumulating, deduped candidate list
- Thread models through _static_walk_fk_edges/_resolve_target_cls
- Add CascadeEdge.candidates (None default keeps single-target JSON byte-identical)
- Set target=candidates[0]; candidates=list only when >1
- validate_cascade_ttl_targets loops every candidate (Rule 3: fix broken
  _static_walk_fk_edges caller in test_cascade_sf_held_ref_plan.py)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add CascadePolyBase + CascadePolySub1/2 + CascadePolyOwner/DedupOwner fixtures
- Assert base+subclasses enumerated (len 3), declaration order, dedup, degradation
- RED: Task-1 leaf enumerates verbatim only, so subclasses are not yet collected

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…edges

- _expand_candidates returns {T} union registered subclasses over threaded models
- Base included iff registered (Decision #3); safe_issubclass(T,T) drives it
- Order-preserving, deduped across union members; degrades to single target

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…on + A2 guard

- Golden plan JSON/hash regression (0bc1f0e973ecfcf4, no candidates key)
- Validator fails fast on a non-first candidate lacking Meta.ttl (model_name)
- Guard: no pre-existing single-target model is silently expanded
- Add candidates= param to _edge/_entry/_plan hand-build helpers

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…smatched_class counter

- library.lua: multi-class push_child branch gated on edge.candidates; first-colon
  {class}:{pk} prefix split via string.match; exact candidate membership; nil prefix
  is an uncounted dead-end; non-candidate/absent-from-plan increments a new
  cascade_apply-scope mismatched_class local; 3-element return tuple (D-01/D-03)
- result.py: CascadeResult.mismatched_class: int = 0 (defaulted, forward-compat)
- base.py: real-Redis results[-1] unpacks 3 elements; fakeredis fast-path sets
  mismatched_class=0 explicitly
- tests: new tracer test_cascade_multi_class_apply.py (scalar-union re-arm via public API)
- cascade_types.py: register CascadeUnion* fixtures in ALL_CASCADE_MODELS so the
  integration plan bakes their edges (Rule 3 blocking fix)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…the 3-element return

- unit: test_aset_ttl_cascade_flag mock pipe results carry a third element (0)
  and pin mismatched_class in every CascadeResult assertion
- unit: test_cascade_sf_held_ref_fakeredis_fallback + test_cascade_action_boundary
  pin mismatched_class=0 so the fakeredis no-op divergence asserts zero drift
- integration (Rule 3 lockstep): test_cascade_sf_held_ref_apply +
  test_cascade_depth_and_gate compared the raw fcall result to 2-element list
  literals; extended to 3 elements (mismatched_class=0) for the now-3-tuple return
- grep audit: no remaining 2-element unpack/compare of an fcall result; golden
  single-target plan hash 0bc1f0e973ecfcf4 unchanged; full unit cascade suite green

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…icipants

- Add CascadeKeyInitialsError(RapyerError) carrying model_name, mirroring CascadeTargetTtlMissingError
- Export it from rapyer.errors (import block + __all__)
- Add validate_cascade_key_initials(models) beside validate_cascade_ttl_targets: builds the participant set (roots + edge targets/candidates), asserts class_key_initials() == __name__, no Redis I/O
- Wire the guard into init_rapyer() right after validate_cascade_ttl_targets, pre-freeze
- D-04 docstrings on _unwrap_relational_target and CascadeEdge.candidates: class identity resolved from {class}:{pk} prefix; class_key_initials() must equal __name__

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…cipant scope

- Conforming participant plan raises nothing
- Override on a NON-root reached candidate raises CascadeKeyInitialsError (D-02 participant-scope)
- Override on a cascade root also raises
- Assert model_name equals offending __name__ and message names the overridden initials
- All local fixtures use init_with_rapyer=False; guard called on LOCAL model lists, never REDIS_MODELS

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-pk fixtures

- CascadeUnionListOwner/DictOwner/SetOwner/PQOwner extend the union target
  (CascadeUnionMemberA | CascadeUnionMemberB) across list/dict/RedisSet/PQ shapes
- CascadeMultiClassDiamond{Leaf,MemberA,MemberB,Root}: two candidate classes FK a
  single shared leaf so a cascade reaches it via two candidate-class paths (CMCT-08)
- CascadeColonPkMember (Key[str] pk) + CascadeColonPkOwner lock the first-colon
  {class}:{pk} split against a colon-bearing pk (Pitfall 2)
- every new fixture is ttl-bearing and appended to ALL_CASCADE_MODELS
- list/dict/RedisSet/PriorityQueue union owners each enumerate BOTH members
  as candidates (set-equality, order-independent — CMCT-07 ordering)
- mixed-class-diamond root lists both member classes; both members FK the
  same shared leaf class (CMCT-08 support)
- colon-pk union owner enumerates both the colon-pk and plain candidate
- both union candidates resolve/re-arm from the same scalar edge (CMCT-04 adjacency)
- list & dict union owners re-arm every referenced member class (CMCT-05/07)
- RedisSet & RedisPriorityQueue union owners re-arm both member classes (CMCT-07)
- empty collection/set/pq union owners reach no child and never crash (CMCT-07 empty)
- colon-bearing Key[str] pk resolves via first-colon split and re-arms (Pitfall 2)
… + dead-ends

- mixed-class diamond: shared leaf re-armed via both candidate-class paths, no crash (CMCT-08)
- add CascadeUnionDepthRoot fixture (union entry over CascadeChainNode | CascadeUnionMemberB, depth=1)
- depth budget truncates a chain entered THROUGH a resolved-class union edge (CMCT-08 depth clause, direct)
- non-candidate reach: skipped, no TTL applied, mismatched_class tallied (D-03, CMCT-10)
- corrupt no-colon reach: silent dead-end, NOT tallied (CMCT-10)
- Add tests/unit/cascade/test_cascade_multi_class_fakeredis_fallback.py
- Scalar union owner: own main key re-arms, reached member NOT re-armed
- SF-held union set owner: own container key re-arms, reached member NOT re-armed
- Both assert zero-drift CascadeResult(0, 0, mismatched_class=0) fast path
- Local fixture wires union models onto fakeredis without polluting the
  byte-identity-guarded CASCADE_PLANNER_MODELS list
- Add 'Multi-Class FK Targets (Union / Polymorphic Base)' subsection under
  Cascade-Eligible Shapes
- ONE runnable example covering BOTH a union Reference[A|B] FK and a
  polymorphic-base FK with registered subclasses, each re-arming its reached
  child to that child's own Meta.ttl
- Admonition records the {class}:{pk} prefix identity rule: class_key_initials()
  must equal __name__ (enforced by CascadeKeyInitialsError) and class-name
  uniqueness (enforced by DuplicateModelNameError) -- folds in the #262 concern
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c1deb0de-06c1-47f3-ac61-690ab2108866

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Cascade TTL planning and execution now support union and polymorphic foreign-key targets across scalar, collection, and special-field shapes. Redis key prefixes select concrete classes, per-class TTLs are applied, and class mismatches are reported.

Changes

Multi-class cascade support

Layer / File(s) Summary
Plan candidate resolution and validation
rapyer/cascade/planner.py, rapyer/errors/*, rapyer/init.py, tests/unit/cascade/*, tests/models/cascade_types.py
The planner enumerates union and polymorphic candidates, validates every candidate TTL, and rejects cascade participants whose key initials do not match their class names.
Runtime class resolution and result reporting
rapyer/scripts/lua/cascade/library.lua, rapyer/base.py, rapyer/result.py
The Lua cascade resolves concrete classes from Redis key prefixes, skips invalid targets, counts mismatches, and returns three counters through CascadeResult.
Fixtures and behavior coverage
tests/integration/foreign_keys/*, tests/unit/cascade/*
Tests cover scalar, collection, special-field, depth-limited, malformed-key, diamond, fakeredis, and class-drift scenarios.
Cascade documentation
docs/documentation/special-fields/ttl-cascade.md
Documentation and runnable examples describe multi-class targets, per-class TTLs, key-prefix resolution, and initialization validation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: yedidyahkfir

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant aset_ttl
  participant CascadeFunction
  participant Redis
  Client->>aset_ttl: Call aset_ttl(cascade=True)
  aset_ttl->>CascadeFunction: Execute serialized cascade plan
  CascadeFunction->>Redis: Resolve key prefix and refresh concrete target TTL
  CascadeFunction-->>aset_ttl: Return dangling and mismatch counters
  aset_ttl-->>Client: Return CascadeResult
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: multi-class foreign-key cascade support for union and polymorphic-base targets.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gsd/262-cascade-fk-multi-target-pr

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@yedidyakfir yedidyakfir self-assigned this Aug 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/unit/cascade/test_aset_ttl_cascade_flag.py (1)

91-94: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the stale "two-element result" comment.

The mock now returns three elements and the assertion checks mismatched_class. The comment still describes a two-element result.

📝 Proposed comment fix
     # Standalone call (no outer pipeline): enqueues run_sha, awaits
-    # pipe.execute() itself, and decodes the two-element result.
+    # pipe.execute() itself, and decodes the three-element result.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/cascade/test_aset_ttl_cascade_flag.py` around lines 91 - 94,
Update the comment above the standalone pipeline mock in fcall_pipeline_spy to
describe decoding a three-element result, including the mismatched_class value
asserted by the test; leave the mock behavior and assertions unchanged.
tests/integration/foreign_keys/test_cascade_multi_class_apply.py (1)

328-381: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a real-Redis polymorphic-target case.

The suite covers union targets end-to-end. Polymorphic base targets are covered only at plan level. A subclass-key reach through a Reference[CascadePolyBase] edge exercises a different candidate-enumeration path. Adding one case would close that gap.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/foreign_keys/test_cascade_multi_class_apply.py` around
lines 328 - 381, The integration suite needs a real-Redis cascade test for
polymorphic base references, not just union targets and plan-level coverage. Add
an async test alongside the existing cascade reach tests that creates a concrete
subclass target referenced through CascadePolyBase, persists the relevant keys,
runs apply_cascade, and verifies the subclass candidate is handled with the
expected TTL behavior and result counters. Reuse the existing polymorphic model
and helper symbols from the test module.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/documentation/special-fields/ttl-cascade.md`:
- Line 154: Update the code block beginning at the ``` marker in ttl-cascade.md
to use the repository-required indented Markdown style, unless the project
configuration explicitly intends fenced blocks; otherwise adjust the relevant
Markdown lint configuration consistently.
- Around line 144-149: Update the TTL cascade documentation’s return description
and fakeredis example to include all CascadeResult fields, including
mismatched_class, and use the complete constructor shape. Document that
mismatched_class counts both valid model classes outside the edge candidate set
and colon-bearing class prefixes absent from CASCADE_PLAN, while colon-free
corrupt keys remain uncounted.

---

Nitpick comments:
In `@tests/integration/foreign_keys/test_cascade_multi_class_apply.py`:
- Around line 328-381: The integration suite needs a real-Redis cascade test for
polymorphic base references, not just union targets and plan-level coverage. Add
an async test alongside the existing cascade reach tests that creates a concrete
subclass target referenced through CascadePolyBase, persists the relevant keys,
runs apply_cascade, and verifies the subclass candidate is handled with the
expected TTL behavior and result counters. Reuse the existing polymorphic model
and helper symbols from the test module.

In `@tests/unit/cascade/test_aset_ttl_cascade_flag.py`:
- Around line 91-94: Update the comment above the standalone pipeline mock in
fcall_pipeline_spy to describe decoding a three-element result, including the
mismatched_class value asserted by the test; leave the mock behavior and
assertions unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ca81bc2-e438-46dd-ba9d-6c5d11b9bef3

📥 Commits

Reviewing files that changed from the base of the PR and between c4db3d6 and efcbacb.

📒 Files selected for processing (21)
  • docs/documentation/special-fields/ttl-cascade.md
  • rapyer/base.py
  • rapyer/cascade/planner.py
  • rapyer/errors/__init__.py
  • rapyer/errors/cascade.py
  • rapyer/init.py
  • rapyer/result.py
  • rapyer/scripts/lua/cascade/library.lua
  • tests/integration/foreign_keys/test_cascade_depth_and_gate.py
  • tests/integration/foreign_keys/test_cascade_multi_class_apply.py
  • tests/integration/foreign_keys/test_cascade_sf_held_ref_apply.py
  • tests/models/cascade_types.py
  • tests/unit/cascade/test_aset_ttl_cascade_flag.py
  • tests/unit/cascade/test_cascade_action_boundary.py
  • tests/unit/cascade/test_cascade_key_initials_guard.py
  • tests/unit/cascade/test_cascade_multi_candidate_plan.py
  • tests/unit/cascade/test_cascade_multi_class_fakeredis_fallback.py
  • tests/unit/cascade/test_cascade_plan_injection.py
  • tests/unit/cascade/test_cascade_sf_held_ref_fakeredis_fallback.py
  • tests/unit/cascade/test_cascade_sf_held_ref_plan.py
  • tests/unit/cascade/test_cascade_ttl_required_validation.py

Comment on lines +144 to +149
In both cases the edge carries **all** candidate classes, and the cascade resolves
each reached child's *actual* class at traversal time from its stored key's
`{class}:{pk}` prefix, then re-arms that child to **its own** resolved class's
`Meta.ttl` — exactly as with a single-target FK. A child whose class is a valid model
but is *not* among the edge's candidates is skipped (never re-armed) and counted as
class drift in `CascadeResult.mismatched_class`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document the complete mismatched_class contract.

This section introduces mismatched_class, but the later return section still lists only dangling_children and dangling_special. The fakeredis example also uses CascadeResult(0, 0). The runtime counts a colon-bearing prefix that is absent from CASCADE_PLAN, not only a valid model outside the candidate set. Update the return description and examples to list all fields and document both mismatch cases. Keep colon-free corrupt keys uncounted.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/documentation/special-fields/ttl-cascade.md` around lines 144 - 149,
Update the TTL cascade documentation’s return description and fakeredis example
to include all CascadeResult fields, including mismatched_class, and use the
complete constructor shape. Document that mismatched_class counts both valid
model classes outside the edge candidate set and colon-bearing class prefixes
absent from CASCADE_PLAN, while colon-free corrupt keys remain uncounted.

The single runnable example below shows **both** shapes — a union FK and a
polymorphic-base FK — each re-arming its reached child to that child's own `Meta.ttl`:

```python

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the Markdown code-block style.

markdownlint-cli2 reports MD046 at Line 154. Convert this example to the repository-required indented style, or update the Markdown lint configuration if fenced blocks are intentional here.

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 154-154: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/documentation/special-fields/ttl-cascade.md` at line 154, Update the
code block beginning at the ``` marker in ttl-cascade.md to use the
repository-required indented Markdown style, unless the project configuration
explicitly intends fenced blocks; otherwise adjust the relevant Markdown lint
configuration consistently.

Source: Linters/SAST tools

@codspeed-hq

codspeed-hq Bot commented Aug 6, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 171 untouched benchmarks


Comparing gsd/262-cascade-fk-multi-target-pr (d098c87) with develop (c4db3d6)

Open in CodSpeed

YedidyaHKfir and others added 2 commits August 13, 2026 12:29
…ationale as one-line # comments

Docstrings state only what a function does; implementation and decision
rationale moved to single-line # comments over the block they explain.

- _unwrap_relational_target / _expand_candidates: drop the D-04 and
  Decision-#3 essays, keep a one-line summary each
- CascadeEdge.candidates, CascadeResult.mismatched_class: one-line intent
- validate_cascade_key_initials, CascadeKeyInitialsError: black-box docstring
- library.lua push_child: 40 lines of prose down to three # lines

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…; fix import order

Test comments now sit over the block they explain and stay one line;
descriptive test names carry the rest. Also drops plan-task and
requirement-ID tags from section headers.

- test_cascade_multi_class_apply.py: 12 comment paragraphs condensed
- multi-candidate plan / key-initials / fakeredis-fallback modules: one-line
  module docstrings, per-block notes
- cascade_types.py fixtures: one-line docstrings, matching the file's style
- ruff I001 on test_cascade_multi_candidate_plan.py (pre-existing, never
  caught because CI lint never ran)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 13, 2026

Copy link
Copy Markdown

YED-105

YED-228

@github-actions

Copy link
Copy Markdown

Coverage report

Total coverage: 99%

Full report
Name                                                     Stmts   Miss  Cover
----------------------------------------------------------------------------
rapyer/__init__.py                                           5      0   100%
rapyer/actions.py                                          213      0   100%
rapyer/base.py                                             869      2    99%
rapyer/cascade/__init__.py                                   3      0   100%
rapyer/cascade/planner.py                                  210      9    96%
rapyer/cascade/spec.py                                      13      0   100%
rapyer/cascade/ttl.py                                        5      0   100%
rapyer/config.py                                            45      0   100%
rapyer/context.py                                           40      0   100%
rapyer/errors/__init__.py                                   11      0   100%
rapyer/errors/base.py                                       23      0   100%
rapyer/errors/cascade.py                                    12      0   100%
rapyer/errors/delete.py                                      3      0   100%
rapyer/errors/find.py                                       15      0   100%
rapyer/fields/__init__.py                                    4      0   100%
rapyer/fields/expression.py                                108      0   100%
rapyer/fields/index.py                                      20      0   100%
rapyer/fields/key.py                                        19      0   100%
rapyer/fields/safe_load.py                                  14      0   100%
rapyer/init.py                                              68      0   100%
rapyer/links.py                                              2      0   100%
rapyer/result.py                                            32      0   100%
rapyer/scripts/__init__.py                                   5      0   100%
rapyer/scripts/constants.py                                 17      0   100%
rapyer/scripts/loader.py                                    38      0   100%
rapyer/scripts/lua/__init__.py                               0      0   100%
rapyer/scripts/lua/atomic/__init__.py                        0      0   100%
rapyer/scripts/lua/cascade/__init__.py                       0      0   100%
rapyer/scripts/lua/datetime/__init__.py                      0      0   100%
rapyer/scripts/lua/dict/__init__.py                          0      0   100%
rapyer/scripts/lua/list/__init__.py                          0      0   100%
rapyer/scripts/lua/numeric/__init__.py                       0      0   100%
rapyer/scripts/lua/sf/__init__.py                            0      0   100%
rapyer/scripts/lua/sf/redis_priority_queue/__init__.py       0      0   100%
rapyer/scripts/lua/sf/redis_set/__init__.py                  0      0   100%
rapyer/scripts/lua/string/__init__.py                        0      0   100%
rapyer/scripts/registry.py                                  63      0   100%
rapyer/types/__init__.py                                    13      0   100%
rapyer/types/base.py                                       103      0   100%
rapyer/types/byte.py                                        33      0   100%
rapyer/types/convert.py                                     53      0   100%
rapyer/types/datetime.py                                    77      0   100%
rapyer/types/dct.py                                        116      0   100%
rapyer/types/float.py                                       65      0   100%
rapyer/types/foreign_key.py                                 68      0   100%
rapyer/types/generic.py                                     83      0   100%
rapyer/types/init.py                                        10      0   100%
rapyer/types/integer.py                                     58      0   100%
rapyer/types/lst.py                                        129      0   100%
rapyer/types/priority_queue.py                             112      0   100%
rapyer/types/redis_set.py                                  206      0   100%
rapyer/types/relational.py                                  24      0   100%
rapyer/types/special.py                                     39      0   100%
rapyer/types/string.py                                      22      0   100%
rapyer/typing_support.py                                     3      0   100%
rapyer/utils/__init__.py                                     0      0   100%
rapyer/utils/annotation.py                                  62      1    98%
rapyer/utils/fields.py                                      43      0   100%
rapyer/utils/pythonic.py                                    21      0   100%
rapyer/utils/redis.py                                       77      0   100%
----------------------------------------------------------------------------
TOTAL                                                     3274     12    99%

Comment thread rapyer/cascade/planner.py Outdated
model_cls: Any,
parent_path: str,
fks: list[CascadeEdge],
models: list,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list of what? improve annotation

YedidyaHKfir and others added 2 commits August 13, 2026 16:21
…TL-cascade page section

Multi-class FK reach closes a gap in the original cascade rather than
adding a user-facing capability, so it does not warrant its own
documentation section. Reverts the page to its develop state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…eased entry since v1.3.4

Only #288 had an entry; five merged items were missing.

- [1.3.6] new: SF-held reference cascade (#289, Added) and multi-class
  union / polymorphic-base FK reach (#290, Fixed)
- [1.3.5] backfilled: the configurable TTL cascade feature itself (#283),
  the init_rapyer client-rebind fix (#276), runtime CPU optimizations (#263)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… on planner model-list annotations

PR #290 review: bare `list` did not say list of what. Use the
`list[type["AtomicRedisModel"]]` form already used by build_cascade_plan
for every model-list parameter, return, and accumulator.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@yedidyakfir
yedidyakfir merged commit c358d93 into develop Aug 16, 2026
57 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Aug 16, 2026
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.

2 participants