Skip to content

Consistent parameter validation in wrappers #4189

@seisman

Description

@seisman

In PyGMT wrappers, we typically need to validate parameters, for example, to ensure that required parameters are provided and that mutually exclusive parameters are not used together.

Currently, parameter validation is done inconsistently across wrappers. This is further complicated because most parameters are aliases of GMT’s single-letter options, especially after migrating to the new alias system.

  1. Check short-form parameters in kwargs directly. e.g.,

pygmt/pygmt/src/filter1d.py

Lines 114 to 116 in 4c7e356

if kwargs.get("F") is None:
msg = "Pass a required argument to 'filter_type'."
raise GMTInvalidInput(msg)

  • Pros: Early validation and simple.
  • Cons: Doesn’t work with the new alias system.
  1. Check long-form parameters directly, e.g.,

if projection is None:
msg = "The projection must be specified."
raise GMTInvalidInput(msg)

  • Pros: Simple and intuitive.
  • Cons: Doesn’t catch users passing short-form options like R="...".
  1. Check both long-form and short-form parameters in kwargs,e.g.,

if kwargs.get("I") is None or kwargs.get("R", region) is None:
msg = "Both 'region' and 'spacing' must be specified."
raise GMTInvalidInput(msg)

Here kwargs.get("R", region) checks both region and R.

Pros:

  • Covers both long- and short- forms
  • Works before initializing AliasSystem so early validation

Cons:

  • Slightly hard to read and sometimes we may forget to check both
  1. Check the aliasdict after initializing AliasSystem, e.g., aliasdict.get("r") in PR pygmt.grdsample: Add check and test for exclusive parameters 'toggle' and 'registration' #4183.

if toggle and aliasdict.get("r") is not None:
msg = "Parameters 'toggle' and 'registration' cannot be used together."
raise GMTInvalidInput(msg)

Pros:

  • Handles both long and short forms
  • Readale and no need to check the long-form explicitely

Cons

  • Must be done after initializing AliasSystem
  • Not all parameters are used in the Aliasystem, which means sometimes we still need to use option 2

I guess option 3 is better?

Metadata

Metadata

Assignees

No one assigned

    Labels

    maintenanceBoring but important stuff for the core devs

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions