Skip to content

fix: make symbol containers immutable without a setattr hook - #5825

Merged
BradyPlanden merged 2 commits into
mainfrom
fix/zero-cost-symbol-immutability
Sep 30, 2026
Merged

BradyPlanden merged 2 commits into
mainfrom
fix/zero-cost-symbol-immutability

Conversation

@BradyPlanden

@BradyPlanden BradyPlanden commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Description

The Bencher check is currently failing on test_parameterise: this report shows 1.01 ms against an 804 µs baseline. The regression comes from #5779. Its test-suite mutation guard, which also covers the benchmarks, hooks Symbol.__setattr__ and walks the stack on every slot a constructor writes, and children and domain built a write-through view on every access.

  • children, domain and input_names return immutable tuples that compare equal to lists, and domains returns a read-only copy. Editing them raises TypeError instead of warning.
  • The runtime __setattr__ hook is replaced by a test that statically rejects post-construction slot writes in PyBaMM's own code.
  • Setting entries_string and calling set_evaluation_array in place now emit SymbolMutationDeprecationWarning.

Bencher results

image

Type of change

Add an entry under # [Unreleased] in CHANGELOG.md, in one of ## Breaking changes, ## Deprecated, ## Features, or ## Bug fixes (include PR number; breaking and deprecation entries need a one-line migration note). Internal-only PRs — refactor, docs, CI, tests — can skip this. See RELEASE.md for the full policy.

Important checks:

Please confirm the following before marking the PR as ready for review:

  • No style issues: nox -s pre-commit
  • All tests pass: nox -s tests
  • The documentation builds: nox -s doctests
  • Code is commented for hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

@BradyPlanden
BradyPlanden requested a review from a team as a code owner September 30, 2026 12:42
BradyPlanden added a commit that referenced this pull request Sep 30, 2026
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

@codecov

codecov Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.41379% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.08%. Comparing base (bd57250) to head (91b2439).

Files with missing lines Patch % Lines
...ckages/pybamm/src/pybamm/expression_tree/symbol.py 96.00% 3 Missing ⚠️
...amm/src/pybamm/expression_tree/binary_operators.py 60.00% 2 Missing ⚠️
...ges/pybamm/src/pybamm/expression_tree/parameter.py 87.50% 2 Missing ⚠️
...ackages/pybamm/src/pybamm/expression_tree/array.py 92.30% 1 Missing ⚠️
...s/pybamm/src/pybamm/expression_tree/interpolant.py 88.88% 1 Missing ⚠️
.../pybamm/src/pybamm/expression_tree/state_vector.py 90.00% 1 Missing ⚠️
...bamm/src/pybamm/expression_tree/unary_operators.py 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5825      +/-   ##
==========================================
+ Coverage   97.99%   98.08%   +0.08%     
==========================================
  Files         346      346              
  Lines       35309    35275      -34     
==========================================
- Hits        34601    34599       -2     
+ Misses        708      676      -32     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

@MarcBerliner MarcBerliner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

Symbol.children, the domain accessors and FunctionParameter.input_names now
return immutable tuple subclasses that compare equal to lists, and
Symbol.domains returns a read-only copy, so editing them raises TypeError
instead of silently desynchronising the symbol's identity.

The test suite's mutation guard no longer patches Symbol.__setattr__ (which
walked the stack on every slot write); post-construction slot writes are
instead rejected by a static AST scan of PyBaMM's code, tests, examples and
notebooks. Setting Array/Interpolant.entries_string and calling
StateVector.set_evaluation_array are now deprecated in-place updates.

Under the guard, expression construction is ~2x faster and parameterisation
~25% faster, recovering most of the test_parameterise regression from #5779.
@BradyPlanden
BradyPlanden force-pushed the fix/zero-cost-symbol-immutability branch from 1b39a7e to 91b2439 Compare September 30, 2026 14:19
@BradyPlanden
BradyPlanden enabled auto-merge (squash) September 30, 2026 14:19
@BradyPlanden
BradyPlanden merged commit 0ef15f2 into main Sep 30, 2026
41 of 43 checks passed
@BradyPlanden
BradyPlanden deleted the fix/zero-cost-symbol-immutability branch September 30, 2026 14:47
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