astropy / astropy/ccdproc

array-api-strict triage: escape-site mapping of the remaining test failures

Open
#941 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
93
Forks
92
Avg merge
14h 44m
Merged PRs (30d)
30

Description

### Context

The tooling from #937 and #939 is implemented on branch [`array-api-strict-triage-tooling`](https://github.com/mwcraig/ccdproc/tree/array-api-strict-triage-tooling) (mwcraig fork, commit 94ca9ec):

- `CCDPROC_ARRAY_LIBRARY=array-api-strict` test backend with fixture arrays placed on the non-default `Device("device1")`, so any implicit conversion to numpy raises — the same failure signal as CuPy's device-to-host error, with no GPU needed. Includes a `py313-strict` tox env and CI job.
- Escape-site dedupe report (`CCDPROC_TRIAGE_ESCAPES=1`): groups test failures by the innermost non-test ccdproc frame.
- `backend_xfail` / `backend_skip` markers applied per backend; documented limitations (astroscrappy, `scipy.ndimage.median_filter`, reproject, `block_reduce`/`block_replicate`) are now xfailed under array-api-strict.
- Escape logger (`CCDPROC_LOG_ARRAY_ESCAPES=1`): warns when `np.asarray`/`np.asanyarray`/`np.ma.asanyarray` receive a non-numpy array-API array, catching backends that convert silently (dask, JAX).

### Results

Full suite under `CCDPROC_ARRAY_LIBRARY=array-api-strict`: **139 failed / 192 passed / 5 skipped**. After marking documented limitations: **109 failed / 30 xfailed**. As predicted in #939, the dedupe report collapses the failures to about ten distinct escape sites.

### Escape-site → root-cause mapping

| Escape site | Failures | Root cause | Tracked in |
|---|---|---|---|
| `combiner.py:189` `Combiner.__init__` | 44 | Stacks per-image arrays by building a nested Array; array-api-strict rejects this ("Use stack instead"). Likely also the biggest CuPy failure source. | #965 |
| `_ccddata_wrapper_for_array_api.py:74` `_arithmetic_wrapper` | 11 | Device-mismatch / dtype coercion inside the CCDData arithmetic wrapper | possibly related to #927 |
| combiner scaling tests | ~9 | `Quantity` leaking into array-API arithmetic (`TypeError: Expected Array or Python scalar`) | #936 |
| `test_ccdproc.py:174` `test_subtract_overscan` | 6 | numpy-only `.copy()` method called on an Array (test-only) | #969 |
| `core.py:862` `subtract_dark` | 4 | ~~unit-mismatch/device issue~~ device-propagation bug (`xp.asarray(scale_factor)` on default device) masked as a bogus `UnitsError` by a broad `except` — units actually match | #966 |
| `core.py:611` `subtract_overscan` (via `ccd_process`) | 4 | median fallback doesn't handle namespaces without `median`/`allclose` | #906 |
| `core.py:1459` `rebin` | 4 | numpy-only `coordinates.astype("i")` method instead of `xp.astype(...)` | #967 |
| `core.py:459` `create_deviation` | 1 | bool-dtype handling in `__mul__` (`data * ~mask`) | #968 |
| `core.py:1233` `sigma_func` + gain/deviation singletons | ~4 | densification / device mismatch via `astropy.stats` | #929 |
| `test_ccdproc_logging.py:75` (+ `test_rebin.py:70`) | 1 | test-suite code using raw numpy (`np.zeros_like`) on foreign-device arrays; ~~an `ImageFileCollection` gap~~ (did not reproduce at d329ac5 — `test_image_collection.py` passes 77/77) | #970 (test-only) |

Xfailed as documented limitations (30 tests): astroscrappy (`cosmicray_lacosmic`, 21), `scipy.ndimage.median_filter` (`cosmicray_median`, 7 — overlaps #935), `reproject` (`wcs_project`, 4 — see #930/#940), `block_reduce`/`block_replicate` (3 — see #940).

### Suggested next steps

- ~~Decide whether the rows marked "no existing issue" get their own issues~~ Done (2026-08-01): each formerly-unissued row was re-verified at branch tip d329ac5 and filed as #965–#970. Verification corrected two rows, struck through above: the `subtract_dark` failure is a device bug, not a unit mismatch (#966), and the `ImageFileCollection` gap did not reproduce (#970 covers the remaining test-only `np.zeros_like` defect).
- Once `sparse` (#938) is wired up the same way, failures reproducing under both proxies can be treated as confirmed CuPy bugs per the #909 strategy.

---
Follow-up to #909, #937, #939. Counts from a 2026-07-06 run on the branch above.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Qri8rDgkWjCT7Yb7QKJrhf

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the array-api-strict tooling on the array-api-strict-triage-tooling branch and rerun the strict test suite. Inspect the listed escape sites in combiner.py, _ccddata_wrapper_for_array_api.py, core.py, and the named tests, then compare failures with issues #965–#970. Done means the remaining failures are mapped to confirmed root causes or tracked follow-up issues.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
testing, tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.