from brian2 import check_units)
Decorator to check units of arguments passed to a function
- In case the input arguments or the return value do not have the expected dimensions.
- If an input argument or return value was expected to be a boolean but is not.
This decorator will destroy the signature of the original function, and replace it with the signature
(*args, **kwds). Other decorators will do the same thing, and this decorator critically needs to know the signature of the function it is acting on, so it is important that it is the first decorator to act on a function. It cannot be used in combination with another decorator that also needs to know the signature of the function.
Note that the
booltype is “strict”, i.e. it expects a proper boolean value and does not accept 0 or 1. This is not the case the other way round, declaring an argument or return value as “1” does allow for a
>>> from brian2.units import * >>> @check_units(I=amp, R=ohm, wibble=metre, result=volt) ... def getvoltage(I, R, **k): ... return I*R
You don’t have to check the units of every variable in the function, and you can define what the units should be for variables that aren’t explicitly named in the definition of the function. For example, the code above checks that the variable wibble should be a length, so writing
>>> getvoltage(1*amp, 1*ohm, wibble=1) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... DimensionMismatchError: Function "getvoltage" variable "wibble" has wrong dimensions, dimensions were (1) (m)
>>> getvoltage(1*amp, 1*ohm, wibble=1*metre) 1. * volt
passes. String arguments or
Noneare not checked
>>> getvoltage(1*amp, 1*ohm, wibble='hello') 1. * volt
By using the special name
result, you can check the return value of the function.
You can also use
boolas a special value to check for a unitless number or a boolean value, respectively: >>> @check_units(value=1, absolute=bool, result=bool) … def is_high(value, absolute=False): … if absolute: … return abs(value) >= 5 … else: … return value >= 5
This will then again raise an error if the argument if not of the expected type: >>> is_high(7) True >>> is_high(-7, True) True >>> is_high(3, 4) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): … TypeError: Function “is_high” expected a boolean value for argument “absolute” but got 4.