unyt/dimensions.py
def accepts(**arg_units):
    def check_accepts(f):
        def new_f(*args, **kwargs):
def returns(r_unit):
    def check_returns(f):
        def new_f(*args, **kwargs):
def _has_dimensions(quant, dim):
unyt/testing.py
def assert_allclose_units(actual, desired, rtol=1e-7, atol=0, **kwargs):
    """Raise an error if two objects are not equal up to desired tolerance

    This is a wrapper for :func:`numpy.testing.assert_allclose` that also
    verifies unit consistency

    Parameters
    ----------
    actual : array-like
        Array obtained (possibly with attached units)
    desired : array-like
        Array to compare with (possibly with attached units)
    rtol : float, optional
        Relative tolerance, defaults to 1e-7
    atol : float or quantity, optional
        Absolute tolerance. If units are attached, they must be consistent
        with the units of ``actual`` and ``desired``. If no units are attached,
        assumes the same units as ``desired``. Defaults to zero.

    See Also
    --------
    :func:`unyt.array.allclose_units`

    Notes
    -----
    Also accepts additional keyword arguments accepted by
    :func:`numpy.testing.assert_allclose`, see the documentation of that
    function for details.

    Examples
    --------
    >>> import unyt as u
    >>> actual = [1e-5, 1e-3, 1e-1]*u.m
    >>> desired = actual.to("cm")
    >>> assert_allclose_units(actual, desired)
    """
    if not allclose_units(actual, desired, rtol, atol, **kwargs):
        raise AssertionError
unyt/exceptions.py
class UnitConversionError(Exception):
    """An error raised when converting to a unit with different dimensions.

    Example
    -------

    >>> import unyt as u
    >>> data = 3*u.g
    >>> data.to('m')  # doctest: +IGNORE_EXCEPTION_DETAIL +NORMALIZE_WHITESPACE
    Traceback (most recent call last):
    ...
    unyt.exceptions.UnitConversionError: Cannot convert between 'g'
    (dim '(mass)') and 'm' (dim '(length)').
    """

    def __init__(self, unit1, dimension1, unit2, dimension2):
        self.unit1 = unit1
        self.unit2 = unit2
        self.dimension1 = dimension1
        self.dimension2 = dimension2
        Exception.__init__(self)

    def __str__(self):
        err = "Cannot convert between '%s' (dim '%s') and '%s' " "(dim '%s')." % (
            self.unit1,
            self.dimension1,
            self.unit2,
            self.dimension2,
        )
        return err
unyt/_unit_lookup_table.py
def generate_name_alternatives():
    def append_name(n, okey, key):
unyt/exceptions.py
class UnitsNotReducible(Exception):
    """Raised when a unit cannot be safely represented in a unit system

    Example
    -------

    >>> from unyt import A, cm
    >>> data = 12*A/cm
    >>> data.in_cgs()\
  # doctest: +IGNORE_EXCEPTION_DETAIL +NORMALIZE_WHITESPACE
    Traceback (most recent call last):
    ...
    unyt.exceptions.UnitsNotReducible: The unit "A/cm" (dimensions
    "(current_mks)/(length)") cannot be reduced to an expression
    within the cgs system of units.
    """

    def __init__(self, unit, units_base):
        self.unit = unit
        self.units_base = units_base
        Exception.__init__(self)

    def __str__(self):
        err = (
            'The unit "%s" (dimensions "%s") cannot be reduced to an '
            "expression within the %s system of units."
            % (self.unit, self.unit.dimensions, self.units_base)
        )
        return err
unyt/unit_registry.py
class UnitRegistry:
    """A registry for unit symbols"""

    _unit_system_id = None

    def __init__(self, add_default_symbols=True, lut=None, unit_system=None):
        self._unit_object_cache = {}
        if lut:
            self.lut = lut
        else:
            self.lut = {}

        self.unit_system = _sanitize_unit_system(unit_system, None)

        if add_default_symbols:
            self.lut.update(default_unit_symbol_lut)

    def __getitem__(self, key):
        try:
            ret = self.lut[str(key)]
        except KeyError:
            try:
                _lookup_unit_symbol(str(key), self.lut)
                ret = self.lut[str(key)]
            except UnitParseError:
                raise SymbolNotFoundError(
                    "The symbol '%s' does not exist in this registry." % key
                )
        return ret

    def __contains__(self, item):
        if str(item) in self.lut:
            return True
        try:
            _lookup_unit_symbol(str(item), self.lut)
            return True
        except UnitParseError:
            return False

    @property
    def unit_system_id(self):
        """
        This is a unique identifier for the unit registry created
        from a FNV hash. It is needed to register a dataset's code
        unit system in the unit system registry.
        """
        if self._unit_system_id is None:
            hash_data = bytearray()
            for k, v in sorted(self.lut.items()):
                hash_data.extend(k.encode("utf8"))
                hash_data.extend(repr(v).encode("utf8"))
            m = md5()
            m.update(hash_data)
            self._unit_system_id = str(m.hexdigest())
        return self._unit_system_id

    @property
    def prefixable_units(self):
        return [u for u in self.lut if self.lut[u][4]]

    def add(
        self,
        symbol,
        base_value,
        dimensions,
        tex_repr=None,
        offset=None,
        prefixable=False,
    ):
        """
        Add a symbol to this registry.

        Parameters
        ----------

        symbol : str
           The name of the unit
        base_value : float
           The scaling from the units value to the equivalent SI unit
           with the same dimensions
        dimensions : expr
           The dimensions of the unit
        tex_repr : str, optional
           The LaTeX representation of the unit. If not provided a LaTeX
           representation is automatically generated from the name of
           the unit.
        offset : float, optional
           If set, the zero-point offset to apply to the unit to convert
           to SI. This is mostly used for units like Farhenheit and
           Celcius that are not defined on an absolute scale.
        prefixable : bool
           If True, then SI-prefix versions of the unit will be created
           along with the unit itself.

        """
        from unyt.unit_object import _validate_dimensions

        self._unit_system_id = None

        # Validate
        if not isinstance(base_value, float):
            raise UnitParseError(
                "base_value (%s) must be a float, got a %s."
                % (base_value, type(base_value))
            )

        if offset is not None:
            if not isinstance(offset, float):
                raise UnitParseError(
                    "offset value (%s) must be a float, got a %s."
                    % (offset, type(offset))
                )
        else:
            offset = 0.0

        _validate_dimensions(dimensions)

        if tex_repr is None:
            # make educated guess that will look nice in most cases
            tex_repr = r"\rm{" + symbol.replace("_", r"\ ") + "}"

        # Add to lut
        self.lut[symbol] = (base_value, dimensions, offset, tex_repr, prefixable)

    def remove(self, symbol):
        """
        Remove the entry for the unit matching `symbol`.

        Parameters
        ----------

        symbol : str
           The name of the unit symbol to remove from the registry.

        """
        self._unit_system_id = None

        if symbol not in self.lut:
            raise SymbolNotFoundError(
                "Tried to remove the symbol '%s', but it does not exist "
                "in this registry." % symbol
            )

        del self.lut[symbol]

    def modify(self, symbol, base_value):
        """
        Change the base value of a unit symbol.  Useful for adjusting code
        units after parsing parameters.

        Parameters
        ----------

        symbol : str
           The name of the symbol to modify
        base_value : float
           The new base_value for the symbol.

        """
        self._unit_system_id = None

        if symbol not in self.lut:
            raise SymbolNotFoundError(
                "Tried to modify the symbol '%s', but it does not exist "
                "in this registry." % symbol
            )

        if hasattr(base_value, "in_base"):
            new_dimensions = base_value.units.dimensions
            base_value = base_value.in_base("mks")
            base_value = base_value.value
        else:
            new_dimensions = self.lut[symbol][1]

        self.lut[symbol] = (float(base_value), new_dimensions) + self.lut[symbol][2:]

    def keys(self):
        """
        Print out the units contained in the lookup table.

        """
        return self.lut.keys()

    def to_json(self):
        """
        Returns a json-serialized version of the unit registry
        """
        sanitized_lut = {}
        for k, v in self.lut.items():
            san_v = list(v)
            repr_dims = str(v[1])
            san_v[1] = repr_dims
            sanitized_lut[k] = tuple(san_v)

        return json.dumps(sanitized_lut)

    @classmethod
    def from_json(cls, json_text):
        """
        Returns a UnitRegistry object from a json-serialized unit registry

        Parameters
        ----------

        json_text : str
           A string containing a json represention of a UnitRegistry
        """
        data = json.loads(json_text)
        lut = _correct_old_unit_registry(data, sympify=True)
        return cls(lut=lut, add_default_symbols=False)

    def list_same_dimensions(self, unit_object):
        """
        Return a list of base unit names that this registry knows about that
        are of equivalent dimensions to *unit_object*.
        """
        equiv = [k for k, v in self.lut.items() if v[1] is unit_object.dimensions]
        equiv = list(sorted(set(equiv)))
        return equiv
unyt/unit_systems.py
def add_symbols(namespace, registry):
def add_constants(namespace, registry):
def _split_prefix(symbol_str, unit_symbol_lut):
def _get_system_unit_string(dims, base_units):
    def __init__(
        self,
        name,
        length_unit,
        mass_unit,
        time_unit,
        temperature_unit="K",
        angle_unit="rad",
        current_mks_unit="A",
        luminous_intensity_unit="cd",
        logarithmic_unit="Np",
        registry=None,
    ):
    def __getitem__(self, key):
    def __setitem__(self, key, value):
    def __str__(self):
    def __repr__(self):
    def has_current_mks(self):
class UnitSystem(object):
unyt/exceptions.py
class InvalidUnitOperation(Exception):
    """Raised when an operation on a unit object is not allowed

    Example
    -------

    >>> from unyt import cm, g
    >>> cm + g  # doctest: +IGNORE_EXCEPTION_DETAIL +NORMALIZE_WHITESPACE
    Traceback (most recent call last):
    ...
    unyt.exceptions.InvalidUnitOperation: addition with unit objects
    is not allowed
    """

    pass
unyt/_physical_ratios.py
HUGE = 1.0e90
TINY = 1.0e-40
unyt/unit_object.py
def _get_latex_representation(expr, registry):
    def __init__(self):
    def ua(self):
    def uq(self):
    def __new__(
        cls,
        unit_expr=sympy_one,
        base_value=None,
        base_offset=0.0,
        dimensions=None,
        registry=None,
        latex_repr=None,
    ):
    def latex_repr(self):
    def units(self):
    def __hash__(self):
    def __repr__(self):
    def __str__(self):
    def __add__(self, u):
    def __radd__(self, u):
    def __sub__(self, u):
    def __rsub__(self, u):
    def __iadd__(self, u):
    def __isub__(self, u):
    def __imul__(self, u):
    def __itruediv__(self, u):
    def __rmul__(self, u):
    def __mul__(self, u):
    def __truediv__(self, u):
    def __rtruediv__(self, u):
    def __pow__(self, p):
    def __eq__(self, u):
    def __ne__(self, u):
    def copy(self):
    def __deepcopy__(self, memodict=None):
    def same_dimensions_as(self, other_unit):
    def is_dimensionless(self):
    def is_code_unit(self):
    def list_equivalencies(self):
    def has_equivalent(self, equiv):
    def get_base_equivalent(self, unit_system=None):
    def get_cgs_equivalent(self):
    def get_mks_equivalent(self):
    def get_conversion_factor(self, other_units, dtype=None):
    def latex_representation(self):
    def as_coeff_unit(self):
    def simplify(self):
def _factor_pairs(expr):
def _create_unit_from_factor(factor, registry):
def _cancel_mul(expr, registry):
def _em_conversion(orig_units, conv_data, to_units=None, unit_system=None):
def _check_em_conversion(unit, to_unit=None, unit_system=None, registry=None):
def _get_conversion_factor(old_units, new_units, dtype):
def _get_unit_data_from_expr(unit_expr, unit_symbol_lut):
def _validate_dimensions(dimensions):
def define_unit(
    symbol, value, tex_repr=None, offset=None, prefixable=False, registry=None
):
class _ImportCache(object):
class Unit(object):
NULL_UNIT = Unit()
unyt/array.py
class unyt_quantity(unyt_array):
    """
    A scalar associated with a unit.

    Parameters
    ----------

    input_scalar : an integer or floating point scalar
        The scalar to attach units to
    input_units : String unit specification, unit symbol object, or astropy
                  units
        The units of the quantity. Powers must be specified using python syntax
        (cm**3, not cm^3).
    registry : A UnitRegistry object
        The registry to create units from. If input_units is already associated
        with a unit registry and this is specified, this will be used instead
        of the registry associated with the unit object.
    dtype : data-type
        The dtype of the array data.
    name : string
        The name of the scalar. Defaults to None. This attribute does not propagate
        through mathematical operations, but is preserved under indexing
        and unit conversions.

    Examples
    --------

    >>> a = unyt_quantity(3., 'cm')
    >>> b = unyt_quantity(2., 'm')
    >>> print(a + b)
    203.0 cm
    >>> print(b + a)
    2.03 m

    NumPy ufuncs will pass through units where appropriate.

    >>> import numpy as np
    >>> from unyt import g, cm
    >>> a = 12*g/cm**3
    >>> print(np.abs(a))
    12 g/cm**3

    and strip them when it would be annoying to deal with them.

    >>> print(np.log10(a))
    1.0791812460476249

    """

    def __new__(
        cls,
        input_scalar,
        units=None,
        registry=None,
        dtype=None,
        bypass_validation=False,
        input_units=None,
        name=None,
    ):
        if input_units is not None:
            warnings.warn(
                "input_units has been deprecated, please use units instead",
                DeprecationWarning,
                stacklevel=2,
            )
        if units is not None:
            input_units = units
        if not (
            bypass_validation
            or isinstance(input_scalar, (numeric_type, np.number, np.ndarray))
        ):
            raise RuntimeError("unyt_quantity values must be numeric")
        if input_units is None:
            units = getattr(input_scalar, "units", None)
        else:
            units = input_units
        ret = unyt_array.__new__(
            cls,
            np.asarray(input_scalar),
            units,
            registry,
            dtype=dtype,
            bypass_validation=bypass_validation,
            name=name,
        )
        if ret.size > 1:
            raise RuntimeError("unyt_quantity instances must be scalars")
        return ret

    def __round__(self):
        return type(self)(round(float(self)), self.units)


Question: import numpy as np
import operator
import pickle
import pytest
import unyt.unit_symbols as unit_symbols
    import unyt as u
    import unyt as u
    import unyt
    import unyt
from numpy.testing import (
    assert_almost_equal,
    assert_allclose,
    assert_array_almost_equal_nulp,
    assert_equal,
)
from sympy import Symbol
from unyt.array import unyt_quantity
from unyt.testing import assert_allclose_units
from unyt.unit_registry import UnitRegistry
from unyt.dimensions import (
    mass,
    length,
    time,
    temperature,
    energy,
    magnetic_field_cgs,
    magnetic_field_mks,
    power,
    rate,
)
from unyt.exceptions import InvalidUnitOperation, UnitsNotReducible, UnitConversionError
from unyt.unit_object import default_unit_registry, Unit, UnitParseError
from unyt.unit_systems import cgs_unit_system, UnitSystem
from unyt._unit_lookup_table import (
    default_unit_symbol_lut,
    name_alternatives,
    unit_prefixes,
)
from unyt._physical_ratios import (
    m_per_pc,
    sec_per_year,
    m_per_km,
    m_per_mpc,
    mass_sun_kg,
)
    from sympy import nsimplify
    from unyt import dimensionless
    from unyt import electrostatic_unit, elementary_charge_cgs
    from unyt import m
    from unyt import degF, dimensionless
    from unyt import UnitRegistry
    from unyt import cm
    from unyt import A, cm
    from unyt._unit_lookup_table import (
        default_unit_name_alternatives,
        name_alternatives,
        inv_name_alternatives,
    )
    from unyt import Unit
    from unyt import Unit, attosecond, second
    from unyt import Unit
# -*- coding: utf-8 -*-
"""
Test symbolic unit handling.




"""

# -----------------------------------------------------------------------------
# Copyright (c) 2018, yt Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the LICENSE file, distributed with this software.
# -----------------------------------------------------------------------------





def test_no_conflicting_symbols():
    """
    Check unit symbol definitions for conflicts.

    """
    full_set = set(default_unit_symbol_lut.keys())

    # go through all possible prefix combos
    for symbol in default_unit_symbol_lut.keys():
        if default_unit_symbol_lut[symbol][4]:
            keys = unit_prefixes.keys()
        else:
            keys = [symbol]
        for prefix in keys:
            new_symbol = "%s%s" % (prefix, symbol)

            # test if we have seen this symbol
            assert new_symbol not in full_set, "Duplicate symbol: %s" % new_symbol

            full_set.add(new_symbol)


def test_dimensionless():
    """
    Create dimensionless unit and check attributes.

    """
    u1 = Unit()

    assert u1.is_dimensionless
    assert u1.expr == 1
    assert u1.base_value == 1
    assert u1.dimensions == 1
    assert u1 != "hello!"
    assert (u1 == "hello") is False

    u2 = Unit("")

    assert u2.is_dimensionless
    assert u2.expr == 1
    assert u2.base_value == 1
    assert u2.dimensions == 1

    assert_equal(u1.latex_repr, "")
    assert_equal(u2.latex_repr, "")


def test_create_from_string():
    """
    Create units with strings and check attributes.

    """

    u1 = Unit("kg * m**2 * s**-2")
    assert u1.dimensions == energy
    assert u1.base_value == 1.0

    # make sure order doesn't matter
    u2 = Unit("m**2 * s**-2 * kg")
    assert u2.dimensions == energy
    assert u2.base_value == 1.0

    # Test rationals
    u3 = Unit("kg**0.5 * m**-0.5 * s**-1")
    assert u3.dimensions == magnetic_field_cgs
    assert u3.base_value == 1.0

    # sqrt functions
    u4 = Unit("sqrt(kg)/sqrt(m)/s")
    assert u4.dimensions == magnetic_field_cgs
    assert u4.base_value == 1.0

    # commutative sqrt function
    u5 = Unit("sqrt(kg/m)/s")
    assert u5.dimensions == magnetic_field_cgs
    assert u5.base_value == 1.0

    # nonzero CGS conversion factor
    u6 = Unit("Msun/pc**3")

Answer:     assert u6.dimensions == mass / length ** 3