One option would be to just look up the dimensionality for all contained units and take the first one that matches:
from pint.registry import UnitsContainer
def root_unit(dim):
uc = UnitsContainer({dim: 1})
return next(ureg.get_root_units(unit)[1] for unit in ureg if ureg.get_dimensionality(unit) == uc)
print(root_unit('[currency]')) # EUR
print(root_unit('[mass]')) # gram
Note also that units are mapped to dimensions in the underlying RegistryCache
, stored as ureg._cache
. So if you don't mind relying on private members, you can do the lookup there:
In [14]: [k for k, v in ureg._cache.dimensionality.items() if v == UnitsContainer({'[currency]': 1})]
Out[14]:
[<ParserHelper(1, {'EUR': 1})>,
<ParserHelper(1, {'USD': 1})>,
<ParserHelper(1, {'DKK': 1})>,
<ParserHelper(1, {'JPY': 1})>,
<ParserHelper(1, {'GBP': 1})>]
In particular, turning [currency]
into EUR
amounts to
def root_unit(dim):
uc = UnitsContainer({dim: 1})
return next(ureg.get_root_units(k)[1] for k, v in ureg._cache.dimensionality.items() if v == uc)
ureg._build_cache()
print(root_unit('[currency]')) # EUR
print(root_unit('[mass]')) # gram
This would all be a bit more straightforward if the dimensionality itself were a key in RegistryCache.root_units
but still, could be worse.
Note the necessary ureg._build_cache()
, though: The cache is built only before you load your definition. A priori, this is fair enough since it's up to UnitRegistry
itself how it wants to cache its lookup, and it shouldn't be a problem in practice since it only fails because you're loading your own definition, and once you're loading your own definition, well, you already have the information you're looking for in the definition itself!
However, there does seem to be a bug in this case, as the return values of exposed methods end up depending on the registry's internal state:
In [26]: ureg.get_compatible_units('EUR') # Fails
---------------------------------------------------------------------------
KeyError
In [27]: ureg._build_cache()
In [28]: ureg.get_compatible_units('EUR') # No longer fails
Out[28]: frozenset()