Skip to content

feat: raise error when updating a read-only attribute - #1281

Draft
ogenstad wants to merge 3 commits into
stablefrom
pog-em-/chore-raise-error-updating-attribute-sdk-mcbri
Draft

feat: raise error when updating a read-only attribute#1281
ogenstad wants to merge 3 commits into
stablefrom
pog-em-/chore-raise-error-updating-attribute-sdk-mcbri

Conversation

@ogenstad

@ogenstad ogenstad commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Why

Updating a read-only attribute via the SDK failed silently: the value was accepted in memory, then quietly dropped from the mutation at save time, so the change never reached the server and the caller got no signal. This makes it easy to believe a value was written when it never was.

Goal: surface the problem at the point of assignment instead of hiding it.

Closes #1248

What changed

Behavioral changes

  • Assigning to a read-only attribute (e.g. node.some_readonly_attr.value = "x") now raises ReadOnlyAttributeError immediately, instead of silently discarding the value.
  • infrahubctl object update now rejects a read-only field passed via --set with a clear error at validation time, instead of silently no-op'ing (it previously even printed a false "Updated ..." line).

What stayed the same

  • Loading read-only values from the API and re-querying them still work: the Attribute constructor and the internal population path set the backing value directly and bypass the new guard. A re-query builds a fresh node through the constructor, so read-only data always repopulates.
  • Read-only attributes remain excluded from the mutation payload.

Implementation notes

  • New ReadOnlyAttributeError exception.
  • The guard lives in the Attribute.value setter; an internal _set_value() bypass is used by the two pool re-population sites in node.py.
  • Removed a dead _read_only = ["updated_at", "is_inherited"] list that was defined but never referenced.

How to review

Start with infrahub_sdk/node/attribute.py (the setter guard + _set_value bypass), then infrahub_sdk/node/node.py (the two internal call sites), then infrahub_sdk/ctl/object/update.py (validation-time rejection). Tests follow.

How to test

uv run pytest tests/unit/sdk/test_node.py tests/unit/sdk/test_file_object.py tests/unit/sdk/pool/ tests/unit/ctl/object/test_update.py
uv run invoke format lint-code

Impact & rollout

  • Backward compatibility: potentially breaking. Code that assigned to a read-only attribute and relied on the previous silent no-op will now raise ReadOnlyAttributeError. This is called out prominently in the changelog fragment. Callers must stop writing to read-only attributes.
  • Config/env changes: none.
  • Deployment notes: safe to deploy; behavior change only affects callers that were (ineffectively) writing to read-only attributes.

Follow-up (out of scope here)

tests/unit/ctl/object/test_update.py is built on unittest.mock (MagicMock/AsyncMock/patch), which we are trying to move away from. This PR minimizes its footprint (schema-attribute stubs use SimpleNamespace, not MagicMock) but the new read-only rejection test still relies on the file's existing mock-based CLI harness. A separate, unrelated change should move this file (and its siblings) off MagicMock toward real schema fixtures.

Checklist

  • Tests added/updated
  • Changelog entry added (changelog/1248.changed.md, flagged as potentially breaking)
  • External docs updated (no user-facing doc covers this path)
  • Internal .md docs updated (n/a)

Assigning to a read-only attribute previously failed silently: the value
was dropped from the mutation payload at save time with no signal to the
caller. Setting a read-only attribute now raises ReadOnlyAttributeError,
while loading and re-querying read-only values keep working (those go
through the constructor / internal population path).

infrahubctl object update now rejects a read-only --set field at
validation time with a clear message instead of silently no-op'ing.
@ogenstad ogenstad added the type/feature New feature or request label Aug 26, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 26, 2026

Copy link
Copy Markdown

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 131e072
Status: ✅  Deploy successful!
Preview URL: https://ba9abd53.infrahub-sdk-python.pages.dev
Branch Preview URL: https://pog-em--chore-raise-error-up.infrahub-sdk-python.pages.dev

View logs

@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
infrahub_sdk/node/node.py 50.00% 1 Missing ⚠️
@@            Coverage Diff             @@
##           stable    #1281      +/-   ##
==========================================
+ Coverage   84.16%   84.17%   +0.01%     
==========================================
  Files         147      147              
  Lines       13045    13058      +13     
  Branches     1930     1932       +2     
==========================================
+ Hits        10979    10992      +13     
  Misses       1503     1503              
  Partials      563      563              
Flag Coverage Δ
integration-tests 38.97% <18.75%> (-0.04%) ⬇️
python-3.10 56.99% <68.75%> (-0.01%) ⬇️
python-3.11 57.00% <68.75%> (+0.01%) ⬆️
python-3.12 56.99% <68.75%> (-0.01%) ⬇️
python-3.13 56.99% <68.75%> (-0.01%) ⬇️
python-3.14 56.99% <68.75%> (-0.01%) ⬇️
python-filler-3.12 23.69% <25.00%> (+<0.01%) ⬆️

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

Files with missing lines Coverage Δ
infrahub_sdk/ctl/object/update.py 76.76% <100.00%> (+0.97%) ⬆️
infrahub_sdk/exceptions.py 90.00% <100.00%> (+0.30%) ⬆️
infrahub_sdk/node/attribute.py 100.00% <100.00%> (ø)
infrahub_sdk/node/node.py 87.77% <50.00%> (ø)
🚀 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
Contributor

Choose a reason for hiding this comment

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

No issues found across 8 files

Re-trigger cubic

…k usage

Replace the _value-poking test helper with a _fetched_file_node helper that
builds the node through the public constructor data payload (the path a real
query uses). Swap the CTL update schema-attribute stubs from MagicMock to
SimpleNamespace.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature: raise error when updating read-only attribute in SDK

1 participant