subtract_dark(..., scale=True) fails under CCDPROC_ARRAY_LIBRARY=array-api-strict with a UnitsError, but the units involved are identical ('adu' == 'adu') — the message is misleading. 4/9 parametrized cases in test_subtract_dark fail: exactly the four with scale=True (explicit_times/exposure_keyword don't matter).
FAILED test_subtract_dark[True-True-True]
FAILED test_subtract_dark[True-True-False]
FAILED test_subtract_dark[True-False-True]
FAILED test_subtract_dark[True-False-False]
E astropy.units.errors.UnitsError: Unit 'adu' of the uncalibrated image
does not match unit 'adu' of the calibration image
ccdproc/core.py:862: UnitsError
Root cause (note: the #941 table called this a "unit-mismatch/device issue" — the unit-mismatch half is wrong; it is purely a device-propagation bug). In ccdproc/core.py:855 (branch array-api-strict-triage-tooling), the scale-factor array is built without a device argument:
_master_scaled = _master_scaled.multiply(xp.asarray(scale_factor))
The test harness places fixture arrays on non-default device1 (see ccdproc/conftest.py), but xp.asarray(scale_factor) defaults to CPU_DEVICE. The elementwise multiply then raises:
ValueError: Arrays from two different devices (array_api_strict.Device('device1')
and array_api_strict.Device('CPU_DEVICE')) can not be combined.
The broad except (u.UnitsError, u.UnitConversionError, ValueError) at core.py:859 swallows that ValueError and re-raises it as a bogus UnitsError about non-matching units, masking the real problem. This is the same class of bug a CuPy user would hit as a device-to-host error.
Suggested fix: construct the scale-factor array on the same device as the data (e.g. pass device= from the master's array), and narrow the blanket ValueError catch at core.py:859 so genuine non-unit failures aren't relabeled as unit errors.
Part of the array-API triage in #941; found with the array-api-strict tooling from #937/#939. Verified at branch tip d329ac5 (2026-08-01); the true underlying exception was confirmed by reproducing the scale=True path directly, bypassing the catch-all.
🤖 Generated with Claude Code
subtract_dark(..., scale=True)fails underCCDPROC_ARRAY_LIBRARY=array-api-strictwith aUnitsError, but the units involved are identical ('adu' == 'adu') — the message is misleading. 4/9 parametrized cases intest_subtract_darkfail: exactly the four withscale=True(explicit_times/exposure_keyworddon't matter).Root cause (note: the #941 table called this a "unit-mismatch/device issue" — the unit-mismatch half is wrong; it is purely a device-propagation bug). In
ccdproc/core.py:855(brancharray-api-strict-triage-tooling), the scale-factor array is built without a device argument:The test harness places fixture arrays on non-default
device1(seeccdproc/conftest.py), butxp.asarray(scale_factor)defaults toCPU_DEVICE. The elementwise multiply then raises:The broad
except (u.UnitsError, u.UnitConversionError, ValueError)atcore.py:859swallows thatValueErrorand re-raises it as a bogusUnitsErrorabout non-matching units, masking the real problem. This is the same class of bug a CuPy user would hit as a device-to-host error.Suggested fix: construct the scale-factor array on the same device as the data (e.g. pass
device=from the master's array), and narrow the blanketValueErrorcatch atcore.py:859so genuine non-unit failures aren't relabeled as unit errors.Part of the array-API triage in #941; found with the array-api-strict tooling from #937/#939. Verified at branch tip d329ac5 (2026-08-01); the true underlying exception was confirmed by reproducing the
scale=Truepath directly, bypassing the catch-all.🤖 Generated with Claude Code