Note: tracking issue — NOT implemented in PR #798 (won't-fix as a bug; optional hardening only).
Context
Architecture review ARC-7 (P2→P3, downgraded — not reproduced as a bug). _update_inplace swaps self._raster
via __dict__.update(new.__dict__) without flushing/closing the prior handle.
Problem / Current Behaviour
The feared "file stays locked on Windows" outcome does not occur: a probe showed a weakref to the old handle
becomes None and os.remove(old_file) succeeds immediately after the swap — CPython refcounting drops the last
reference and SWIG's finalizer calls GDALClose. Engines hold only a weakref.proxy to the Dataset, not the
raster. Nothing is broken today.
Affected locations
| File |
Symbol |
Notes |
src/pyramids/dataset/dataset.py |
_update_inplace |
prior _raster not explicitly flushed/closed |
Proposed Solution
Optional hardening only: capture prev = self._raster and prev.FlushCache() if prev is not src (matching the
explicit flush in ops/io.py _create_copy_and_reopen). Guards a future lingering reference / non-refcounting
interpreter.
Out of Scope
Any change premised on a current bug (there is none on CPython).
Effort Estimate
Size: S — but low value; kept as a tracked optional-hardening note.
Definition of Done
Note: tracking issue — NOT implemented in PR #798 (won't-fix as a bug; optional hardening only).
Context
Architecture review ARC-7 (P2→P3, downgraded — not reproduced as a bug).
_update_inplaceswapsself._rastervia
__dict__.update(new.__dict__)without flushing/closing the prior handle.Problem / Current Behaviour
The feared "file stays locked on Windows" outcome does not occur: a probe showed a
weakrefto the old handlebecomes
Noneandos.remove(old_file)succeeds immediately after the swap — CPython refcounting drops the lastreference and SWIG's finalizer calls
GDALClose. Engines hold only aweakref.proxyto theDataset, not theraster. Nothing is broken today.
Affected locations
src/pyramids/dataset/dataset.py_update_inplace_rasternot explicitly flushed/closedProposed Solution
Optional hardening only: capture
prev = self._rasterandprev.FlushCache()ifprev is not src(matching theexplicit flush in
ops/io.py_create_copy_and_reopen). Guards a future lingering reference / non-refcountinginterpreter.
Out of Scope
Any change premised on a current bug (there is none on CPython).
Effort Estimate
Size:
S— but low value; kept as a tracked optional-hardening note.Definition of Done
_update_inplaceflushes the prior handle when it differs from the incoming src