Skip to content

空间热路径四处静默错误:整数栅格掩膜失效 / apply_raster 无 else / mask 缓存不失效 / apply_agents 吞异常成 NaN #153

Description

@SongshGeo

空间模块的热路径上有四处「不报错但结果是错的」,都会把错误伪装成合法数据。按危害排序:


1. 整数栅格的掩膜从未生效

abses/utils/func.pyset_null_values 对整数数组重绑定局部变量

if arr.dtype.kind in {"f", "i"}:
    if arr.dtype.kind == "i":
        arr = arr.astype(float, copy=True)   # ← 之后的写入落在副本上
    null_value = np.nan
...
arr[mask] = null_value
return arr

abses/space/patch.py_add_attribute 丢弃返回值

if apply_mask:
    set_null_values(data, ~self.mask)        # ← 返回值无人接收

结果:float / str 数组按预期被掩膜,int 数组完全没有被掩膜,掩膜区的原始整数值被当作有效数据写进格子。同一个函数对不同 dtype 一会儿原地改、一会儿返副本,是这个 bug 的根。

建议set_null_values 统一为「返回新数组」的纯函数语义,调用点改为 data = set_null_values(data, ~self.mask)


2. apply_raster 遇到不支持的输入静默返回 None

abses/space/patch.py 的类型分派没有 else

if isinstance(data, np.ndarray):
    ...
elif isinstance(data, xr.DataArray):
    ...
elif isinstance(data, xr.Dataset):
    ...
# 没有 else

module.apply_raster([1, 2, 3], attr_name="x") 返回 None、不加属性、不报错。

建议:补 else: raise TypeError(...)


3. mask setter 不清 cells_lst 的缓存

@functools.cached_property
def cells_lst(self): return ActorsList(self.model, self.array_cells[self.mask])

@mask.setter
def mask(self, array): self._mask = array.astype(bool)   # ← 没有失效缓存

一旦 cells_lst / agents / random / select({...}) 中任何一个先被读过,之后再赋值 module.mask 就被静默忽略;而 xda 读的是实时 mask,于是同一个对象的两个视图会给出互相矛盾的结果

建议:setter 里 self.__dict__.pop("cells_lst", None)


4. apply_agents 把所有用户异常转成 NaN

abses/space/patch.pyapply_agents 里有四个 except Exception,其中 _to_float 连日志都不打:

def _to_float(val):
    try:
        return float(val)
    except Exception:
        return float("nan")     # 静默

因为跑在 np.vectorize 里逐格子执行,一个写坏的 aggregator 会:

  • 刷出与格子数同量级的 warning(大栅格可达 10^6 行);
  • 返回一个看起来完全合法的全 NaN 数组。

建议:改为累计失败计数、只发一条聚合 warning(附第一条 traceback),并让非用户错误(MemoryError、拼写导致的 AttributeError 等)正常向上抛。


验收标准

  • 整数栅格 apply_raster(int_array, apply_mask=True) 后,掩膜区的格子属性为 NaN。
  • apply_raster 传入不支持的类型时抛 TypeError
  • 读过 cells_lst 之后再改 maskcells_lstxda 保持一致。
  • apply_agents 的 aggregator 抛异常时,warning 条数不随栅格大小增长。
  • 以上四条各有回归测试。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions