Repository navigation
fix: deep-copy global WSV defaults in Workspace constructor - #1192
Merged
Merged
Conversation
A plain copy of the defaults map shared the underlying value objects between all workspaces and the global defaults, so writes to `out` variables silently corrupted every other workspace. Use `Wsv::copied()` per variable instead.
Two workspaces must not share the value objects of variables initialized from the global defaults: a method writing its `out` variable in one workspace must not change the other workspace or workspaces created later. This guards the deep-copy introduced in 30f04ec ("deep-copy global WSV defaults in Workspace constructor").
Contributor
|
Please merge. Good find. |
riclarsson
approved these changes
Oct 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Constructing a
Workspaceused to initialize its variables with a plain copy of the global defaults map. SinceWsvstores its value through astd::shared_ptr, that copy shared the underlying value objects between every workspace and the global defaults, so a method writing itsoutvariable in place silently corrupted the same variable in all other workspaces — including workspaces created later. This branch deep-copies each default variable in theWorkspaceconstructor and adds a regression test that pins the behavior in place.Changes
src/workspace_class.h: TheWorkspaceconstructor now initializes its variable map by deep-copying each global default withWsv::copied()(per-type copy dispatch) instead of copying the map itself, so every workspace owns independent value objects and writes tooutvariables stay local to that workspace.tests/python/workspaces-do-not-share-defaults.py: New regression test that callsjac_targetsAddTemperature()on one workspace and asserts that a second workspace, and one constructed only after the call, are unaffected. It fails on the base commit and passes with the fix.Reproduction
Standalone script demonstrating the bug:
Output on the base commit (bug):
Expected output with this branch (fix):
The corruption also affected workspaces created after the method call, because the global defaults themselves were mutated;
tests/python/workspaces-do-not-share-defaults.pycovers that case as well.