Skip to content

Parameter dependency rollback corrupts state and masks the original error #272

Description

@rozyczko

Findings V-H8, V-H7, V-M4, V-M3 in DEEP_ANALYSIS.md (parent #261).

The make_dependent_on happy path is sound; the error paths are not (src/easyscience/variable/parameter.py):

  • V-H8 (lines 365-369, 443-451, 928-946): when _process_dependency_unique_names fails, _revert_dependency(skip_detach=True) calls make_independent(), which ignores skip_detach, detaches observers never attached (ValueError: list.remove(x)), and del self._clean_dependency_string on an attribute never set (AttributeError). The user's real error is replaced by an internal crash and the parameter is left half-dependent (_independent already False, _dependency_map partially populated).
  • V-H7 (lines 336-339, 414-422, 236-237): desired_unit as sc.Unit passes validation but _convert_unit hard-requires str (descriptor_number.py:377-378); the TypeError is rebranded as a misleading UnitError (or propagates uncaught from _update()). A documented, validated input type always fails.
  • V-M4 (lines 412-422): _fixed is clobbered before failure points and never restored — a fixed=True parameter comes out of a failed call unfixed; on the bare-name path the shared dependency object is left unit-converted.
  • V-M3 (lines 335, 979): the caller's dependency_map dict is stored by reference and silently mutated with injected __UniqueName__ keys.

Fix pattern: validate and compute into temporaries, commit only at the end; snapshot (_fixed, _dependency_map, observer attachments) and restore exactly that snapshot on failure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions