validate_quantities

plasmapy.utils.decorators.validators.validate_quantities(func=None, validations_on_return=None, **validations)[source]

A decorator to β€˜validate’ β€” control and convert β€” the units and values of input and return arguments to a function or method. Arguments are expected to be astropy Quantity objects.

Parameters:
  • func – The function to be decorated

  • validations_on_return (dictionary of validation specifications) – Specifications for unit and value validations on the return of the function being wrapped. (see quantity validations for valid specifications.

  • **validations (dictionary of validation specifications) –

    Specifications for unit and value validations on the input arguments of the function being wrapped. Each keyword argument in validations is the name of a function argument to be validated and the keyword value contains the unit and value validation specifications.

    Unit and value validations can be defined by passing one of the astropy units, a list of astropy units, or a dictionary containing the keys defined below. Units can also be defined with function annotations, but must be consistent with decorator **validations arguments if used concurrently. If a key is omitted, then the default value will be assumed.

    Key

    Type

    Description

    units

    list of desired astropy units

    equivalencies

    [DEFAULT None] A list of equivalent pairs to try if
    the units are not directly convertible.

    pass_equivalent_units

    bool

    [DEFAULT False] allow equivalent units
    to pass

    can_be_negative

    bool

    [DEFAULT True] values can be negative

    can_be_complex

    bool

    [DEFAULT False] values can be complex numbers

    can_be_inf

    bool

    [DEFAULT True] values can be inf

    can_be_nan

    bool

    [DEFAULT True] values can be nan

    none_shall_pass

    bool

    [DEFAULT False] values can be a python None

    can_be_zero

    bool

    [DEFAULT True] values can be zero

Notes

  • Validation of function arguments *args and **kwargs is not supported.

  • None values will pass when None is included in the list of specified units, is set as a default value for the function argument, or none_shall_pass is set to True. If none_shall_pass is doubly/triply defined through the mentioned options, then they all must be consistent with each other.

  • If units are not specified in validations, then the decorator will attempt to identify desired units by examining the function annotations.

  • Full functionality is defined by the class ValidateQuantities.

Examples

Define unit and value validations with decorator parameters:

import astropy.units as u
from plasmapy.utils.decorators import validate_quantities

@validate_quantities(
    mass={"units": u.g, "can_be_negative": False},
    vel=u.cm / u.s,
    validations_on_return=[u.g * u.cm / u.s, u.kg * u.m / u.s],
)
def foo(mass, vel):
    return mass * vel


# on a method
class Foo:
    @validate_quantities(
        mass={"units": u.g, "can_be_negative": False},
        vel=u.cm / u.s,
        validations_on_return=[u.g * u.cm / u.s, u.kg * u.m / u.s],
    )
    def bar(self, mass, vel):
        return mass * vel

Define units with function annotations:

@validate_quantities(mass={"can_be_negative": False})
def foo(mass: u.g, vel: u.cm / u.s) -> u.g * u.cm / u.s:
    return mass * vel


# rely only on annotations
@validate_quantities
def foo(x: u.cm, time: u.s) -> u.cm / u.s:
    return x / time


# on a method
class Foo:
    @validate_quantities(mass={"can_be_negative": False})
    def bar(self, mass: u.g, vel: u.cm / u.s) -> u.g * u.cm / u.s:
        return mass * vel

Define units using type hint annotations:

@validate_quantities
def foo(x: u.Quantity[u.m], time: u.Quantity[u.s]) -> u.Quantity[u.m / u.s]:
    return x / time

Allow None values to pass:

@validate_quantities(
    arg2={"none_shall_pass": True}, validations_on_return=[u.cm, None]
)
def foo(arg1: u.cm, arg2: u.cm = None):
    return None

Allow return values to have equivalent units:

@validate_quantities(
    arg1={"units": u.cm},
    validations_on_return={"units": u.km, "pass_equivalent_units": True},
)
def foo(arg1):
    return arg1

Allow equivalent units to pass with specified equivalencies:

@validate_quantities(
    arg1={
        "units": u.K,
        "equivalencies": u.temperature(),
        "pass_equivalent_units": True,
    }
)
def foo(arg1):
    return arg1