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:

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

@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:

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

@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:

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

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

Allow return values to have equivalent units:

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

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

Allow equivalent units to pass with specified equivalencies:

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

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