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.
Findings V-H8, V-H7, V-M4, V-M3 in DEEP_ANALYSIS.md (parent #261).
The
make_dependent_onhappy path is sound; the error paths are not (src/easyscience/variable/parameter.py):_process_dependency_unique_namesfails,_revert_dependency(skip_detach=True)callsmake_independent(), which ignoresskip_detach, detaches observers never attached (ValueError: list.remove(x)), anddel self._clean_dependency_stringon an attribute never set (AttributeError). The user's real error is replaced by an internal crash and the parameter is left half-dependent (_independentalready False,_dependency_mappartially populated).desired_unitassc.Unitpasses validation but_convert_unithard-requiresstr(descriptor_number.py:377-378); theTypeErroris rebranded as a misleadingUnitError(or propagates uncaught from_update()). A documented, validated input type always fails._fixedis clobbered before failure points and never restored — afixed=Trueparameter comes out of a failed call unfixed; on the bare-name path the shared dependency object is left unit-converted.dependency_mapdict 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.