Changed Systems and Groups to be aware of the Registry in which they are.
Additionally used SourceIterator and improved error reporting
This commit is contained in:
194
pint/systems.py
194
pint/systems.py
@@ -13,35 +13,42 @@ from __future__ import division, unicode_literals, print_function, absolute_impo
|
||||
|
||||
import re
|
||||
|
||||
from .unit import Definition, UnitDefinition, DefinitionSyntaxError
|
||||
from .util import to_units_container, UnitsContainer
|
||||
from .unit import Definition, UnitDefinition, DefinitionSyntaxError, RedefinitionError
|
||||
from .util import to_units_container, SharedRegistryObject, SourceIterator
|
||||
|
||||
|
||||
class Group(object):
|
||||
"""A group is a list of units.
|
||||
class _Group(SharedRegistryObject):
|
||||
"""A group is a set of units.
|
||||
|
||||
Units can be added directly or by including other groups.
|
||||
|
||||
Members are computed dynamically, that is if a unit is added to a group X
|
||||
all groups that include X are affected.
|
||||
|
||||
The group belongs to one Registry.
|
||||
|
||||
It can be specified in the definition file as:
|
||||
|
||||
@group <name> [using <group 1>, ..., <group N>]
|
||||
<definition 1>
|
||||
...
|
||||
<definition N>
|
||||
@end
|
||||
|
||||
"""
|
||||
|
||||
#: Regex to match the header parts of a context.
|
||||
#: Regex to match the header parts of a definition.
|
||||
_header_re = re.compile('@group\s+(?P<name>\w+)\s*(using\s(?P<used_groups>.*))*')
|
||||
|
||||
def __init__(self, name, groups_systems):
|
||||
def __init__(self, name):
|
||||
"""
|
||||
:param name: Name of the group
|
||||
:param name: Name of the group. If not given, a root Group will be created.
|
||||
:type name: str
|
||||
:param groups_systems: dictionary containing groups and system.
|
||||
The newly created group will be added after creation.
|
||||
:type groups_systems: dict[str, Group | System]
|
||||
:param groups: dictionary like object groups and system.
|
||||
The newly created group will be added after creation.
|
||||
:type groups: dict[str | Group]
|
||||
"""
|
||||
|
||||
if name in groups_systems:
|
||||
t = 'group' if isinstance(groups_systems['name'], Group) else 'system'
|
||||
raise ValueError('The system name already in use by a %s' % t)
|
||||
|
||||
# The name of the group.
|
||||
#: type: str
|
||||
self.name = name
|
||||
@@ -58,21 +65,19 @@ class Group(object):
|
||||
#: :type: set[str]
|
||||
self._used_by = set()
|
||||
|
||||
#: Maps group name to Group.
|
||||
#: :type: dict[str, Group]
|
||||
self._groups_systems = groups_systems
|
||||
|
||||
self._groups_systems[self.name] = self
|
||||
# Add this group to the group dictionary
|
||||
self._REGISTRY._groups[self.name] = self
|
||||
|
||||
if name != 'root':
|
||||
# All groups are added to root group
|
||||
groups_systems['root'].add_groups(name)
|
||||
self._REGISTRY._groups['root'].add_groups(name)
|
||||
|
||||
#: A cache of the included units.
|
||||
#: None indicates that the cache has been invalidated.
|
||||
#: :type: frozenset[str] | None
|
||||
self._computed_members = None
|
||||
|
||||
|
||||
@property
|
||||
def members(self):
|
||||
"""Names of the units that are members of the group.
|
||||
@@ -95,13 +100,13 @@ class Group(object):
|
||||
"""Invalidate computed members in this Group and all parent nodes.
|
||||
"""
|
||||
self._computed_members = None
|
||||
d = self._groups_systems
|
||||
d = self._REGISTRY._groups
|
||||
for name in self._used_by:
|
||||
d[name].invalidate_members()
|
||||
|
||||
def iter_used_groups(self):
|
||||
pending = set(self._used_groups)
|
||||
d = self._groups_systems
|
||||
d = self._REGISTRY._groups
|
||||
while pending:
|
||||
name = pending.pop()
|
||||
group = d[name]
|
||||
@@ -124,6 +129,10 @@ class Group(object):
|
||||
|
||||
self.invalidate_members()
|
||||
|
||||
@property
|
||||
def non_inherited_unit_names(self):
|
||||
return frozenset(self._unit_names)
|
||||
|
||||
def remove_units(self, *unit_names):
|
||||
"""Remove units from group.
|
||||
|
||||
@@ -139,7 +148,7 @@ class Group(object):
|
||||
|
||||
:type group_names: str
|
||||
"""
|
||||
d = self._groups_systems
|
||||
d = self._REGISTRY._groups
|
||||
for group_name in group_names:
|
||||
|
||||
grp = d[group_name]
|
||||
@@ -157,28 +166,26 @@ class Group(object):
|
||||
|
||||
:type group_names: str
|
||||
"""
|
||||
d = self._groups_systems
|
||||
d = self._REGISTRY._groups
|
||||
for group_name in group_names:
|
||||
grp = d[group_name]
|
||||
|
||||
self._used_groups.remove(group_name)
|
||||
grp._used_by.remove(self.name)
|
||||
|
||||
|
||||
self.invalidate_members()
|
||||
|
||||
@classmethod
|
||||
def from_lines(cls, lines, define_func, group_dict):
|
||||
def from_lines(cls, lines, define_func):
|
||||
"""Return a Group object parsing an iterable of lines.
|
||||
|
||||
:param lines: iterable
|
||||
:type lines: list[str]
|
||||
:param define_func: Function to define a unit in the registry.
|
||||
:type define_func: str -> None
|
||||
:param group_dict: Maps group name to Group.
|
||||
:type group_dict: dict[str, Group]
|
||||
"""
|
||||
header, lines = lines[0], lines[1:]
|
||||
lines = SourceIterator(lines)
|
||||
lineno, header = next(lines)
|
||||
|
||||
r = cls._header_re.search(header)
|
||||
name = r.groupdict()['name'].strip()
|
||||
@@ -189,19 +196,26 @@ class Group(object):
|
||||
group_names = ()
|
||||
|
||||
unit_names = []
|
||||
for line in lines:
|
||||
for lineno, line in lines:
|
||||
if '=' in line:
|
||||
# Is a definition
|
||||
definition = Definition.from_string(line)
|
||||
if not isinstance(definition, UnitDefinition):
|
||||
raise DefinitionSyntaxError('Only UnitDefinition are valid inside _used_groups, '
|
||||
'not %s' % type(definition))
|
||||
define_func(definition)
|
||||
'not %s' % type(definition), lineno=lineno)
|
||||
|
||||
try:
|
||||
define_func(definition)
|
||||
except (RedefinitionError, DefinitionSyntaxError) as ex:
|
||||
if ex.lineno is None:
|
||||
ex.lineno = lineno
|
||||
raise ex
|
||||
|
||||
unit_names.append(definition.name)
|
||||
else:
|
||||
unit_names.append(line.strip())
|
||||
|
||||
grp = cls(name, group_dict)
|
||||
grp = cls(name)
|
||||
|
||||
grp.add_units(*unit_names)
|
||||
|
||||
@@ -210,34 +224,46 @@ class Group(object):
|
||||
|
||||
return grp
|
||||
|
||||
def __getattr__(self, item):
|
||||
return self._REGISTRY
|
||||
|
||||
class System(object):
|
||||
|
||||
class _System(SharedRegistryObject):
|
||||
"""A system is a Group plus a set of base units.
|
||||
|
||||
@system <name> [using <group 1>, ..., <group N>]
|
||||
<rule 1>
|
||||
...
|
||||
<rule N>
|
||||
@end
|
||||
Members are computed dynamically, that is if a unit is added to a group X
|
||||
all groups that include X are affected.
|
||||
|
||||
The System belongs to one Registry.
|
||||
|
||||
It can be specified in the definition file as:
|
||||
|
||||
@system <name> [using <group 1>, ..., <group N>]
|
||||
<rule 1>
|
||||
...
|
||||
<rule N>
|
||||
@end
|
||||
|
||||
The syntax for the rule is:
|
||||
|
||||
new_unit_name : old_unit_name
|
||||
|
||||
where:
|
||||
- old_unit_name: a root unit part which is going to be removed from the system.
|
||||
- new_unit_name: a non root unit which is going to replace the old_unit.
|
||||
|
||||
If the new_unit_name and the old_unit_name, the later and the colon can be ommited.
|
||||
"""
|
||||
|
||||
#: Regex to match the header parts of a context.
|
||||
_header_re = re.compile('@system\s+(?P<name>\w+)\s*(using\s(?P<used_groups>.*))*')
|
||||
|
||||
def __init__(self, name, groups_systems):
|
||||
def __init__(self, name):
|
||||
"""
|
||||
:param name: Name of the group
|
||||
:type name: str
|
||||
:param groups_systems: dictionary containing groups and system.
|
||||
The newly created group will be added after creation.
|
||||
:type groups_systems: dict[str, Group | System]
|
||||
"""
|
||||
|
||||
if name in groups_systems:
|
||||
t = 'group' if isinstance(groups_systems[name], Group) else 'system'
|
||||
raise ValueError('The system name (%s) already in use by a %s' % (name, t))
|
||||
|
||||
#: Name of the system
|
||||
#: :type: str
|
||||
self.name = name
|
||||
@@ -257,18 +283,17 @@ class System(object):
|
||||
#: :type: frozenset | None
|
||||
self._computed_members = None
|
||||
|
||||
#: Maps group name to Group.
|
||||
self._group_systems_dict = groups_systems
|
||||
|
||||
self._group_systems_dict[self.name] = self
|
||||
# Add this system to the system dictionary
|
||||
self._REGISTRY._systems[self.name] = self
|
||||
|
||||
@property
|
||||
def members(self):
|
||||
d = self._REGISTRY._groups
|
||||
if self._computed_members is None:
|
||||
self._computed_members = set()
|
||||
|
||||
for group_name in self._used_groups:
|
||||
self._computed_members |= self._group_systems_dict[group_name].members
|
||||
self._computed_members |= d[group_name].members
|
||||
|
||||
self._computed_members = frozenset(self._computed_members)
|
||||
|
||||
@@ -298,8 +323,10 @@ class System(object):
|
||||
self.invalidate_members()
|
||||
|
||||
@classmethod
|
||||
def from_lines(cls, lines, get_root_func, group_dict):
|
||||
header, lines = lines[0], lines[1:]
|
||||
def from_lines(cls, lines, get_root_func):
|
||||
lines = SourceIterator(lines)
|
||||
|
||||
lineno, header = next(lines)
|
||||
|
||||
r = cls._header_re.search(header)
|
||||
name = r.groupdict()['name'].strip()
|
||||
@@ -313,7 +340,7 @@ class System(object):
|
||||
|
||||
base_unit_names = {}
|
||||
derived_unit_names = []
|
||||
for line in lines:
|
||||
for lineno, line in lines:
|
||||
line = line.strip()
|
||||
|
||||
# We would identify a
|
||||
@@ -360,7 +387,7 @@ class System(object):
|
||||
|
||||
base_unit_names[old_unit] = {new_unit: 1./value}
|
||||
|
||||
system = cls(name, group_dict)
|
||||
system = cls(name)
|
||||
|
||||
system.add_groups(*group_names)
|
||||
|
||||
@@ -370,54 +397,19 @@ class System(object):
|
||||
return system
|
||||
|
||||
|
||||
class GSManager(object):
|
||||
def build_group_class(registry):
|
||||
|
||||
def __init__(self):
|
||||
#: :type: dict[str, Group | System]
|
||||
self._groups_systems = dict()
|
||||
self._root_group = Group('root', self._groups_systems)
|
||||
class Group(_Group):
|
||||
pass
|
||||
|
||||
def add_system_from_lines(self, lines, get_root_func):
|
||||
System.from_lines(lines, get_root_func, self._groups_systems)
|
||||
Group._REGISTRY = registry
|
||||
return Group
|
||||
|
||||
def add_group_from_lines(self, lines, define_func):
|
||||
Group.from_lines(lines, define_func, self._groups_systems)
|
||||
|
||||
def get_group(self, name, create_if_needed=True):
|
||||
"""Return a Group.
|
||||
def build_system_class(registry):
|
||||
|
||||
:param name: Name of the group.
|
||||
:param create_if_needed: Create a group if not Found. If False, raise an Exception.
|
||||
:return: Group
|
||||
"""
|
||||
try:
|
||||
return self._groups_systems[name]
|
||||
except KeyError:
|
||||
if create_if_needed:
|
||||
if name == 'root':
|
||||
raise ValueError('The name root is reserved.')
|
||||
return Group(name, self._groups_systems)
|
||||
else:
|
||||
raise KeyError('No group %s found.' % name)
|
||||
class System(_System):
|
||||
pass
|
||||
|
||||
def get_system(self, name, create_if_needed=True):
|
||||
"""Return a Group.
|
||||
|
||||
:param name: Name of the system
|
||||
:param create_if_needed: Create a group if not Found. If False, raise an Exception.
|
||||
:return: System
|
||||
"""
|
||||
|
||||
try:
|
||||
return self._groups_systems[name]
|
||||
except KeyError:
|
||||
if create_if_needed:
|
||||
return System(name, self._groups_systems)
|
||||
else:
|
||||
raise KeyError('No system found named %s.' % name)
|
||||
|
||||
def __getitem__(self, item):
|
||||
if item in self._groups_systems:
|
||||
return self._groups_systems[item]
|
||||
|
||||
raise KeyError('No group or system found named %s.' % item)
|
||||
System._REGISTRY = registry
|
||||
return System
|
||||
|
||||
158
pint/unit.py
158
pint/unit.py
@@ -29,7 +29,7 @@ from .util import (logger, pi_theorem, solve_dependencies, ParserHelper,
|
||||
string_preprocessor, find_connected_nodes,
|
||||
find_shortest_path, UnitsContainer, _is_dim,
|
||||
SharedRegistryObject, to_units_container,
|
||||
fix_str_conversions)
|
||||
fix_str_conversions, SourceIterator)
|
||||
|
||||
from .compat import tokenizer, string_types, NUMERIC_TYPES, long_type, zip_longest
|
||||
from .formatting import siunitx_format_unit
|
||||
@@ -43,19 +43,6 @@ from .pint_eval import build_eval_tree
|
||||
from . import systems
|
||||
|
||||
|
||||
def _capture_till_end(ifile):
|
||||
context = []
|
||||
for no, line in ifile:
|
||||
line = line.strip()
|
||||
if line.startswith('@end'):
|
||||
break
|
||||
elif line.startswith('@'):
|
||||
raise DefinitionSyntaxError('cannot nest @ directives', lineno=no)
|
||||
context.append(line)
|
||||
return context
|
||||
|
||||
|
||||
|
||||
@fix_str_conversions
|
||||
class _Unit(SharedRegistryObject):
|
||||
"""Implements a class to describe a unit supporting math operations.
|
||||
@@ -68,8 +55,7 @@ class _Unit(SharedRegistryObject):
|
||||
default_format = ''
|
||||
|
||||
def __reduce__(self):
|
||||
from . import _build_unit
|
||||
return _build_unit, (self._units)
|
||||
return self.Unit, (self._units)
|
||||
|
||||
def __new__(cls, units):
|
||||
inst = object.__new__(cls)
|
||||
@@ -283,6 +269,7 @@ class UnitRegistry(object):
|
||||
def __init__(self, filename='', force_ndarray=False, default_as_delta=True,
|
||||
autoconvert_offset_to_baseunit=False,
|
||||
on_redefinition='warn', system=None):
|
||||
|
||||
self.Unit = build_unit_class(self)
|
||||
self.Quantity = build_quantity_class(self, force_ndarray)
|
||||
self.Measurement = build_measurement_class(self, force_ndarray)
|
||||
@@ -290,11 +277,23 @@ class UnitRegistry(object):
|
||||
#: Action to take in case a unit is redefined. 'warn', 'raise', 'ignore'
|
||||
self._on_redefinition = on_redefinition
|
||||
|
||||
#: Map between name (string) and value (string) of defaults stored in the definitions file.
|
||||
self._defaults = {}
|
||||
|
||||
#: Map dimension name (string) to its definition (DimensionDefinition).
|
||||
self._dimensions = {}
|
||||
|
||||
#: :type: systems.GSManager
|
||||
self._gsmanager = systems.GSManager()
|
||||
#: Map system name to system.
|
||||
#: :type: dict[ str | System]
|
||||
self._systems = {}
|
||||
|
||||
#: Map group name to group.
|
||||
#: :type: dict[ str | Group]
|
||||
self._groups = {}
|
||||
self.Group = systems.build_group_class(self)
|
||||
self._groups['root'] = self.Group('root')
|
||||
self.System = systems.build_system_class(self)
|
||||
|
||||
|
||||
#: Map unit name (string) to its definition (UnitDefinition).
|
||||
#: Might contain prefixed units.
|
||||
@@ -336,9 +335,6 @@ class UnitRegistry(object):
|
||||
#: non-multiplicative units as their *delta* counterparts.
|
||||
self.default_as_delta = default_as_delta
|
||||
|
||||
#: System name to be used by default.
|
||||
self._default_system_name = None
|
||||
|
||||
# Determines if quantities with offset units are converted to their
|
||||
# base units on multiplication and division.
|
||||
self.autoconvert_offset_to_baseunit = autoconvert_offset_to_baseunit
|
||||
@@ -350,9 +346,15 @@ class UnitRegistry(object):
|
||||
|
||||
self.define(UnitDefinition('pi', 'π', (), ScaleConverter(math.pi)))
|
||||
|
||||
self._build_cache()
|
||||
#: Copy units in root group to the default group
|
||||
if 'group' in self._defaults:
|
||||
grp = self.get_group(self._defaults['group'], True)
|
||||
grp.add_units(*self.get_group('root', False).non_inherited_unit_names)
|
||||
|
||||
self.set_default_system(system)
|
||||
#: System name to be used by default.
|
||||
self._system = system or self._defaults.get('system', None)
|
||||
|
||||
self._build_cache()
|
||||
|
||||
def __name__(self):
|
||||
return 'UnitRegistry'
|
||||
@@ -390,24 +392,46 @@ class UnitRegistry(object):
|
||||
:param create_if_needed: Create a group if not Found. If False, raise an Exception.
|
||||
:return: Group
|
||||
"""
|
||||
return self._gsmanager.get_group(name, create_if_needed)
|
||||
if name in self._groups:
|
||||
return self._groups[name]
|
||||
|
||||
if not create_if_needed:
|
||||
raise ValueError('Unkown group %s' % name)
|
||||
|
||||
return self.Group(name)
|
||||
|
||||
@property
|
||||
def systems(self):
|
||||
return set(self._systems.keys())
|
||||
|
||||
@property
|
||||
def system(self):
|
||||
return self._system
|
||||
|
||||
@system.setter
|
||||
def system(self, name):
|
||||
if name:
|
||||
if name not in self._systems:
|
||||
raise ValueError('Unknown system %s' % name)
|
||||
|
||||
self._base_units_cache = {}
|
||||
|
||||
self._system = name
|
||||
|
||||
def get_system(self, name, create_if_needed=True):
|
||||
"""Return a Group.
|
||||
|
||||
:param registry:
|
||||
:param name: Name of the group to be
|
||||
:param create_if_needed: Create a group if not Found. If False, raise an Exception.
|
||||
:return: System
|
||||
"""
|
||||
return self._gsmanager.get_system(name, create_if_needed)
|
||||
if name in self._systems:
|
||||
return self._systems[name]
|
||||
|
||||
def set_default_system(self, name):
|
||||
# Test if exists
|
||||
if name:
|
||||
system = self._gsmanager.get_system(name, False)
|
||||
self._default_system_name = name
|
||||
self._base_units_cache = {}
|
||||
if not create_if_needed:
|
||||
raise ValueError('Unkown system %s' % name)
|
||||
|
||||
return self.System(name)
|
||||
|
||||
def add_context(self, context):
|
||||
"""Add a context object to the registry.
|
||||
@@ -531,12 +555,11 @@ class UnitRegistry(object):
|
||||
# the added contexts are removed from the active one.
|
||||
self.disable_contexts(len(names))
|
||||
|
||||
def define(self, definition):
|
||||
def define(self, definition, add_to_root_group=False):
|
||||
"""Add unit to the registry.
|
||||
"""
|
||||
if isinstance(definition, string_types):
|
||||
definition = Definition.from_string(definition)
|
||||
|
||||
if isinstance(definition, DimensionDefinition):
|
||||
d, di = self._dimensions, None
|
||||
elif isinstance(definition, UnitDefinition):
|
||||
@@ -550,6 +573,10 @@ class UnitRegistry(object):
|
||||
|
||||
self.define(DimensionDefinition(dimension, '', (), None, is_base=True))
|
||||
|
||||
# We add all units to the root group
|
||||
if add_to_root_group:
|
||||
self.get_group('root').add_units(definition.name)
|
||||
|
||||
elif isinstance(definition, PrefixDefinition):
|
||||
d, di = self._prefixes, None
|
||||
else:
|
||||
@@ -596,7 +623,8 @@ class UnitRegistry(object):
|
||||
|
||||
self.define(UnitDefinition(d_name, d_symbol, d_aliases,
|
||||
ScaleConverter(definition.converter.scale),
|
||||
d_reference, definition.is_base))
|
||||
d_reference, definition.is_base),
|
||||
add_to_root_group=True)
|
||||
|
||||
def load_definitions(self, file, is_resource=False):
|
||||
"""Add units and prefixes defined in a definition text file.
|
||||
@@ -619,11 +647,8 @@ class UnitRegistry(object):
|
||||
msg = getattr(e, 'message', '') or str(e)
|
||||
raise ValueError('While opening {0}\n{1}'.format(file, msg))
|
||||
|
||||
ifile = enumerate(file, 1)
|
||||
ifile = SourceIterator(file)
|
||||
for no, line in ifile:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
if line.startswith('@import'):
|
||||
if is_resource:
|
||||
path = line[7:].strip()
|
||||
@@ -634,27 +659,30 @@ class UnitRegistry(object):
|
||||
path = os.getcwd()
|
||||
path = os.path.join(path, os.path.normpath(line[7:].strip()))
|
||||
self.load_definitions(path, is_resource)
|
||||
|
||||
elif line.startswith('@defaults'):
|
||||
next(ifile)
|
||||
for lineno, part in ifile.block_iter():
|
||||
k, v = part.split('=')
|
||||
self._defaults[k.strip()] = v.strip()
|
||||
|
||||
elif line.startswith('@context'):
|
||||
context = [line, ] + _capture_till_end(ifile)
|
||||
try:
|
||||
self.add_context(Context.from_lines(context, self.get_dimensionality))
|
||||
except KeyError as e:
|
||||
raise DefinitionSyntaxError('unknown dimension {0} in context'.format(str(e)), lineno=no)
|
||||
elif line.startswith('@system'):
|
||||
context = [line, ] + _capture_till_end(ifile)
|
||||
try:
|
||||
self._gsmanager.add_system_from_lines(context, self.get_root_units)
|
||||
self.add_context(Context.from_lines(ifile.block_iter(),
|
||||
self.get_dimensionality))
|
||||
except KeyError as e:
|
||||
raise DefinitionSyntaxError('unknown dimension {0} in context'.format(str(e)), lineno=no)
|
||||
|
||||
elif line.startswith('@group'):
|
||||
context = [line, ] + _capture_till_end(ifile)
|
||||
try:
|
||||
self._gsmanager.add_group_from_lines(context, self.define)
|
||||
except KeyError as e:
|
||||
raise DefinitionSyntaxError('unknown dimension {0} in context'.format(str(e)), lineno=no)
|
||||
self.Group.from_lines(ifile.block_iter(), self.define)
|
||||
|
||||
elif line.startswith('@system'):
|
||||
self.System.from_lines(ifile.block_iter(), self.get_root_units)
|
||||
|
||||
else:
|
||||
try:
|
||||
self.define(Definition.from_string(line))
|
||||
self.define(Definition.from_string(line),
|
||||
add_to_root_group=True)
|
||||
except (RedefinitionError, DefinitionSyntaxError) as ex:
|
||||
if ex.lineno is None:
|
||||
ex.lineno = no
|
||||
@@ -881,15 +909,15 @@ class UnitRegistry(object):
|
||||
:return:
|
||||
"""
|
||||
|
||||
# The cache is only done for check_nonmult=True
|
||||
if check_nonmult and input_units in self._base_units_cache:
|
||||
if system is None:
|
||||
system = self._system
|
||||
|
||||
# The cache is only done for check_nonmult=True and the current system.
|
||||
if check_nonmult and system == self._system and input_units in self._base_units_cache:
|
||||
return self._base_units_cache[input_units]
|
||||
|
||||
factor, units = self.get_root_units(input_units, check_nonmult)
|
||||
|
||||
if system is None:
|
||||
system = self._default_system_name
|
||||
|
||||
if not system:
|
||||
return factor, units
|
||||
|
||||
@@ -898,7 +926,7 @@ class UnitRegistry(object):
|
||||
|
||||
destination_units = UnitsContainer()
|
||||
|
||||
bu = self._gsmanager.get_system(system, False).base_units
|
||||
bu = self.get_system(system, False).base_units
|
||||
|
||||
for unit, value in units.items():
|
||||
if unit in bu:
|
||||
@@ -933,11 +961,14 @@ class UnitRegistry(object):
|
||||
"""
|
||||
input_units = to_units_container(input_units)
|
||||
|
||||
if group_or_system is None:
|
||||
group_or_system = self._system
|
||||
|
||||
equiv = self._get_compatible_units(input_units, group_or_system)
|
||||
|
||||
return frozenset(self.Unit(eq) for eq in equiv)
|
||||
|
||||
def _get_compatible_units(self, input_units, group_or_system=None):
|
||||
def _get_compatible_units(self, input_units, group_or_system):
|
||||
"""
|
||||
"""
|
||||
if not input_units:
|
||||
@@ -955,7 +986,12 @@ class UnitRegistry(object):
|
||||
ret |= self._dimensional_equivalents[node]
|
||||
|
||||
if group_or_system:
|
||||
members = self._gsmanager[group_or_system].members
|
||||
if group_or_system in self._systems:
|
||||
members = self._systems[group_or_system].members
|
||||
elif group_or_system in self._groups:
|
||||
members = self._groups[group_or_system].members
|
||||
else:
|
||||
raise ValueError("Unknown Group o System with name '%s'" % group_or_system)
|
||||
return frozenset(ret.intersection(members))
|
||||
|
||||
return ret
|
||||
|
||||
Reference in New Issue
Block a user