Skip to content

Type cardinality-one relationships as an assignable descriptor (#1064)#1067

Merged
FragmentedPacket merged 15 commits into
developfrom
ihs-relationship-assignment-1064
Jun 9, 2026
Merged

Type cardinality-one relationships as an assignable descriptor (#1064)#1067
FragmentedPacket merged 15 commits into
developfrom
ihs-relationship-assignment-1064

Conversation

@FragmentedPacket

@FragmentedPacket FragmentedPacket commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Fixes #1064. Stacked on #1063 (base branch is ihs-relatednode-generic-1063); retarget once #1063 / #763 merge.

Problem

Generated cardinality-one relationships are typed read-only as RelatedNode, but the documented way to set a relationship is node.rel = "<id>" or node.rel = peer_node. Under mypy/ty (since py.typed in 1.19.0) every such assignment fails with Incompatible types in assignment ... variable has type "RelatedNode" (assignment).

Change

  • Adds a typing-only descriptor RelationshipAttribute / RelationshipAttributeSync (in infrahub_sdk/node/related_node.py). It reads back as RelatedNode[Peer] (so .peer keeps the peer type from bug: RelatedNode.peer is typed InfrahubNode, losing the peer type during relationship traversal #1063) and accepts assignment of str | list[str] | Peer | None, mirroring the runtime InfrahubNode.__setattr__, which wraps the assigned value in a RelatedNode.
  • infrahubctl protocols now emits cardinality-one relationships as RelationshipAttribute[Peer] (cardinality-many stays RelationshipManager[Peer]).
  • The descriptor only appears in generated protocols and is never instantiated at runtime — purely to give node.rel separate read/assign types.

Verification

  • SDK: mypy (125 files) ✅, ty ✅, ruff ✅, generator test updated, 258 node/relationship/protocol unit tests ✅.
  • Against the downstream AI/DC repo: the relationship-assignment errors (node.rel = "<id>" / = peer) drop to 0. Remaining downstream errors are unrelated (untyped client.create(kind="...") results that need a cast, and an Optional not handled) — not relationship assignments.

Depends on

#1063 (generic RelatedNode) — RelationshipAttribute.__get__ returns RelatedNode[Peer].

🤖 Generated with Claude Code


Summary by cubic

Make cardinality-one relationships assignable in type-checked code by adding a typing-only RelationshipAttribute[...] descriptor. Reads still return RelatedNode[Peer], so .peer keeps its type and node.rel = "<id>" or a peer node now type-checks.

  • Bug Fixes

    • Added RelationshipAttribute/RelationshipAttributeSync that accept str | list[str] | Peer | None and read as RelatedNode[Peer]; typing-only, never used at runtime.
    • Protocols now emit RelationshipAttribute[Peer] for cardinality-one (including parent); many stays RelationshipManager[Peer].
    • Exported via infrahub_sdk.node; removes mypy/ty assignment errors without changing runtime behavior.
  • Migration

    • Regenerate protocols with infrahubctl protocols to pick up the new typing; existing generated files won’t update automatically.

Written for commit c5887f0. Summary will update on new commits.

Review in cubic

solababs and others added 10 commits January 22, 2026 10:50
Parameterise RelatedNode, RelatedNodeSync, RelationshipManager and
RelationshipManagerSync over the peer type (defaulting to InfrahubNode/
InfrahubNodeSync for backward compatibility) and have infrahubctl protocols
emit the peer type for each relationship. Relationship traversal via .peer/
.peers/indexing now preserves the peer type instead of collapsing to the
dynamic InfrahubNode.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Generated cardinality-one relationships now use a RelationshipAttribute
descriptor that reads back as RelatedNode[Peer] but accepts assignment of an id
string, an HFID, a peer node, or None — matching the runtime __setattr__ that
wraps the value in a RelatedNode. Previously relationships were typed read-only
as RelatedNode, so node.rel = "<id>" / node.rel = peer failed type checking.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 7, 2026

Copy link
Copy Markdown

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: c5887f0
Status: ✅  Deploy successful!
Preview URL: https://050bdb6d.infrahub-sdk-python.pages.dev
Branch Preview URL: https://ihs-relationship-assignment.infrahub-sdk-python.pages.dev

View logs

@codecov

codecov Bot commented Jun 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.47059% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
infrahub_sdk/node/related_node.py 73.33% 0 Missing and 4 partials ⚠️
@@             Coverage Diff             @@
##           develop    #1067      +/-   ##
===========================================
- Coverage    82.26%   81.82%   -0.45%     
===========================================
  Files          135      135              
  Lines        11956    11684     -272     
  Branches      1785     1766      -19     
===========================================
- Hits          9836     9560     -276     
- Misses        1573     1575       +2     
- Partials       547      549       +2     
Flag Coverage Δ
integration-tests 41.56% <0.00%> (-0.96%) ⬇️
python-3.10 55.19% <5.88%> (-0.80%) ⬇️
python-3.11 55.19% <5.88%> (-0.82%) ⬇️
python-3.12 55.19% <5.88%> (-0.82%) ⬇️
python-3.13 55.19% <5.88%> (-0.80%) ⬇️
python-3.14 55.19% <5.88%> (-0.80%) ⬇️
python-filler-3.12 22.42% <70.58%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
infrahub_sdk/node/__init__.py 100.00% <100.00%> (ø)
infrahub_sdk/protocols_generator/generator.py 95.12% <100.00%> (ø)
infrahub_sdk/node/related_node.py 91.00% <73.33%> (-1.57%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 6 files

Re-trigger cubic

FragmentedPacket and others added 3 commits June 8, 2026 15:24
…neric-1063

# Conflicts:
#	.pre-commit-config.yaml
#	infrahub_sdk/node/related_node.py
#	infrahub_sdk/node/relationship.py
#	infrahub_sdk/protocols_base.py
The develop merge combined upstream peer/get docstrings with our generic
PeerT/PeerTSync return types, leaving the committed related_node.mdx stale.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts:
#	infrahub_sdk/protocols_generator/generator.py
@FragmentedPacket FragmentedPacket requested a review from a team as a code owner June 8, 2026 22:26
@github-actions github-actions Bot added the type/documentation Improvements or additions to documentation label Jun 8, 2026
Base automatically changed from ihs-relatednode-generic-1063 to develop June 8, 2026 22:30
# Conflicts:
#	infrahub_sdk/node/related_node.py
#	infrahub_sdk/protocols_generator/template.j2
#	tests/unit/sdk/test_protocols_generator.py

@ogenstad ogenstad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, this will be a great improvement! One thing I think is missing here is that the protocols will need to be recreated once this is in place and we should highlight this in the changelog newsfragment so that it's clear that it won't just work out of the box.

Highlight in the 1064 newsfragment that the new relationship-assignment
typing lives in generated protocols, so existing projects must rerun
`infrahubctl protocols` to pick it up — it won't work out of the box.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@FragmentedPacket FragmentedPacket merged commit 78d99cd into develop Jun 9, 2026
21 checks passed
@FragmentedPacket FragmentedPacket deleted the ihs-relationship-assignment-1064 branch June 9, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants