Skip to content

geotiff: write_vrt(nodata=True) silently writes 'True' string into VRT XML #1921

@brendancol

Description

@brendancol

write_vrt(nodata=True) writes <NoDataValue>True</NoDataValue> into the VRT XML, dropping the numeric sentinel the same way to_geotiff did before #1911. bool is a subclass of int, so the typo slips past the isinstance(nodata, (int, float)) guard and the XML emitter just calls str(True). No reader parses "True" as numeric, so the round-trip silently loses the nodata mask.

Reproduce:

import numpy as np, xarray as xr
from xrspatial.geotiff import to_geotiff, write_vrt
arr = xr.DataArray(np.zeros((4,4), dtype=np.uint8), dims=['y','x'])
to_geotiff(arr, '/tmp/src.tif')
write_vrt('/tmp/out.vrt', ['/tmp/src.tif'], nodata=True)
# VRT contains <NoDataValue>True</NoDataValue>

Fix: reject bool / np.bool_ at the write_vrt entry point (and inside the lower-level _vrt.write_vrt as defense in depth), matching the to_geotiff guard added in #1911. Suggested error: TypeError("nodata must be numeric (int or float), got {nodata!r}").

Also: write_geotiff_gpu direct call lacks an explicit top-of-function bool-nodata check. The behaviour is currently correct (build_geo_tags raises), but the rejection is defense-in-depth rather than entry-point parity. A future refactor that moves the build_geo_tags check could regress the GPU writer without anyone noticing.

Found by /sweep-test-coverage pass 15.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions