Skip to content

contours(): n_levels has no validation contract #2895

@brendancol

Description

@brendancol

Describe the bug

contours() doesn't validate its n_levels parameter. The value is only used on the auto-level branch (when levels isn't passed), at xrspatial/contour.py:659:

levels = np.linspace(vmin, vmax, n_levels + 2)[1:-1]

Two things go wrong:

  • n_levels=0 or n_levels=-1 silently returns no contours. np.linspace(vmin, vmax, 2)[1:-1] and np.linspace(vmin, vmax, 1)[1:-1] give back an empty or degenerate level set, so the caller gets an empty result with no hint that the argument was bad.
  • n_levels=2.5 (or any non-integer) raises a raw TypeError from inside numpy ('float' object cannot be interpreted as an integer), which leaks an implementation detail instead of pointing at the parameter.

Expected behavior

n_levels should have an explicit contract: an integer >= 1. Invalid values raise a clear error up front:

  • non-integer (e.g. 2.5, or a bool) -> TypeError that names n_levels
  • integer < 1 (e.g. 0, -1) -> ValueError that names n_levels

Since n_levels is ignored when explicit levels are supplied, the check should only fire on the auto-level branch, so contours(agg, levels=[...], n_levels=0) isn't rejected for no reason.

Additional context

Convention in the codebase: TypeError for wrong type, ValueError for out-of-range. See landforms (inner_radius must be >= 1) in terrain_metrics.py and max_iterations must be >= 1 in balanced_allocation.py.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginput-validationInput validation and error messages

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions