[taurus] 02/04: New upstream version 4.0.3+dfsg
Frédéric-Emmanuel Picca
picca at moszumanska.debian.org
Mon Jan 23 19:12:50 UTC 2017
This is an automated email from the git hooks/post-receive script.
picca pushed a commit to branch master
in repository taurus.
commit cfb3ec16e6b54dea7f5b6b18ede9b71092bd5184
Author: Picca Frédéric-Emmanuel <picca at debian.org>
Date: Mon Jan 23 18:31:56 2017 +0100
New upstream version 4.0.3+dfsg
---
lib/taurus/external/argparse/LICENSE.txt | 20 -
lib/taurus/external/argparse/argparse_local.py | 2362 --------------------
lib/taurus/external/enum/enum/__init__.py | 809 -------
lib/taurus/external/ordereddict/ordereddict.py | 153 --
lib/taurus/external/pint/pint_local/AUTHORS | 41 -
lib/taurus/external/pint/pint_local/LICENSE | 33 -
lib/taurus/external/pint/pint_local/__init__.py | 126 --
.../external/pint/pint_local/compat/__init__.py | 129 --
.../external/pint/pint_local/compat/chainmap.py | 153 --
.../external/pint/pint_local/compat/lrucache.py | 177 --
.../external/pint/pint_local/compat/nullhandler.py | 32 -
.../external/pint/pint_local/compat/tokenize.py | 640 ------
.../external/pint/pint_local/constants_en.txt | 51 -
lib/taurus/external/pint/pint_local/context.py | 239 --
lib/taurus/external/pint/pint_local/converters.py | 82 -
lib/taurus/external/pint/pint_local/default_en.txt | 377 ----
lib/taurus/external/pint/pint_local/definitions.py | 157 --
lib/taurus/external/pint/pint_local/errors.py | 113 -
lib/taurus/external/pint/pint_local/formatting.py | 200 --
lib/taurus/external/pint/pint_local/measurement.py | 99 -
lib/taurus/external/pint/pint_local/pint_eval.py | 258 ---
lib/taurus/external/pint/pint_local/quantity.py | 1337 -----------
lib/taurus/external/pint/pint_local/systems.py | 423 ----
lib/taurus/external/pint/pint_local/unit.py | 1375 ------------
lib/taurus/external/pint/pint_local/util.py | 643 ------
setup.cfg | 1 +
26 files changed, 1 insertion(+), 10029 deletions(-)
diff --git a/lib/taurus/external/argparse/LICENSE.txt b/lib/taurus/external/argparse/LICENSE.txt
deleted file mode 100644
index 640bc78..0000000
--- a/lib/taurus/external/argparse/LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-argparse is (c) 2006-2009 Steven J. Bethard <steven.bethard at gmail.com>.
-
-The argparse module was contributed to Python as of Python 2.7 and thus
-was licensed under the Python license. Same license applies to all files in
-the argparse package project.
-
-For details about the Python License, please see doc/Python-License.txt.
-
-History
--------
-
-Before (and including) argparse 1.1, the argparse package was licensed under
-Apache License v2.0.
-
-After argparse 1.1, all project files from the argparse project were deleted
-due to license compatibility issues between Apache License 2.0 and GNU GPL v2.
-
-The project repository then had a clean start with some files taken from
-Python 2.7.1, so definitely all files are under Python License now.
-
diff --git a/lib/taurus/external/argparse/argparse_local.py b/lib/taurus/external/argparse/argparse_local.py
deleted file mode 100644
index 32d948c..0000000
--- a/lib/taurus/external/argparse/argparse_local.py
+++ /dev/null
@@ -1,2362 +0,0 @@
-# Author: Steven J. Bethard <steven.bethard at gmail.com>.
-
-"""Command-line parsing library
-
-This module is an optparse-inspired command-line parsing library that:
-
- - handles both optional and positional arguments
- - produces highly informative usage messages
- - supports parsers that dispatch to sub-parsers
-
-The following is a simple usage example that sums integers from the
-command-line and writes the result to a file::
-
- parser = argparse.ArgumentParser(
- description='sum the integers at the command line')
- parser.add_argument(
- 'integers', metavar='int', nargs='+', type=int,
- help='an integer to be summed')
- parser.add_argument(
- '--log', default=sys.stdout, type=argparse.FileType('w'),
- help='the file where the sum should be written')
- args = parser.parse_args()
- args.log.write('%s' % sum(args.integers))
- args.log.close()
-
-The module contains the following public classes:
-
- - ArgumentParser -- The main entry point for command-line parsing. As the
- example above shows, the add_argument() method is used to populate
- the parser with actions for optional and positional arguments. Then
- the parse_args() method is invoked to convert the args at the
- command-line into an object with attributes.
-
- - ArgumentError -- The exception raised by ArgumentParser objects when
- there are errors with the parser's actions. Errors raised while
- parsing the command-line are caught by ArgumentParser and emitted
- as command-line messages.
-
- - FileType -- A factory for defining types of files to be created. As the
- example above shows, instances of FileType are typically passed as
- the type= argument of add_argument() calls.
-
- - Action -- The base class for parser actions. Typically actions are
- selected by passing strings like 'store_true' or 'append_const' to
- the action= argument of add_argument(). However, for greater
- customization of ArgumentParser actions, subclasses of Action may
- be defined and passed as the action= argument.
-
- - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
- ArgumentDefaultsHelpFormatter -- Formatter classes which
- may be passed as the formatter_class= argument to the
- ArgumentParser constructor. HelpFormatter is the default,
- RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
- not to change the formatting for help text, and
- ArgumentDefaultsHelpFormatter adds information about argument defaults
- to the help.
-
-All other classes in this module are considered implementation details.
-(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
-considered public as object names -- the API of the formatter objects is
-still considered an implementation detail.)
-"""
-
-__version__ = '1.2.1'
-__all__ = [
- 'ArgumentParser',
- 'ArgumentError',
- 'ArgumentTypeError',
- 'FileType',
- 'HelpFormatter',
- 'ArgumentDefaultsHelpFormatter',
- 'RawDescriptionHelpFormatter',
- 'RawTextHelpFormatter',
- 'Namespace',
- 'Action',
- 'ONE_OR_MORE',
- 'OPTIONAL',
- 'PARSER',
- 'REMAINDER',
- 'SUPPRESS',
- 'ZERO_OR_MORE',
-]
-
-
-import copy as _copy
-import os as _os
-import re as _re
-import sys as _sys
-import textwrap as _textwrap
-
-from gettext import gettext as _
-
-try:
- set
-except NameError:
- # for python < 2.4 compatibility (sets module is there since 2.3):
- from sets import Set as set
-
-try:
- basestring
-except NameError:
- basestring = str
-
-try:
- sorted
-except NameError:
- # for python < 2.4 compatibility:
- def sorted(iterable, reverse=False):
- result = list(iterable)
- result.sort()
- if reverse:
- result.reverse()
- return result
-
-
-def _callable(obj):
- return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
-
-
-SUPPRESS = '==SUPPRESS=='
-
-OPTIONAL = '?'
-ZERO_OR_MORE = '*'
-ONE_OR_MORE = '+'
-PARSER = 'A...'
-REMAINDER = '...'
-_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
-
-# =============================
-# Utility functions and classes
-# =============================
-
-class _AttributeHolder(object):
- """Abstract base class that provides __repr__.
-
- The __repr__ method returns a string in the format::
- ClassName(attr=name, attr=name, ...)
- The attributes are determined either by a class-level attribute,
- '_kwarg_names', or by inspecting the instance __dict__.
- """
-
- def __repr__(self):
- type_name = type(self).__name__
- arg_strings = []
- for arg in self._get_args():
- arg_strings.append(repr(arg))
- for name, value in self._get_kwargs():
- arg_strings.append('%s=%r' % (name, value))
- return '%s(%s)' % (type_name, ', '.join(arg_strings))
-
- def _get_kwargs(self):
- return sorted(self.__dict__.items())
-
- def _get_args(self):
- return []
-
-
-def _ensure_value(namespace, name, value):
- if getattr(namespace, name, None) is None:
- setattr(namespace, name, value)
- return getattr(namespace, name)
-
-
-# ===============
-# Formatting Help
-# ===============
-
-class HelpFormatter(object):
- """Formatter for generating usage messages and argument help strings.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def __init__(self,
- prog,
- indent_increment=2,
- max_help_position=24,
- width=None):
-
- # default setting for width
- if width is None:
- try:
- width = int(_os.environ['COLUMNS'])
- except (KeyError, ValueError):
- width = 80
- width -= 2
-
- self._prog = prog
- self._indent_increment = indent_increment
- self._max_help_position = max_help_position
- self._width = width
-
- self._current_indent = 0
- self._level = 0
- self._action_max_length = 0
-
- self._root_section = self._Section(self, None)
- self._current_section = self._root_section
-
- self._whitespace_matcher = _re.compile(r'\s+')
- self._long_break_matcher = _re.compile(r'\n\n\n+')
-
- # ===============================
- # Section and indentation methods
- # ===============================
- def _indent(self):
- self._current_indent += self._indent_increment
- self._level += 1
-
- def _dedent(self):
- self._current_indent -= self._indent_increment
- assert self._current_indent >= 0, 'Indent decreased below 0.'
- self._level -= 1
-
- class _Section(object):
-
- def __init__(self, formatter, parent, heading=None):
- self.formatter = formatter
- self.parent = parent
- self.heading = heading
- self.items = []
-
- def format_help(self):
- # format the indented section
- if self.parent is not None:
- self.formatter._indent()
- join = self.formatter._join_parts
- for func, args in self.items:
- func(*args)
- item_help = join([func(*args) for func, args in self.items])
- if self.parent is not None:
- self.formatter._dedent()
-
- # return nothing if the section was empty
- if not item_help:
- return ''
-
- # add the heading if the section was non-empty
- if self.heading is not SUPPRESS and self.heading is not None:
- current_indent = self.formatter._current_indent
- heading = '%*s%s:\n' % (current_indent, '', self.heading)
- else:
- heading = ''
-
- # join the section-initial newline, the heading and the help
- return join(['\n', heading, item_help, '\n'])
-
- def _add_item(self, func, args):
- self._current_section.items.append((func, args))
-
- # ========================
- # Message building methods
- # ========================
- def start_section(self, heading):
- self._indent()
- section = self._Section(self, self._current_section, heading)
- self._add_item(section.format_help, [])
- self._current_section = section
-
- def end_section(self):
- self._current_section = self._current_section.parent
- self._dedent()
-
- def add_text(self, text):
- if text is not SUPPRESS and text is not None:
- self._add_item(self._format_text, [text])
-
- def add_usage(self, usage, actions, groups, prefix=None):
- if usage is not SUPPRESS:
- args = usage, actions, groups, prefix
- self._add_item(self._format_usage, args)
-
- def add_argument(self, action):
- if action.help is not SUPPRESS:
-
- # find all invocations
- get_invocation = self._format_action_invocation
- invocations = [get_invocation(action)]
- for subaction in self._iter_indented_subactions(action):
- invocations.append(get_invocation(subaction))
-
- # update the maximum item length
- invocation_length = max([len(s) for s in invocations])
- action_length = invocation_length + self._current_indent
- self._action_max_length = max(self._action_max_length,
- action_length)
-
- # add the item to the list
- self._add_item(self._format_action, [action])
-
- def add_arguments(self, actions):
- for action in actions:
- self.add_argument(action)
-
- # =======================
- # Help-formatting methods
- # =======================
- def format_help(self):
- help = self._root_section.format_help()
- if help:
- help = self._long_break_matcher.sub('\n\n', help)
- help = help.strip('\n') + '\n'
- return help
-
- def _join_parts(self, part_strings):
- return ''.join([part
- for part in part_strings
- if part and part is not SUPPRESS])
-
- def _format_usage(self, usage, actions, groups, prefix):
- if prefix is None:
- prefix = _('usage: ')
-
- # if usage is specified, use that
- if usage is not None:
- usage = usage % dict(prog=self._prog)
-
- # if no optionals or positionals are available, usage is just prog
- elif usage is None and not actions:
- usage = '%(prog)s' % dict(prog=self._prog)
-
- # if optionals and positionals are available, calculate usage
- elif usage is None:
- prog = '%(prog)s' % dict(prog=self._prog)
-
- # split optionals from positionals
- optionals = []
- positionals = []
- for action in actions:
- if action.option_strings:
- optionals.append(action)
- else:
- positionals.append(action)
-
- # build full usage string
- format = self._format_actions_usage
- action_usage = format(optionals + positionals, groups)
- usage = ' '.join([s for s in [prog, action_usage] if s])
-
- # wrap the usage parts if it's too long
- text_width = self._width - self._current_indent
- if len(prefix) + len(usage) > text_width:
-
- # break usage into wrappable parts
- part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
- opt_usage = format(optionals, groups)
- pos_usage = format(positionals, groups)
- opt_parts = _re.findall(part_regexp, opt_usage)
- pos_parts = _re.findall(part_regexp, pos_usage)
- assert ' '.join(opt_parts) == opt_usage
- assert ' '.join(pos_parts) == pos_usage
-
- # helper for wrapping lines
- def get_lines(parts, indent, prefix=None):
- lines = []
- line = []
- if prefix is not None:
- line_len = len(prefix) - 1
- else:
- line_len = len(indent) - 1
- for part in parts:
- if line_len + 1 + len(part) > text_width:
- lines.append(indent + ' '.join(line))
- line = []
- line_len = len(indent) - 1
- line.append(part)
- line_len += len(part) + 1
- if line:
- lines.append(indent + ' '.join(line))
- if prefix is not None:
- lines[0] = lines[0][len(indent):]
- return lines
-
- # if prog is short, follow it with optionals or positionals
- if len(prefix) + len(prog) <= 0.75 * text_width:
- indent = ' ' * (len(prefix) + len(prog) + 1)
- if opt_parts:
- lines = get_lines([prog] + opt_parts, indent, prefix)
- lines.extend(get_lines(pos_parts, indent))
- elif pos_parts:
- lines = get_lines([prog] + pos_parts, indent, prefix)
- else:
- lines = [prog]
-
- # if prog is long, put it on its own line
- else:
- indent = ' ' * len(prefix)
- parts = opt_parts + pos_parts
- lines = get_lines(parts, indent)
- if len(lines) > 1:
- lines = []
- lines.extend(get_lines(opt_parts, indent))
- lines.extend(get_lines(pos_parts, indent))
- lines = [prog] + lines
-
- # join lines into usage
- usage = '\n'.join(lines)
-
- # prefix with 'usage:'
- return '%s%s\n\n' % (prefix, usage)
-
- def _format_actions_usage(self, actions, groups):
- # find group indices and identify actions in groups
- group_actions = set()
- inserts = {}
- for group in groups:
- try:
- start = actions.index(group._group_actions[0])
- except ValueError:
- continue
- else:
- end = start + len(group._group_actions)
- if actions[start:end] == group._group_actions:
- for action in group._group_actions:
- group_actions.add(action)
- if not group.required:
- if start in inserts:
- inserts[start] += ' ['
- else:
- inserts[start] = '['
- inserts[end] = ']'
- else:
- if start in inserts:
- inserts[start] += ' ('
- else:
- inserts[start] = '('
- inserts[end] = ')'
- for i in range(start + 1, end):
- inserts[i] = '|'
-
- # collect all actions format strings
- parts = []
- for i, action in enumerate(actions):
-
- # suppressed arguments are marked with None
- # remove | separators for suppressed arguments
- if action.help is SUPPRESS:
- parts.append(None)
- if inserts.get(i) == '|':
- inserts.pop(i)
- elif inserts.get(i + 1) == '|':
- inserts.pop(i + 1)
-
- # produce all arg strings
- elif not action.option_strings:
- part = self._format_args(action, action.dest)
-
- # if it's in a group, strip the outer []
- if action in group_actions:
- if part[0] == '[' and part[-1] == ']':
- part = part[1:-1]
-
- # add the action string to the list
- parts.append(part)
-
- # produce the first way to invoke the option in brackets
- else:
- option_string = action.option_strings[0]
-
- # if the Optional doesn't take a value, format is:
- # -s or --long
- if action.nargs == 0:
- part = '%s' % option_string
-
- # if the Optional takes a value, format is:
- # -s ARGS or --long ARGS
- else:
- default = action.dest.upper()
- args_string = self._format_args(action, default)
- part = '%s %s' % (option_string, args_string)
-
- # make it look optional if it's not required or in a group
- if not action.required and action not in group_actions:
- part = '[%s]' % part
-
- # add the action string to the list
- parts.append(part)
-
- # insert things at the necessary indices
- for i in sorted(inserts, reverse=True):
- parts[i:i] = [inserts[i]]
-
- # join all the action items with spaces
- text = ' '.join([item for item in parts if item is not None])
-
- # clean up separators for mutually exclusive groups
- open = r'[\[(]'
- close = r'[\])]'
- text = _re.sub(r'(%s) ' % open, r'\1', text)
- text = _re.sub(r' (%s)' % close, r'\1', text)
- text = _re.sub(r'%s *%s' % (open, close), r'', text)
- text = _re.sub(r'\(([^|]*)\)', r'\1', text)
- text = text.strip()
-
- # return the text
- return text
-
- def _format_text(self, text):
- if '%(prog)' in text:
- text = text % dict(prog=self._prog)
- text_width = self._width - self._current_indent
- indent = ' ' * self._current_indent
- return self._fill_text(text, text_width, indent) + '\n\n'
-
- def _format_action(self, action):
- # determine the required width and the entry label
- help_position = min(self._action_max_length + 2,
- self._max_help_position)
- help_width = self._width - help_position
- action_width = help_position - self._current_indent - 2
- action_header = self._format_action_invocation(action)
-
- # ho nelp; start on same line and add a final newline
- if not action.help:
- tup = self._current_indent, '', action_header
- action_header = '%*s%s\n' % tup
-
- # short action name; start on the same line and pad two spaces
- elif len(action_header) <= action_width:
- tup = self._current_indent, '', action_width, action_header
- action_header = '%*s%-*s ' % tup
- indent_first = 0
-
- # long action name; start on the next line
- else:
- tup = self._current_indent, '', action_header
- action_header = '%*s%s\n' % tup
- indent_first = help_position
-
- # collect the pieces of the action help
- parts = [action_header]
-
- # if there was help for the action, add lines of help text
- if action.help:
- help_text = self._expand_help(action)
- help_lines = self._split_lines(help_text, help_width)
- parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
- for line in help_lines[1:]:
- parts.append('%*s%s\n' % (help_position, '', line))
-
- # or add a newline if the description doesn't end with one
- elif not action_header.endswith('\n'):
- parts.append('\n')
-
- # if there are any sub-actions, add their help as well
- for subaction in self._iter_indented_subactions(action):
- parts.append(self._format_action(subaction))
-
- # return a single string
- return self._join_parts(parts)
-
- def _format_action_invocation(self, action):
- if not action.option_strings:
- metavar, = self._metavar_formatter(action, action.dest)(1)
- return metavar
-
- else:
- parts = []
-
- # if the Optional doesn't take a value, format is:
- # -s, --long
- if action.nargs == 0:
- parts.extend(action.option_strings)
-
- # if the Optional takes a value, format is:
- # -s ARGS, --long ARGS
- else:
- default = action.dest.upper()
- args_string = self._format_args(action, default)
- for option_string in action.option_strings:
- parts.append('%s %s' % (option_string, args_string))
-
- return ', '.join(parts)
-
- def _metavar_formatter(self, action, default_metavar):
- if action.metavar is not None:
- result = action.metavar
- elif action.choices is not None:
- choice_strs = [str(choice) for choice in action.choices]
- result = '{%s}' % ','.join(choice_strs)
- else:
- result = default_metavar
-
- def format(tuple_size):
- if isinstance(result, tuple):
- return result
- else:
- return (result, ) * tuple_size
- return format
-
- def _format_args(self, action, default_metavar):
- get_metavar = self._metavar_formatter(action, default_metavar)
- if action.nargs is None:
- result = '%s' % get_metavar(1)
- elif action.nargs == OPTIONAL:
- result = '[%s]' % get_metavar(1)
- elif action.nargs == ZERO_OR_MORE:
- result = '[%s [%s ...]]' % get_metavar(2)
- elif action.nargs == ONE_OR_MORE:
- result = '%s [%s ...]' % get_metavar(2)
- elif action.nargs == REMAINDER:
- result = '...'
- elif action.nargs == PARSER:
- result = '%s ...' % get_metavar(1)
- else:
- formats = ['%s' for _ in range(action.nargs)]
- result = ' '.join(formats) % get_metavar(action.nargs)
- return result
-
- def _expand_help(self, action):
- params = dict(vars(action), prog=self._prog)
- for name in list(params):
- if params[name] is SUPPRESS:
- del params[name]
- for name in list(params):
- if hasattr(params[name], '__name__'):
- params[name] = params[name].__name__
- if params.get('choices') is not None:
- choices_str = ', '.join([str(c) for c in params['choices']])
- params['choices'] = choices_str
- return self._get_help_string(action) % params
-
- def _iter_indented_subactions(self, action):
- try:
- get_subactions = action._get_subactions
- except AttributeError:
- pass
- else:
- self._indent()
- for subaction in get_subactions():
- yield subaction
- self._dedent()
-
- def _split_lines(self, text, width):
- text = self._whitespace_matcher.sub(' ', text).strip()
- return _textwrap.wrap(text, width)
-
- def _fill_text(self, text, width, indent):
- text = self._whitespace_matcher.sub(' ', text).strip()
- return _textwrap.fill(text, width, initial_indent=indent,
- subsequent_indent=indent)
-
- def _get_help_string(self, action):
- return action.help
-
-
-class RawDescriptionHelpFormatter(HelpFormatter):
- """Help message formatter which retains any formatting in descriptions.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def _fill_text(self, text, width, indent):
- return ''.join([indent + line for line in text.splitlines(True)])
-
-
-class RawTextHelpFormatter(RawDescriptionHelpFormatter):
- """Help message formatter which retains formatting of all help text.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def _split_lines(self, text, width):
- return text.splitlines()
-
-
-class ArgumentDefaultsHelpFormatter(HelpFormatter):
- """Help message formatter which adds default values to argument help.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def _get_help_string(self, action):
- help = action.help
- if '%(default)' not in action.help:
- if action.default is not SUPPRESS:
- defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
- if action.option_strings or action.nargs in defaulting_nargs:
- help += ' (default: %(default)s)'
- return help
-
-
-# =====================
-# Options and Arguments
-# =====================
-
-def _get_action_name(argument):
- if argument is None:
- return None
- elif argument.option_strings:
- return '/'.join(argument.option_strings)
- elif argument.metavar not in (None, SUPPRESS):
- return argument.metavar
- elif argument.dest not in (None, SUPPRESS):
- return argument.dest
- else:
- return None
-
-
-class ArgumentError(Exception):
- """An error from creating or using an argument (optional or positional).
-
- The string value of this exception is the message, augmented with
- information about the argument that caused it.
- """
-
- def __init__(self, argument, message):
- self.argument_name = _get_action_name(argument)
- self.message = message
-
- def __str__(self):
- if self.argument_name is None:
- format = '%(message)s'
- else:
- format = 'argument %(argument_name)s: %(message)s'
- return format % dict(message=self.message,
- argument_name=self.argument_name)
-
-
-class ArgumentTypeError(Exception):
- """An error from trying to convert a command line string to a type."""
- pass
-
-
-# ==============
-# Action classes
-# ==============
-
-class Action(_AttributeHolder):
- """Information about how to convert command line strings to Python objects.
-
- Action objects are used by an ArgumentParser to represent the information
- needed to parse a single argument from one or more strings from the
- command line. The keyword arguments to the Action constructor are also
- all attributes of Action instances.
-
- Keyword Arguments:
-
- - option_strings -- A list of command-line option strings which
- should be associated with this action.
-
- - dest -- The name of the attribute to hold the created object(s)
-
- - nargs -- The number of command-line arguments that should be
- consumed. By default, one argument will be consumed and a single
- value will be produced. Other values include:
- - N (an integer) consumes N arguments (and produces a list)
- - '?' consumes zero or one arguments
- - '*' consumes zero or more arguments (and produces a list)
- - '+' consumes one or more arguments (and produces a list)
- Note that the difference between the default and nargs=1 is that
- with the default, a single value will be produced, while with
- nargs=1, a list containing a single value will be produced.
-
- - const -- The value to be produced if the option is specified and the
- option uses an action that takes no values.
-
- - default -- The value to be produced if the option is not specified.
-
- - type -- The type which the command-line arguments should be converted
- to, should be one of 'string', 'int', 'float', 'complex' or a
- callable object that accepts a single string argument. If None,
- 'string' is assumed.
-
- - choices -- A container of values that should be allowed. If not None,
- after a command-line argument has been converted to the appropriate
- type, an exception will be raised if it is not a member of this
- collection.
-
- - required -- True if the action must always be specified at the
- command line. This is only meaningful for optional command-line
- arguments.
-
- - help -- The help string describing the argument.
-
- - metavar -- The name to be used for the option's argument with the
- help string. If None, the 'dest' value will be used as the name.
- """
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar=None):
- self.option_strings = option_strings
- self.dest = dest
- self.nargs = nargs
- self.const = const
- self.default = default
- self.type = type
- self.choices = choices
- self.required = required
- self.help = help
- self.metavar = metavar
-
- def _get_kwargs(self):
- names = [
- 'option_strings',
- 'dest',
- 'nargs',
- 'const',
- 'default',
- 'type',
- 'choices',
- 'help',
- 'metavar',
- ]
- return [(name, getattr(self, name)) for name in names]
-
- def __call__(self, parser, namespace, values, option_string=None):
- raise NotImplementedError(_('.__call__() not defined'))
-
-
-class _StoreAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar=None):
- if nargs == 0:
- raise ValueError('nargs for store actions must be > 0; if you '
- 'have nothing to store, actions such as store '
- 'true or store const may be more appropriate')
- if const is not None and nargs != OPTIONAL:
- raise ValueError('nargs must be %r to supply const' % OPTIONAL)
- super(_StoreAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, self.dest, values)
-
-
-class _StoreConstAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- const,
- default=None,
- required=False,
- help=None,
- metavar=None):
- super(_StoreConstAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=0,
- const=const,
- default=default,
- required=required,
- help=help)
-
- def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, self.dest, self.const)
-
-
-class _StoreTrueAction(_StoreConstAction):
-
- def __init__(self,
- option_strings,
- dest,
- default=False,
- required=False,
- help=None):
- super(_StoreTrueAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- const=True,
- default=default,
- required=required,
- help=help)
-
-
-class _StoreFalseAction(_StoreConstAction):
-
- def __init__(self,
- option_strings,
- dest,
- default=True,
- required=False,
- help=None):
- super(_StoreFalseAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- const=False,
- default=default,
- required=required,
- help=help)
-
-
-class _AppendAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar=None):
- if nargs == 0:
- raise ValueError('nargs for append actions must be > 0; if arg '
- 'strings are not supplying the value to append, '
- 'the append const action may be more appropriate')
- if const is not None and nargs != OPTIONAL:
- raise ValueError('nargs must be %r to supply const' % OPTIONAL)
- super(_AppendAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- items = _copy.copy(_ensure_value(namespace, self.dest, []))
- items.append(values)
- setattr(namespace, self.dest, items)
-
-
-class _AppendConstAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- const,
- default=None,
- required=False,
- help=None,
- metavar=None):
- super(_AppendConstAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=0,
- const=const,
- default=default,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- items = _copy.copy(_ensure_value(namespace, self.dest, []))
- items.append(self.const)
- setattr(namespace, self.dest, items)
-
-
-class _CountAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- default=None,
- required=False,
- help=None):
- super(_CountAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=0,
- default=default,
- required=required,
- help=help)
-
- def __call__(self, parser, namespace, values, option_string=None):
- new_count = _ensure_value(namespace, self.dest, 0) + 1
- setattr(namespace, self.dest, new_count)
-
-
-class _HelpAction(Action):
-
- def __init__(self,
- option_strings,
- dest=SUPPRESS,
- default=SUPPRESS,
- help=None):
- super(_HelpAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- default=default,
- nargs=0,
- help=help)
-
- def __call__(self, parser, namespace, values, option_string=None):
- parser.print_help()
- parser.exit()
-
-
-class _VersionAction(Action):
-
- def __init__(self,
- option_strings,
- version=None,
- dest=SUPPRESS,
- default=SUPPRESS,
- help="show program's version number and exit"):
- super(_VersionAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- default=default,
- nargs=0,
- help=help)
- self.version = version
-
- def __call__(self, parser, namespace, values, option_string=None):
- version = self.version
- if version is None:
- version = parser.version
- formatter = parser._get_formatter()
- formatter.add_text(version)
- parser.exit(message=formatter.format_help())
-
-
-class _SubParsersAction(Action):
-
- class _ChoicesPseudoAction(Action):
-
- def __init__(self, name, help):
- sup = super(_SubParsersAction._ChoicesPseudoAction, self)
- sup.__init__(option_strings=[], dest=name, help=help)
-
- def __init__(self,
- option_strings,
- prog,
- parser_class,
- dest=SUPPRESS,
- help=None,
- metavar=None):
-
- self._prog_prefix = prog
- self._parser_class = parser_class
- self._name_parser_map = {}
- self._choices_actions = []
-
- super(_SubParsersAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=PARSER,
- choices=self._name_parser_map,
- help=help,
- metavar=metavar)
-
- def add_parser(self, name, **kwargs):
- # set prog from the existing prefix
- if kwargs.get('prog') is None:
- kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
-
- # create a pseudo-action to hold the choice help
- if 'help' in kwargs:
- help = kwargs.pop('help')
- choice_action = self._ChoicesPseudoAction(name, help)
- self._choices_actions.append(choice_action)
-
- # create the parser and add it to the map
- parser = self._parser_class(**kwargs)
- self._name_parser_map[name] = parser
- return parser
-
- def _get_subactions(self):
- return self._choices_actions
-
- def __call__(self, parser, namespace, values, option_string=None):
- parser_name = values[0]
- arg_strings = values[1:]
-
- # set the parser name if requested
- if self.dest is not SUPPRESS:
- setattr(namespace, self.dest, parser_name)
-
- # select the parser
- try:
- parser = self._name_parser_map[parser_name]
- except KeyError:
- tup = parser_name, ', '.join(self._name_parser_map)
- msg = _('unknown parser %r (choices: %s)' % tup)
- raise ArgumentError(self, msg)
-
- # parse all the remaining options into the namespace
- # store any unrecognized options on the object, so that the top
- # level parser can decide what to do with them
- namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
- if arg_strings:
- vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
- getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
-
-
-# ==============
-# Type classes
-# ==============
-
-class FileType(object):
- """Factory for creating file object types
-
- Instances of FileType are typically passed as type= arguments to the
- ArgumentParser add_argument() method.
-
- Keyword Arguments:
- - mode -- A string indicating how the file is to be opened. Accepts the
- same values as the builtin open() function.
- - bufsize -- The file's desired buffer size. Accepts the same values as
- the builtin open() function.
- """
-
- def __init__(self, mode='r', bufsize=None):
- self._mode = mode
- self._bufsize = bufsize
-
- def __call__(self, string):
- # the special argument "-" means sys.std{in,out}
- if string == '-':
- if 'r' in self._mode:
- return _sys.stdin
- elif 'w' in self._mode:
- return _sys.stdout
- else:
- msg = _('argument "-" with mode %r' % self._mode)
- raise ValueError(msg)
-
- # all other arguments are used as file names
- if self._bufsize:
- return open(string, self._mode, self._bufsize)
- else:
- return open(string, self._mode)
-
- def __repr__(self):
- args = [self._mode, self._bufsize]
- args_str = ', '.join([repr(arg) for arg in args if arg is not None])
- return '%s(%s)' % (type(self).__name__, args_str)
-
-# ===========================
-# Optional and Positional Parsing
-# ===========================
-
-class Namespace(_AttributeHolder):
- """Simple object for storing attributes.
-
- Implements equality by attribute names and values, and provides a simple
- string representation.
- """
-
- def __init__(self, **kwargs):
- for name in kwargs:
- setattr(self, name, kwargs[name])
-
- __hash__ = None
-
- def __eq__(self, other):
- return vars(self) == vars(other)
-
- def __ne__(self, other):
- return not (self == other)
-
- def __contains__(self, key):
- return key in self.__dict__
-
-
-class _ActionsContainer(object):
-
- def __init__(self,
- description,
- prefix_chars,
- argument_default,
- conflict_handler):
- super(_ActionsContainer, self).__init__()
-
- self.description = description
- self.argument_default = argument_default
- self.prefix_chars = prefix_chars
- self.conflict_handler = conflict_handler
-
- # set up registries
- self._registries = {}
-
- # register actions
- self.register('action', None, _StoreAction)
- self.register('action', 'store', _StoreAction)
- self.register('action', 'store_const', _StoreConstAction)
- self.register('action', 'store_true', _StoreTrueAction)
- self.register('action', 'store_false', _StoreFalseAction)
- self.register('action', 'append', _AppendAction)
- self.register('action', 'append_const', _AppendConstAction)
- self.register('action', 'count', _CountAction)
- self.register('action', 'help', _HelpAction)
- self.register('action', 'version', _VersionAction)
- self.register('action', 'parsers', _SubParsersAction)
-
- # raise an exception if the conflict handler is invalid
- self._get_handler()
-
- # action storage
- self._actions = []
- self._option_string_actions = {}
-
- # groups
- self._action_groups = []
- self._mutually_exclusive_groups = []
-
- # defaults storage
- self._defaults = {}
-
- # determines whether an "option" looks like a negative number
- self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
-
- # whether or not there are any optionals that look like negative
- # numbers -- uses a list so it can be shared and edited
- self._has_negative_number_optionals = []
-
- # ====================
- # Registration methods
- # ====================
- def register(self, registry_name, value, object):
- registry = self._registries.setdefault(registry_name, {})
- registry[value] = object
-
- def _registry_get(self, registry_name, value, default=None):
- return self._registries[registry_name].get(value, default)
-
- # ==================================
- # Namespace default accessor methods
- # ==================================
- def set_defaults(self, **kwargs):
- self._defaults.update(kwargs)
-
- # if these defaults match any existing arguments, replace
- # the previous default on the object with the new one
- for action in self._actions:
- if action.dest in kwargs:
- action.default = kwargs[action.dest]
-
- def get_default(self, dest):
- for action in self._actions:
- if action.dest == dest and action.default is not None:
- return action.default
- return self._defaults.get(dest, None)
-
-
- # =======================
- # Adding argument actions
- # =======================
- def add_argument(self, *args, **kwargs):
- """
- add_argument(dest, ..., name=value, ...)
- add_argument(option_string, option_string, ..., name=value, ...)
- """
-
- # if no positional args are supplied or only one is supplied and
- # it doesn't look like an option string, parse a positional
- # argument
- chars = self.prefix_chars
- if not args or len(args) == 1 and args[0][0] not in chars:
- if args and 'dest' in kwargs:
- raise ValueError('dest supplied twice for positional argument')
- kwargs = self._get_positional_kwargs(*args, **kwargs)
-
- # otherwise, we're adding an optional argument
- else:
- kwargs = self._get_optional_kwargs(*args, **kwargs)
-
- # if no default was supplied, use the parser-level default
- if 'default' not in kwargs:
- dest = kwargs['dest']
- if dest in self._defaults:
- kwargs['default'] = self._defaults[dest]
- elif self.argument_default is not None:
- kwargs['default'] = self.argument_default
-
- # create the action object, and add it to the parser
- action_class = self._pop_action_class(kwargs)
- if not _callable(action_class):
- raise ValueError('unknown action "%s"' % action_class)
- action = action_class(**kwargs)
-
- # raise an error if the action type is not callable
- type_func = self._registry_get('type', action.type, action.type)
- if not _callable(type_func):
- raise ValueError('%r is not callable' % type_func)
-
- return self._add_action(action)
-
- def add_argument_group(self, *args, **kwargs):
- group = _ArgumentGroup(self, *args, **kwargs)
- self._action_groups.append(group)
- return group
-
- def add_mutually_exclusive_group(self, **kwargs):
- group = _MutuallyExclusiveGroup(self, **kwargs)
- self._mutually_exclusive_groups.append(group)
- return group
-
- def _add_action(self, action):
- # resolve any conflicts
- self._check_conflict(action)
-
- # add to actions list
- self._actions.append(action)
- action.container = self
-
- # index the action by any option strings it has
- for option_string in action.option_strings:
- self._option_string_actions[option_string] = action
-
- # set the flag if any option strings look like negative numbers
- for option_string in action.option_strings:
- if self._negative_number_matcher.match(option_string):
- if not self._has_negative_number_optionals:
- self._has_negative_number_optionals.append(True)
-
- # return the created action
- return action
-
- def _remove_action(self, action):
- self._actions.remove(action)
-
- def _add_container_actions(self, container):
- # collect groups by titles
- title_group_map = {}
- for group in self._action_groups:
- if group.title in title_group_map:
- msg = _('cannot merge actions - two groups are named %r')
- raise ValueError(msg % (group.title))
- title_group_map[group.title] = group
-
- # map each action to its group
- group_map = {}
- for group in container._action_groups:
-
- # if a group with the title exists, use that, otherwise
- # create a new group matching the container's group
- if group.title not in title_group_map:
- title_group_map[group.title] = self.add_argument_group(
- title=group.title,
- description=group.description,
- conflict_handler=group.conflict_handler)
-
- # map the actions to their new group
- for action in group._group_actions:
- group_map[action] = title_group_map[group.title]
-
- # add container's mutually exclusive groups
- # NOTE: if add_mutually_exclusive_group ever gains title= and
- # description= then this code will need to be expanded as above
- for group in container._mutually_exclusive_groups:
- mutex_group = self.add_mutually_exclusive_group(
- required=group.required)
-
- # map the actions to their new mutex group
- for action in group._group_actions:
- group_map[action] = mutex_group
-
- # add all actions to this container or their group
- for action in container._actions:
- group_map.get(action, self)._add_action(action)
-
- def _get_positional_kwargs(self, dest, **kwargs):
- # make sure required is not specified
- if 'required' in kwargs:
- msg = _("'required' is an invalid argument for positionals")
- raise TypeError(msg)
-
- # mark positional arguments as required if at least one is
- # always required
- if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
- kwargs['required'] = True
- if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
- kwargs['required'] = True
-
- # return the keyword arguments with no option strings
- return dict(kwargs, dest=dest, option_strings=[])
-
- def _get_optional_kwargs(self, *args, **kwargs):
- # determine short and long option strings
- option_strings = []
- long_option_strings = []
- for option_string in args:
- # error on strings that don't start with an appropriate prefix
- if not option_string[0] in self.prefix_chars:
- msg = _('invalid option string %r: '
- 'must start with a character %r')
- tup = option_string, self.prefix_chars
- raise ValueError(msg % tup)
-
- # strings starting with two prefix characters are long options
- option_strings.append(option_string)
- if option_string[0] in self.prefix_chars:
- if len(option_string) > 1:
- if option_string[1] in self.prefix_chars:
- long_option_strings.append(option_string)
-
- # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
- dest = kwargs.pop('dest', None)
- if dest is None:
- if long_option_strings:
- dest_option_string = long_option_strings[0]
- else:
- dest_option_string = option_strings[0]
- dest = dest_option_string.lstrip(self.prefix_chars)
- if not dest:
- msg = _('dest= is required for options like %r')
- raise ValueError(msg % option_string)
- dest = dest.replace('-', '_')
-
- # return the updated keyword arguments
- return dict(kwargs, dest=dest, option_strings=option_strings)
-
- def _pop_action_class(self, kwargs, default=None):
- action = kwargs.pop('action', default)
- return self._registry_get('action', action, action)
-
- def _get_handler(self):
- # determine function from conflict handler string
- handler_func_name = '_handle_conflict_%s' % self.conflict_handler
- try:
- return getattr(self, handler_func_name)
- except AttributeError:
- msg = _('invalid conflict_resolution value: %r')
- raise ValueError(msg % self.conflict_handler)
-
- def _check_conflict(self, action):
-
- # find all options that conflict with this option
- confl_optionals = []
- for option_string in action.option_strings:
- if option_string in self._option_string_actions:
- confl_optional = self._option_string_actions[option_string]
- confl_optionals.append((option_string, confl_optional))
-
- # resolve any conflicts
- if confl_optionals:
- conflict_handler = self._get_handler()
- conflict_handler(action, confl_optionals)
-
- def _handle_conflict_error(self, action, conflicting_actions):
- message = _('conflicting option string(s): %s')
- conflict_string = ', '.join([option_string
- for option_string, action
- in conflicting_actions])
- raise ArgumentError(action, message % conflict_string)
-
- def _handle_conflict_resolve(self, action, conflicting_actions):
-
- # remove all conflicting options
- for option_string, action in conflicting_actions:
-
- # remove the conflicting option
- action.option_strings.remove(option_string)
- self._option_string_actions.pop(option_string, None)
-
- # if the option now has no option string, remove it from the
- # container holding it
- if not action.option_strings:
- action.container._remove_action(action)
-
-
-class _ArgumentGroup(_ActionsContainer):
-
- def __init__(self, container, title=None, description=None, **kwargs):
- # add any missing keyword arguments by checking the container
- update = kwargs.setdefault
- update('conflict_handler', container.conflict_handler)
- update('prefix_chars', container.prefix_chars)
- update('argument_default', container.argument_default)
- super_init = super(_ArgumentGroup, self).__init__
- super_init(description=description, **kwargs)
-
- # group attributes
- self.title = title
- self._group_actions = []
-
- # share most attributes with the container
- self._registries = container._registries
- self._actions = container._actions
- self._option_string_actions = container._option_string_actions
- self._defaults = container._defaults
- self._has_negative_number_optionals = \
- container._has_negative_number_optionals
-
- def _add_action(self, action):
- action = super(_ArgumentGroup, self)._add_action(action)
- self._group_actions.append(action)
- return action
-
- def _remove_action(self, action):
- super(_ArgumentGroup, self)._remove_action(action)
- self._group_actions.remove(action)
-
-
-class _MutuallyExclusiveGroup(_ArgumentGroup):
-
- def __init__(self, container, required=False):
- super(_MutuallyExclusiveGroup, self).__init__(container)
- self.required = required
- self._container = container
-
- def _add_action(self, action):
- if action.required:
- msg = _('mutually exclusive arguments must be optional')
- raise ValueError(msg)
- action = self._container._add_action(action)
- self._group_actions.append(action)
- return action
-
- def _remove_action(self, action):
- self._container._remove_action(action)
- self._group_actions.remove(action)
-
-
-class ArgumentParser(_AttributeHolder, _ActionsContainer):
- """Object for parsing command line strings into Python objects.
-
- Keyword Arguments:
- - prog -- The name of the program (default: sys.argv[0])
- - usage -- A usage message (default: auto-generated from arguments)
- - description -- A description of what the program does
- - epilog -- Text following the argument descriptions
- - parents -- Parsers whose arguments should be copied into this one
- - formatter_class -- HelpFormatter class for printing help messages
- - prefix_chars -- Characters that prefix optional arguments
- - fromfile_prefix_chars -- Characters that prefix files containing
- additional arguments
- - argument_default -- The default value for all arguments
- - conflict_handler -- String indicating how to handle conflicts
- - add_help -- Add a -h/-help option
- """
-
- def __init__(self,
- prog=None,
- usage=None,
- description=None,
- epilog=None,
- version=None,
- parents=[],
- formatter_class=HelpFormatter,
- prefix_chars='-',
- fromfile_prefix_chars=None,
- argument_default=None,
- conflict_handler='error',
- add_help=True):
-
- if version is not None:
- import warnings
- warnings.warn(
- """The "version" argument to ArgumentParser is deprecated. """
- """Please use """
- """"add_argument(..., action='version', version="N", ...)" """
- """instead""", DeprecationWarning)
-
- superinit = super(ArgumentParser, self).__init__
- superinit(description=description,
- prefix_chars=prefix_chars,
- argument_default=argument_default,
- conflict_handler=conflict_handler)
-
- # default setting for prog
- if prog is None:
- prog = _os.path.basename(_sys.argv[0])
-
- self.prog = prog
- self.usage = usage
- self.epilog = epilog
- self.version = version
- self.formatter_class = formatter_class
- self.fromfile_prefix_chars = fromfile_prefix_chars
- self.add_help = add_help
-
- add_group = self.add_argument_group
- self._positionals = add_group(_('positional arguments'))
- self._optionals = add_group(_('optional arguments'))
- self._subparsers = None
-
- # register types
- def identity(string):
- return string
- self.register('type', None, identity)
-
- # add help and version arguments if necessary
- # (using explicit default to override global argument_default)
- if '-' in prefix_chars:
- default_prefix = '-'
- else:
- default_prefix = prefix_chars[0]
- if self.add_help:
- self.add_argument(
- default_prefix+'h', default_prefix*2+'help',
- action='help', default=SUPPRESS,
- help=_('show this help message and exit'))
- if self.version:
- self.add_argument(
- default_prefix+'v', default_prefix*2+'version',
- action='version', default=SUPPRESS,
- version=self.version,
- help=_("show program's version number and exit"))
-
- # add parent arguments and defaults
- for parent in parents:
- self._add_container_actions(parent)
- try:
- defaults = parent._defaults
- except AttributeError:
- pass
- else:
- self._defaults.update(defaults)
-
- # =======================
- # Pretty __repr__ methods
- # =======================
- def _get_kwargs(self):
- names = [
- 'prog',
- 'usage',
- 'description',
- 'version',
- 'formatter_class',
- 'conflict_handler',
- 'add_help',
- ]
- return [(name, getattr(self, name)) for name in names]
-
- # ==================================
- # Optional/Positional adding methods
- # ==================================
- def add_subparsers(self, **kwargs):
- if self._subparsers is not None:
- self.error(_('cannot have multiple subparser arguments'))
-
- # add the parser class to the arguments if it's not present
- kwargs.setdefault('parser_class', type(self))
-
- if 'title' in kwargs or 'description' in kwargs:
- title = _(kwargs.pop('title', 'subcommands'))
- description = _(kwargs.pop('description', None))
- self._subparsers = self.add_argument_group(title, description)
- else:
- self._subparsers = self._positionals
-
- # prog defaults to the usage message of this parser, skipping
- # optional arguments and with no "usage:" prefix
- if kwargs.get('prog') is None:
- formatter = self._get_formatter()
- positionals = self._get_positional_actions()
- groups = self._mutually_exclusive_groups
- formatter.add_usage(self.usage, positionals, groups, '')
- kwargs['prog'] = formatter.format_help().strip()
-
- # create the parsers action and add it to the positionals list
- parsers_class = self._pop_action_class(kwargs, 'parsers')
- action = parsers_class(option_strings=[], **kwargs)
- self._subparsers._add_action(action)
-
- # return the created parsers action
- return action
-
- def _add_action(self, action):
- if action.option_strings:
- self._optionals._add_action(action)
- else:
- self._positionals._add_action(action)
- return action
-
- def _get_optional_actions(self):
- return [action
- for action in self._actions
- if action.option_strings]
-
- def _get_positional_actions(self):
- return [action
- for action in self._actions
- if not action.option_strings]
-
- # =====================================
- # Command line argument parsing methods
- # =====================================
- def parse_args(self, args=None, namespace=None):
- args, argv = self.parse_known_args(args, namespace)
- if argv:
- msg = _('unrecognized arguments: %s')
- self.error(msg % ' '.join(argv))
- return args
-
- def parse_known_args(self, args=None, namespace=None):
- # args default to the system args
- if args is None:
- args = _sys.argv[1:]
-
- # default Namespace built from parser defaults
- if namespace is None:
- namespace = Namespace()
-
- # add any action defaults that aren't present
- for action in self._actions:
- if action.dest is not SUPPRESS:
- if not hasattr(namespace, action.dest):
- if action.default is not SUPPRESS:
- default = action.default
- if isinstance(action.default, basestring):
- default = self._get_value(action, default)
- setattr(namespace, action.dest, default)
-
- # add any parser defaults that aren't present
- for dest in self._defaults:
- if not hasattr(namespace, dest):
- setattr(namespace, dest, self._defaults[dest])
-
- # parse the arguments and exit if there are any errors
- try:
- namespace, args = self._parse_known_args(args, namespace)
- if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
- args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
- delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
- return namespace, args
- except ArgumentError:
- err = _sys.exc_info()[1]
- self.error(str(err))
-
- def _parse_known_args(self, arg_strings, namespace):
- # replace arg strings that are file references
- if self.fromfile_prefix_chars is not None:
- arg_strings = self._read_args_from_files(arg_strings)
-
- # map all mutually exclusive arguments to the other arguments
- # they can't occur with
- action_conflicts = {}
- for mutex_group in self._mutually_exclusive_groups:
- group_actions = mutex_group._group_actions
- for i, mutex_action in enumerate(mutex_group._group_actions):
- conflicts = action_conflicts.setdefault(mutex_action, [])
- conflicts.extend(group_actions[:i])
- conflicts.extend(group_actions[i + 1:])
-
- # find all option indices, and determine the arg_string_pattern
- # which has an 'O' if there is an option at an index,
- # an 'A' if there is an argument, or a '-' if there is a '--'
- option_string_indices = {}
- arg_string_pattern_parts = []
- arg_strings_iter = iter(arg_strings)
- for i, arg_string in enumerate(arg_strings_iter):
-
- # all args after -- are non-options
- if arg_string == '--':
- arg_string_pattern_parts.append('-')
- for arg_string in arg_strings_iter:
- arg_string_pattern_parts.append('A')
-
- # otherwise, add the arg to the arg strings
- # and note the index if it was an option
- else:
- option_tuple = self._parse_optional(arg_string)
- if option_tuple is None:
- pattern = 'A'
- else:
- option_string_indices[i] = option_tuple
- pattern = 'O'
- arg_string_pattern_parts.append(pattern)
-
- # join the pieces together to form the pattern
- arg_strings_pattern = ''.join(arg_string_pattern_parts)
-
- # converts arg strings to the appropriate and then takes the action
- seen_actions = set()
- seen_non_default_actions = set()
-
- def take_action(action, argument_strings, option_string=None):
- seen_actions.add(action)
- argument_values = self._get_values(action, argument_strings)
-
- # error if this argument is not allowed with other previously
- # seen arguments, assuming that actions that use the default
- # value don't really count as "present"
- if argument_values is not action.default:
- seen_non_default_actions.add(action)
- for conflict_action in action_conflicts.get(action, []):
- if conflict_action in seen_non_default_actions:
- msg = _('not allowed with argument %s')
- action_name = _get_action_name(conflict_action)
- raise ArgumentError(action, msg % action_name)
-
- # take the action if we didn't receive a SUPPRESS value
- # (e.g. from a default)
- if argument_values is not SUPPRESS:
- action(self, namespace, argument_values, option_string)
-
- # function to convert arg_strings into an optional action
- def consume_optional(start_index):
-
- # get the optional identified at this index
- option_tuple = option_string_indices[start_index]
- action, option_string, explicit_arg = option_tuple
-
- # identify additional optionals in the same arg string
- # (e.g. -xyz is the same as -x -y -z if no args are required)
- match_argument = self._match_argument
- action_tuples = []
- while True:
-
- # if we found no optional action, skip it
- if action is None:
- extras.append(arg_strings[start_index])
- return start_index + 1
-
- # if there is an explicit argument, try to match the
- # optional's string arguments to only this
- if explicit_arg is not None:
- arg_count = match_argument(action, 'A')
-
- # if the action is a single-dash option and takes no
- # arguments, try to parse more single-dash options out
- # of the tail of the option string
- chars = self.prefix_chars
- if arg_count == 0 and option_string[1] not in chars:
- action_tuples.append((action, [], option_string))
- char = option_string[0]
- option_string = char + explicit_arg[0]
- new_explicit_arg = explicit_arg[1:] or None
- optionals_map = self._option_string_actions
- if option_string in optionals_map:
- action = optionals_map[option_string]
- explicit_arg = new_explicit_arg
- else:
- msg = _('ignored explicit argument %r')
- raise ArgumentError(action, msg % explicit_arg)
-
- # if the action expect exactly one argument, we've
- # successfully matched the option; exit the loop
- elif arg_count == 1:
- stop = start_index + 1
- args = [explicit_arg]
- action_tuples.append((action, args, option_string))
- break
-
- # error if a double-dash option did not use the
- # explicit argument
- else:
- msg = _('ignored explicit argument %r')
- raise ArgumentError(action, msg % explicit_arg)
-
- # if there is no explicit argument, try to match the
- # optional's string arguments with the following strings
- # if successful, exit the loop
- else:
- start = start_index + 1
- selected_patterns = arg_strings_pattern[start:]
- arg_count = match_argument(action, selected_patterns)
- stop = start + arg_count
- args = arg_strings[start:stop]
- action_tuples.append((action, args, option_string))
- break
-
- # add the Optional to the list and return the index at which
- # the Optional's string args stopped
- assert action_tuples
- for action, args, option_string in action_tuples:
- take_action(action, args, option_string)
- return stop
-
- # the list of Positionals left to be parsed; this is modified
- # by consume_positionals()
- positionals = self._get_positional_actions()
-
- # function to convert arg_strings into positional actions
- def consume_positionals(start_index):
- # match as many Positionals as possible
- match_partial = self._match_arguments_partial
- selected_pattern = arg_strings_pattern[start_index:]
- arg_counts = match_partial(positionals, selected_pattern)
-
- # slice off the appropriate arg strings for each Positional
- # and add the Positional and its args to the list
- for action, arg_count in zip(positionals, arg_counts):
- args = arg_strings[start_index: start_index + arg_count]
- start_index += arg_count
- take_action(action, args)
-
- # slice off the Positionals that we just parsed and return the
- # index at which the Positionals' string args stopped
- positionals[:] = positionals[len(arg_counts):]
- return start_index
-
- # consume Positionals and Optionals alternately, until we have
- # passed the last option string
- extras = []
- start_index = 0
- if option_string_indices:
- max_option_string_index = max(option_string_indices)
- else:
- max_option_string_index = -1
- while start_index <= max_option_string_index:
-
- # consume any Positionals preceding the next option
- next_option_string_index = min([
- index
- for index in option_string_indices
- if index >= start_index])
- if start_index != next_option_string_index:
- positionals_end_index = consume_positionals(start_index)
-
- # only try to parse the next optional if we didn't consume
- # the option string during the positionals parsing
- if positionals_end_index > start_index:
- start_index = positionals_end_index
- continue
- else:
- start_index = positionals_end_index
-
- # if we consumed all the positionals we could and we're not
- # at the index of an option string, there were extra arguments
- if start_index not in option_string_indices:
- strings = arg_strings[start_index:next_option_string_index]
- extras.extend(strings)
- start_index = next_option_string_index
-
- # consume the next optional and any arguments for it
- start_index = consume_optional(start_index)
-
- # consume any positionals following the last Optional
- stop_index = consume_positionals(start_index)
-
- # if we didn't consume all the argument strings, there were extras
- extras.extend(arg_strings[stop_index:])
-
- # if we didn't use all the Positional objects, there were too few
- # arg strings supplied.
- if positionals:
- self.error(_('too few arguments'))
-
- # make sure all required actions were present
- for action in self._actions:
- if action.required:
- if action not in seen_actions:
- name = _get_action_name(action)
- self.error(_('argument %s is required') % name)
-
- # make sure all required groups had one option present
- for group in self._mutually_exclusive_groups:
- if group.required:
- for action in group._group_actions:
- if action in seen_non_default_actions:
- break
-
- # if no actions were used, report the error
- else:
- names = [_get_action_name(action)
- for action in group._group_actions
- if action.help is not SUPPRESS]
- msg = _('one of the arguments %s is required')
- self.error(msg % ' '.join(names))
-
- # return the updated namespace and the extra arguments
- return namespace, extras
-
- def _read_args_from_files(self, arg_strings):
- # expand arguments referencing files
- new_arg_strings = []
- for arg_string in arg_strings:
-
- # for regular arguments, just add them back into the list
- if arg_string[0] not in self.fromfile_prefix_chars:
- new_arg_strings.append(arg_string)
-
- # replace arguments referencing files with the file content
- else:
- try:
- args_file = open(arg_string[1:])
- try:
- arg_strings = []
- for arg_line in args_file.read().splitlines():
- for arg in self.convert_arg_line_to_args(arg_line):
- arg_strings.append(arg)
- arg_strings = self._read_args_from_files(arg_strings)
- new_arg_strings.extend(arg_strings)
- finally:
- args_file.close()
- except IOError:
- err = _sys.exc_info()[1]
- self.error(str(err))
-
- # return the modified argument list
- return new_arg_strings
-
- def convert_arg_line_to_args(self, arg_line):
- return [arg_line]
-
- def _match_argument(self, action, arg_strings_pattern):
- # match the pattern for this action to the arg strings
- nargs_pattern = self._get_nargs_pattern(action)
- match = _re.match(nargs_pattern, arg_strings_pattern)
-
- # raise an exception if we weren't able to find a match
- if match is None:
- nargs_errors = {
- None: _('expected one argument'),
- OPTIONAL: _('expected at most one argument'),
- ONE_OR_MORE: _('expected at least one argument'),
- }
- default = _('expected %s argument(s)') % action.nargs
- msg = nargs_errors.get(action.nargs, default)
- raise ArgumentError(action, msg)
-
- # return the number of arguments matched
- return len(match.group(1))
-
- def _match_arguments_partial(self, actions, arg_strings_pattern):
- # progressively shorten the actions list by slicing off the
- # final actions until we find a match
- result = []
- for i in range(len(actions), 0, -1):
- actions_slice = actions[:i]
- pattern = ''.join([self._get_nargs_pattern(action)
- for action in actions_slice])
- match = _re.match(pattern, arg_strings_pattern)
- if match is not None:
- result.extend([len(string) for string in match.groups()])
- break
-
- # return the list of arg string counts
- return result
-
- def _parse_optional(self, arg_string):
- # if it's an empty string, it was meant to be a positional
- if not arg_string:
- return None
-
- # if it doesn't start with a prefix, it was meant to be positional
- if not arg_string[0] in self.prefix_chars:
- return None
-
- # if the option string is present in the parser, return the action
- if arg_string in self._option_string_actions:
- action = self._option_string_actions[arg_string]
- return action, arg_string, None
-
- # if it's just a single character, it was meant to be positional
- if len(arg_string) == 1:
- return None
-
- # if the option string before the "=" is present, return the action
- if '=' in arg_string:
- option_string, explicit_arg = arg_string.split('=', 1)
- if option_string in self._option_string_actions:
- action = self._option_string_actions[option_string]
- return action, option_string, explicit_arg
-
- # search through all possible prefixes of the option string
- # and all actions in the parser for possible interpretations
- option_tuples = self._get_option_tuples(arg_string)
-
- # if multiple actions match, the option string was ambiguous
- if len(option_tuples) > 1:
- options = ', '.join([option_string
- for action, option_string, explicit_arg in option_tuples])
- tup = arg_string, options
- self.error(_('ambiguous option: %s could match %s') % tup)
-
- # if exactly one action matched, this segmentation is good,
- # so return the parsed action
- elif len(option_tuples) == 1:
- option_tuple, = option_tuples
- return option_tuple
-
- # if it was not found as an option, but it looks like a negative
- # number, it was meant to be positional
- # unless there are negative-number-like options
- if self._negative_number_matcher.match(arg_string):
- if not self._has_negative_number_optionals:
- return None
-
- # if it contains a space, it was meant to be a positional
- if ' ' in arg_string:
- return None
-
- # it was meant to be an optional but there is no such option
- # in this parser (though it might be a valid option in a subparser)
- return None, arg_string, None
-
- def _get_option_tuples(self, option_string):
- result = []
-
- # option strings starting with two prefix characters are only
- # split at the '='
- chars = self.prefix_chars
- if option_string[0] in chars and option_string[1] in chars:
- if '=' in option_string:
- option_prefix, explicit_arg = option_string.split('=', 1)
- else:
- option_prefix = option_string
- explicit_arg = None
- for option_string in self._option_string_actions:
- if option_string.startswith(option_prefix):
- action = self._option_string_actions[option_string]
- tup = action, option_string, explicit_arg
- result.append(tup)
-
- # single character options can be concatenated with their arguments
- # but multiple character options always have to have their argument
- # separate
- elif option_string[0] in chars and option_string[1] not in chars:
- option_prefix = option_string
- explicit_arg = None
- short_option_prefix = option_string[:2]
- short_explicit_arg = option_string[2:]
-
- for option_string in self._option_string_actions:
- if option_string == short_option_prefix:
- action = self._option_string_actions[option_string]
- tup = action, option_string, short_explicit_arg
- result.append(tup)
- elif option_string.startswith(option_prefix):
- action = self._option_string_actions[option_string]
- tup = action, option_string, explicit_arg
- result.append(tup)
-
- # shouldn't ever get here
- else:
- self.error(_('unexpected option string: %s') % option_string)
-
- # return the collected option tuples
- return result
-
- def _get_nargs_pattern(self, action):
- # in all examples below, we have to allow for '--' args
- # which are represented as '-' in the pattern
- nargs = action.nargs
-
- # the default (None) is assumed to be a single argument
- if nargs is None:
- nargs_pattern = '(-*A-*)'
-
- # allow zero or one arguments
- elif nargs == OPTIONAL:
- nargs_pattern = '(-*A?-*)'
-
- # allow zero or more arguments
- elif nargs == ZERO_OR_MORE:
- nargs_pattern = '(-*[A-]*)'
-
- # allow one or more arguments
- elif nargs == ONE_OR_MORE:
- nargs_pattern = '(-*A[A-]*)'
-
- # allow any number of options or arguments
- elif nargs == REMAINDER:
- nargs_pattern = '([-AO]*)'
-
- # allow one argument followed by any number of options or arguments
- elif nargs == PARSER:
- nargs_pattern = '(-*A[-AO]*)'
-
- # all others should be integers
- else:
- nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
-
- # if this is an optional action, -- is not allowed
- if action.option_strings:
- nargs_pattern = nargs_pattern.replace('-*', '')
- nargs_pattern = nargs_pattern.replace('-', '')
-
- # return the pattern
- return nargs_pattern
-
- # ========================
- # Value conversion methods
- # ========================
- def _get_values(self, action, arg_strings):
- # for everything but PARSER args, strip out '--'
- if action.nargs not in [PARSER, REMAINDER]:
- arg_strings = [s for s in arg_strings if s != '--']
-
- # optional argument produces a default when not present
- if not arg_strings and action.nargs == OPTIONAL:
- if action.option_strings:
- value = action.const
- else:
- value = action.default
- if isinstance(value, basestring):
- value = self._get_value(action, value)
- self._check_value(action, value)
-
- # when nargs='*' on a positional, if there were no command-line
- # args, use the default if it is anything other than None
- elif (not arg_strings and action.nargs == ZERO_OR_MORE and
- not action.option_strings):
- if action.default is not None:
- value = action.default
- else:
- value = arg_strings
- self._check_value(action, value)
-
- # single argument or optional argument produces a single value
- elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
- arg_string, = arg_strings
- value = self._get_value(action, arg_string)
- self._check_value(action, value)
-
- # REMAINDER arguments convert all values, checking none
- elif action.nargs == REMAINDER:
- value = [self._get_value(action, v) for v in arg_strings]
-
- # PARSER arguments convert all values, but check only the first
- elif action.nargs == PARSER:
- value = [self._get_value(action, v) for v in arg_strings]
- self._check_value(action, value[0])
-
- # all other types of nargs produce a list
- else:
- value = [self._get_value(action, v) for v in arg_strings]
- for v in value:
- self._check_value(action, v)
-
- # return the converted value
- return value
-
- def _get_value(self, action, arg_string):
- type_func = self._registry_get('type', action.type, action.type)
- if not _callable(type_func):
- msg = _('%r is not callable')
- raise ArgumentError(action, msg % type_func)
-
- # convert the value to the appropriate type
- try:
- result = type_func(arg_string)
-
- # ArgumentTypeErrors indicate errors
- except ArgumentTypeError:
- name = getattr(action.type, '__name__', repr(action.type))
- msg = str(_sys.exc_info()[1])
- raise ArgumentError(action, msg)
-
- # TypeErrors or ValueErrors also indicate errors
- except (TypeError, ValueError):
- name = getattr(action.type, '__name__', repr(action.type))
- msg = _('invalid %s value: %r')
- raise ArgumentError(action, msg % (name, arg_string))
-
- # return the converted value
- return result
-
- def _check_value(self, action, value):
- # converted value must be one of the choices (if specified)
- if action.choices is not None and value not in action.choices:
- tup = value, ', '.join(map(repr, action.choices))
- msg = _('invalid choice: %r (choose from %s)') % tup
- raise ArgumentError(action, msg)
-
- # =======================
- # Help-formatting methods
- # =======================
- def format_usage(self):
- formatter = self._get_formatter()
- formatter.add_usage(self.usage, self._actions,
- self._mutually_exclusive_groups)
- return formatter.format_help()
-
- def format_help(self):
- formatter = self._get_formatter()
-
- # usage
- formatter.add_usage(self.usage, self._actions,
- self._mutually_exclusive_groups)
-
- # description
- formatter.add_text(self.description)
-
- # positionals, optionals and user-defined groups
- for action_group in self._action_groups:
- formatter.start_section(action_group.title)
- formatter.add_text(action_group.description)
- formatter.add_arguments(action_group._group_actions)
- formatter.end_section()
-
- # epilog
- formatter.add_text(self.epilog)
-
- # determine help from format above
- return formatter.format_help()
-
- def format_version(self):
- import warnings
- warnings.warn(
- 'The format_version method is deprecated -- the "version" '
- 'argument to ArgumentParser is no longer supported.',
- DeprecationWarning)
- formatter = self._get_formatter()
- formatter.add_text(self.version)
- return formatter.format_help()
-
- def _get_formatter(self):
- return self.formatter_class(prog=self.prog)
-
- # =====================
- # Help-printing methods
- # =====================
- def print_usage(self, file=None):
- if file is None:
- file = _sys.stdout
- self._print_message(self.format_usage(), file)
-
- def print_help(self, file=None):
- if file is None:
- file = _sys.stdout
- self._print_message(self.format_help(), file)
-
- def print_version(self, file=None):
- import warnings
- warnings.warn(
- 'The print_version method is deprecated -- the "version" '
- 'argument to ArgumentParser is no longer supported.',
- DeprecationWarning)
- self._print_message(self.format_version(), file)
-
- def _print_message(self, message, file=None):
- if message:
- if file is None:
- file = _sys.stderr
- file.write(message)
-
- # ===============
- # Exiting methods
- # ===============
- def exit(self, status=0, message=None):
- if message:
- self._print_message(message, _sys.stderr)
- _sys.exit(status)
-
- def error(self, message):
- """error(message: string)
-
- Prints a usage message incorporating the message to stderr and
- exits.
-
- If you override this in a subclass, it should not return -- it
- should either exit or raise an exception.
- """
- self.print_usage(_sys.stderr)
- self.exit(2, _('%s: error: %s\n') % (self.prog, message))
diff --git a/lib/taurus/external/enum/enum/__init__.py b/lib/taurus/external/enum/enum/__init__.py
deleted file mode 100644
index cbc3fba..0000000
--- a/lib/taurus/external/enum/enum/__init__.py
+++ /dev/null
@@ -1,809 +0,0 @@
-# Copyright (c) 2013, Ethan Furman.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# Redistributions of source code must retain the above
-# copyright notice, this list of conditions and the
-# following disclaimer.
-#
-# Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials
-# provided with the distribution.
-#
-# Neither the name Ethan Furman nor the names of any
-# contributors may be used to endorse or promote products
-# derived from this software without specific prior written
-# permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-"""Python Enumerations"""
-
-import sys as _sys
-
-__all__ = ['Enum', 'IntEnum', 'unique']
-
-pyver = float('%s.%s' % _sys.version_info[:2])
-
-try:
- any
-except NameError:
- def any(iterable):
- for element in iterable:
- if element:
- return True
- return False
-
-try:
- from collections import OrderedDict
-except ImportError:
- OrderedDict = None
-
-try:
- basestring
-except NameError:
- # In Python 2 basestring is the ancestor of both str and unicode
- # in Python 3 it's just str, but was missing in 3.1
- basestring = str
-
-class _RouteClassAttributeToGetattr(object):
- """Route attribute access on a class to __getattr__.
-
- This is a descriptor, used to define attributes that act differently when
- accessed through an instance and through a class. Instance access remains
- normal, but access to an attribute through a class will be routed to the
- class's __getattr__ method; this is done by raising AttributeError.
-
- """
- def __init__(self, fget=None):
- self.fget = fget
-
- def __get__(self, instance, ownerclass=None):
- if instance is None:
- raise AttributeError()
- return self.fget(instance)
-
- def __set__(self, instance, value):
- raise AttributeError("can't set attribute")
-
- def __delete__(self, instance):
- raise AttributeError("can't delete attribute")
-
-
-def _is_descriptor(obj):
- """Returns True if obj is a descriptor, False otherwise."""
- return (
- hasattr(obj, '__get__') or
- hasattr(obj, '__set__') or
- hasattr(obj, '__delete__'))
-
-
-def _is_dunder(name):
- """Returns True if a __dunder__ name, False otherwise."""
- return (name[:2] == name[-2:] == '__' and
- name[2:3] != '_' and
- name[-3:-2] != '_' and
- len(name) > 4)
-
-
-def _is_sunder(name):
- """Returns True if a _sunder_ name, False otherwise."""
- return (name[0] == name[-1] == '_' and
- name[1:2] != '_' and
- name[-2:-1] != '_' and
- len(name) > 2)
-
-
-def _make_class_unpicklable(cls):
- """Make the given class un-picklable."""
- def _break_on_call_reduce(self, protocol=None):
- raise TypeError('%r cannot be pickled' % self)
- cls.__reduce_ex__ = _break_on_call_reduce
- #cls.__reduce__ = _break_on_call_reduce
- cls.__module__ = '<unknown>'
-
-
-class _EnumDict(dict):
- """Track enum member order and ensure member names are not reused.
-
- EnumMeta will use the names found in self._member_names as the
- enumeration member names.
-
- """
- def __init__(self):
- super(_EnumDict, self).__init__()
- self._member_names = []
-
- def __setitem__(self, key, value):
- """Changes anything not dundered or not a descriptor.
-
- If a descriptor is added with the same name as an enum member, the name
- is removed from _member_names (this may leave a hole in the numerical
- sequence of values).
-
- If an enum member name is used twice, an error is raised; duplicate
- values are not checked for.
-
- Single underscore (sunder) names are reserved.
-
- Note: in 3.x __order__ is simply discarded as a not necessary piece
- leftover from 2.x
-
- """
- if pyver >= 3.0 and key == '__order__':
- return
- if _is_sunder(key):
- raise ValueError('_names_ are reserved for future Enum use')
- elif _is_dunder(key):
- pass
- elif key in self._member_names:
- # descriptor overwriting an enum?
- raise TypeError('Attempted to reuse key: %r' % key)
- elif not _is_descriptor(value):
- if key in self:
- # enum overwriting a descriptor?
- raise TypeError('Key already defined as: %r' % self[key])
- self._member_names.append(key)
- super(_EnumDict, self).__setitem__(key, value)
-
-
-# Dummy value for Enum as EnumMeta explicity checks for it, but of course until
-# EnumMeta finishes running the first time the Enum class doesn't exist. This
-# is also why there are checks in EnumMeta like `if Enum is not None`
-Enum = None
-
-
-class EnumMeta(type):
- """Metaclass for Enum"""
- @classmethod
- def __prepare__(metacls, cls, bases):
- return _EnumDict()
-
- def __new__(metacls, cls, bases, classdict):
- # an Enum class is final once enumeration items have been defined; it
- # cannot be mixed with other types (int, float, etc.) if it has an
- # inherited __new__ unless a new __new__ is defined (or the resulting
- # class will fail).
- if type(classdict) is dict:
- original_dict = classdict
- classdict = _EnumDict()
- for k, v in original_dict.items():
- classdict[k] = v
-
- member_type, first_enum = metacls._get_mixins_(bases)
- #if member_type is object:
- # use_args = False
- #else:
- # use_args = True
- __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
- first_enum)
- # save enum items into separate mapping so they don't get baked into
- # the new class
- members = dict((k, classdict[k]) for k in classdict._member_names)
- for name in classdict._member_names:
- del classdict[name]
-
- # py2 support for definition order
- __order__ = classdict.get('__order__')
- if __order__ is None:
- __order__ = classdict._member_names
- if pyver < 3.0:
- order_specified = False
- else:
- order_specified = True
- else:
- del classdict['__order__']
- order_specified = True
- if pyver < 3.0:
- __order__ = __order__.replace(',', ' ').split()
- aliases = [name for name in members if name not in __order__]
- __order__ += aliases
-
- # check for illegal enum names (any others?)
- invalid_names = set(members) & set(['mro'])
- if invalid_names:
- raise ValueError('Invalid enum member name(s): %s' % (
- ', '.join(invalid_names), ))
-
- # create our new Enum type
- enum_class = super(EnumMeta, metacls).__new__(metacls, cls, bases, classdict)
- enum_class._member_names_ = [] # names in random order
- if order_specified and OrderedDict is not None:
- enum_class._member_map_ = OrderedDict()
- else:
- enum_class._member_map_ = {} # name->value map
- enum_class._member_type_ = member_type
-
- # Reverse value->name map for hashable values.
- enum_class._value2member_map_ = {}
-
- # instantiate them, checking for duplicates as we go
- # we instantiate first instead of checking for duplicates first in case
- # a custom __new__ is doing something funky with the values -- such as
- # auto-numbering ;)
- if __new__ is None:
- __new__ = enum_class.__new__
- for member_name in __order__:
- value = members[member_name]
- if not isinstance(value, tuple):
- args = (value, )
- else:
- args = value
- if member_type is tuple: # special case for tuple enums
- args = (args, ) # wrap it one more time
- if not use_args or not args:
- enum_member = __new__(enum_class)
- if not hasattr(enum_member, '_value_'):
- enum_member._value_ = value
- else:
- enum_member = __new__(enum_class, *args)
- if not hasattr(enum_member, '_value_'):
- enum_member._value_ = member_type(*args)
- value = enum_member._value_
- enum_member._name_ = member_name
- enum_member.__objclass__ = enum_class
- enum_member.__init__(*args)
- # If another member with the same value was already defined, the
- # new member becomes an alias to the existing one.
- for name, canonical_member in enum_class._member_map_.items():
- if canonical_member.value == enum_member._value_:
- enum_member = canonical_member
- break
- else:
- # Aliases don't appear in member names (only in __members__).
- enum_class._member_names_.append(member_name)
- enum_class._member_map_[member_name] = enum_member
- try:
- # This may fail if value is not hashable. We can't add the value
- # to the map, and by-value lookups for this value will be
- # linear.
- enum_class._value2member_map_[value] = enum_member
- except TypeError:
- pass
-
- # in Python2.x we cannot know definition order, so go with value order
- # unless __order__ was specified in the class definition
- if not order_specified:
- enum_class._member_names_ = [
- e[0] for e in sorted(
- [(name, enum_class._member_map_[name]) for name in enum_class._member_names_],
- key=lambda t: t[1]._value_
- )]
-
- # double check that repr and friends are not the mixin's or various
- # things break (such as pickle)
- if Enum is not None:
- setattr(enum_class, '__getnewargs__', Enum.__getnewargs__)
- setattr(enum_class, '__reduce_ex__', Enum.__reduce_ex__)
- for name in ('__repr__', '__str__', '__format__', ):
- class_method = getattr(enum_class, name)
- obj_method = getattr(member_type, name, None)
- enum_method = getattr(first_enum, name, None)
- if obj_method is not None and obj_method is class_method:
- setattr(enum_class, name, enum_method)
-
- # check for a __getnewargs__, and if not present sabotage
- # pickling, since it won't work anyway
- if member_type is not object:
- methods = ('__getnewargs_ex__', '__getnewargs__',
- '__reduce_ex__', '__reduce__')
- if not any(map(member_type.__dict__.get, methods)):
- _make_class_unpicklable(enum_class)
-
- # method resolution and int's are not playing nice
- # Python's less than 2.6 use __cmp__
-
- if pyver < 2.6:
-
- if issubclass(enum_class, int):
- setattr(enum_class, '__cmp__', getattr(int, '__cmp__'))
-
- elif pyver < 3.0:
-
- if issubclass(enum_class, int):
- for method in (
- '__le__',
- '__lt__',
- '__gt__',
- '__ge__',
- '__eq__',
- '__ne__',
- '__hash__',
- ):
- setattr(enum_class, method, getattr(int, method))
-
- # replace any other __new__ with our own (as long as Enum is not None,
- # anyway) -- again, this is to support pickle
- if Enum is not None:
- # if the user defined their own __new__, save it before it gets
- # clobbered in case they subclass later
- if save_new:
- setattr(enum_class, '__member_new__', enum_class.__dict__['__new__'])
- setattr(enum_class, '__new__', Enum.__dict__['__new__'])
- return enum_class
-
- def __call__(cls, value, names=None, module=None, type=None):
- """Either returns an existing member, or creates a new enum class.
-
- This method is used both when an enum class is given a value to match
- to an enumeration member (i.e. Color(3)) and for the functional API
- (i.e. Color = Enum('Color', names='red green blue')).
-
- When used for the functional API: `module`, if set, will be stored in
- the new class' __module__ attribute; `type`, if set, will be mixed in
- as the first base class.
-
- Note: if `module` is not set this routine will attempt to discover the
- calling module by walking the frame stack; if this is unsuccessful
- the resulting class will not be pickleable.
-
- """
- if names is None: # simple value lookup
- return cls.__new__(cls, value)
- # otherwise, functional API: we're creating a new Enum type
- return cls._create_(value, names, module=module, type=type)
-
- def __contains__(cls, member):
- return isinstance(member, cls) and member.name in cls._member_map_
-
- def __delattr__(cls, attr):
- # nicer error message when someone tries to delete an attribute
- # (see issue19025).
- if attr in cls._member_map_:
- raise AttributeError(
- "%s: cannot delete Enum member." % cls.__name__)
- super(EnumMeta, cls).__delattr__(attr)
-
- def __dir__(self):
- return (['__class__', '__doc__', '__members__', '__module__'] +
- self._member_names_)
-
- @property
- def __members__(cls):
- """Returns a mapping of member name->value.
-
- This mapping lists all enum members, including aliases. Note that this
- is a copy of the internal mapping.
-
- """
- return cls._member_map_.copy()
-
- def __getattr__(cls, name):
- """Return the enum member matching `name`
-
- We use __getattr__ instead of descriptors or inserting into the enum
- class' __dict__ in order to support `name` and `value` being both
- properties for enum members (which live in the class' __dict__) and
- enum members themselves.
-
- """
- if _is_dunder(name):
- raise AttributeError(name)
- try:
- return cls._member_map_[name]
- except KeyError:
- raise AttributeError(name)
-
- def __getitem__(cls, name):
- return cls._member_map_[name]
-
- def __iter__(cls):
- return (cls._member_map_[name] for name in cls._member_names_)
-
- def __reversed__(cls):
- return (cls._member_map_[name] for name in reversed(cls._member_names_))
-
- def __len__(cls):
- return len(cls._member_names_)
-
- def __repr__(cls):
- return "<enum %r>" % cls.__name__
-
- def __setattr__(cls, name, value):
- """Block attempts to reassign Enum members.
-
- A simple assignment to the class namespace only changes one of the
- several possible ways to get an Enum member from the Enum class,
- resulting in an inconsistent Enumeration.
-
- """
- member_map = cls.__dict__.get('_member_map_', {})
- if name in member_map:
- raise AttributeError('Cannot reassign members.')
- super(EnumMeta, cls).__setattr__(name, value)
-
- def _create_(cls, class_name, names=None, module=None, type=None):
- """Convenience method to create a new Enum class.
-
- `names` can be:
-
- * A string containing member names, separated either with spaces or
- commas. Values are auto-numbered from 1.
- * An iterable of member names. Values are auto-numbered from 1.
- * An iterable of (member name, value) pairs.
- * A mapping of member name -> value.
-
- """
- metacls = cls.__class__
- if type is None:
- bases = (cls, )
- else:
- bases = (type, cls)
- classdict = metacls.__prepare__(class_name, bases)
- __order__ = []
-
- # special processing needed for names?
- if isinstance(names, basestring):
- names = names.replace(',', ' ').split()
- if isinstance(names, (tuple, list)) and isinstance(names[0], basestring):
- names = [(e, i+1) for (i, e) in enumerate(names)]
-
- # Here, names is either an iterable of (name, value) or a mapping.
- for item in names:
- if isinstance(item, basestring):
- member_name, member_value = item, names[item]
- else:
- member_name, member_value = item
- classdict[member_name] = member_value
- __order__.append(member_name)
- # only set __order__ in classdict if name/value was not from a mapping
- if not isinstance(item, basestring):
- classdict['__order__'] = ' '.join(__order__)
- enum_class = metacls.__new__(metacls, class_name, bases, classdict)
-
- # TODO: replace the frame hack if a blessed way to know the calling
- # module is ever developed
- if module is None:
- try:
- module = _sys._getframe(2).f_globals['__name__']
- except (AttributeError, ValueError):
- pass
- if module is None:
- _make_class_unpicklable(enum_class)
- else:
- enum_class.__module__ = module
-
- return enum_class
-
- @staticmethod
- def _get_mixins_(bases):
- """Returns the type for creating enum members, and the first inherited
- enum class.
-
- bases: the tuple of bases that was given to __new__
-
- """
- if not bases or Enum is None:
- return object, Enum
-
-
- # double check that we are not subclassing a class with existing
- # enumeration members; while we're at it, see if any other data
- # type has been mixed in so we can use the correct __new__
- member_type = first_enum = None
- for base in bases:
- if (base is not Enum and
- issubclass(base, Enum) and
- base._member_names_):
- raise TypeError("Cannot extend enumerations")
- # base is now the last base in bases
- if not issubclass(base, Enum):
- raise TypeError("new enumerations must be created as "
- "`ClassName([mixin_type,] enum_type)`")
-
- # get correct mix-in type (either mix-in type of Enum subclass, or
- # first base if last base is Enum)
- if not issubclass(bases[0], Enum):
- member_type = bases[0] # first data type
- first_enum = bases[-1] # enum type
- else:
- for base in bases[0].__mro__:
- # most common: (IntEnum, int, Enum, object)
- # possible: (<Enum 'AutoIntEnum'>, <Enum 'IntEnum'>,
- # <class 'int'>, <Enum 'Enum'>,
- # <class 'object'>)
- if issubclass(base, Enum):
- if first_enum is None:
- first_enum = base
- else:
- if member_type is None:
- member_type = base
-
- return member_type, first_enum
-
- if pyver < 3.0:
- @staticmethod
- def _find_new_(classdict, member_type, first_enum):
- """Returns the __new__ to be used for creating the enum members.
-
- classdict: the class dictionary given to __new__
- member_type: the data type whose __new__ will be used by default
- first_enum: enumeration to check for an overriding __new__
-
- """
- # now find the correct __new__, checking to see of one was defined
- # by the user; also check earlier enum classes in case a __new__ was
- # saved as __member_new__
- __new__ = classdict.get('__new__', None)
- if __new__:
- return None, True, True # __new__, save_new, use_args
-
- N__new__ = getattr(None, '__new__')
- O__new__ = getattr(object, '__new__')
- if Enum is None:
- E__new__ = N__new__
- else:
- E__new__ = Enum.__dict__['__new__']
- # check all possibles for __member_new__ before falling back to
- # __new__
- for method in ('__member_new__', '__new__'):
- for possible in (member_type, first_enum):
- try:
- target = possible.__dict__[method]
- except (AttributeError, KeyError):
- target = getattr(possible, method, None)
- if target not in [
- None,
- N__new__,
- O__new__,
- E__new__,
- ]:
- if method == '__member_new__':
- classdict['__new__'] = target
- return None, False, True
- if isinstance(target, staticmethod):
- target = target.__get__(member_type)
- __new__ = target
- break
- if __new__ is not None:
- break
- else:
- __new__ = object.__new__
-
- # if a non-object.__new__ is used then whatever value/tuple was
- # assigned to the enum member name will be passed to __new__ and to the
- # new enum member's __init__
- if __new__ is object.__new__:
- use_args = False
- else:
- use_args = True
-
- return __new__, False, use_args
- else:
- @staticmethod
- def _find_new_(classdict, member_type, first_enum):
- """Returns the __new__ to be used for creating the enum members.
-
- classdict: the class dictionary given to __new__
- member_type: the data type whose __new__ will be used by default
- first_enum: enumeration to check for an overriding __new__
-
- """
- # now find the correct __new__, checking to see of one was defined
- # by the user; also check earlier enum classes in case a __new__ was
- # saved as __member_new__
- __new__ = classdict.get('__new__', None)
-
- # should __new__ be saved as __member_new__ later?
- save_new = __new__ is not None
-
- if __new__ is None:
- # check all possibles for __member_new__ before falling back to
- # __new__
- for method in ('__member_new__', '__new__'):
- for possible in (member_type, first_enum):
- target = getattr(possible, method, None)
- if target not in (
- None,
- None.__new__,
- object.__new__,
- Enum.__new__,
- ):
- __new__ = target
- break
- if __new__ is not None:
- break
- else:
- __new__ = object.__new__
-
- # if a non-object.__new__ is used then whatever value/tuple was
- # assigned to the enum member name will be passed to __new__ and to the
- # new enum member's __init__
- if __new__ is object.__new__:
- use_args = False
- else:
- use_args = True
-
- return __new__, save_new, use_args
-
-
-########################################################
-# In order to support Python 2 and 3 with a single
-# codebase we have to create the Enum methods separately
-# and then use the `type(name, bases, dict)` method to
-# create the class.
-########################################################
-temp_enum_dict = {}
-temp_enum_dict['__doc__'] = "Generic enumeration.\n\n Derive from this class to define new enumerations.\n\n"
-
-def __new__(cls, value):
- # all enum instances are actually created during class construction
- # without calling this method; this method is called by the metaclass'
- # __call__ (i.e. Color(3) ), and by pickle
- if type(value) is cls:
- # For lookups like Color(Color.red)
- value = value.value
- #return value
- # by-value search for a matching enum member
- # see if it's in the reverse mapping (for hashable values)
- try:
- if value in cls._value2member_map_:
- return cls._value2member_map_[value]
- except TypeError:
- # not there, now do long search -- O(n) behavior
- for member in cls._member_map_.values():
- if member.value == value:
- return member
- raise ValueError("%s is not a valid %s" % (value, cls.__name__))
-temp_enum_dict['__new__'] = __new__
-del __new__
-
-def __repr__(self):
- return "<%s.%s: %r>" % (
- self.__class__.__name__, self._name_, self._value_)
-temp_enum_dict['__repr__'] = __repr__
-del __repr__
-
-def __str__(self):
- return "%s.%s" % (self.__class__.__name__, self._name_)
-temp_enum_dict['__str__'] = __str__
-del __str__
-
-def __dir__(self):
- added_behavior = [m for m in self.__class__.__dict__ if m[0] != '_']
- return (['__class__', '__doc__', '__module__', 'name', 'value'] + added_behavior)
-temp_enum_dict['__dir__'] = __dir__
-del __dir__
-
-def __format__(self, format_spec):
- # mixed-in Enums should use the mixed-in type's __format__, otherwise
- # we can get strange results with the Enum name showing up instead of
- # the value
-
- # pure Enum branch
- if self._member_type_ is object:
- cls = str
- val = str(self)
- # mix-in branch
- else:
- cls = self._member_type_
- val = self.value
- return cls.__format__(val, format_spec)
-temp_enum_dict['__format__'] = __format__
-del __format__
-
-
-####################################
-# Python's less than 2.6 use __cmp__
-
-if pyver < 2.6:
-
- def __cmp__(self, other):
- if type(other) is self.__class__:
- if self is other:
- return 0
- return -1
- return NotImplemented
- raise TypeError("unorderable types: %s() and %s()" % (self.__class__.__name__, other.__class__.__name__))
- temp_enum_dict['__cmp__'] = __cmp__
- del __cmp__
-
-else:
-
- def __le__(self, other):
- raise TypeError("unorderable types: %s() <= %s()" % (self.__class__.__name__, other.__class__.__name__))
- temp_enum_dict['__le__'] = __le__
- del __le__
-
- def __lt__(self, other):
- raise TypeError("unorderable types: %s() < %s()" % (self.__class__.__name__, other.__class__.__name__))
- temp_enum_dict['__lt__'] = __lt__
- del __lt__
-
- def __ge__(self, other):
- raise TypeError("unorderable types: %s() >= %s()" % (self.__class__.__name__, other.__class__.__name__))
- temp_enum_dict['__ge__'] = __ge__
- del __ge__
-
- def __gt__(self, other):
- raise TypeError("unorderable types: %s() > %s()" % (self.__class__.__name__, other.__class__.__name__))
- temp_enum_dict['__gt__'] = __gt__
- del __gt__
-
-
-def __eq__(self, other):
- if type(other) is self.__class__:
- return self is other
- return NotImplemented
-temp_enum_dict['__eq__'] = __eq__
-del __eq__
-
-def __ne__(self, other):
- if type(other) is self.__class__:
- return self is not other
- return NotImplemented
-temp_enum_dict['__ne__'] = __ne__
-del __ne__
-
-def __getnewargs__(self):
- return (self._value_, )
-temp_enum_dict['__getnewargs__'] = __getnewargs__
-del __getnewargs__
-
-def __hash__(self):
- return hash(self._name_)
-temp_enum_dict['__hash__'] = __hash__
-del __hash__
-
-def __reduce_ex__(self, proto):
- return self.__class__, self.__getnewargs__()
-temp_enum_dict['__reduce_ex__'] = __reduce_ex__
-del __reduce_ex__
-
-# _RouteClassAttributeToGetattr is used to provide access to the `name`
-# and `value` properties of enum members while keeping some measure of
-# protection from modification, while still allowing for an enumeration
-# to have members named `name` and `value`. This works because enumeration
-# members are not set directly on the enum class -- __getattr__ is
-# used to look them up.
-
- at _RouteClassAttributeToGetattr
-def name(self):
- return self._name_
-temp_enum_dict['name'] = name
-del name
-
- at _RouteClassAttributeToGetattr
-def value(self):
- return self._value_
-temp_enum_dict['value'] = value
-del value
-
-Enum = EnumMeta('Enum', (object, ), temp_enum_dict)
-del temp_enum_dict
-
-# Enum has now been created
-###########################
-
-class IntEnum(int, Enum):
- """Enum where members are also (and must be) ints"""
-
-
-def unique(enumeration):
- """Class decorator that ensures only unique members exist in an enumeration."""
- duplicates = []
- for name, member in enumeration.__members__.items():
- if name != member.name:
- duplicates.append((name, member.name))
- if duplicates:
- duplicate_names = ', '.join(
- ["%s -> %s" % (alias, name) for (alias, name) in duplicates]
- )
- raise ValueError('duplicate names found in %r: %s' %
- (enumeration, duplicate_names)
- )
- return enumeration
diff --git a/lib/taurus/external/ordereddict/ordereddict.py b/lib/taurus/external/ordereddict/ordereddict.py
deleted file mode 100644
index f09d261..0000000
--- a/lib/taurus/external/ordereddict/ordereddict.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# -*- coding: utf-8 -*-
-
-##############################################################################
-##
-## This file is part of Taurus
-##
-## http://taurus-scada.org
-##
-## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
-##
-## Taurus is free software: you can redistribute it and/or modify
-## it under the terms of the GNU Lesser General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## Taurus is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU Lesser General Public License for more details.
-##
-## You should have received a copy of the GNU Lesser General Public License
-## along with Taurus. If not, see <http://www.gnu.org/licenses/>.
-##
-##############################################################################
-
-# Copyright (c) 2009 Raymond Hettinger
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-
-from UserDict import DictMixin
-
-
-class OrderedDict(dict, DictMixin):
-
- def __init__(self, *args, **kwds):
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__end
- except AttributeError:
- self.clear()
- self.update(*args, **kwds)
-
- def clear(self):
- self.__end = end = []
- end += [None, end, end] # sentinel node for doubly linked list
- self.__map = {} # key --> [key, prev, next]
- dict.clear(self)
-
- def __setitem__(self, key, value):
- if key not in self:
- end = self.__end
- curr = end[1]
- curr[2] = end[1] = self.__map[key] = [key, curr, end]
- dict.__setitem__(self, key, value)
-
- def __delitem__(self, key):
- dict.__delitem__(self, key)
- key, prev_, next_ = self.__map.pop(key)
- prev_[2] = next_
- next_[1] = prev_
-
- def __iter__(self):
- end = self.__end
- curr = end[2]
- while curr is not end:
- yield curr[0]
- curr = curr[2]
-
- def __reversed__(self):
- end = self.__end
- curr = end[1]
- while curr is not end:
- yield curr[0]
- curr = curr[1]
-
- def popitem(self, last=True):
- if not self:
- raise KeyError('dictionary is empty')
- if last:
- key = reversed(self).next()
- else:
- key = iter(self).next()
- value = self.pop(key)
- return key, value
-
- def __reduce__(self):
- items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__end
- del self.__map, self.__end
- inst_dict = vars(self).copy()
- self.__map, self.__end = tmp
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def keys(self):
- return list(self)
-
- setdefault = DictMixin.setdefault
- update = DictMixin.update
- pop = DictMixin.pop
- values = DictMixin.values
- items = DictMixin.items
- iterkeys = DictMixin.iterkeys
- itervalues = DictMixin.itervalues
- iteritems = DictMixin.iteritems
-
- def __repr__(self):
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
-
- def copy(self):
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- if isinstance(other, OrderedDict):
- if len(self) != len(other):
- return False
- for p, q in zip(self.items(), other.items()):
- if p != q:
- return False
- return True
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
diff --git a/lib/taurus/external/pint/pint_local/AUTHORS b/lib/taurus/external/pint/pint_local/AUTHORS
deleted file mode 100644
index 6c7f068..0000000
--- a/lib/taurus/external/pint/pint_local/AUTHORS
+++ /dev/null
@@ -1,41 +0,0 @@
-Pint is written and maintained by Hernan E. Grecco <hernan.grecco at gmail.com>.
-
-Other contributors, listed alphabetically, are:
-
-* Aaron Coleman
-* Alexander Böhn <fish2000 at gmail.com>
-* Ana Krivokapic <akrivokapic1 at gmail.com>
-* Andrea Zonca <code at andreazonca.com>
-* Brend Wanders <b.wanders at utwente.nl>
-* choloepus
-* coutinho <coutinho at esrf.fr>
-* Daniel Sokolowski <daniel.sokolowski at danols.com>
-* Dave Brooks <dave at bcs.co.nz>
-* David Linke
-* Ed Schofield <ed at pythoncharmers.com>
-* Eduard Bopp <eduard.bopp at aepsil0n.de>
-* Eli <elifab at gmail.com>
-* Felix Hummel <felix at felixhummel.de>
-* Giel van Schijndel <me at mortis.eu>
-* James Rowe <jnrowe at gmail.com>
-* Jim Turner <jturner314 at gmail.com>
-* Joel B. Mohler <joel at kiwistrawberry.us>
-* John David Reaver <jdreaver at adlerhorst.com>
-* Jonas Olson <jolson at kth.se>
-* Kaido Kert <kaidokert at gmail.com>
-* Kenneth D. Mankoff <mankoff at gmail.com>
-* Kevin Davies <kdavies4 at gmail.com>
-* Luke Campbell <luke.s.campbell at gmail.com>
-* Matthieu Dartiailh <marul at laposte.net>
-* Nate Bogdanowicz <natezb at gmail.com>
-* Peter Grayson <jpgrayson at gmail.com>
-* Richard Barnes <rbarnes at umn.edu>
-* Ryan Dwyer <ryanpdwyer at gmail.com>
-* Ryan Kingsbury <RyanSKingsbury at alumni.unc.edu>
-* Sundar Raman <cybertoast at gmail.com>
-* Tiago Coutinho <coutinho at esrf.fr>
-* Thomas Kluyver <takowl at gmail.com>
-* Tom Ritchford <tom at swirly.com>
-* Virgil Dupras <virgil.dupras at savoirfairelinux.com>
-
-(If you think that your name belongs here, please let the maintainer know)
diff --git a/lib/taurus/external/pint/pint_local/LICENSE b/lib/taurus/external/pint/pint_local/LICENSE
deleted file mode 100644
index 49aec52..0000000
--- a/lib/taurus/external/pint/pint_local/LICENSE
+++ /dev/null
@@ -1,33 +0,0 @@
-Copyright (c) 2012 by Hernan E. Grecco and contributors. See AUTHORS
-for more details.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms of the software as well
-as documentation, with or without modification, are permitted provided
-that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
-* The names of the contributors may not be used to endorse or
- promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
diff --git a/lib/taurus/external/pint/pint_local/__init__.py b/lib/taurus/external/pint/pint_local/__init__.py
deleted file mode 100644
index ba4e847..0000000
--- a/lib/taurus/external/pint/pint_local/__init__.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint
- ~~~~
-
- Pint is Python module/package to define, operate and manipulate
- **physical quantities**: the product of a numerical value and a
- unit of measurement. It allows arithmetic operations between them
- and conversions from and to different units.
-
- :copyright: (c) 2012 by Hernan E. Grecco.
- :license: BSD, see LICENSE for more details.
-"""
-from __future__ import with_statement
-import os
-import subprocess
-import pkg_resources
-from .formatting import formatter
-from .unit import (UnitRegistry, LazyRegistry)
-from .errors import (DimensionalityError, OffsetUnitCalculusError,
- UndefinedUnitError)
-from .util import pi_theorem, logger
-
-from .context import Context
-
-
-try: # pragma: no cover
- __version__ = pkg_resources.get_distribution('pint').version
-except: # pragma: no cover
- # we seem to have a local copy not installed without setuptools
- # so the reported version will be unknown
- __version__ = "unknown"
-
-
-#: A Registry with the default units and constants.
-_DEFAULT_REGISTRY = LazyRegistry()
-
-#: Registry used for unpickling operations.
-_APP_REGISTRY = _DEFAULT_REGISTRY
-
-
-def _build_quantity(value, units):
- """Build Quantity using the Application registry.
- Used only for unpickling operations.
- """
- global _APP_REGISTRY
- return _APP_REGISTRY.Quantity(value, units)
-
-
-def set_application_registry(registry):
- """Set the application registry which is used for unpickling operations.
-
- :param registry: a UnitRegistry instance.
- """
- assert isinstance(registry, UnitRegistry)
- global _APP_REGISTRY
- logger.debug('Changing app registry from %r to %r.', _APP_REGISTRY, registry)
- _APP_REGISTRY = registry
-
-
-def _run_pyroma(data): # pragma: no cover
- """Run pyroma (used to perform checks before releasing a new version).
- """
- import sys
- from zest.releaser.utils import ask
- if not ask("Run pyroma on the package before uploading?"):
- return
- try:
- from pyroma import run
- result = run(data['tagdir'])
- if result != 10:
- if not ask("Continue?"):
- sys.exit(1)
- except ImportError:
- if not ask("pyroma not available. Continue?"):
- sys.exit(1)
-
-
-def _check_travis(data): # pragma: no cover
- """Check if Travis reports that everything is ok.
- (used to perform checks before releasing a new version).
- """
- import json
- import sys
-
- from zest.releaser.utils import system, ask
- if not ask('Check with Travis before releasing?'):
- return
-
- try:
- # Python 3
- from urllib.request import urlopen
- def get(url):
- return urlopen(url).read().decode('utf-8')
-
- except ImportError:
- # Python 2
- from urllib2 import urlopen
- def get(url):
- return urlopen(url).read()
-
- url = 'https://api.github.com/repos/%s/%s/status/%s'
-
- username = 'hgrecco'
- repo = 'pint'
- commit = system('git rev-parse HEAD')
-
- try:
- result = json.loads(get(url % (username, repo, commit)))['state']
- print('Travis says: %s' % result)
- if result != 'success':
- if not ask('Do you want to continue anyway?', default=False):
- sys.exit(1)
- except Exception:
- print('Could not determine the commit state with Travis.')
- if ask('Do you want to continue anyway?', default=False):
- sys.exit(1)
-
-
-def test():
- """Run all tests.
-
- :return: a :class:`unittest.TestResult` object
- """
- from .testsuite import run
- return run()
diff --git a/lib/taurus/external/pint/pint_local/compat/__init__.py b/lib/taurus/external/pint/pint_local/compat/__init__.py
deleted file mode 100644
index 7442967..0000000
--- a/lib/taurus/external/pint/pint_local/compat/__init__.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.compat
- ~~~~~~~~~~~
-
- Compatibility layer.
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-import sys
-
-from io import BytesIO
-from numbers import Number
-from decimal import Decimal
-
-from . import tokenize
-
-ENCODING_TOKEN = tokenize.ENCODING
-
-PYTHON3 = sys.version >= '3'
-
-def tokenizer(input_string):
- for tokinfo in tokenize.tokenize(BytesIO(input_string.encode('utf-8')).readline):
- if tokinfo.type == ENCODING_TOKEN:
- continue
- yield tokinfo
-
-
-if PYTHON3:
- string_types = str
-
- def u(x):
- return x
-
- maketrans = str.maketrans
-
- long_type = int
-else:
- string_types = basestring
-
- import codecs
-
- def u(x):
- return codecs.unicode_escape_decode(x)[0]
-
- maketrans = lambda f, t: dict((ord(a), b) for a, b in zip(f, t))
-
- long_type = long
-
-if sys.version_info < (2, 7):
- try:
- import unittest2 as unittest
- except ImportError:
- raise Exception("Testing Pint in Python 2.6 requires package 'unittest2'")
-else:
- import unittest
-
-
-try:
- from collections import Chainmap
-except ImportError:
- from .chainmap import ChainMap
-
-try:
- from functools import lru_cache
-except ImportError:
- from .lrucache import lru_cache
-
-try:
- from logging import NullHandler
-except ImportError:
- from .nullhandler import NullHandler
-
-try:
- from itertools import zip_longest
-except ImportError:
- from itertools import izip_longest as zip_longest
-
-try:
- import numpy as np
- from numpy import ndarray
-
- HAS_NUMPY = True
- NUMPY_VER = np.__version__
- NUMERIC_TYPES = (Number, Decimal, ndarray, np.number)
-
- def _to_magnitude(value, force_ndarray=False):
- if isinstance(value, (dict, bool)) or value is None:
- raise TypeError('Invalid magnitude for Quantity: {0!r}'.format(value))
- elif isinstance(value, string_types) and value == '':
- raise ValueError('Quantity magnitude cannot be an empty string.')
- elif isinstance(value, (list, tuple)):
- return np.asarray(value)
- if force_ndarray:
- return np.asarray(value)
- return value
-
-except ImportError:
-
- np = None
-
- class ndarray(object):
- pass
-
- HAS_NUMPY = False
- NUMPY_VER = '0'
- NUMERIC_TYPES = (Number, Decimal)
-
- def _to_magnitude(value, force_ndarray=False):
- if isinstance(value, (dict, bool)) or value is None:
- raise TypeError('Invalid magnitude for Quantity: {0!r}'.format(value))
- elif isinstance(value, string_types) and value == '':
- raise ValueError('Quantity magnitude cannot be an empty string.')
- elif isinstance(value, (list, tuple)):
- raise TypeError('lists and tuples are valid magnitudes for '
- 'Quantity only when NumPy is present.')
- return value
-
-try:
- from uncertainties import ufloat
- HAS_UNCERTAINTIES = True
-except ImportError:
- ufloat = None
- HAS_UNCERTAINTIES = False
-
diff --git a/lib/taurus/external/pint/pint_local/compat/chainmap.py b/lib/taurus/external/pint/pint_local/compat/chainmap.py
deleted file mode 100644
index f4c9a4e..0000000
--- a/lib/taurus/external/pint/pint_local/compat/chainmap.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.compat.chainmap
- ~~~~~~~~~~~~~~~~~~~~
-
- Taken from the Python 3.3 source code.
-
- :copyright: 2013, PSF
- :license: PSF License
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-import sys
-
-from collections import MutableMapping
-if sys.version_info < (3, 0):
- from thread import get_ident
-elif sys.version_info < (3, 3):
- from _thread import get_ident
-else:
- from threading import get_ident
-
-
-def _recursive_repr(fillvalue='...'):
- 'Decorator to make a repr function return fillvalue for a recursive call'
-
- def decorating_function(user_function):
- repr_running = set()
-
- def wrapper(self):
- key = id(self), get_ident()
- if key in repr_running:
- return fillvalue
- repr_running.add(key)
- try:
- result = user_function(self)
- finally:
- repr_running.discard(key)
- return result
-
- # Can't use functools.wraps() here because of bootstrap issues
- wrapper.__module__ = getattr(user_function, '__module__')
- wrapper.__doc__ = getattr(user_function, '__doc__')
- wrapper.__name__ = getattr(user_function, '__name__')
- wrapper.__annotations__ = getattr(user_function, '__annotations__', {})
- return wrapper
-
- return decorating_function
-
-
-class ChainMap(MutableMapping):
- ''' A ChainMap groups multiple dicts (or other mappings) together
- to create a single, updateable view.
-
- The underlying mappings are stored in a list. That list is public and can
- accessed or updated using the *maps* attribute. There is no other state.
-
- Lookups search the underlying mappings successively until a key is found.
- In contrast, writes, updates, and deletions only operate on the first
- mapping.
-
- '''
-
- def __init__(self, *maps):
- '''Initialize a ChainMap by setting *maps* to the given mappings.
- If no mappings are provided, a single empty dictionary is used.
-
- '''
- self.maps = list(maps) or [{}] # always at least one map
-
- def __missing__(self, key):
- raise KeyError(key)
-
- def __getitem__(self, key):
- for mapping in self.maps:
- try:
- return mapping[key] # can't use 'key in mapping' with defaultdict
- except KeyError:
- pass
- return self.__missing__(key) # support subclasses that define __missing__
-
- def get(self, key, default=None):
- return self[key] if key in self else default
-
- def __len__(self):
- return len(set().union(*self.maps)) # reuses stored hash values if possible
-
- def __iter__(self):
- return iter(set().union(*self.maps))
-
- def __contains__(self, key):
- return any(key in m for m in self.maps)
-
- def __bool__(self):
- return any(self.maps)
-
- @_recursive_repr()
- def __repr__(self):
- return '{0.__class__.__name__}({1})'.format(
- self, ', '.join(map(repr, self.maps)))
-
- @classmethod
- def fromkeys(cls, iterable, *args):
- 'Create a ChainMap with a single dict created from the iterable.'
- return cls(dict.fromkeys(iterable, *args))
-
- def copy(self):
- 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
- return self.__class__(self.maps[0].copy(), *self.maps[1:])
-
- __copy__ = copy
-
- def new_child(self, m=None): # like Django's _Context.push()
- '''
- New ChainMap with a new map followed by all previous maps. If no
- map is provided, an empty dict is used.
- '''
- if m is None:
- m = {}
- return self.__class__(m, *self.maps)
-
- @property
- def parents(self): # like Django's _Context.pop()
- 'New ChainMap from maps[1:].'
- return self.__class__(*self.maps[1:])
-
- def __setitem__(self, key, value):
- self.maps[0][key] = value
-
- def __delitem__(self, key):
- try:
- del self.maps[0][key]
- except KeyError:
- raise KeyError('Key not found in the first mapping: {!r}'.format(key))
-
- def popitem(self):
- 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
- try:
- return self.maps[0].popitem()
- except KeyError:
- raise KeyError('No keys found in the first mapping.')
-
- def pop(self, key, *args):
- 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
- try:
- return self.maps[0].pop(key, *args)
- except KeyError:
- raise KeyError('Key not found in the first mapping: {!r}'.format(key))
-
- def clear(self):
- 'Clear maps[0], leaving maps[1:] intact.'
- self.maps[0].clear()
diff --git a/lib/taurus/external/pint/pint_local/compat/lrucache.py b/lib/taurus/external/pint/pint_local/compat/lrucache.py
deleted file mode 100644
index 868b598..0000000
--- a/lib/taurus/external/pint/pint_local/compat/lrucache.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.compat.lrucache
- ~~~~~~~~~~~~~~~~~~~~
-
- LRU (least recently used) cache backport.
-
- From https://code.activestate.com/recipes/578078-py26-and-py30-backport-of-python-33s-lru-cache/
-
- :copyright: 2004, Raymond Hettinger,
- :license: MIT License
-"""
-
-from collections import namedtuple
-from functools import update_wrapper
-from threading import RLock
-
-_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])
-
-class _HashedSeq(list):
- __slots__ = 'hashvalue'
-
- def __init__(self, tup, hash=hash):
- self[:] = tup
- self.hashvalue = hash(tup)
-
- def __hash__(self):
- return self.hashvalue
-
-def _make_key(args, kwds, typed,
- kwd_mark = (object(),),
- fasttypes = set((int, str, frozenset, type(None))),
- sorted=sorted, tuple=tuple, type=type, len=len):
- 'Make a cache key from optionally typed positional and keyword arguments'
- key = args
- if kwds:
- sorted_items = sorted(kwds.items())
- key += kwd_mark
- for item in sorted_items:
- key += item
- if typed:
- key += tuple(type(v) for v in args)
- if kwds:
- key += tuple(type(v) for k, v in sorted_items)
- elif len(key) == 1 and type(key[0]) in fasttypes:
- return key[0]
- return _HashedSeq(key)
-
-def lru_cache(maxsize=100, typed=False):
- """Least-recently-used cache decorator.
-
- If *maxsize* is set to None, the LRU features are disabled and the cache
- can grow without bound.
-
- If *typed* is True, arguments of different types will be cached separately.
- For example, f(3.0) and f(3) will be treated as distinct calls with
- distinct results.
-
- Arguments to the cached function must be hashable.
-
- View the cache statistics named tuple (hits, misses, maxsize, currsize) with
- f.cache_info(). Clear the cache and statistics with f.cache_clear().
- Access the underlying function with f.__wrapped__.
-
- See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
-
- """
-
- # Users should only access the lru_cache through its public API:
- # cache_info, cache_clear, and f.__wrapped__
- # The internals of the lru_cache are encapsulated for thread safety and
- # to allow the implementation to change (including a possible C version).
-
- def decorating_function(user_function):
-
- cache = dict()
- stats = [0, 0] # make statistics updateable non-locally
- HITS, MISSES = 0, 1 # names for the stats fields
- make_key = _make_key
- cache_get = cache.get # bound method to lookup key or return None
- _len = len # localize the global len() function
- lock = RLock() # because linkedlist updates aren't threadsafe
- root = [] # root of the circular doubly linked list
- root[:] = [root, root, None, None] # initialize by pointing to self
- nonlocal_root = [root] # make updateable non-locally
- PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
-
- if maxsize == 0:
-
- def wrapper(*args, **kwds):
- # no caching, just do a statistics update after a successful call
- result = user_function(*args, **kwds)
- stats[MISSES] += 1
- return result
-
- elif maxsize is None:
-
- def wrapper(*args, **kwds):
- # simple caching without ordering or size limit
- key = make_key(args, kwds, typed)
- result = cache_get(key, root) # root used here as a unique not-found sentinel
- if result is not root:
- stats[HITS] += 1
- return result
- result = user_function(*args, **kwds)
- cache[key] = result
- stats[MISSES] += 1
- return result
-
- else:
-
- def wrapper(*args, **kwds):
- # size limited caching that tracks accesses by recency
- key = make_key(args, kwds, typed) if kwds or typed else args
- with lock:
- link = cache_get(key)
- if link is not None:
- # record recent use of the key by moving it to the front of the list
- root, = nonlocal_root
- link_prev, link_next, key, result = link
- link_prev[NEXT] = link_next
- link_next[PREV] = link_prev
- last = root[PREV]
- last[NEXT] = root[PREV] = link
- link[PREV] = last
- link[NEXT] = root
- stats[HITS] += 1
- return result
- result = user_function(*args, **kwds)
- with lock:
- root, = nonlocal_root
- if key in cache:
- # getting here means that this same key was added to the
- # cache while the lock was released. since the link
- # update is already done, we need only return the
- # computed result and update the count of misses.
- pass
- elif _len(cache) >= maxsize:
- # use the old root to store the new key and result
- oldroot = root
- oldroot[KEY] = key
- oldroot[RESULT] = result
- # empty the oldest link and make it the new root
- root = nonlocal_root[0] = oldroot[NEXT]
- oldkey = root[KEY]
- oldvalue = root[RESULT]
- root[KEY] = root[RESULT] = None
- # now update the cache dictionary for the new links
- del cache[oldkey]
- cache[key] = oldroot
- else:
- # put result in a new link at the front of the list
- last = root[PREV]
- link = [last, root, key, result]
- last[NEXT] = root[PREV] = cache[key] = link
- stats[MISSES] += 1
- return result
-
- def cache_info():
- """Report cache statistics"""
- with lock:
- return _CacheInfo(stats[HITS], stats[MISSES], maxsize, len(cache))
-
- def cache_clear():
- """Clear the cache and cache statistics"""
- with lock:
- cache.clear()
- root = nonlocal_root[0]
- root[:] = [root, root, None, None]
- stats[:] = [0, 0]
-
- wrapper.__wrapped__ = user_function
- wrapper.cache_info = cache_info
- wrapper.cache_clear = cache_clear
- return update_wrapper(wrapper, user_function)
-
- return decorating_function
diff --git a/lib/taurus/external/pint/pint_local/compat/nullhandler.py b/lib/taurus/external/pint/pint_local/compat/nullhandler.py
deleted file mode 100644
index 288cbb3..0000000
--- a/lib/taurus/external/pint/pint_local/compat/nullhandler.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.compat.nullhandler
- ~~~~~~~~~~~~~~~~~~~~~~~
-
- Taken from the Python 2.7 source code.
-
- :copyright: 2013, PSF
- :license: PSF License
-"""
-
-
-import logging
-
-class NullHandler(logging.Handler):
- """
- This handler does nothing. It's intended to be used to avoid the
- "No handlers could be found for logger XXX" one-off warning. This is
- important for library code, which may contain code to log events. If a user
- of the library does not configure logging, the one-off warning might be
- produced; to avoid this, the library developer simply needs to instantiate
- a NullHandler and add it to the top-level logger of the library module or
- package.
- """
- def handle(self, record):
- pass
-
- def emit(self, record):
- pass
-
- def createLock(self):
- self.lock = None
diff --git a/lib/taurus/external/pint/pint_local/compat/tokenize.py b/lib/taurus/external/pint/pint_local/compat/tokenize.py
deleted file mode 100644
index 3166224..0000000
--- a/lib/taurus/external/pint/pint_local/compat/tokenize.py
+++ /dev/null
@@ -1,640 +0,0 @@
-"""Tokenization help for Python programs.
-
-tokenize(readline) is a generator that breaks a stream of bytes into
-Python tokens. It decodes the bytes according to PEP-0263 for
-determining source file encoding.
-
-It accepts a readline-like method which is called repeatedly to get the
-next line of input (or b"" for EOF). It generates 5-tuples with these
-members:
-
- the token type (see token.py)
- the token (a string)
- the starting (row, column) indices of the token (a 2-tuple of ints)
- the ending (row, column) indices of the token (a 2-tuple of ints)
- the original line (string)
-
-It is designed to match the working of the Python tokenizer exactly, except
-that it produces COMMENT tokens for comments and gives type OP for all
-operators. Additionally, all token lists start with an ENCODING token
-which tells you which encoding was used to decode the bytes stream.
-"""
-
-__author__ = 'Ka-Ping Yee <ping at lfw.org>'
-__credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, '
- 'Skip Montanaro, Raymond Hettinger, Trent Nelson, '
- 'Michael Foord')
-
-from codecs import lookup, BOM_UTF8
-import collections
-import io
-from io import TextIOWrapper
-from itertools import chain
-import re
-import sys
-from token import *
-
-try:
- reASCII = re.ASCII
-except:
- reASCII = 0
-
-
-try:
- unicode
- _name_re = re.compile(r"\w*$", re.UNICODE)
- def isidentifier(s):
- if s[0] in '0123456789':
- return False
- return bool(_name_re.match(s))
-except NameError:
- def isidentifier(s):
- return s.isidentifier()
-
-
-cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', reASCII)
-blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', reASCII)
-
-COMMENT = N_TOKENS
-tok_name[COMMENT] = 'COMMENT'
-NL = N_TOKENS + 1
-tok_name[NL] = 'NL'
-ENCODING = N_TOKENS + 2
-tok_name[ENCODING] = 'ENCODING'
-N_TOKENS += 3
-EXACT_TOKEN_TYPES = {
- '(': LPAR,
- ')': RPAR,
- '[': LSQB,
- ']': RSQB,
- ':': COLON,
- ',': COMMA,
- ';': SEMI,
- '+': PLUS,
- '-': MINUS,
- '*': STAR,
- '/': SLASH,
- '|': VBAR,
- '&': AMPER,
- '<': LESS,
- '>': GREATER,
- '=': EQUAL,
- '.': DOT,
- '%': PERCENT,
- '{': LBRACE,
- '}': RBRACE,
- '==': EQEQUAL,
- '!=': NOTEQUAL,
- '<=': LESSEQUAL,
- '>=': GREATEREQUAL,
- '~': TILDE,
- '^': CIRCUMFLEX,
- '<<': LEFTSHIFT,
- '>>': RIGHTSHIFT,
- '**': DOUBLESTAR,
- '+=': PLUSEQUAL,
- '-=': MINEQUAL,
- '*=': STAREQUAL,
- '/=': SLASHEQUAL,
- '%=': PERCENTEQUAL,
- '&=': AMPEREQUAL,
- '|=': VBAREQUAL,
- '^=': CIRCUMFLEXEQUAL,
- '<<=': LEFTSHIFTEQUAL,
- '>>=': RIGHTSHIFTEQUAL,
- '**=': DOUBLESTAREQUAL,
- '//': DOUBLESLASH,
- '//=': DOUBLESLASHEQUAL,
- '@': AT
-}
-
-class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')):
- def __repr__(self):
- annotated_type = '%d (%s)' % (self.type, tok_name[self.type])
- return ('TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' %
- self._replace(type=annotated_type))
-
- @property
- def exact_type(self):
- if self.type == OP and self.string in EXACT_TOKEN_TYPES:
- return EXACT_TOKEN_TYPES[self.string]
- else:
- return self.type
-
-def group(*choices): return '(' + '|'.join(choices) + ')'
-def any(*choices): return group(*choices) + '*'
-def maybe(*choices): return group(*choices) + '?'
-
-# Note: we use unicode matching for names ("\w") but ascii matching for
-# number literals.
-Whitespace = r'[ \f\t]*'
-Comment = r'#[^\r\n]*'
-Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
-Name = r'\w+'
-
-Hexnumber = r'0[xX][0-9a-fA-F]+'
-Binnumber = r'0[bB][01]+'
-Octnumber = r'0[oO][0-7]+'
-Decnumber = r'(?:0+|[1-9][0-9]*)'
-Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber)
-Exponent = r'[eE][-+]?[0-9]+'
-Pointfloat = group(r'[0-9]+\.[0-9]*', r'\.[0-9]+') + maybe(Exponent)
-Expfloat = r'[0-9]+' + Exponent
-Floatnumber = group(Pointfloat, Expfloat)
-Imagnumber = group(r'[0-9]+[jJ]', Floatnumber + r'[jJ]')
-Number = group(Imagnumber, Floatnumber, Intnumber)
-
-StringPrefix = r'(?:[bB][rR]?|[rR][bB]?|[uU])?'
-
-# Tail end of ' string.
-Single = r"[^'\\]*(?:\\.[^'\\]*)*'"
-# Tail end of " string.
-Double = r'[^"\\]*(?:\\.[^"\\]*)*"'
-# Tail end of ''' string.
-Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
-# Tail end of """ string.
-Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
-Triple = group(StringPrefix + "'''", StringPrefix + '"""')
-# Single-line ' or " string.
-String = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
- StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*"')
-
-# Because of leftmost-then-longest match semantics, be sure to put the
-# longest operators first (e.g., if = came before ==, == would get
-# recognized as two instances of =).
-Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"!=",
- r"//=?", r"->",
- r"[+\-*/%&|^=<>]=?",
- r"~")
-
-Bracket = '[][(){}]'
-Special = group(r'\r?\n', r'\.\.\.', r'[:;.,@]')
-Funny = group(Operator, Bracket, Special)
-
-PlainToken = group(Number, Funny, String, Name)
-Token = Ignore + PlainToken
-
-# First (or only) line of ' or " string.
-ContStr = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*" +
- group("'", r'\\\r?\n'),
- StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
- group('"', r'\\\r?\n'))
-PseudoExtras = group(r'\\\r?\n|\Z', Comment, Triple)
-PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
-
-def _compile(expr):
- return re.compile(expr, re.UNICODE)
-
-endpats = {"'": Single, '"': Double,
- "'''": Single3, '"""': Double3,
- "r'''": Single3, 'r"""': Double3,
- "b'''": Single3, 'b"""': Double3,
- "R'''": Single3, 'R"""': Double3,
- "B'''": Single3, 'B"""': Double3,
- "br'''": Single3, 'br"""': Double3,
- "bR'''": Single3, 'bR"""': Double3,
- "Br'''": Single3, 'Br"""': Double3,
- "BR'''": Single3, 'BR"""': Double3,
- "rb'''": Single3, 'rb"""': Double3,
- "Rb'''": Single3, 'Rb"""': Double3,
- "rB'''": Single3, 'rB"""': Double3,
- "RB'''": Single3, 'RB"""': Double3,
- "u'''": Single3, 'u"""': Double3,
- "R'''": Single3, 'R"""': Double3,
- "U'''": Single3, 'U"""': Double3,
- 'r': None, 'R': None, 'b': None, 'B': None,
- 'u': None, 'U': None}
-
-triple_quoted = {}
-for t in ("'''", '"""',
- "r'''", 'r"""', "R'''", 'R"""',
- "b'''", 'b"""', "B'''", 'B"""',
- "br'''", 'br"""', "Br'''", 'Br"""',
- "bR'''", 'bR"""', "BR'''", 'BR"""',
- "rb'''", 'rb"""', "rB'''", 'rB"""',
- "Rb'''", 'Rb"""', "RB'''", 'RB"""',
- "u'''", 'u"""', "U'''", 'U"""',
- ):
- triple_quoted[t] = t
-single_quoted = {}
-for t in ("'", '"',
- "r'", 'r"', "R'", 'R"',
- "b'", 'b"', "B'", 'B"',
- "br'", 'br"', "Br'", 'Br"',
- "bR'", 'bR"', "BR'", 'BR"' ,
- "rb'", 'rb"', "rB'", 'rB"',
- "Rb'", 'Rb"', "RB'", 'RB"' ,
- "u'", 'u"', "U'", 'U"',
- ):
- single_quoted[t] = t
-
-tabsize = 8
-
-class TokenError(Exception): pass
-
-class StopTokenizing(Exception): pass
-
-
-class Untokenizer:
-
- def __init__(self):
- self.tokens = []
- self.prev_row = 1
- self.prev_col = 0
- self.encoding = None
-
- def add_whitespace(self, start):
- row, col = start
- if row < self.prev_row or row == self.prev_row and col < self.prev_col:
- raise ValueError("start ({},{}) precedes previous end ({},{})"
- .format(row, col, self.prev_row, self.prev_col))
- row_offset = row - self.prev_row
- if row_offset:
- self.tokens.append("\\\n" * row_offset)
- self.prev_col = 0
- col_offset = col - self.prev_col
- if col_offset:
- self.tokens.append(" " * col_offset)
-
- def untokenize(self, iterable):
- it = iter(iterable)
- for t in it:
- if len(t) == 2:
- self.compat(t, it)
- break
- tok_type, token, start, end, line = t
- if tok_type == ENCODING:
- self.encoding = token
- continue
- if tok_type == ENDMARKER:
- break
- self.add_whitespace(start)
- self.tokens.append(token)
- self.prev_row, self.prev_col = end
- if tok_type in (NEWLINE, NL):
- self.prev_row += 1
- self.prev_col = 0
- return "".join(self.tokens)
-
- def compat(self, token, iterable):
- indents = []
- toks_append = self.tokens.append
- startline = token[0] in (NEWLINE, NL)
- prevstring = False
-
- for tok in chain([token], iterable):
- toknum, tokval = tok[:2]
- if toknum == ENCODING:
- self.encoding = tokval
- continue
-
- if toknum in (NAME, NUMBER):
- tokval += ' '
-
- # Insert a space between two consecutive strings
- if toknum == STRING:
- if prevstring:
- tokval = ' ' + tokval
- prevstring = True
- else:
- prevstring = False
-
- if toknum == INDENT:
- indents.append(tokval)
- continue
- elif toknum == DEDENT:
- indents.pop()
- continue
- elif toknum in (NEWLINE, NL):
- startline = True
- elif startline and indents:
- toks_append(indents[-1])
- startline = False
- toks_append(tokval)
-
-
-def untokenize(iterable):
- """Transform tokens back into Python source code.
- It returns a bytes object, encoded using the ENCODING
- token, which is the first token sequence output by tokenize.
-
- Each element returned by the iterable must be a token sequence
- with at least two elements, a token number and token value. If
- only two tokens are passed, the resulting output is poor.
-
- Round-trip invariant for full input:
- Untokenized source will match input source exactly
-
- Round-trip invariant for limited intput:
- # Output bytes will tokenize the back to the input
- t1 = [tok[:2] for tok in tokenize(f.readline)]
- newcode = untokenize(t1)
- readline = BytesIO(newcode).readline
- t2 = [tok[:2] for tok in tokenize(readline)]
- assert t1 == t2
- """
- ut = Untokenizer()
- out = ut.untokenize(iterable)
- if ut.encoding is not None:
- out = out.encode(ut.encoding)
- return out
-
-
-def _get_normal_name(orig_enc):
- """Imitates get_normal_name in tokenizer.c."""
- # Only care about the first 12 characters.
- enc = orig_enc[:12].lower().replace("_", "-")
- if enc == "utf-8" or enc.startswith("utf-8-"):
- return "utf-8"
- if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
- enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
- return "iso-8859-1"
- return orig_enc
-
-def detect_encoding(readline):
- """
- The detect_encoding() function is used to detect the encoding that should
- be used to decode a Python source file. It requires one argument, readline,
- in the same way as the tokenize() generator.
-
- It will call readline a maximum of twice, and return the encoding used
- (as a string) and a list of any lines (left as bytes) it has read in.
-
- It detects the encoding from the presence of a utf-8 bom or an encoding
- cookie as specified in pep-0263. If both a bom and a cookie are present,
- but disagree, a SyntaxError will be raised. If the encoding cookie is an
- invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
- 'utf-8-sig' is returned.
-
- If no encoding is specified, then the default of 'utf-8' will be returned.
- """
- try:
- filename = readline.__self__.name
- except AttributeError:
- filename = None
- bom_found = False
- encoding = None
- default = 'utf-8'
- def read_or_stop():
- try:
- return readline()
- except StopIteration:
- return b''
-
- def find_cookie(line):
- try:
- # Decode as UTF-8. Either the line is an encoding declaration,
- # in which case it should be pure ASCII, or it must be UTF-8
- # per default encoding.
- line_string = line.decode('utf-8')
- except UnicodeDecodeError:
- msg = "invalid or missing encoding declaration"
- if filename is not None:
- msg = '{} for {!r}'.format(msg, filename)
- raise SyntaxError(msg)
-
- match = cookie_re.match(line_string)
- if not match:
- return None
- encoding = _get_normal_name(match.group(1))
- try:
- codec = lookup(encoding)
- except LookupError:
- # This behaviour mimics the Python interpreter
- if filename is None:
- msg = "unknown encoding: " + encoding
- else:
- msg = "unknown encoding for {!r}: {}".format(filename,
- encoding)
- raise SyntaxError(msg)
-
- if bom_found:
- if encoding != 'utf-8':
- # This behaviour mimics the Python interpreter
- if filename is None:
- msg = 'encoding problem: utf-8'
- else:
- msg = 'encoding problem for {!r}: utf-8'.format(filename)
- raise SyntaxError(msg)
- encoding += '-sig'
- return encoding
-
- first = read_or_stop()
- if first.startswith(BOM_UTF8):
- bom_found = True
- first = first[3:]
- default = 'utf-8-sig'
- if not first:
- return default, []
-
- encoding = find_cookie(first)
- if encoding:
- return encoding, [first]
- if not blank_re.match(first):
- return default, [first]
-
- second = read_or_stop()
- if not second:
- return default, [first]
-
- encoding = find_cookie(second)
- if encoding:
- return encoding, [first, second]
-
- return default, [first, second]
-
-
-def open(filename):
- """Open a file in read only mode using the encoding detected by
- detect_encoding().
- """
- buffer = io.open(filename, 'rb')
- encoding, lines = detect_encoding(buffer.readline)
- buffer.seek(0)
- text = TextIOWrapper(buffer, encoding, line_buffering=True)
- text.mode = 'r'
- return text
-
-
-def tokenize(readline):
- """
- The tokenize() generator requires one argment, readline, which
- must be a callable object which provides the same interface as the
- readline() method of built-in file objects. Each call to the function
- should return one line of input as bytes. Alternately, readline
- can be a callable function terminating with StopIteration:
- readline = open(myfile, 'rb').__next__ # Example of alternate readline
-
- The generator produces 5-tuples with these members: the token type; the
- token string; a 2-tuple (srow, scol) of ints specifying the row and
- column where the token begins in the source; a 2-tuple (erow, ecol) of
- ints specifying the row and column where the token ends in the source;
- and the line on which the token was found. The line passed is the
- logical line; continuation lines are included.
-
- The first token sequence will always be an ENCODING token
- which tells you which encoding was used to decode the bytes stream.
- """
- # This import is here to avoid problems when the itertools module is not
- # built yet and tokenize is imported.
- from itertools import chain, repeat
- encoding, consumed = detect_encoding(readline)
- rl_gen = iter(readline, b"")
- empty = repeat(b"")
-
- try:
- return _tokenize(chain(consumed, rl_gen, empty).__next__, encoding)
- except AttributeError:
- return _tokenize(chain(consumed, rl_gen, empty).next, encoding)
-
-
-def _tokenize(readline, encoding):
- lnum = parenlev = continued = 0
- numchars = '0123456789'
- contstr, needcont = '', 0
- contline = None
- indents = [0]
-
- if encoding is not None:
- if encoding == "utf-8-sig":
- # BOM will already have been stripped.
- encoding = "utf-8"
- yield TokenInfo(ENCODING, encoding, (0, 0), (0, 0), '')
- while True: # loop over lines in stream
- try:
- line = readline()
- except StopIteration:
- line = b''
-
- if encoding is not None:
- line = line.decode(encoding)
- lnum += 1
- pos, max = 0, len(line)
-
- if contstr: # continued string
- if not line:
- raise TokenError("EOF in multi-line string", strstart)
- endmatch = endprog.match(line)
- if endmatch:
- pos = end = endmatch.end(0)
- yield TokenInfo(STRING, contstr + line[:end],
- strstart, (lnum, end), contline + line)
- contstr, needcont = '', 0
- contline = None
- elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
- yield TokenInfo(ERRORTOKEN, contstr + line,
- strstart, (lnum, len(line)), contline)
- contstr = ''
- contline = None
- continue
- else:
- contstr = contstr + line
- contline = contline + line
- continue
-
- elif parenlev == 0 and not continued: # new statement
- if not line: break
- column = 0
- while pos < max: # measure leading whitespace
- if line[pos] == ' ':
- column += 1
- elif line[pos] == '\t':
- column = (column//tabsize + 1)*tabsize
- elif line[pos] == '\f':
- column = 0
- else:
- break
- pos += 1
- if pos == max:
- break
-
- if line[pos] in '#\r\n': # skip comments or blank lines
- if line[pos] == '#':
- comment_token = line[pos:].rstrip('\r\n')
- nl_pos = pos + len(comment_token)
- yield TokenInfo(COMMENT, comment_token,
- (lnum, pos), (lnum, pos + len(comment_token)), line)
- yield TokenInfo(NL, line[nl_pos:],
- (lnum, nl_pos), (lnum, len(line)), line)
- else:
- yield TokenInfo((NL, COMMENT)[line[pos] == '#'], line[pos:],
- (lnum, pos), (lnum, len(line)), line)
- continue
-
- if column > indents[-1]: # count indents or dedents
- indents.append(column)
- yield TokenInfo(INDENT, line[:pos], (lnum, 0), (lnum, pos), line)
- while column < indents[-1]:
- if column not in indents:
- raise IndentationError(
- "unindent does not match any outer indentation level",
- ("<tokenize>", lnum, pos, line))
- indents = indents[:-1]
- yield TokenInfo(DEDENT, '', (lnum, pos), (lnum, pos), line)
-
- else: # continued statement
- if not line:
- raise TokenError("EOF in multi-line statement", (lnum, 0))
- continued = 0
-
- while pos < max:
- pseudomatch = _compile(PseudoToken).match(line, pos)
- if pseudomatch: # scan for tokens
- start, end = pseudomatch.span(1)
- spos, epos, pos = (lnum, start), (lnum, end), end
- if start == end:
- continue
- token, initial = line[start:end], line[start]
-
- if (initial in numchars or # ordinary number
- (initial == '.' and token != '.' and token != '...')):
- yield TokenInfo(NUMBER, token, spos, epos, line)
- elif initial in '\r\n':
- yield TokenInfo(NL if parenlev > 0 else NEWLINE,
- token, spos, epos, line)
- elif initial == '#':
- assert not token.endswith("\n")
- yield TokenInfo(COMMENT, token, spos, epos, line)
- elif token in triple_quoted:
- endprog = _compile(endpats[token])
- endmatch = endprog.match(line, pos)
- if endmatch: # all on one line
- pos = endmatch.end(0)
- token = line[start:pos]
- yield TokenInfo(STRING, token, spos, (lnum, pos), line)
- else:
- strstart = (lnum, start) # multiple lines
- contstr = line[start:]
- contline = line
- break
- elif initial in single_quoted or \
- token[:2] in single_quoted or \
- token[:3] in single_quoted:
- if token[-1] == '\n': # continued string
- strstart = (lnum, start)
- endprog = _compile(endpats[initial] or
- endpats[token[1]] or
- endpats[token[2]])
- contstr, needcont = line[start:], 1
- contline = line
- break
- else: # ordinary string
- yield TokenInfo(STRING, token, spos, epos, line)
- elif isidentifier(initial): # ordinary name
- yield TokenInfo(NAME, token, spos, epos, line)
- elif initial == '\\': # continued stmt
- continued = 1
- else:
- if initial in '([{':
- parenlev += 1
- elif initial in ')]}':
- parenlev -= 1
- yield TokenInfo(OP, token, spos, epos, line)
- else:
- yield TokenInfo(ERRORTOKEN, line[pos],
- (lnum, pos), (lnum, pos+1), line)
- pos += 1
-
- for indent in indents[1:]: # pop remaining indent levels
- yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '')
- yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '')
diff --git a/lib/taurus/external/pint/pint_local/constants_en.txt b/lib/taurus/external/pint/pint_local/constants_en.txt
deleted file mode 100644
index 2b67545..0000000
--- a/lib/taurus/external/pint/pint_local/constants_en.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-# Default Pint constants definition file
-# Based on the International System of Units
-# Language: english
-# Source: http://physics.nist.gov/cuu/Constants/Table/allascii.txt
-# :copyright: 2013 by Pint Authors, see AUTHORS for more details.
-
-speed_of_light = 299792458 * meter / second = c
-standard_gravity = 9.806650 * meter / second ** 2 = g_0 = g_n = gravity
-vacuum_permeability = 4 * pi * 1e-7 * newton / ampere ** 2 = mu_0 = magnetic_constant
-vacuum_permittivity = 1 / (mu_0 * c **2 ) = epsilon_0 = electric_constant
-Z_0 = mu_0 * c = impedance_of_free_space = characteristic_impedance_of_vacuum
-
-# 0.000 000 29 e-34
-planck_constant = 6.62606957e-34 J s = h
-hbar = planck_constant / (2 * pi) = ħ
-
-# 0.000 80 e-11
-newtonian_constant_of_gravitation = 6.67384e-11 m^3 kg^-1 s^-2
-
-# 0.000 000 035 e-19
-# elementary_charge = 1.602176565e-19 C = e
-
-# 0.000 0075
-molar_gas_constant = 8.3144621 J mol^-1 K^-1 = R
-
-# 0.000 000 0024 e-3
-fine_structure_constant = 7.2973525698e-3
-
-# 0.000 000 27 e23
-avogadro_number = 6.02214129e23 mol^-1 =N_A
-
-# 0.000 0013 e-23
-boltzmann_constant = 1.3806488e-23 J K^-1 = k
-
-# 0.000 021 e-8
-stefan_boltzmann_constant = 5.670373e-8 W m^-2 K^-4 = σ
-
-# 0.000 0053 e10
-wien_frequency_displacement_law_constant = 5.8789254e10 Hz K^-1
-
-# 0.000 055
-rydberg_constant = 10973731.568539 m^-1
-
-# 0.000 000 40 e-31
-electron_mass = 9.10938291e-31 kg = m_e
-
-# 0.000 000 074 e-27
-neutron_mass = 1.674927351e-27 kg = m_n
-
-# 0.000 000 074 e-27
-proton_mass = 1.672621777e-27 kg = m_p
diff --git a/lib/taurus/external/pint/pint_local/context.py b/lib/taurus/external/pint/pint_local/context.py
deleted file mode 100644
index 7635ca4..0000000
--- a/lib/taurus/external/pint/pint_local/context.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.context
- ~~~~~~~~~~~~
-
- Functions and classes related to context definitions and application.
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-
-import re
-from collections import defaultdict
-import weakref
-
-from .compat import ChainMap
-from .util import (ParserHelper, UnitsContainer, string_types,
- to_units_container)
-
-#: Regex to match the header parts of a context.
-_header_re = re.compile('@context\s*(?P<defaults>\(.*\))?\s+(?P<name>\w+)\s*(=(?P<aliases>.*))*')
-
-#: Regex to match variable names in an equation.
-_varname_re = re.compile('[A-Za-z_][A-Za-z0-9_]*')
-
-
-def _expression_to_function(eq):
- def func(ureg, value, **kwargs):
- return ureg.parse_expression(eq, value=value, **kwargs)
- return func
-
-
-class Context(object):
- """A specialized container that defines transformation functions from one
- dimension to another. Each Dimension are specified using a UnitsContainer.
- Simple transformation are given with a function taking a single parameter.
-
- >>> timedim = UnitsContainer({'[time]': 1})
- >>> spacedim = UnitsContainer({'[length]': 1})
- >>> def f(time):
- ... 'Time to length converter'
- ... return 3. * time
- >>> c = Context()
- >>> c.add_transformation(timedim, spacedim, f)
- >>> c.transform(timedim, spacedim, 2)
- 6
-
- Conversion functions may take optional keyword arguments and the context
- can have default values for these arguments.
-
- >>> def f(time, n):
- ... 'Time to length converter, n is the index of refraction of the material'
- ... return 3. * time / n
- >>> c = Context(n=3)
- >>> c.add_transformation(timedim, spacedim, f)
- >>> c.transform(timedim, spacedim, 2)
- 2
-
- """
-
- def __init__(self, name, aliases=(), defaults=None):
-
- self.name = name
- self.aliases = aliases
-
- #: Maps (src, dst) -> transformation function
- self.funcs = {}
-
- #: Maps defaults variable names to values
- self.defaults = defaults or {}
-
- #: Maps (src, dst) -> self
- #: Used as a convenience dictionary to be composed by ContextChain
- self.relation_to_context = weakref.WeakValueDictionary()
-
- @classmethod
- def from_context(cls, context, **defaults):
- """Creates a new context that shares the funcs dictionary with the
- original context. The default values are copied from the original
- context and updated with the new defaults.
-
- If defaults is empty, return the same context.
- """
- if defaults:
- newdef = dict(context.defaults, **defaults)
- c = cls(context.name, context.aliases, newdef)
- c.funcs = context.funcs
- for edge in context.funcs.keys():
- c.relation_to_context[edge] = c
- return c
- return context
-
- @classmethod
- def from_lines(cls, lines, to_base_func=None):
- header, lines = lines[0], lines[1:]
-
- r = _header_re.search(header)
- name = r.groupdict()['name'].strip()
- aliases = r.groupdict()['aliases']
- if aliases:
- aliases = tuple(a.strip() for a in r.groupdict()['aliases'].split('='))
- else:
- aliases = ()
- defaults = r.groupdict()['defaults']
-
- if defaults:
- def to_num(val):
- val = complex(val)
- if not val.imag:
- return val.real
- return val
-
- try:
- _txt = defaults
- defaults = (part.split('=') for part in defaults.strip('()').split(','))
- defaults = dict((str(k).strip(), to_num(v))
- for k, v in defaults)
- except (ValueError, TypeError):
- raise ValueError('Could not parse Context definition defaults: %s', _txt)
-
- ctx = cls(name, aliases, defaults)
- else:
- ctx = cls(name, aliases)
-
- names = set()
- for line in lines:
- line = line.strip()
- if not line or line.startswith('#'):
- continue
-
- rel, eq = line.split(':')
- names.update(_varname_re.findall(eq))
-
- func = _expression_to_function(eq)
-
- if '<->' in rel:
- src, dst = (ParserHelper.from_string(s)
- for s in rel.split('<->'))
- if to_base_func:
- src = to_base_func(src)
- dst = to_base_func(dst)
- ctx.add_transformation(src, dst, func)
- ctx.add_transformation(dst, src, func)
- elif '->' in rel:
- src, dst = (ParserHelper.from_string(s)
- for s in rel.split('->'))
- if to_base_func:
- src = to_base_func(src)
- dst = to_base_func(dst)
- ctx.add_transformation(src, dst, func)
- else:
- raise ValueError('Relationships must be specified with <-> or ->.')
-
- if defaults:
- missing_pars = set(defaults.keys()).difference(set(names))
- if missing_pars:
- raise ValueError('Context parameters {0} not found in any equation.'.format(missing_pars))
-
- return ctx
-
- def add_transformation(self, src, dst, func):
- """Add a transformation function to the context.
- """
- _key = self.__keytransform__(src, dst)
- self.funcs[_key] = func
- self.relation_to_context[_key] = self
-
- def remove_transformation(self, src, dst):
- """Add a transformation function to the context.
- """
- _key = self.__keytransform__(src, dst)
- del self.funcs[_key]
- del self.relation_to_context[_key]
-
- @staticmethod
- def __keytransform__(src, dst):
- return to_units_container(src), to_units_container(dst)
-
- def transform(self, src, dst, registry, value):
- """Transform a value.
- """
- _key = self.__keytransform__(src, dst)
- return self.funcs[_key](registry, value, **self.defaults)
-
-
-class ContextChain(ChainMap):
- """A specialized ChainMap for contexts that simplifies finding rules
- to transform from one dimension to another.
- """
-
- def __init__(self, *args, **kwargs):
- super(ContextChain, self).__init__(*args, **kwargs)
- self._graph = None
- self._contexts = []
-
- def insert_contexts(self, *contexts):
- """Insert one or more contexts in reversed order the chained map.
- (A rule in last context will take precedence)
-
- To facilitate the identification of the context with the matching rule,
- the *relation_to_context* dictionary of the context is used.
- """
- self._contexts.insert(0, contexts)
- self.maps = [ctx.relation_to_context for ctx in reversed(contexts)] + self.maps
- self._graph = None
-
- def remove_contexts(self, n):
- """Remove the last n inserted contexts from the chain.
- """
- self._contexts = self._contexts[n:]
- self.maps = self.maps[n:]
- self._graph = None
-
- @property
- def defaults(self):
- if self:
- return list(self.maps[0].values())[0].defaults
- return {}
-
- @property
- def graph(self):
- """The graph relating
- """
- if self._graph is None:
- self._graph = defaultdict(set)
- for fr_, to_ in self:
- self._graph[fr_].add(to_)
- return self._graph
-
- def transform(self, src, dst, registry, value):
- """Transform the value, finding the rule in the chained context.
- (A rule in last context will take precedence)
-
- :raises: KeyError if the rule is not found.
- """
- return self[(src, dst)].transform(src, dst, registry, value)
diff --git a/lib/taurus/external/pint/pint_local/converters.py b/lib/taurus/external/pint/pint_local/converters.py
deleted file mode 100644
index 0768537..0000000
--- a/lib/taurus/external/pint/pint_local/converters.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.converters
- ~~~~~~~~~
-
- Functions and classes related to unit conversions.
-
- :copyright: 2014 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-from __future__ import (division, unicode_literals, print_function,
- absolute_import)
-
-
-class Converter(object):
- """Base class for value converters.
- """
-
- is_multiplicative = True
-
- def to_reference(self, value, inplace=False):
- return value
-
- def from_reference(self, value, inplace=False):
- return value
-
-
-class ScaleConverter(Converter):
- """A linear transformation
- """
-
- is_multiplicative = True
-
- def __init__(self, scale):
- self.scale = scale
-
- def to_reference(self, value, inplace=False):
- if inplace:
- value *= self.scale
- else:
- value = value * self.scale
-
- return value
-
- def from_reference(self, value, inplace=False):
- if inplace:
- value /= self.scale
- else:
- value = value / self.scale
-
- return value
-
-
-class OffsetConverter(Converter):
- """An affine transformation
- """
-
- def __init__(self, scale, offset):
- self.scale = scale
- self.offset = offset
-
- @property
- def is_multiplicative(self):
- return self.offset == 0
-
- def to_reference(self, value, inplace=False):
- if inplace:
- value *= self.scale
- value += self.offset
- else:
- value = value * self.scale + self.offset
-
- return value
-
- def from_reference(self, value, inplace=False):
- if inplace:
- value -= self.offset
- value /= self.scale
- else:
- value = (value - self.offset) / self.scale
-
- return value
diff --git a/lib/taurus/external/pint/pint_local/default_en.txt b/lib/taurus/external/pint/pint_local/default_en.txt
deleted file mode 100644
index a1145c7..0000000
--- a/lib/taurus/external/pint/pint_local/default_en.txt
+++ /dev/null
@@ -1,377 +0,0 @@
-# Default Pint units definition file
-# Based on the International System of Units
-# Language: english
-# :copyright: 2013 by Pint Authors, see AUTHORS for more details.
-
-# decimal prefixes
-yocto- = 1e-24 = y-
-zepto- = 1e-21 = z-
-atto- = 1e-18 = a-
-femto- = 1e-15 = f-
-pico- = 1e-12 = p-
-nano- = 1e-9 = n-
-micro- = 1e-6 = u- = µ-
-milli- = 1e-3 = m-
-centi- = 1e-2 = c-
-deci- = 1e-1 = d-
-deca- = 1e+1 = da-
-hecto- = 1e2 = h-
-kilo- = 1e3 = k-
-mega- = 1e6 = M-
-giga- = 1e9 = G-
-tera- = 1e12 = T-
-peta- = 1e15 = P-
-exa- = 1e18 = E-
-zetta- = 1e21 = Z-
-yotta- = 1e24 = Y-
-
-# binary_prefixes
-kibi- = 2**10 = Ki-
-mebi- = 2**20 = Mi-
-gibi- = 2**30 = Gi-
-tebi- = 2**40 = Ti-
-pebi- = 2**50 = Pi-
-exbi- = 2**60 = Ei-
-zebi- = 2**70 = Zi-
-yobi- = 2**80 = Yi-
-
-# reference
-meter = [length] = m = metre
-second = [time] = s = sec
-ampere = [current] = A = amp
-candela = [luminosity] = cd = candle
-gram = [mass] = g
-mole = [substance] = mol
-kelvin = [temperature]; offset: 0 = K = degK
-radian = [] = rad
-bit = []
-count = []
-
- at import constants_en.txt
-
-# acceleration
-[acceleration] = [length] / [time] ** 2
-
-# Angle
-turn = 2 * pi * radian = revolution = cycle = circle
-degree = pi / 180 * radian = deg = arcdeg = arcdegree = angular_degree
-arcminute = arcdeg / 60 = arcmin = arc_minute = angular_minute
-arcsecond = arcmin / 60 = arcsec = arc_second = angular_second
-steradian = radian ** 2 = sr
-
-# Area
-[area] = [length] ** 2
-are = 100 * m**2
-barn = 1e-28 * m ** 2 = b
-cmil = 5.067075e-10 * m ** 2 = circular_mils
-darcy = 9.869233e-13 * m ** 2
-acre = 4046.8564224 * m ** 2 = international_acre
-hectare = 100 * are = ha
-US_survey_acre = 160 * rod ** 2
-
-# EM
-esu = 1 * erg**0.5 * centimeter**0.5 = statcoulombs = statC = franklin = Fr
-esu_per_second = 1 * esu / second = statampere
-ampere_turn = 1 * A
-gilbert = 10 / (4 * pi ) * ampere_turn
-coulomb = ampere * second = C
-volt = joule / coulomb = V
-farad = coulomb / volt = F
-ohm = volt / ampere = Ω
-siemens = ampere / volt = S = mho
-weber = volt * second = Wb
-tesla = weber / meter ** 2 = T
-henry = weber / ampere = H
-elementary_charge = 1.602176487e-19 * coulomb = e
-chemical_faraday = 9.64957e4 * coulomb
-physical_faraday = 9.65219e4 * coulomb
-faraday = 96485.3399 * coulomb = C12_faraday
-gamma = 1e-9 * tesla
-gauss = 1e-4 * tesla
-maxwell = 1e-8 * weber = mx
-oersted = 1000 / (4 * pi) * A / m = Oe
-statfarad = 1.112650e-12 * farad = statF = stF
-stathenry = 8.987554e11 * henry = statH = stH
-statmho = 1.112650e-12 * siemens = statS = stS
-statohm = 8.987554e11 * ohm
-statvolt = 2.997925e2 * volt = statV = stV
-unit_pole = 1.256637e-7 * weber
-
-# Energy
-[energy] = [force] * [length]
-joule = newton * meter = J
-erg = dyne * centimeter
-btu = 1.05505585262e3 * joule = Btu = BTU = british_thermal_unit
-electron_volt = 1.60217653e-19 * J = eV
-quadrillion_btu = 10**15 * btu = quad
-thm = 100000 * BTU = therm = EC_therm
-cal = 4.184 * joule = calorie = thermochemical_calorie
-international_steam_table_calorie = 4.1868 * joule
-ton_TNT = 4.184e9 * joule = tTNT
-US_therm = 1.054804e8 * joule
-watt_hour = watt * hour = Wh = watthour
-hartree = 4.35974394e-18 * joule = E_h = hartree_energy
-
-# Force
-[force] = [mass] * [acceleration]
-newton = kilogram * meter / second ** 2 = N
-dyne = gram * centimeter / second ** 2 = dyn
-force_kilogram = g_0 * kilogram = kgf = kilogram_force = pond
-force_gram = g_0 * gram = gf = gram_force
-force_ounce = g_0 * ounce = ozf = ounce_force
-force_pound = g_0 * lb = lbf = pound_force
-force_ton = 2000 * force_pound = ton_force
-poundal = lb * feet / second ** 2 = pdl
-kip = 1000*lbf
-
-# Frequency
-[frequency] = 1 / [time]
-hertz = 1 / second = Hz = rps
-revolutions_per_minute = revolution / minute = rpm
-counts_per_second = count / second = cps
-
-# Heat
-#RSI = degK * meter ** 2 / watt
-#clo = 0.155 * RSI = clos
-#R_value = foot ** 2 * degF * hour / btu
-
-# Information
-byte = 8 * bit = Bo = octet
-baud = bit / second = Bd = bps
-
-# Irradiance
-peak_sun_hour = 1000 * watt_hour / meter**2 = PSH
-langley = thermochemical_calorie / centimeter**2 = Langley
-
-# Length
-angstrom = 1e-10 * meter = Å = ångström = Å
-inch = 2.54 * centimeter = in = international_inch = inches = international_inches
-foot = 12 * inch = ft = international_foot = feet = international_feet
-mile = 5280 * foot = mi = international_mile
-yard = 3 * feet = yd = international_yard
-mil = inch / 1000 = thou
-parsec = 3.08568025e16 * meter = pc
-light_year = speed_of_light * julian_year = ly = lightyear
-astronomical_unit = 149597870691 * meter = au
-nautical_mile = 1.852e3 * meter = nmi
-printers_point = 127 * millimeter / 360 = point
-printers_pica = 12 * printers_point = pica
-US_survey_foot = 1200 * meter / 3937
-US_survey_yard = 3 * US_survey_foot
-US_survey_mile = 5280 * US_survey_foot = US_statute_mile
-rod = 16.5 * US_survey_foot = pole = perch
-furlong = 660 * US_survey_foot
-fathom = 6 * US_survey_foot
-chain = 66 * US_survey_foot
-barleycorn = inch / 3
-arpentlin = 191.835 * feet
-kayser = 1 / centimeter = wavenumber
-
-# Mass
-dram = oz / 16 = dr = avoirdupois_dram
-ounce = 28.349523125 * gram = oz = avoirdupois_ounce
-pound = 0.45359237 * kilogram = lb = avoirdupois_pound
-stone = 14 * lb = st
-carat = 200 * milligram
-grain = 64.79891 * milligram = gr
-long_hundredweight = 112 * lb
-short_hundredweight = 100 * lb
-metric_ton = 1000 * kilogram = t = tonne
-pennyweight = 24 * gram = dwt
-slug = 14.59390 * kilogram
-troy_ounce = 480 * grain = toz = apounce = apothecary_ounce
-troy_pound = 12 * toz = tlb = appound = apothecary_pound
-drachm = 60 * grain = apdram = apothecary_dram
-atomic_mass_unit = 1.660538782e-27 * kilogram = u = amu = dalton = Da
-scruple = 20 * grain
-bag = 94 * lb
-ton = 2000 * lb = short_ton
-
-# Textile
-denier = gram / (9000 * meter)
-tex = gram/ (1000 * meter)
-dtex = decitex
-
-# Photometry
-lumen = candela * steradian = lm
-lux = lumen / meter ** 2 = lx
-
-# Power
-[power] = [energy] / [time]
-watt = joule / second = W = volt_ampere = VA
-horsepower = 33000 * ft * lbf / min = hp = UK_horsepower = British_horsepower
-boiler_horsepower = 33475 * btu / hour
-metric_horsepower = 75 * force_kilogram * meter / second
-electric_horsepower = 746 * watt
-hydraulic_horsepower = 550 * feet * lbf / second
-refrigeration_ton = 12000 * btu / hour = ton_of_refrigeration
-
-# Pressure
-[pressure] = [force] / [area]
-Hg = gravity * 13.59510 * gram / centimeter ** 3 = mercury = conventional_mercury
-mercury_60F = gravity * 13.5568 * gram / centimeter ** 3
-H2O = gravity * 1000 * kilogram / meter ** 3 = h2o = water = conventional_water
-water_4C = gravity * 999.972 * kilogram / meter ** 3 = water_39F
-water_60F = gravity * 999.001 * kilogram / m ** 3
-pascal = newton / meter ** 2 = Pa
-bar = 100000 * pascal
-atmosphere = 101325 * pascal = atm = standard_atmosphere
-technical_atmosphere = kilogram * gravity / centimeter ** 2 = at
-torr = atm / 760
-psi = pound * gravity / inch ** 2 = pound_force_per_square_inch
-ksi = kip / inch ** 2 = kip_per_square_inch
-barye = 0.1 * newton / meter ** 2 = barie = barad = barrie = baryd = Ba
-mmHg = millimeter * Hg = mm_Hg = millimeter_Hg = millimeter_Hg_0C
-cmHg = centimeter * Hg = cm_Hg = centimeter_Hg
-inHg = inch * Hg = in_Hg = inch_Hg = inch_Hg_32F
-inch_Hg_60F = inch * mercury_60F
-inch_H2O_39F = inch * water_39F
-inch_H2O_60F = inch * water_60F
-footH2O = ft * water
-cmH2O = centimeter * water
-foot_H2O = ft * water = ftH2O
-standard_liter_per_minute = 1.68875 * Pa * m ** 3 / s = slpm = slm
-
-# Radiation
-Bq = Hz = becquerel
-curie = 3.7e10 * Bq = Ci
-rutherford = 1e6*Bq = rd = Rd
-Gy = joule / kilogram = gray = Sv = sievert
-rem = 1e-2 * sievert
-rads = 1e-2 * gray
-roentgen = 2.58e-4 * coulomb / kilogram
-
-# Temperature
-degC = kelvin; offset: 273.15 = celsius
-degR = 5 / 9 * kelvin; offset: 0 = rankine
-degF = 5 / 9 * kelvin; offset: 255.372222 = fahrenheit
-
-# Time
-minute = 60 * second = min
-hour = 60 * minute = hr
-day = 24 * hour
-week = 7 * day
-fortnight = 2 * week
-year = 31556925.9747 * second
-month = year/12
-shake = 1e-8 * second
-sidereal_day = day / 1.00273790935079524
-sidereal_hour = sidereal_day/24
-sidereal_minute=sidereal_hour/60
-sidereal_second =sidereal_minute/60
-sidereal_year = 366.25636042 * sidereal_day
-sidereal_month = 27.321661 * sidereal_day
-tropical_month = 27.321661 * day
-synodic_month = 29.530589 * day = lunar_month
-common_year = 365 * day
-leap_year = 366 * day
-julian_year = 365.25 * day
-gregorian_year = 365.2425 * day
-millenium = 1000 * year = millenia = milenia = milenium
-eon = 1e9 * year
-work_year = 2056 * hour
-work_month = work_year/12
-
-# Velocity
-[speed] = [length] / [time]
-knot = nautical_mile / hour = kt = knot_international = international_knot = nautical_miles_per_hour
-mph = mile / hour = MPH
-kph = kilometer / hour = KPH
-
-# Viscosity
-[viscosity] = [pressure] * [time]
-poise = 1e-1 * Pa * second = P
-stokes = 1e-4 * meter ** 2 / second = St
-rhe = 10 / (Pa * s)
-
-# Volume
-[volume] = [length] ** 3
-liter = 1e-3 * m ** 3 = l = L = litre
-cc = centimeter ** 3 = cubic_centimeter
-stere = meter ** 3
-gross_register_ton = 100 * foot ** 3 = register_ton = GRT
-acre_foot = acre * foot = acre_feet
-board_foot = foot ** 2 * inch = FBM
-bushel = 2150.42 * inch ** 3 = bu = US_bushel
-dry_gallon = bushel / 8 = US_dry_gallon
-dry_quart = dry_gallon / 4 = US_dry_quart
-dry_pint = dry_quart / 2 = US_dry_pint
-gallon = 231 * inch ** 3 = liquid_gallon = US_liquid_gallon
-quart = gallon / 4 = liquid_quart = US_liquid_quart
-pint = quart / 2 = pt = liquid_pint = US_liquid_pint
-cup = pint / 2 = liquid_cup = US_liquid_cup
-gill = cup / 2 = liquid_gill = US_liquid_gill
-fluid_ounce = gill / 4 = floz = US_fluid_ounce = US_liquid_ounce
-imperial_bushel = 36.36872 * liter = UK_bushel
-imperial_gallon = imperial_bushel / 8 = UK_gallon
-imperial_quart = imperial_gallon / 4 = UK_quart
-imperial_pint = imperial_quart / 2 = UK_pint
-imperial_cup = imperial_pint / 2 = UK_cup
-imperial_gill = imperial_cup / 2 = UK_gill
-imperial_floz = imperial_gill / 5 = UK_fluid_ounce = imperial_fluid_ounce
-barrel = 42 * gallon = bbl
-tablespoon = floz / 2 = tbsp = Tbsp = Tblsp = tblsp = tbs = Tbl
-teaspoon = tablespoon / 3 = tsp
-peck = bushel / 4 = pk
-fluid_dram = floz / 8 = fldr = fluidram
-firkin = barrel / 4
-
-
- at context(n=1) spectroscopy = sp
- # n index of refraction of the medium.
- [length] <-> [frequency]: speed_of_light / n / value
- [frequency] -> [energy]: planck_constant * value
- [energy] -> [frequency]: value / planck_constant
- at end
-
- at context boltzmann
- [temperature] -> [energy]: boltzmann_constant * value
- [energy] -> [temperature]: value / boltzmann_constant
- at end
-
- at context(mw=0,volume=0,solvent_mass=0) chemistry = chem
- # mw is the molecular weight of the species
- # volume is the volume of the solution
- # solvent_mass is the mass of solvent in the solution
-
- # moles -> mass require the molecular weight
- [substance] -> [mass]: value * mw
- [mass] -> [substance]: value / mw
-
- # moles/volume -> mass/volume and moles/mass -> mass / mass
- # require the molecular weight
- [substance] / [volume] -> [mass] / [volume]: value * mw
- [mass] / [volume] -> [substance] / [volume]: value / mw
- [substance] / [mass] -> [mass] / [mass]: value * mw
- [mass] / [mass] -> [substance] / [mass]: value / mw
-
- # moles/volume -> moles requires the solution volume
- [substance] / [volume] -> [substance]: value * volume
- [substance] -> [substance] / [volume]: value / volume
-
- # moles/mass -> moles requires the solvent (usually water) mass
- [substance] / [mass] -> [substance]: value * solvent_mass
- [substance] -> [substance] / [mass]: value / solvent_mass
-
- # moles/mass -> moles/volume require the solvent mass and the volume
- [substance] / [mass] -> [substance]/[volume]: value * solvent_mass / volume
- [substance] / [volume] -> [substance] / [mass]: value / solvent_mass * volume
-
- at end
-
- at system mks
- meter
- kilogram
- second
- at end
-
- at system cgs
- centimeter
- gram
- second
- at end
-
- at system imperial
- yard
- pound
- at end
diff --git a/lib/taurus/external/pint/pint_local/definitions.py b/lib/taurus/external/pint/pint_local/definitions.py
deleted file mode 100644
index a25fd73..0000000
--- a/lib/taurus/external/pint/pint_local/definitions.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.definitions
- ~~~~~~~~~
-
- Functions and classes related to unit definitions.
-
- :copyright: 2014 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import (division, unicode_literals, print_function,
- absolute_import)
-
-from .converters import ScaleConverter, OffsetConverter
-from .util import UnitsContainer, _is_dim, ParserHelper
-from .compat import string_types
-
-
-class Definition(object):
- """Base class for definitions.
-
- :param name: name.
- :param symbol: a short name or symbol for the definition
- :param aliases: iterable of other names.
- :param converter: an instance of Converter.
- """
-
- def __init__(self, name, symbol, aliases, converter):
- self._name = name
- self._symbol = symbol
- self._aliases = aliases
- self._converter = converter
-
- @property
- def is_multiplicative(self):
- return self._converter.is_multiplicative
-
- @classmethod
- def from_string(cls, definition):
- """Parse a definition
- """
- name, definition = definition.split('=', 1)
- name = name.strip()
-
- result = [res.strip() for res in definition.split('=')]
- value, aliases = result[0], tuple(result[1:])
- symbol, aliases = (aliases[0], aliases[1:]) if aliases else (None,
- aliases)
-
- if name.startswith('['):
- return DimensionDefinition(name, symbol, aliases, value)
- elif name.endswith('-'):
- name = name.rstrip('-')
- return PrefixDefinition(name, symbol, aliases, value)
- else:
- return UnitDefinition(name, symbol, aliases, value)
-
- @property
- def name(self):
- return self._name
-
- @property
- def symbol(self):
- return self._symbol or self._name
-
- @property
- def has_symbol(self):
- return bool(self._symbol)
-
- @property
- def aliases(self):
- return self._aliases
-
- @property
- def converter(self):
- return self._converter
-
- def __str__(self):
- return self.name
-
-
-class PrefixDefinition(Definition):
- """Definition of a prefix.
- """
-
- def __init__(self, name, symbol, aliases, converter):
- if isinstance(converter, string_types):
- converter = ScaleConverter(eval(converter))
- aliases = tuple(alias.strip('-') for alias in aliases)
- if symbol:
- symbol = symbol.strip('-')
- super(PrefixDefinition, self).__init__(name, symbol, aliases,
- converter)
-
-
-class UnitDefinition(Definition):
- """Definition of a unit.
-
- :param reference: Units container with reference units.
- :param is_base: indicates if it is a base unit.
- """
-
- def __init__(self, name, symbol, aliases, converter,
- reference=None, is_base=False):
- self.reference = reference
- self.is_base = is_base
- if isinstance(converter, string_types):
- if ';' in converter:
- [converter, modifiers] = converter.split(';', 2)
- modifiers = dict((key.strip(), eval(value)) for key, value in
- (part.split(':')
- for part in modifiers.split(';')))
- else:
- modifiers = {}
-
- converter = ParserHelper.from_string(converter)
- if all(_is_dim(key) for key in converter.keys()):
- self.is_base = True
- elif not any(_is_dim(key) for key in converter.keys()):
- self.is_base = False
- else:
- raise ValueError('Cannot mix dimensions and units in the same definition. '
- 'Base units must be referenced only to dimensions. '
- 'Derived units must be referenced only to units.')
- self.reference = UnitsContainer(converter)
- if modifiers.get('offset', 0.) != 0.:
- converter = OffsetConverter(converter.scale,
- modifiers['offset'])
- else:
- converter = ScaleConverter(converter.scale)
-
- super(UnitDefinition, self).__init__(name, symbol, aliases, converter)
-
-
-class DimensionDefinition(Definition):
- """Definition of a dimension.
- """
-
- def __init__(self, name, symbol, aliases, converter,
- reference=None, is_base=False):
- self.reference = reference
- self.is_base = is_base
- if isinstance(converter, string_types):
- converter = ParserHelper.from_string(converter)
- if not converter:
- self.is_base = True
- elif all(_is_dim(key) for key in converter.keys()):
- self.is_base = False
- else:
- raise ValueError('Base dimensions must be referenced to None. '
- 'Derived dimensions must only be referenced '
- 'to dimensions.')
- self.reference = UnitsContainer(converter)
-
- super(DimensionDefinition, self).__init__(name, symbol, aliases,
- converter=None)
diff --git a/lib/taurus/external/pint/pint_local/errors.py b/lib/taurus/external/pint/pint_local/errors.py
deleted file mode 100644
index 4d86198..0000000
--- a/lib/taurus/external/pint/pint_local/errors.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.errors
- ~~~~~~~~~
-
- Functions and classes related to unit definitions and conversions.
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-from __future__ import (division, unicode_literals, print_function,
- absolute_import)
-
-from .compat import string_types
-
-
-class DefinitionSyntaxError(ValueError):
- """Raised when a textual definition has a syntax error.
- """
-
- def __init__(self, msg, filename=None, lineno=None):
- super(ValueError, self).__init__()
- self.msg = msg
- self.filename = None
- self.lineno = None
-
- def __str__(self):
- mess = "While opening {0}, in line {1}: "
- return mess.format(self.filename, self.lineno) + self.msg
-
-
-class RedefinitionError(ValueError):
- """Raised when a unit or prefix is redefined.
- """
-
- def __init__(self, name, definition_type):
- super(ValueError, self).__init__()
- self.name = name
- self.definition_type = definition_type
- self.filename = None
- self.lineno = None
-
- def __str__(self):
- msg = "cannot redefine '{0}' ({1})".format(self.name,
- self.definition_type)
- if self.filename:
- mess = "While opening {0}, in line {1}: "
- return mess.format(self.filename, self.lineno) + msg
- return msg
-
-
-class UndefinedUnitError(ValueError):
- """Raised when the units are not defined in the unit registry.
- """
-
- def __init__(self, unit_names):
- super(ValueError, self).__init__()
- self.unit_names = unit_names
-
- def __str__(self):
- mess = "'{0}' is not defined in the unit registry"
- mess_plural = "'{0}' are not defined in the unit registry"
- if isinstance(self.unit_names, string_types):
- return mess.format(self.unit_names)
- elif isinstance(self.unit_names, (list, tuple))\
- and len(self.unit_names) == 1:
- return mess.format(self.unit_names[0])
- elif isinstance(self.unit_names, set) and len(self.unit_names) == 1:
- uname = list(self.unit_names)[0]
- return mess.format(uname)
- else:
- return mess_plural.format(self.unit_names)
-
-
-class DimensionalityError(ValueError):
- """Raised when trying to convert between incompatible units.
- """
-
- def __init__(self, units1, units2, dim1=None, dim2=None, extra_msg=''):
- super(DimensionalityError, self).__init__()
- self.units1 = units1
- self.units2 = units2
- self.dim1 = dim1
- self.dim2 = dim2
- self.extra_msg = extra_msg
-
- def __str__(self):
- if self.dim1 or self.dim2:
- dim1 = ' ({0})'.format(self.dim1)
- dim2 = ' ({0})'.format(self.dim2)
- else:
- dim1 = ''
- dim2 = ''
-
- msg = "Cannot convert from '{0}'{1} to '{2}'{3}" + self.extra_msg
-
- return msg.format(self.units1, dim1, self.units2, dim2)
-
-
-class OffsetUnitCalculusError(ValueError):
- """Raised on ambiguous operations with offset units.
- """
- def __init__(self, units1, units2='', extra_msg=''):
- super(ValueError, self).__init__()
- self.units1 = units1
- self.units2 = units2
- self.extra_msg = extra_msg
-
- def __str__(self):
- msg = ("Ambiguous operation with offset unit (%s)." %
- ', '.join(['%s' % u for u in [self.units1, self.units2] if u])
- + self.extra_msg)
- return msg.format(self.units1, self.units2)
diff --git a/lib/taurus/external/pint/pint_local/formatting.py b/lib/taurus/external/pint/pint_local/formatting.py
deleted file mode 100644
index f9b43d0..0000000
--- a/lib/taurus/external/pint/pint_local/formatting.py
+++ /dev/null
@@ -1,200 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.formatter
- ~~~~~~~~~~~~~~
-
- Format units for pint.
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-import re
-
-__JOIN_REG_EXP = re.compile("\{\d*\}")
-
-
-def _join(fmt, iterable):
- """Join an iterable with the format specified in fmt.
-
- The format can be specified in two ways:
- - PEP3101 format with two replacement fields (eg. '{0} * {1}')
- - The concatenating string (eg. ' * ')
- """
- if not iterable:
- return ''
- if not __JOIN_REG_EXP.search(fmt):
- return fmt.join(iterable)
- miter = iter(iterable)
- first = next(miter)
- for val in miter:
- ret = fmt.format(first, val)
- first = ret
- return first
-
-_PRETTY_EXPONENTS = '⁰¹²³⁴⁵⁶⁷⁸⁹'
-
-
-def _pretty_fmt_exponent(num):
- """Format an number into a pretty printed exponent.
- """
- # TODO: Will not work for decimals
- ret = '{0:n}'.format(num).replace('-', '⁻')
- for n in range(10):
- ret = ret.replace(str(n), _PRETTY_EXPONENTS[n])
- return ret
-
-
-#: _FORMATS maps format specifications to the corresponding argument set to
-#: formatter().
-_FORMATS = {
- 'P': { # Pretty format.
- 'as_ratio': True,
- 'single_denominator': False,
- 'product_fmt': '·',
- 'division_fmt': '/',
- 'power_fmt': '{0}{1}',
- 'parentheses_fmt': '({0})',
- 'exp_call': _pretty_fmt_exponent,
- },
-
- 'L': { # Latex format.
- 'as_ratio': True,
- 'single_denominator': True,
- 'product_fmt': r' \cdot ',
- 'division_fmt': r'\frac[{0}][{1}]',
- 'power_fmt': '{0}^[{1}]',
- 'parentheses_fmt': r'\left({0}\right)',
- },
-
- 'H': { # HTML format.
- 'as_ratio': True,
- 'single_denominator': True,
- 'product_fmt': r' ',
- 'division_fmt': r'{0}/{1}',
- 'power_fmt': '{0}<sup>{1}</sup>',
- 'parentheses_fmt': r'({0})',
- },
-
- '': { # Default format.
- 'as_ratio': True,
- 'single_denominator': False,
- 'product_fmt': ' * ',
- 'division_fmt': ' / ',
- 'power_fmt': '{0} ** {1}',
- 'parentheses_fmt': r'({0})',
- },
-
- 'C': { # Compact format.
- 'as_ratio': True,
- 'single_denominator': False,
- 'product_fmt': '*', # TODO: Should this just be ''?
- 'division_fmt': '/',
- 'power_fmt': '{0}**{1}',
- 'parentheses_fmt': r'({0})',
- },
- }
-
-
-def formatter(items, as_ratio=True, single_denominator=False,
- product_fmt=' * ', division_fmt=' / ', power_fmt='{0} ** {1}',
- parentheses_fmt='({0})', exp_call=lambda x: '{0:n}'.format(x)):
- """Format a list of (name, exponent) pairs.
-
- :param items: a list of (name, exponent) pairs.
- :param as_ratio: True to display as ratio, False as negative powers.
- :param single_denominator: all with terms with negative exponents are
- collected together.
- :param product_fmt: the format used for multiplication.
- :param division_fmt: the format used for division.
- :param power_fmt: the format used for exponentiation.
- :param parentheses_fmt: the format used for parenthesis.
-
- :return: the formula as a string.
- """
-
- if not items:
- return ''
-
- if as_ratio:
- fun = lambda x: exp_call(abs(x))
- else:
- fun = exp_call
-
- pos_terms, neg_terms = [], []
-
- for key, value in sorted(items):
- if value == 1:
- pos_terms.append(key)
- elif value > 0:
- pos_terms.append(power_fmt.format(key, fun(value)))
- elif value == -1 and as_ratio:
- neg_terms.append(key)
- else:
- neg_terms.append(power_fmt.format(key, fun(value)))
-
- if not as_ratio:
- # Show as Product: positive * negative terms ** -1
- return _join(product_fmt, pos_terms + neg_terms)
-
- # Show as Ratio: positive terms / negative terms
- pos_ret = _join(product_fmt, pos_terms) or '1'
-
- if not neg_terms:
- return pos_ret
-
- if single_denominator:
- neg_ret = _join(product_fmt, neg_terms)
- if len(neg_terms) > 1:
- neg_ret = parentheses_fmt.format(neg_ret)
- else:
- neg_ret = _join(division_fmt, neg_terms)
-
- return _join(division_fmt, [pos_ret, neg_ret])
-
-# Extract just the type from the specification mini-langage: see
-# http://docs.python.org/2/library/string.html#format-specification-mini-language
-# We also add uS for uncertainties.
-_BASIC_TYPES = frozenset('bcdeEfFgGnosxX%uS')
-_KNOWN_TYPES = frozenset(list(_FORMATS.keys()) + ['~'])
-
-def _parse_spec(spec):
- result = ''
- for ch in reversed(spec):
- if ch == '~' or ch in _BASIC_TYPES:
- continue
- elif ch in _KNOWN_TYPES:
- if result:
- raise ValueError("expected ':' after format specifier")
- else:
- result = ch
- elif ch.isalpha():
- raise ValueError("Unknown conversion specified " + ch)
- else:
- break
- return result
-
-
-def format_unit(unit, spec):
- if not unit:
- return 'dimensionless'
-
- spec = _parse_spec(spec)
- fmt = {}
- # Convert keys and values to str to avoid a bug in Python2.6
- for k, v in _FORMATS[spec].items():
- fmt[str(k)] = str(v)
-
- result = formatter(unit.items(), **fmt)
- if spec == 'L':
- result = result.replace('[', '{').replace(']', '}')
- return result
-
-
-def remove_custom_flags(spec):
- for flag in _KNOWN_TYPES:
- if flag:
- spec = spec.replace(flag, '')
- return spec
diff --git a/lib/taurus/external/pint/pint_local/measurement.py b/lib/taurus/external/pint/pint_local/measurement.py
deleted file mode 100644
index e82591d..0000000
--- a/lib/taurus/external/pint/pint_local/measurement.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.measurement
- ~~~~~~~~~~~~~~~~
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-from .compat import ufloat
-from .formatting import _FORMATS
-
-MISSING = object()
-
-
-class _Measurement(object):
- """Implements a class to describe a quantity with uncertainty.
-
- :param value: The most likely value of the measurement.
- :type value: Quantity or Number
- :param error: The error or uncertainty of the measurement.
- :type error: Quantity or Number
- """
-
- def __new__(cls, value, error, units=MISSING):
- if units is MISSING:
- try:
- value, units = value.magnitude, value.units
- except AttributeError:
- try:
- value, error, units = value.nominal_value, value.std_dev, error
- except AttributeError:
- units = ''
- try:
- error = error.to(units).magnitude
- except AttributeError:
- pass
-
- inst = super(_Measurement, cls).__new__(cls, ufloat(value, error), units)
-
- if error < 0:
- raise ValueError('The magnitude of the error cannot be negative'.format(value, error))
- return inst
-
- @property
- def value(self):
- return self._REGISTRY.Quantity(self.magnitude.nominal_value, self.units)
-
- @property
- def error(self):
- return self._REGISTRY.Quantity(self.magnitude.std_dev, self.units)
-
- @property
- def rel(self):
- return float(abs(self.magnitude.std_dev / self.magnitude.nominal_value))
-
- def __repr__(self):
- return "<Measurement({0:.2f}, {1:.2f}, {2})>".format(self.magnitude.nominal_value,
- self.magnitude.std_dev,
- self.units)
-
- def __str__(self):
- return '{0}'.format(self)
-
- def __format__(self, spec):
- if 'L' in spec:
- newpm = pm = r' \pm '
- pars = _FORMATS['L']['parentheses_fmt']
- elif 'P' in spec:
- newpm = pm = '±'
- pars = _FORMATS['P']['parentheses_fmt']
- else:
- newpm = pm = '+/-'
- pars = _FORMATS['']['parentheses_fmt']
-
- if 'C' in spec:
- sp = ''
- newspec = spec.replace('C', '')
- pars = _FORMATS['C']['parentheses_fmt']
- else:
- sp = ' '
- newspec = spec
-
- if 'H' in spec:
- newpm = '±'
- newspec = spec.replace('H', '')
- pars = _FORMATS['H']['parentheses_fmt']
-
- mag = format(self.magnitude, newspec).replace(pm, sp + newpm + sp)
-
- if 'L' in newspec and 'S' in newspec:
- mag = mag.replace('(', r'\left(').replace(')', r'\right)')
-
- if 'uS' in newspec or 'ue' in newspec or 'u%' in newspec:
- return mag + ' ' + format(self.units, spec)
- else:
- return pars.format(mag) + ' ' + format(self.units, spec)
diff --git a/lib/taurus/external/pint/pint_local/pint_eval.py b/lib/taurus/external/pint/pint_local/pint_eval.py
deleted file mode 100644
index bae61c0..0000000
--- a/lib/taurus/external/pint/pint_local/pint_eval.py
+++ /dev/null
@@ -1,258 +0,0 @@
-'''
-Created on Mar 4, 2015
-
- at author: aaron
-'''
-
-from decimal import Decimal
-import math
-import operator
-
-import token as tokenlib
-
-#for controlling order of operations
-_OP_PRIORITY = {
- '**' : 3,
- '^' : 3,
- 'unary' : 2,
- '*' : 1,
- '' : 1, #operator for implicit ops
- '/' : 1,
- '+' : 0,
- '-' : 0
-}
-
-_BINARY_OPERATOR_MAP = {
- '**': operator.pow,
- '*': operator.mul,
- '': operator.mul, #operator for implicit ops
- '/': operator.truediv,
- '+': operator.add,
- '-': operator.sub
-}
-
-_UNARY_OPERATOR_MAP = {
- '+': lambda x : x,
- '-': lambda x : x * -1
-}
-
-
-class EvalTreeNode(object):
-
- def __init__(self, left, operator=None, right=None):
- '''
- left + operator + right --> binary op
- left + operator --> unary op
- left + right --> implicit op
- left --> single value
- '''
- self.left = left
- self.operator = operator
- self.right = right
-
- def to_string(self):
- #for debugging purposes
- if self.right:
- comps = [self.left.to_string()]
- if self.operator:
- comps.append(self.operator[1])
- comps.append(self.right.to_string())
- elif self.operator:
- comps = [self.operator[1], self.left.to_string()]
- else:
- return self.left[1]
- return '(%s)' % ' '.join(comps)
-
- def evaluate(self, define_op, bin_op=_BINARY_OPERATOR_MAP, un_op=_UNARY_OPERATOR_MAP):
- '''
- define_op is a callable that translates tokens into objects
- bin_op and un_op provide functions for performing binary and unary operations
- '''
-
- if self.right:
- #binary or implicit operator
- op_text = self.operator[1] if self.operator else ''
- if op_text not in bin_op:
- raise Exception('missing binary operator "%s"' % op_text)
- left = self.left.evaluate(define_op, bin_op, un_op)
- return bin_op[op_text](left, self.right.evaluate(define_op, bin_op, un_op))
- elif self.operator:
- #unary operator
- op_text = self.operator[1]
- if op_text not in un_op:
- raise Exception('missing unary operator "%s"' % op_text)
- return un_op[op_text](self.left.evaluate(define_op, bin_op, un_op))
- else:
- #single value
- return define_op(self.left)
-
-
-def build_eval_tree(tokens, op_priority=_OP_PRIORITY, index=0, depth=0, prev_op=None, ):
- '''
- Params:
- Index, depth, and prev_op used recursively, so don't touch.
- Tokens is an iterable of tokens from an expression to be evaluated.
-
- Transform the tokens from an expression into a recursive parse tree, following order of operations.
- Operations can include binary ops (3 + 4), implicit ops (3 kg), or unary ops (-1).
-
- General Strategy:
- 1) Get left side of operator
- 2) If no tokens left, return final result
- 3) Get operator
- 4) Use recursion to create tree starting at token on right side of operator (start at step #1)
- 4.1) If recursive call encounters an operator with lower or equal priority to step #2, exit recursion
- 5) Combine left side, operator, and right side into a new left side
- 6) Go back to step #2
- '''
- if depth == 0 and prev_op == None:
- #ensure tokens is list so we can access by index
- tokens = list(tokens)
-
- result = None
-
- while True:
- current_token = tokens[index]
- token_type = current_token[0]
- token_text = current_token[1]
-
- if token_type == tokenlib.OP:
- if token_text == ')':
- if prev_op == None:
- raise Exception('unopened parentheses in tokens: %s' % current_token)
- elif prev_op == '(':
- #close parenthetical group
- return result, index
- else:
- #parenthetical group ending, but we need to close sub-operations within group
- return result, index - 1
- elif token_text == '(':
- #gather parenthetical group
- right, index = build_eval_tree(tokens, op_priority, index+1, 0, token_text)
- if not tokens[index][1] == ')':
- raise Exception('weird exit from parentheses')
- if result:
- #implicit op with a parenthetical group, i.e. "3 (kg ** 2)"
- result = EvalTreeNode(left=result, right=right)
- else:
- #get first token
- result = right
- elif token_text in op_priority:
- if result:
- #equal-priority operators are grouped in a left-to-right order, unless they're
- #exponentiation, in which case they're grouped right-to-left
- #this allows us to get the expected behavior for multiple exponents
- # (2^3^4) --> (2^(3^4))
- # (2 * 3 / 4) --> ((2 * 3) / 4)
- if op_priority[token_text] <= op_priority.get(prev_op, -1) and token_text not in ['**', '^']:
- #previous operator is higher priority, so end previous binary op
- return result, index - 1
- #get right side of binary op
- right, index = build_eval_tree(tokens, op_priority, index+1, depth+1, token_text)
- result = EvalTreeNode(left=result, operator=current_token, right=right)
- else:
- #unary operator
- right, index = build_eval_tree(tokens, op_priority, index+1, depth+1, 'unary')
- result = EvalTreeNode(left=right, operator=current_token)
- elif token_type == tokenlib.NUMBER or token_type == tokenlib.NAME:
- if result:
- #tokens with an implicit operation i.e. "1 kg"
- if op_priority[''] <= op_priority.get(prev_op, -1):
- #previous operator is higher priority than implicit, so end previous binary op
- return result, index - 1
- right, index = build_eval_tree(tokens, op_priority, index, depth+1, '')
- result = EvalTreeNode(left=result, right=right)
- else:
- #get first token
- result = EvalTreeNode(left=current_token)
-
- if tokens[index][0] == tokenlib.ENDMARKER:
- if prev_op == '(':
- raise Exception('unclosed parentheses in tokens')
- if depth > 0 or prev_op:
- #have to close recursion
- return result, index
- else:
- #recursion all closed, so just return the final result
- return result
-
- if index + 1 >= len(tokens):
- #should hit ENDMARKER before this ever happens
- raise Exception('unexpected end to tokens')
-
- index += 1
-
-def _test_build_tree(input_text):
- '''
-
- ####
- >>> _test_build_tree('3') #single number
- u'3'
- >>> _test_build_tree('1 + 2') #basic addition
- u'(1 + 2)'
- >>> _test_build_tree('2 * 3 + 4') #order of operations
- u'((2 * 3) + 4)'
- >>> _test_build_tree('2 * (3 + 4)') #parentheses
- u'(2 * (3 + 4))'
- >>> _test_build_tree('1 + 2 * 3 ** (4 + 3 / 5)') #more order of operations
- u'(1 + (2 * (3 ** (4 + (3 / 5)))))'
- >>> _test_build_tree('1 * ((3 + 4) * 5)') #nested parentheses at beginning
- u'(1 * ((3 + 4) * 5))'
- >>> _test_build_tree('1 * (5 * (3 + 4))') #nested parentheses at end
- u'(1 * (5 * (3 + 4)))'
- >>> _test_build_tree('1 * (5 * (3 + 4) / 6)') #nested parentheses in middle
- u'(1 * ((5 * (3 + 4)) / 6))'
- >>> _test_build_tree('-1') #unary
- u'(- 1)'
- >>> _test_build_tree('3 * -1') #unary
- u'(3 * (- 1))'
- >>> _test_build_tree('3 * --1') #double unary
- u'(3 * (- (- 1)))'
- >>> _test_build_tree('3 * -(2 + 4)') #parenthetical unary
- u'(3 * (- (2 + 4)))'
- >>> _test_build_tree('3 * -((2 + 4))') #parenthetical unary
- u'(3 * (- (2 + 4)))'
- >>> _test_build_tree('3 4') #implicit op
- u'(3 4)'
- >>> _test_build_tree('3 (2 + 4)') #implicit op, then parentheses
- u'(3 (2 + 4))'
- >>> _test_build_tree('(3 ** 4 ) 5') #parentheses, then implicit
- u'((3 ** 4) 5)'
- >>> _test_build_tree('3 4 ** 5') #implicit op, then exponentiation
- u'(3 (4 ** 5))'
- >>> _test_build_tree('3 4 + 5') #implicit op, then addition
- u'((3 4) + 5)'
- >>> _test_build_tree('3 ** 4 5') #power followed by implicit
- u'((3 ** 4) 5)'
- >>> _test_build_tree('3 (4 ** 5)') #implicit with parentheses
- u'(3 (4 ** 5))'
- >>> _test_build_tree('3e-1') #exponent with e
- u'3e-1'
-
- >>> _test_build_tree('kg ** 1 * s ** 2') #multiple units with exponents
- u'((kg ** 1) * (s ** 2))'
- >>> _test_build_tree('kg ** -1 * s ** -2') #multiple units with neg exponents
- u'((kg ** (- 1)) * (s ** (- 2)))'
- >>> _test_build_tree('kg^-1 * s^-2') #multiple units with neg exponents
- u'((kg ^ (- 1)) * (s ^ (- 2)))'
- >>> _test_build_tree('kg^-1 s^-2') #multiple units with neg exponents, implicit op
- u'((kg ^ (- 1)) (s ^ (- 2)))'
-
- >>> _test_build_tree('2 ^ 3 ^ 2') #nested power
- u'(2 ^ (3 ^ 2))'
-
- >>> _test_build_tree('gram * second / meter ** 2') #nested power
- u'((gram * second) / (meter ** 2))'
- >>> _test_build_tree('gram / meter ** 2 / second') #nested power
- u'((gram / (meter ** 2)) / second)'
-
- #units should behave like numbers, so we don't need a bunch of extra tests for them
- >>> _test_build_tree('3 kg + 5') #implicit op, then addition
- u'((3 kg) + 5)'
- '''
- return build_eval_tree(tokenizer(input_text)).to_string()
-
-if __name__ == "__main__":
- import doctest, pint
- from pint.compat import tokenizer
- doctest.testmod()
diff --git a/lib/taurus/external/pint/pint_local/quantity.py b/lib/taurus/external/pint/pint_local/quantity.py
deleted file mode 100644
index 0eba47c..0000000
--- a/lib/taurus/external/pint/pint_local/quantity.py
+++ /dev/null
@@ -1,1337 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.quantity
- ~~~~~~~~~~~~~
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-import copy
-import math
-import operator
-import functools
-import bisect
-
-from .formatting import remove_custom_flags
-from .errors import (DimensionalityError, OffsetUnitCalculusError,
- UndefinedUnitError)
-from .definitions import UnitDefinition
-from .compat import string_types, ndarray, np, _to_magnitude, long_type
-from .util import (logger, UnitsContainer, SharedRegistryObject,
- to_units_container, infer_base_unit)
-
-
-def _eq(first, second, check_all):
- """Comparison of scalars and arrays
- """
- out = first == second
- if check_all and isinstance(out, ndarray):
- return np.all(out)
- return out
-
-
-class _Exception(Exception): # pragma: no cover
-
- def __init__(self, internal):
- self.internal = internal
-
-
-class _Quantity(SharedRegistryObject):
- """Implements a class to describe a physical quantity:
- the product of a numerical value and a unit of measurement.
-
- :param value: value of the physical quantity to be created.
- :type value: str, Quantity or any numeric type.
- :param units: units of the physical quantity to be created.
- :type units: UnitsContainer, str or Quantity.
- """
-
- #: Default formatting string.
- default_format = ''
-
- def __reduce__(self):
- from . import _build_quantity
- return _build_quantity, (self.magnitude, self._units)
-
- def __new__(cls, value, units=None):
- if units is None:
- if isinstance(value, string_types):
- if value == '':
- raise ValueError('Expression to parse as Quantity cannot '
- 'be an empty string.')
- inst = cls._REGISTRY.parse_expression(value)
- return cls.__new__(cls, inst)
- elif isinstance(value, cls):
- inst = copy.copy(value)
- else:
- inst = object.__new__(cls)
- inst._magnitude = _to_magnitude(value, inst.force_ndarray)
- inst._units = UnitsContainer()
- elif isinstance(units, (UnitsContainer, UnitDefinition)):
- inst = object.__new__(cls)
- inst._magnitude = _to_magnitude(value, inst.force_ndarray)
- inst._units = units
- elif isinstance(units, string_types):
- inst = object.__new__(cls)
- inst._magnitude = _to_magnitude(value, inst.force_ndarray)
- inst._units = inst._REGISTRY.parse_units(units)._units
- elif isinstance(units, SharedRegistryObject):
- if isinstance(units, _Quantity) and units.magnitude != 1:
- inst = copy.copy(units)
- logger.warning('Creating new Quantity using a non unity '
- 'Quantity as units.')
- else:
- inst = object.__new__(cls)
- inst._units = units._units
- inst._magnitude = _to_magnitude(value, inst.force_ndarray)
- else:
- raise TypeError('units must be of type str, Quantity or '
- 'UnitsContainer; not {0}.'.format(type(units)))
-
- inst.__used = False
- inst.__handling = None
- return inst
-
- @property
- def debug_used(self):
- return self.__used
-
- def __copy__(self):
- ret = self.__class__(copy.copy(self._magnitude), self._units)
- ret.__used = self.__used
- return ret
-
- def __deepcopy__(self, memo):
- ret = self.__class__(copy.deepcopy(self._magnitude, memo),
- copy.deepcopy(self._units, memo))
- ret.__used = self.__used
- return ret
-
- def __str__(self):
- return format(self)
-
- def __repr__(self):
- return "<Quantity({0}, '{1}')>".format(self._magnitude, self._units)
-
- def __format__(self, spec):
- spec = spec or self.default_format
- if '#' in spec:
- spec = spec.replace('#', '')
- obj = self.to_compact()
- else:
- obj = self
- return '{0} {1}'.format(
- format(obj.magnitude, remove_custom_flags(spec)),
- format(obj.units, spec))
-
- # IPython related code
- def _repr_html_(self):
- return self.__format__('H')
-
- def _repr_latex_(self):
- return "$" + self.__format__('L') + "$"
-
- @property
- def magnitude(self):
- """Quantity's magnitude. Long form for `m`
- """
- return self._magnitude
-
- @property
- def m(self):
- """Quantity's magnitude. Short form for `magnitude`
- """
- return self._magnitude
-
- def m_as(self, unit):
- """Quantity's magnitude expressed in particular units.
-
- :param other: destination units.
- :type other: Quantity, str or dict
- """
- return (self / unit).to('').magnitude
-
- @property
- def units(self):
- """Quantity's units. Long form for `u`
-
- :rtype: UnitContainer
- """
- return self._REGISTRY.Unit(self._units)
-
- @property
- def u(self):
- """Quantity's units. Short form for `units`
-
- :rtype: UnitContainer
- """
- return self._REGISTRY.Unit(self._units)
-
- @property
- def unitless(self):
- """Return true if the quantity does not have units.
- """
- return not bool(self.to_root_units()._units)
-
- @property
- def dimensionless(self):
- """Return true if the quantity is dimensionless.
- """
- tmp = self.to_root_units()
-
- return not bool(tmp.dimensionality)
-
- @property
- def dimensionality(self):
- """Quantity's dimensionality (e.g. {length: 1, time: -1})
- """
- try:
- return self._dimensionality
- except AttributeError:
- self._dimensionality = self._REGISTRY._get_dimensionality(self._units)
-
- return self._dimensionality
-
- def compatible_units(self, *contexts):
- if contexts:
- with self._REGISTRY.context(*contexts):
- return self._REGISTRY.get_compatible_units(self._units)
-
- return self._REGISTRY.get_compatible_units(self._units)
-
- def _convert_magnitude_not_inplace(self, other, *contexts, **ctx_kwargs):
- if contexts:
- with self._REGISTRY.context(*contexts, **ctx_kwargs):
- return self._REGISTRY.convert(self._magnitude, self._units, other)
-
- return self._REGISTRY.convert(self._magnitude, self._units, other)
-
- def _convert_magnitude(self, other, *contexts, **ctx_kwargs):
- if contexts:
- with self._REGISTRY.context(*contexts, **ctx_kwargs):
- return self._REGISTRY.convert(self._magnitude, self._units, other)
-
- return self._REGISTRY.convert(self._magnitude, self._units, other,
- inplace=isinstance(self._magnitude, ndarray))
-
- def ito(self, other=None, *contexts, **ctx_kwargs):
- """Inplace rescale to different units.
-
- :param other: destination units.
- :type other: Quantity, str or dict
- """
- other = to_units_container(other, self._REGISTRY)
-
- self._magnitude = self._convert_magnitude(other, *contexts,
- **ctx_kwargs)
- self._units = other
-
- return None
-
- def to(self, other=None, *contexts, **ctx_kwargs):
- """Return Quantity rescaled to different units.
-
- :param other: destination units.
- :type other: Quantity, str or dict
- """
- other = to_units_container(other, self._REGISTRY)
-
- magnitude = self._convert_magnitude_not_inplace(other, *contexts, **ctx_kwargs)
-
- return self.__class__(magnitude, other)
-
- def ito_root_units(self):
- """Return Quantity rescaled to base units
- """
-
- _, other = self._REGISTRY._get_root_units(self._units)
-
- self._magnitude = self._convert_magnitude(other)
- self._units = other
-
- return None
-
- def to_root_units(self):
- """Return Quantity rescaled to base units
- """
- _, other = self._REGISTRY._get_root_units(self._units)
-
- magnitude = self._convert_magnitude_not_inplace(other)
-
- return self.__class__(magnitude, other)
-
- def ito_base_units(self):
- """Return Quantity rescaled to base units
- """
-
- _, other = self._REGISTRY._get_base_units(self._units)
-
- self._magnitude = self._convert_magnitude(other)
- self._units = other
-
- return None
-
- def to_base_units(self):
- """Return Quantity rescaled to base units
- """
- _, other = self._REGISTRY._get_base_units(self._units)
-
- magnitude = self._convert_magnitude_not_inplace(other)
-
- return self.__class__(magnitude, other)
-
-
- def to_compact(self, unit=None):
- """Return Quantity rescaled to compact, human-readable units.
-
- To get output in terms of a different unit, use the unit parameter.
-
- >>> import pint
- >>> ureg = pint.UnitRegistry()
- >>> (200e-9*ureg.s).to_compact()
- <Quantity(200.0, 'nanosecond')>
- >>> (1e-2*ureg('kg m/s^2')).to_compact('N')
- <Quantity(10.0, 'millinewton')>
- """
- if self.unitless:
- return self
-
- SI_prefixes = {}
- for prefix in self._REGISTRY._prefixes.values():
- try:
- scale = prefix.converter.scale
- # Kludgy way to check if this is an SI prefix
- log10_scale = int(math.log10(scale))
- if log10_scale == math.log10(scale):
- SI_prefixes[log10_scale] = prefix.name
- except:
- SI_prefixes[0] = ''
-
- SI_prefixes = sorted(SI_prefixes.items())
- SI_powers = [item[0] for item in SI_prefixes]
- SI_bases = [item[1] for item in SI_prefixes]
-
- if unit is None:
- unit = infer_base_unit(self)
-
- q_base = self.to(unit)
-
- magnitude = q_base.magnitude
- # Only changes the prefix on the first unit in the UnitContainer
- unit_str = list(q_base._units.items())[0][0]
- unit_power = list(q_base._units.items())[0][1]
-
- if unit_power > 0:
- power = int(math.floor(math.log10(magnitude) / unit_power / 3)) * 3
- else:
- power = int(math.ceil(math.log10(magnitude) / unit_power / 3)) * 3
-
- prefix = SI_bases[bisect.bisect_left(SI_powers, power)]
-
- new_unit_str = prefix+unit_str
- new_unit_container = q_base._units.rename(unit_str, new_unit_str)
-
- return self.to(new_unit_container)
-
- # Mathematical operations
- def __int__(self):
- if self.dimensionless:
- return int(self._convert_magnitude_not_inplace(UnitsContainer()))
- raise DimensionalityError(self._units, 'dimensionless')
-
- def __long__(self):
- if self.dimensionless:
- return long_type(self._convert_magnitude_not_inplace(UnitsContainer()))
- raise DimensionalityError(self._units, 'dimensionless')
-
- def __float__(self):
- if self.dimensionless:
- return float(self._convert_magnitude_not_inplace(UnitsContainer()))
- raise DimensionalityError(self._units, 'dimensionless')
-
- def __complex__(self):
- if self.dimensionless:
- return complex(self._convert_magnitude_not_inplace(UnitsContainer()))
- raise DimensionalityError(self._units, 'dimensionless')
-
- def _iadd_sub(self, other, op):
- """Perform addition or subtraction operation in-place and return the result.
-
- :param other: object to be added to / subtracted from self
- :type other: Quantity or any type accepted by :func:`_to_magnitude`
- :param op: operator function (e.g. operator.add, operator.isub)
- :type op: function
- """
- if not self._check(other):
- # other not from same Registry or not a Quantity
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
- if _eq(other, 0, True):
- # If the other value is 0 (but not Quantity 0)
- # do the operation without checking units.
- # We do the calculation instead of just returning the same
- # value to enforce any shape checking and type casting due to
- # the operation.
- self._magnitude = op(self._magnitude, other_magnitude)
- elif self.dimensionless:
- self.ito(UnitsContainer())
- self._magnitude = op(self._magnitude, other_magnitude)
- else:
- raise DimensionalityError(self._units, 'dimensionless')
- return self
-
- if not self.dimensionality == other.dimensionality:
- raise DimensionalityError(self._units, other._units,
- self.dimensionality,
- other.dimensionality)
-
- # Next we define some variables to make if-clauses more readable.
- self_non_mul_units = self._get_non_multiplicative_units()
- is_self_multiplicative = len(self_non_mul_units) == 0
- if len(self_non_mul_units) == 1:
- self_non_mul_unit = self_non_mul_units[0]
- other_non_mul_units = other._get_non_multiplicative_units()
- is_other_multiplicative = len(other_non_mul_units) == 0
- if len(other_non_mul_units) == 1:
- other_non_mul_unit = other_non_mul_units[0]
-
- # Presence of non-multiplicative units gives rise to several cases.
- if is_self_multiplicative and is_other_multiplicative:
- if self._units == other._units:
- self._magnitude = op(self._magnitude, other._magnitude)
- # If only self has a delta unit, other determines unit of result.
- elif self._get_delta_units() and not other._get_delta_units():
- self._magnitude = op(self._convert_magnitude(other._units),
- other._magnitude)
- self._units = other._units
- else:
- self._magnitude = op(self._magnitude,
- other.to(self._units)._magnitude)
-
- elif (op == operator.isub and len(self_non_mul_units) == 1
- and self._units[self_non_mul_unit] == 1
- and not other._has_compatible_delta(self_non_mul_unit)):
- if self._units == other._units:
- self._magnitude = op(self._magnitude, other._magnitude)
- else:
- self._magnitude = op(self._magnitude,
- other.to(self._units)._magnitude)
- self._units = self._units.rename(self_non_mul_unit,
- 'delta_' + self_non_mul_unit)
-
- elif (op == operator.isub and len(other_non_mul_units) == 1
- and other._units[other_non_mul_unit] == 1
- and not self._has_compatible_delta(other_non_mul_unit)):
- # we convert to self directly since it is multiplicative
- self._magnitude = op(self._magnitude,
- other.to(self._units)._magnitude)
-
- elif (len(self_non_mul_units) == 1
- # order of the dimension of offset unit == 1 ?
- and self._units[self_non_mul_unit] == 1
- and other._has_compatible_delta(self_non_mul_unit)):
- # Replace offset unit in self by the corresponding delta unit.
- # This is done to prevent a shift by offset in the to()-call.
- tu = self._units.rename(self_non_mul_unit,
- 'delta_' + self_non_mul_unit)
- self._magnitude = op(self._magnitude, other.to(tu)._magnitude)
- elif (len(other_non_mul_units) == 1
- # order of the dimension of offset unit == 1 ?
- and other._units[other_non_mul_unit] == 1
- and self._has_compatible_delta(other_non_mul_unit)):
- # Replace offset unit in other by the corresponding delta unit.
- # This is done to prevent a shift by offset in the to()-call.
- tu = other._units.rename(other_non_mul_unit,
- 'delta_' + other_non_mul_unit)
- self._magnitude = op(self._convert_magnitude(tu), other._magnitude)
- self._units = other._units
- else:
- raise OffsetUnitCalculusError(self._units, other._units)
-
- return self
-
- def _add_sub(self, other, op):
- """Perform addition or subtraction operation and return the result.
-
- :param other: object to be added to / subtracted from self
- :type other: Quantity or any type accepted by :func:`_to_magnitude`
- :param op: operator function (e.g. operator.add, operator.isub)
- :type op: function
- """
- if not self._check(other):
- # other not from same Registry or not a Quantity
- if _eq(other, 0, True):
- # If the other value is 0 (but not Quantity 0)
- # do the operation without checking units.
- # We do the calculation instead of just returning the same
- # value to enforce any shape checking and type casting due to
- # the operation.
- units = self._units
- magnitude = op(self._magnitude,
- _to_magnitude(other, self.force_ndarray))
- elif self.dimensionless:
- units = UnitsContainer()
- magnitude = op(self.to(units)._magnitude,
- _to_magnitude(other, self.force_ndarray))
- else:
- raise DimensionalityError(self._units, 'dimensionless')
- return self.__class__(magnitude, units)
-
- if not self.dimensionality == other.dimensionality:
- raise DimensionalityError(self._units, other._units,
- self.dimensionality,
- other.dimensionality)
-
- # Next we define some variables to make if-clauses more readable.
- self_non_mul_units = self._get_non_multiplicative_units()
- is_self_multiplicative = len(self_non_mul_units) == 0
- if len(self_non_mul_units) == 1:
- self_non_mul_unit = self_non_mul_units[0]
- other_non_mul_units = other._get_non_multiplicative_units()
- is_other_multiplicative = len(other_non_mul_units) == 0
- if len(other_non_mul_units) == 1:
- other_non_mul_unit = other_non_mul_units[0]
-
- # Presence of non-multiplicative units gives rise to several cases.
- if is_self_multiplicative and is_other_multiplicative:
- if self._units == other._units:
- magnitude = op(self._magnitude, other._magnitude)
- units = self._units
- # If only self has a delta unit, other determines unit of result.
- elif self._get_delta_units() and not other._get_delta_units():
- magnitude = op(self._convert_magnitude(other._units),
- other._magnitude)
- units = other._units
- else:
- units = self._units
- magnitude = op(self._magnitude,
- other.to(self._units).magnitude)
-
- elif (op == operator.sub and len(self_non_mul_units) == 1
- and self._units[self_non_mul_unit] == 1
- and not other._has_compatible_delta(self_non_mul_unit)):
- if self._units == other._units:
- magnitude = op(self._magnitude, other._magnitude)
- else:
- magnitude = op(self._magnitude,
- other.to(self._units)._magnitude)
- units = self._units.rename(self_non_mul_unit,
- 'delta_' + self_non_mul_unit)
-
- elif (op == operator.sub and len(other_non_mul_units) == 1
- and other._units[other_non_mul_unit] == 1
- and not self._has_compatible_delta(other_non_mul_unit)):
- # we convert to self directly since it is multiplicative
- magnitude = op(self._magnitude,
- other.to(self._units)._magnitude)
- units = self._units
-
- elif (len(self_non_mul_units) == 1
- # order of the dimension of offset unit == 1 ?
- and self._units[self_non_mul_unit] == 1
- and other._has_compatible_delta(self_non_mul_unit)):
- # Replace offset unit in self by the corresponding delta unit.
- # This is done to prevent a shift by offset in the to()-call.
- tu = self._units.rename(self_non_mul_unit,
- 'delta_' + self_non_mul_unit)
- magnitude = op(self._magnitude, other.to(tu).magnitude)
- units = self._units
- elif (len(other_non_mul_units) == 1
- # order of the dimension of offset unit == 1 ?
- and other._units[other_non_mul_unit] == 1
- and self._has_compatible_delta(other_non_mul_unit)):
- # Replace offset unit in other by the corresponding delta unit.
- # This is done to prevent a shift by offset in the to()-call.
- tu = other._units.rename(other_non_mul_unit,
- 'delta_' + other_non_mul_unit)
- magnitude = op(self._convert_magnitude(tu), other._magnitude)
- units = other._units
- else:
- raise OffsetUnitCalculusError(self._units, other._units)
-
- return self.__class__(magnitude, units)
-
- def __iadd__(self, other):
- if not isinstance(self._magnitude, ndarray):
- return self._add_sub(other, operator.add)
- else:
- return self._iadd_sub(other, operator.iadd)
-
- def __add__(self, other):
- return self._add_sub(other, operator.add)
-
- __radd__ = __add__
-
- def __isub__(self, other):
- if not isinstance(self._magnitude, ndarray):
- return self._add_sub(other, operator.sub)
- else:
- return self._iadd_sub(other, operator.isub)
-
- def __sub__(self, other):
- return self._add_sub(other, operator.sub)
-
- def __rsub__(self, other):
- return -self._add_sub(other, operator.sub)
-
- def _imul_div(self, other, magnitude_op, units_op=None):
- """Perform multiplication or division operation in-place and return the
- result.
-
- :param other: object to be multiplied/divided with self
- :type other: Quantity or any type accepted by :func:`_to_magnitude`
- :param magnitude_op: operator function to perform on the magnitudes
- (e.g. operator.mul)
- :type magnitude_op: function
- :param units_op: operator function to perform on the units; if None,
- *magnitude_op* is used
- :type units_op: function or None
- """
- if units_op is None:
- units_op = magnitude_op
-
- offset_units_self = self._get_non_multiplicative_units()
- no_offset_units_self = len(offset_units_self)
-
- if not self._check(other):
-
- if not self._ok_for_muldiv(no_offset_units_self):
- raise OffsetUnitCalculusError(self._units,
- getattr(other, 'units', ''))
- if len(offset_units_self) == 1:
- if (self._units[offset_units_self[0]] != 1
- or magnitude_op not in [operator.mul, operator.imul]):
- raise OffsetUnitCalculusError(self._units,
- getattr(other, 'units', ''))
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
- self._magnitude = magnitude_op(self._magnitude, other_magnitude)
- self._units = units_op(self._units, UnitsContainer())
- return self
-
- if not isinstance(other, _Quantity):
- self._magnitude = magnitude_op(self._magnitude, 1)
- self._units = units_op(self._units, other._units)
- return self
-
- if not self._ok_for_muldiv(no_offset_units_self):
- raise OffsetUnitCalculusError(self._units, other._units)
- elif no_offset_units_self == 1 and len(self._units) == 1:
- self.ito_root_units()
-
- no_offset_units_other = len(other._get_non_multiplicative_units())
-
- if not other._ok_for_muldiv(no_offset_units_other):
- raise OffsetUnitCalculusError(self._units, other._units)
- elif no_offset_units_other == 1 and len(other._units) == 1:
- other.ito_root_units()
-
- self._magnitude = magnitude_op(self._magnitude, other._magnitude)
- self._units = units_op(self._units, other._units)
-
- return self
-
- def _mul_div(self, other, magnitude_op, units_op=None):
- """Perform multiplication or division operation and return the result.
-
- :param other: object to be multiplied/divided with self
- :type other: Quantity or any type accepted by :func:`_to_magnitude`
- :param magnitude_op: operator function to perform on the magnitudes
- (e.g. operator.mul)
- :type magnitude_op: function
- :param units_op: operator function to perform on the units; if None,
- *magnitude_op* is used
- :type units_op: function or None
- """
- if units_op is None:
- units_op = magnitude_op
-
- offset_units_self = self._get_non_multiplicative_units()
- no_offset_units_self = len(offset_units_self)
-
- if not self._check(other):
-
- if not self._ok_for_muldiv(no_offset_units_self):
- raise OffsetUnitCalculusError(self._units,
- getattr(other, 'units', ''))
- if len(offset_units_self) == 1:
- if (self._units[offset_units_self[0]] != 1
- or magnitude_op not in [operator.mul, operator.imul]):
- raise OffsetUnitCalculusError(self._units,
- getattr(other, 'units', ''))
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
-
- magnitude = magnitude_op(self._magnitude, other_magnitude)
- units = units_op(self._units, UnitsContainer())
-
- return self.__class__(magnitude, units)
-
- if not isinstance(other, _Quantity):
- magnitude = self._magnitude
- units = units_op(self._units, other._units)
- return self.__class__(magnitude, units)
-
- new_self = self
-
- if not self._ok_for_muldiv(no_offset_units_self):
- raise OffsetUnitCalculusError(self._units, other._units)
- elif no_offset_units_self == 1 and len(self._units) == 1:
- new_self = self.to_root_units()
-
- no_offset_units_other = len(other._get_non_multiplicative_units())
-
- if not other._ok_for_muldiv(no_offset_units_other):
- raise OffsetUnitCalculusError(self._units, other._units)
- elif no_offset_units_other == 1 and len(other._units) == 1:
- other = other.to_root_units()
-
- magnitude = magnitude_op(new_self._magnitude, other._magnitude)
- units = units_op(new_self._units, other._units)
-
- return self.__class__(magnitude, units)
-
- def __imul__(self, other):
- if not isinstance(self._magnitude, ndarray):
- return self._mul_div(other, operator.mul)
- else:
- return self._imul_div(other, operator.imul)
-
- def __mul__(self, other):
- return self._mul_div(other, operator.mul)
-
- __rmul__ = __mul__
-
- def __itruediv__(self, other):
- if not isinstance(self._magnitude, ndarray):
- return self._mul_div(other, operator.truediv)
- else:
- return self._imul_div(other, operator.itruediv)
-
- def __truediv__(self, other):
- return self._mul_div(other, operator.truediv)
-
- def __ifloordiv__(self, other):
- if not isinstance(self._magnitude, ndarray):
- return self._mul_div(other, operator.floordiv, units_op=operator.itruediv)
- else:
- return self._imul_div(other, operator.ifloordiv, units_op=operator.itruediv)
-
- def __floordiv__(self, other):
- return self._mul_div(other, operator.floordiv, units_op=operator.truediv)
-
- def __rtruediv__(self, other):
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
-
- no_offset_units_self = len(self._get_non_multiplicative_units())
- if not self._ok_for_muldiv(no_offset_units_self):
- raise OffsetUnitCalculusError(self._units, '')
- elif no_offset_units_self == 1 and len(self._units) == 1:
- self = self.to_root_units()
-
- return self.__class__(other_magnitude / self._magnitude, 1 / self._units)
-
- def __rfloordiv__(self, other):
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
-
- no_offset_units_self = len(self._get_non_multiplicative_units())
- if not self._ok_for_muldiv(no_offset_units_self):
- raise OffsetUnitCalculusError(self._units, '')
- elif no_offset_units_self == 1 and len(self._units) == 1:
- self = self.to_root_units()
-
- return self.__class__(other_magnitude // self._magnitude, 1 / self._units)
-
- __div__ = __truediv__
- __rdiv__ = __rtruediv__
- __idiv__ = __itruediv__
-
- def __ipow__(self, other):
- if not isinstance(self._magnitude, ndarray):
- return self.__pow__(other)
-
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
- else:
- if not self._ok_for_muldiv:
- raise OffsetUnitCalculusError(self._units)
-
- if isinstance(getattr(other, '_magnitude', other), ndarray):
- # arrays are refused as exponent, because they would create
- # len(array) quanitites of len(set(array)) different units
- if np.size(other) > 1:
- raise DimensionalityError(self._units, 'dimensionless')
-
- if other == 1:
- return self
- elif other == 0:
- self._units = UnitsContainer()
- else:
- if not self._is_multiplicative:
- if self._REGISTRY.autoconvert_offset_to_baseunit:
- self.ito_base_units()
- else:
- raise OffsetUnitCalculusError(self._units)
-
- if getattr(other, 'dimensionless', False):
- other = other.to_base_units()
- self._units **= other.magnitude
- elif not getattr(other, 'dimensionless', True):
- raise DimensionalityError(self._units, 'dimensionless')
- else:
- self._units **= other
-
- self._magnitude **= _to_magnitude(other, self.force_ndarray)
- return self
-
- def __pow__(self, other):
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
- else:
- if not self._ok_for_muldiv:
- raise OffsetUnitCalculusError(self._units)
-
- if isinstance(getattr(other, '_magnitude', other), ndarray):
- # arrays are refused as exponent, because they would create
- # len(array) quantities of len(set(array)) different units
- if np.size(other) > 1:
- raise DimensionalityError(self._units, 'dimensionless')
-
- new_self = self
- if other == 1:
- return self
- elif other == 0:
- units = UnitsContainer()
- else:
- if not self._is_multiplicative:
- if self._REGISTRY.autoconvert_offset_to_baseunit:
- new_self = self.to_root_units()
- else:
- raise OffsetUnitCalculusError(self._units)
-
- if getattr(other, 'dimensionless', False):
- units = new_self._units ** other.to_root_units().magnitude
- elif not getattr(other, 'dimensionless', True):
- raise DimensionalityError(self._units, 'dimensionless')
- else:
- units = new_self._units ** other
-
- magnitude = new_self._magnitude ** _to_magnitude(other, self.force_ndarray)
- return self.__class__(magnitude, units)
-
- def __rpow__(self, other):
- try:
- other_magnitude = _to_magnitude(other, self.force_ndarray)
- except TypeError:
- return NotImplemented
- else:
- if not self.dimensionless:
- raise DimensionalityError(self._units, 'dimensionless')
- if isinstance(self._magnitude, ndarray):
- if np.size(self._magnitude) > 1:
- raise DimensionalityError(self._units, 'dimensionless')
- new_self = self.to_root_units()
- return other**new_self._magnitude
-
- def __abs__(self):
- return self.__class__(abs(self._magnitude), self._units)
-
- def __round__(self, ndigits=0):
- return self.__class__(round(self._magnitude, ndigits=ndigits), self._units)
-
- def __pos__(self):
- return self.__class__(operator.pos(self._magnitude), self._units)
-
- def __neg__(self):
- return self.__class__(operator.neg(self._magnitude), self._units)
-
- def __eq__(self, other):
- # We compare to the base class of Quantity because
- # each Quantity class is unique.
- if not isinstance(other, _Quantity):
- return (self.dimensionless and
- _eq(self._convert_magnitude(UnitsContainer()), other, False))
-
- if _eq(self._magnitude, 0, True) and _eq(other._magnitude, 0, True):
- return self.dimensionality == other.dimensionality
-
- if self._units == other._units:
- return _eq(self._magnitude, other._magnitude, False)
-
- try:
- return _eq(self._convert_magnitude_not_inplace(other._units),
- other._magnitude, False)
- except DimensionalityError:
- return False
-
- def __ne__(self, other):
- out = self.__eq__(other)
- if isinstance(out, ndarray):
- return np.logical_not(out)
- return not out
-
- def compare(self, other, op):
- if not isinstance(other, self.__class__):
- if self.dimensionless:
- return op(self._convert_magnitude_not_inplace(UnitsContainer()), other)
- else:
- raise ValueError('Cannot compare Quantity and {0}'.format(type(other)))
-
- if self._units == other._units:
- return op(self._magnitude, other._magnitude)
- if self.dimensionality != other.dimensionality:
- raise DimensionalityError(self._units, other._units,
- self.dimensionality, other.dimensionality)
- return op(self.to_root_units().magnitude,
- other.to_root_units().magnitude)
-
- __lt__ = lambda self, other: self.compare(other, op=operator.lt)
- __le__ = lambda self, other: self.compare(other, op=operator.le)
- __ge__ = lambda self, other: self.compare(other, op=operator.ge)
- __gt__ = lambda self, other: self.compare(other, op=operator.gt)
-
- def __bool__(self):
- return bool(self._magnitude)
-
- __nonzero__ = __bool__
-
- # NumPy Support
- __radian = 'radian'
- __same_units = 'equal greater greater_equal less less_equal not_equal arctan2'.split()
- #: Dictionary mapping ufunc/attributes names to the units that they
- #: require (conversion will be tried).
- __require_units = {'cumprod': '',
- 'arccos': '', 'arcsin': '', 'arctan': '',
- 'arccosh': '', 'arcsinh': '', 'arctanh': '',
- 'exp': '', 'expm1': '', 'exp2': '',
- 'log': '', 'log10': '', 'log1p': '', 'log2': '',
- 'sin': __radian, 'cos': __radian, 'tan': __radian,
- 'sinh': __radian, 'cosh': __radian, 'tanh': __radian,
- 'radians': 'degree', 'degrees': __radian,
- 'deg2rad': 'degree', 'rad2deg': __radian,
- 'logaddexp': '', 'logaddexp2': ''}
-
- #: Dictionary mapping ufunc/attributes names to the units that they
- #: will set on output.
- __set_units = {'cos': '', 'sin': '', 'tan': '',
- 'cosh': '', 'sinh': '', 'tanh': '',
- 'arccos': __radian, 'arcsin': __radian,
- 'arctan': __radian, 'arctan2': __radian,
- 'arccosh': __radian, 'arcsinh': __radian,
- 'arctanh': __radian,
- 'degrees': 'degree', 'radians': __radian,
- 'expm1': '', 'cumprod': '',
- 'rad2deg': 'degree', 'deg2rad': __radian}
-
- #: List of ufunc/attributes names in which units are copied from the
- #: original.
- __copy_units = 'compress conj conjugate copy cumsum diagonal flatten ' \
- 'max mean min ptp ravel repeat reshape round ' \
- 'squeeze std sum take trace transpose ' \
- 'ceil floor hypot rint ' \
- 'add subtract ' \
- 'copysign nextafter trunc ' \
- 'frexp ldexp modf modf__1 ' \
- 'absolute negative remainder fmod mod'.split()
-
- #: Dictionary mapping ufunc/attributes names to the units that they will
- #: set on output. The value is interpreted as the power to which the unit
- #: will be raised.
- __prod_units = {'var': 2, 'prod': 'size', 'multiply': 'mul',
- 'true_divide': 'div', 'divide': 'div', 'floor_divide': 'div',
- 'remainder': 'div',
- 'sqrt': .5, 'square': 2, 'reciprocal': -1}
-
- __skip_other_args = 'ldexp multiply ' \
- 'true_divide divide floor_divide fmod mod ' \
- 'remainder'.split()
-
- __handled = tuple(__same_units) + \
- tuple(__require_units.keys()) + \
- tuple(__prod_units.keys()) + \
- tuple(__copy_units) + tuple(__skip_other_args)
-
- def clip(self, first=None, second=None, out=None, **kwargs):
- min = kwargs.get('min', first)
- max = kwargs.get('max', second)
-
- if min is None and max is None:
- raise TypeError('clip() takes at least 3 arguments (2 given)')
-
- if max is None and 'min' not in kwargs:
- min, max = max, min
-
- kwargs = {'out': out}
-
- if min is not None:
- if isinstance(min, self.__class__):
- kwargs['min'] = min.to(self).magnitude
- elif self.dimensionless:
- kwargs['min'] = min
- else:
- raise DimensionalityError('dimensionless', self._units)
-
- if max is not None:
- if isinstance(max, self.__class__):
- kwargs['max'] = max.to(self).magnitude
- elif self.dimensionless:
- kwargs['max'] = max
- else:
- raise DimensionalityError('dimensionless', self._units)
-
- return self.__class__(self.magnitude.clip(**kwargs), self._units)
-
- def fill(self, value):
- self._units = value._units
- return self.magnitude.fill(value.magnitude)
-
- def put(self, indices, values, mode='raise'):
- if isinstance(values, self.__class__):
- values = values.to(self).magnitude
- elif self.dimensionless:
- values = self.__class__(values, '').to(self)
- else:
- raise DimensionalityError('dimensionless', self._units)
- self.magnitude.put(indices, values, mode)
-
- @property
- def real(self):
- return self.__class__(self._magnitude.real, self._units)
-
- @property
- def imag(self):
- return self.__class__(self._magnitude.imag, self._units)
-
- @property
- def T(self):
- return self.__class__(self._magnitude.T, self._units)
-
- def searchsorted(self, v, side='left'):
- if isinstance(v, self.__class__):
- v = v.to(self).magnitude
- elif self.dimensionless:
- v = self.__class__(v, '').to(self)
- else:
- raise DimensionalityError('dimensionless', self._units)
- return self.magnitude.searchsorted(v, side)
-
- def __ito_if_needed(self, to_units):
- if self.unitless and to_units == 'radian':
- return
-
- self.ito(to_units)
-
- def __numpy_method_wrap(self, func, *args, **kwargs):
- """Convenience method to wrap on the fly numpy method taking
- care of the units.
- """
- if func.__name__ in self.__require_units:
- self.__ito_if_needed(self.__require_units[func.__name__])
-
- value = func(*args, **kwargs)
-
- if func.__name__ in self.__copy_units:
- return self.__class__(value, self._units)
-
- if func.__name__ in self.__prod_units:
- tmp = self.__prod_units[func.__name__]
- if tmp == 'size':
- return self.__class__(value, self._units ** self._magnitude.size)
- return self.__class__(value, self._units ** tmp)
-
- return value
-
- def __len__(self):
- return len(self._magnitude)
-
- def __iter__(self):
- # Allow exception to propagate in case of non-iterable magnitude
- it_mag = iter(self.magnitude)
- return iter((self.__class__(mag, self._units) for mag in it_mag))
-
- def __getattr__(self, item):
- # Attributes starting with `__array_` are common attributes of NumPy ndarray.
- # They are requested by numpy functions.
- if item.startswith('__array_'):
- if isinstance(self._magnitude, ndarray):
- return getattr(self._magnitude, item)
- else:
- # If an `__array_` attributes is requested but the magnitude is not an ndarray,
- # we convert the magnitude to a numpy ndarray.
- self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
- return getattr(self._magnitude, item)
- elif item in self.__handled:
- if not isinstance(self._magnitude, ndarray):
- self._magnitude = _to_magnitude(self._magnitude, True)
- attr = getattr(self._magnitude, item)
- if callable(attr):
- return functools.partial(self.__numpy_method_wrap, attr)
- return attr
- try:
- return getattr(self._magnitude, item)
- except AttributeError as ex:
- raise AttributeError("Neither Quantity object nor its magnitude ({0}) "
- "has attribute '{1}'".format(self._magnitude, item))
-
- def __getitem__(self, key):
- try:
- value = self._magnitude[key]
- return self.__class__(value, self._units)
- except TypeError:
- raise TypeError("Neither Quantity object nor its magnitude ({0})"
- "supports indexing".format(self._magnitude))
-
- def __setitem__(self, key, value):
- try:
- if math.isnan(value):
- self._magnitude[key] = value
- return
- except (TypeError, DimensionalityError):
- pass
-
- try:
- if isinstance(value, self.__class__):
- factor = self.__class__(value.magnitude, value._units / self._units).to_root_units()
- else:
- factor = self.__class__(value, self._units ** (-1)).to_root_units()
-
- if isinstance(factor, self.__class__):
- if not factor.dimensionless:
- raise DimensionalityError(value, self.units,
- extra_msg='. Assign a quantity with the same dimensionality or '
- 'access the magnitude directly as '
- '`obj.magnitude[%s] = %s`' % (key, value))
- self._magnitude[key] = factor.magnitude
- else:
- self._magnitude[key] = factor
-
- except TypeError:
- raise TypeError("Neither Quantity object nor its magnitude ({0})"
- "supports indexing".format(self._magnitude))
-
- def tolist(self):
- units = self._units
- return [self.__class__(value, units).tolist() if isinstance(value, list) else self.__class__(value, units)
- for value in self._magnitude.tolist()]
-
- __array_priority__ = 17
-
- def __array_prepare__(self, obj, context=None):
- # If this uf is handled by Pint, write it down in the handling dictionary.
-
- # name of the ufunc, argument of the ufunc, domain of the ufunc
- # In ufuncs with multiple outputs, domain indicates which output
- # is currently being prepared (eg. see modf).
- # In ufuncs with a single output, domain is 0
- uf, objs, huh = context
-
- if uf.__name__ in self.__handled and huh == 0:
- # Only one ufunc should be handled at a time.
- # If a ufunc is already being handled (and this is not another domain),
- # something is wrong..
- if self.__handling:
- raise Exception('Cannot handled nested ufuncs.\n'
- 'Current: {0}\n'
- 'New: {1}'.format(context, self.__handling))
- self.__handling = context
-
- return obj
-
- def __array_wrap__(self, obj, context=None):
- uf, objs, huh = context
-
- # if this ufunc is not handled by Pint, pass it to the magnitude.
- if uf.__name__ not in self.__handled:
- return self.magnitude.__array_wrap__(obj, context)
-
- try:
- ufname = uf.__name__ if huh == 0 else '{0}__{1}'.format(uf.__name__, huh)
-
- # First, we check the units of the input arguments.
-
- if huh == 0:
- # Do this only when the wrap is called for the first ouput.
-
- # Store the destination units
- dst_units = None
- # List of magnitudes of Quantities with the right units
- # to be used as argument of the ufunc
- mobjs = None
-
- if uf.__name__ in self.__require_units:
- # ufuncs in __require_units
- # require specific units
- # This is more complex that it should be due to automatic
- # conversion between radians/dimensionless
- # TODO: maybe could be simplified using Contexts
- dst_units = self.__require_units[uf.__name__]
- if dst_units == 'radian':
- mobjs = []
- for other in objs:
- unt = getattr(other, '_units', '')
- if unt == 'radian':
- mobjs.append(getattr(other, 'magnitude', other))
- else:
- factor, units = self._REGISTRY._get_root_units(unt)
- if units and units != UnitsContainer({'radian': 1}):
- raise DimensionalityError(units, dst_units)
- mobjs.append(getattr(other, 'magnitude', other) * factor)
- mobjs = tuple(mobjs)
- else:
- dst_units = self._REGISTRY.parse_expression(dst_units)._units
-
- elif len(objs) > 1 and uf.__name__ not in self.__skip_other_args:
- # ufunc with multiple arguments require that all inputs have
- # the same arguments unless they are in __skip_other_args
- dst_units = objs[0]._units
-
- # Do the conversion (if needed) and extract the magnitude for each input.
- if mobjs is None:
- if dst_units is not None:
- mobjs = tuple(self._REGISTRY.convert(getattr(other, 'magnitude', other),
- getattr(other, 'units', ''),
- dst_units)
- for other in objs)
- else:
- mobjs = tuple(getattr(other, 'magnitude', other)
- for other in objs)
-
- # call the ufunc
- out = uf(*mobjs)
-
- # If there are multiple outputs,
- # store them in __handling (uf, objs, huh, out0, out1, ...)
- # and return the first
- if uf.nout > 1:
- self.__handling += out
- out = out[0]
- else:
- # If this is not the first output,
- # just grab the result that was previously calculated.
- out = self.__handling[3 + huh]
-
- # Second, we set the units of the output value.
- if ufname in self.__set_units:
- try:
- out = self.__class__(out, self.__set_units[ufname])
- except:
- raise _Exception(ValueError)
- elif ufname in self.__copy_units:
- try:
- out = self.__class__(out, self._units)
- except:
- raise _Exception(ValueError)
- elif ufname in self.__prod_units:
- tmp = self.__prod_units[ufname]
- if tmp == 'size':
- out = self.__class__(out, self._units ** self._magnitude.size)
- elif tmp == 'div':
- units1 = objs[0]._units if isinstance(objs[0], self.__class__) else UnitsContainer()
- units2 = objs[1]._units if isinstance(objs[1], self.__class__) else UnitsContainer()
- out = self.__class__(out, units1 / units2)
- elif tmp == 'mul':
- units1 = objs[0]._units if isinstance(objs[0], self.__class__) else UnitsContainer()
- units2 = objs[1]._units if isinstance(objs[1], self.__class__) else UnitsContainer()
- out = self.__class__(out, units1 * units2)
- else:
- out = self.__class__(out, self._units ** tmp)
-
- return out
- except (DimensionalityError, UndefinedUnitError) as ex:
- raise ex
- except _Exception as ex:
- raise ex.internal
- except Exception as ex:
- print(ex)
- finally:
- # If this is the last output argument for the ufunc,
- # we are done handling this ufunc.
- if uf.nout == huh + 1:
- self.__handling = None
-
- return self.magnitude.__array_wrap__(obj, context)
-
- # Measurement support
- def plus_minus(self, error, relative=False):
- if isinstance(error, self.__class__):
- if relative:
- raise ValueError('{} is not a valid relative error.'.format(error))
- error = error.to(self._units).magnitude
- else:
- if relative:
- error = error * abs(self.magnitude)
-
- return self._REGISTRY.Measurement(copy.copy(self.magnitude), error, self._units)
-
- # methods/properties that help for math operations with offset units
- @property
- def _is_multiplicative(self):
- """Check if the Quantity object has only multiplicative units.
- """
- return not self._get_non_multiplicative_units()
-
- def _get_non_multiplicative_units(self):
- """Return a list of the of non-multiplicative units of the Quantity object
- """
- offset_units = [unit for unit in self._units.keys()
- if not self._REGISTRY._units[unit].is_multiplicative]
- return offset_units
-
- def _get_delta_units(self):
- """Return list of delta units ot the Quantity object
- """
- delta_units = [u for u in self._units.keys() if u.startswith("delta_")]
- return delta_units
-
- def _has_compatible_delta(self, unit):
- """"Check if Quantity object has a delta_unit that is compatible with unit
- """
- deltas = self._get_delta_units()
- if 'delta_' + unit in deltas:
- return True
- else: # Look for delta units with same dimension as the offset unit
- offset_unit_dim = self._REGISTRY._units[unit].reference
- for d in deltas:
- if self._REGISTRY._units[d].reference == offset_unit_dim:
- return True
- return False
-
- def _ok_for_muldiv(self, no_offset_units=None):
- """Checks if Quantity object can be multiplied or divided
-
- :q: quantity object that is checked
- :no_offset_units: number of offset units in q
- """
- is_ok = True
- if no_offset_units is None:
- no_offset_units = len(self._get_non_multiplicative_units())
- if no_offset_units > 1:
- is_ok = False
- if no_offset_units == 1:
- if len(self._units) > 1:
- is_ok = False
- if (len(self._units) == 1
- and not self._REGISTRY.autoconvert_offset_to_baseunit):
- is_ok = False
- if next(iter(self._units.values())) != 1:
- is_ok = False
- return is_ok
diff --git a/lib/taurus/external/pint/pint_local/systems.py b/lib/taurus/external/pint/pint_local/systems.py
deleted file mode 100644
index 164d089..0000000
--- a/lib/taurus/external/pint/pint_local/systems.py
+++ /dev/null
@@ -1,423 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.systems
- ~~~~~~~~~~~~
-
- Functions and classes related to system definitions and conversions.
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-import re
-
-from .unit import Definition, UnitDefinition, DefinitionSyntaxError
-from .util import to_units_container, UnitsContainer
-
-
-class Group(object):
- """A group is a list 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.
- """
-
- #: Regex to match the header parts of a context.
- _header_re = re.compile('@group\s+(?P<name>\w+)\s*(using\s(?P<used_groups>.*))*')
-
- def __init__(self, name, groups_systems):
- """
- :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 already in use by a %s' % t)
-
- # The name of the group.
- #: type: str
- self.name = name
-
- #: Names of the units in this group.
- #: :type: set[str]
- self._unit_names = set()
-
- #: Names of the groups in this group.
- #: :type: set[str]
- self._used_groups = set()
-
- #: Names of the groups in which this group is contained.
- #: :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
-
- if name != 'root':
- # All groups are added to root group
- groups_systems['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.
-
- Calculated to include to all units in all included _used_groups.
-
- :rtype: frozenset[str]
- """
- if self._computed_members is None:
- self._computed_members = set(self._unit_names)
-
- for _, group in self.iter_used_groups():
- self._computed_members |= group.members
-
- self._computed_members = frozenset(self._computed_members)
-
- return self._computed_members
-
- def invalidate_members(self):
- """Invalidate computed members in this Group and all parent nodes.
- """
- self._computed_members = None
- d = self._groups_systems
- for name in self._used_by:
- d[name].invalidate_members()
-
- def iter_used_groups(self):
- pending = set(self._used_groups)
- d = self._groups_systems
- while pending:
- name = pending.pop()
- group = d[name]
- pending |= group._used_groups
- yield name, d[name]
-
- def is_used_group(self, group_name):
- for name, _ in self.iter_used_groups():
- if name == group_name:
- return True
- return False
-
- def add_units(self, *unit_names):
- """Add units to group.
-
- :type unit_names: str
- """
- for unit_name in unit_names:
- self._unit_names.add(unit_name)
-
- self.invalidate_members()
-
- def remove_units(self, *unit_names):
- """Remove units from group.
-
- :type unit_names: str
- """
- for unit_name in unit_names:
- self._unit_names.remove(unit_name)
-
- self.invalidate_members()
-
- def add_groups(self, *group_names):
- """Add groups to group.
-
- :type group_names: str
- """
- d = self._groups_systems
- for group_name in group_names:
-
- grp = d[group_name]
-
- if grp.is_used_group(self.name):
- raise ValueError('Cyclic relationship found between %s and %s' % (self.name, group_name))
-
- self._used_groups.add(group_name)
- grp._used_by.add(self.name)
-
- self.invalidate_members()
-
- def remove_groups(self, *group_names):
- """Remove groups from group.
-
- :type group_names: str
- """
- d = self._groups_systems
- 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):
- """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:]
-
- r = cls._header_re.search(header)
- name = r.groupdict()['name'].strip()
- groups = r.groupdict()['used_groups']
- if groups:
- group_names = tuple(a.strip() for a in groups.split(','))
- else:
- group_names = ()
-
- unit_names = []
- for 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)
- unit_names.append(definition.name)
- else:
- unit_names.append(line.strip())
-
- grp = cls(name, group_dict)
-
- grp.add_units(*unit_names)
-
- if group_names:
- grp.add_groups(*group_names)
-
- return grp
-
-
-class System(object):
- """A system is a Group plus a set of base units.
-
- @system <name> [using <group 1>, ..., <group N>]
- <rule 1>
- ...
- <rule N>
- @end
-
- """
-
- #: 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):
- """
- :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
-
- #: Maps root unit names to a dict indicating the new unit and its exponent.
- #: :type: dict[str, dict[str, number]]]
- self.base_units = {}
-
- #: Derived unit names.
- #: :type: set(str)
- self.derived_units = set()
-
- #: Names of the _used_groups in used by this system.
- #: :type: set(str)
- self._used_groups = set()
-
- #: :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
-
- @property
- def members(self):
- 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 = frozenset(self._computed_members)
-
- return self._computed_members
-
- def invalidate_members(self):
- """Invalidate computed members in this Group and all parent nodes.
- """
- self._computed_members = None
-
- def add_groups(self, *group_names):
- """Add groups to group.
-
- :type group_names: str
- """
- self._used_groups |= set(group_names)
-
- self.invalidate_members()
-
- def remove_groups(self, *group_names):
- """Remove groups from group.
-
- :type group_names: str
- """
- self._used_groups -= set(group_names)
-
- self.invalidate_members()
-
- @classmethod
- def from_lines(cls, lines, get_root_func, group_dict):
- header, lines = lines[0], lines[1:]
-
- r = cls._header_re.search(header)
- name = r.groupdict()['name'].strip()
- groups = r.groupdict()['used_groups']
-
- # If the systems has no group, it automatically uses the root group.
- if groups:
- group_names = tuple(a.strip() for a in groups.split(','))
- else:
- group_names = ('root', )
-
- base_unit_names = {}
- derived_unit_names = []
- for line in lines:
- line = line.strip()
-
- # We would identify a
- # - old_unit: a root unit part which is going to be removed from the system.
- # - new_unit: a non root unit which is going to replace the old_unit.
-
- if ':' in line:
- # The syntax is new_unit:old_unit
-
- new_unit, old_unit = line.split(':')
- new_unit, old_unit = new_unit.strip(), old_unit.strip()
-
- # The old unit MUST be a root unit, if not raise an error.
- if old_unit != str(get_root_func(old_unit)[1]):
- raise ValueError('In `%s`, the unit at the right of the `:` must be a root unit.' % line)
-
- # Here we find new_unit expanded in terms of root_units
- new_unit_expanded = to_units_container(get_root_func(new_unit)[1])
-
- # We require that the old unit is present in the new_unit expanded
- if old_unit not in new_unit_expanded:
- raise ValueError('Old unit must be a component of new unit')
-
- # Here we invert the equation, in other words
- # we write old units in terms new unit and expansion
- new_unit_dict = dict((new_unit, -1./value)
- for new_unit, value in new_unit_expanded.items()
- if new_unit != old_unit)
- new_unit_dict[new_unit] = 1 / new_unit_expanded[old_unit]
-
- base_unit_names[old_unit] = new_unit_dict
-
- else:
- # The syntax is new_unit
- # old_unit is inferred as the root unit with the same dimensionality.
-
- new_unit = line
- old_unit_dict = to_units_container(get_root_func(line)[1])
-
- if len(old_unit_dict) != 1:
- raise ValueError('The new base must be a root dimension if not discarded unit is specified.')
-
- old_unit, value = dict(old_unit_dict).popitem()
-
- base_unit_names[old_unit] = {new_unit: 1./value}
-
- system = cls(name, group_dict)
-
- system.add_groups(*group_names)
-
- system.base_units.update(**base_unit_names)
- system.derived_units |= set(derived_unit_names)
-
- return system
-
-
-class GSManager(object):
-
- def __init__(self):
- #: :type: dict[str, Group | System]
- self._groups_systems = dict()
- self._root_group = Group('root', self._groups_systems)
-
- def add_system_from_lines(self, lines, get_root_func):
- System.from_lines(lines, get_root_func, self._groups_systems)
-
- 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.
-
- :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)
-
- 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)
diff --git a/lib/taurus/external/pint/pint_local/unit.py b/lib/taurus/external/pint/pint_local/unit.py
deleted file mode 100644
index bbf9dfb..0000000
--- a/lib/taurus/external/pint/pint_local/unit.py
+++ /dev/null
@@ -1,1375 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.unit
- ~~~~~~~~~
-
- Functions and classes related to unit definitions and conversions.
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-import os
-import math
-import itertools
-import functools
-import operator
-import pkg_resources
-from decimal import Decimal
-from contextlib import contextmanager, closing
-from io import open, StringIO
-from collections import defaultdict
-from tokenize import untokenize, NUMBER, STRING, NAME, OP
-from numbers import Number
-
-from .context import Context, ContextChain
-from .util import (logger, pi_theorem, solve_dependencies, ParserHelper,
- string_preprocessor, find_connected_nodes,
- find_shortest_path, UnitsContainer, _is_dim,
- SharedRegistryObject, to_units_container)
-from .compat import tokenizer, string_types, NUMERIC_TYPES, long_type, zip_longest
-from .definitions import (Definition, UnitDefinition, PrefixDefinition,
- DimensionDefinition)
-from .converters import ScaleConverter
-from .errors import (DimensionalityError, UndefinedUnitError,
- DefinitionSyntaxError, RedefinitionError)
-
-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
-
-
-class _Unit(SharedRegistryObject):
- """Implements a class to describe a unit supporting math operations.
-
- :type units: UnitsContainer, str, Unit or Quantity.
-
- """
-
- #: Default formatting string.
- default_format = ''
-
- def __reduce__(self):
- from . import _build_unit
- return _build_unit, (self._units)
-
- def __new__(cls, units):
- inst = object.__new__(cls)
- if isinstance(units, (UnitsContainer, UnitDefinition)):
- inst._units = units
- elif isinstance(units, string_types):
- inst._units = inst._REGISTRY.parse_units(units)._units
- elif isinstance(units, _Unit):
- inst._units = units._units
- else:
- raise TypeError('units must be of type str, Unit or '
- 'UnitsContainer; not {0}.'.format(type(units)))
-
- inst.__used = False
- inst.__handling = None
- return inst
-
- @property
- def debug_used(self):
- return self.__used
-
- def __copy__(self):
- ret = self.__class__(self._units)
- ret.__used = self.__used
- return ret
-
- def __str__(self):
- return format(self)
-
- def __repr__(self):
- return "<Unit('{0}')>".format(self._units)
-
- def __format__(self, spec):
- spec = spec or self.default_format
-
- if '~' in spec:
- if self.dimensionless:
- return ''
- units = UnitsContainer(dict((self._REGISTRY._get_symbol(key),
- value)
- for key, value in self._units.items()))
- spec = spec.replace('~', '')
- else:
- units = self._units
-
- return '%s' % (format(units, spec))
-
- # IPython related code
- def _repr_html_(self):
- return self.__format__('H')
-
- def _repr_latex_(self):
- return "$" + self.__format__('L') + "$"
-
- @property
- def dimensionless(self):
- """Return true if the Unit is dimensionless.
-
- """
- return not bool(self.dimensionality)
-
- @property
- def dimensionality(self):
- """Unit's dimensionality (e.g. {length: 1, time: -1})
-
- """
- try:
- return self._dimensionality
- except AttributeError:
- dim = self._REGISTRY._get_dimensionality(self._units)
- self._dimensionality = dim
-
- return self._dimensionality
-
- def compatible_units(self, *contexts):
- if contexts:
- with self._REGISTRY.context(*contexts):
- return self._REGISTRY.get_compatible_units(self)
-
- return self._REGISTRY.get_compatible_units(self)
-
- def __mul__(self, other):
- if self._check(other):
- if isinstance(other, self.__class__):
- return self.__class__(self._units*other._units)
- else:
- return self._REGISTRY.Quantity(other._magnitude,
- self._units*other._units)
-
- return self._REGISTRY.Quantity(other, self._units)
-
- __rmul__ = __mul__
-
- def __truediv__(self, other):
- if self._check(other):
- if isinstance(other, self.__class__):
- return self.__class__(self._units/other._units)
- else:
- return self._REGISTRY.Quantity(1/other._magnitude,
- self._units/other._units)
-
- return self._REGISTRY.Quantity(1/other, self._units)
-
- def __rtruediv__(self, other):
- # As Unit and Quantity both handle truediv with each other rtruediv can
- # only be called for something different.
- if isinstance(other, NUMERIC_TYPES):
- return self._REGISTRY.Quantity(other, 1/self._units)
- elif isinstance(other, UnitsContainer):
- return self.__class__(other/self._units)
- else:
- return NotImplemented
-
- __div__ = __truediv__
- __rdiv__ = __rtruediv__
-
- def __pow__(self, other):
- if isinstance(other, NUMERIC_TYPES):
- return self.__class__(self._units**other)
-
- else:
- mess = 'Cannot power Unit by {}'.format(type(other))
- raise TypeError(mess)
-
- def __hash__(self):
- return self._units.__hash__()
-
- def __eq__(self, other):
- # We compare to the base class of Unit because each Unit class is
- # unique.
- if self._check(other):
- if isinstance(other, self.__class__):
- return self._units == other._units
- else:
- return other == self._REGISTRY.Quantity(1, self._units)
-
- elif isinstance(other, NUMERIC_TYPES):
- return other == self._REGISTRY.Quantity(1, self._units)
-
- else:
- return self._units == other
-
- def compare(self, other, op):
- self_q = self._REGISTRY.Quantity(1, self)
-
- if isinstance(other, NUMERIC_TYPES):
- return self_q.compare(other, op)
- elif isinstance(other, (_Unit, UnitsContainer, dict)):
- return self_q.compare(self._REGISTRY.Quantity(1, other), op)
- else:
- return NotImplemented
-
- __lt__ = lambda self, other: self.compare(other, op=operator.lt)
- __le__ = lambda self, other: self.compare(other, op=operator.le)
- __ge__ = lambda self, other: self.compare(other, op=operator.ge)
- __gt__ = lambda self, other: self.compare(other, op=operator.gt)
-
- def __int__(self):
- return int(self._REGISTRY.Quantity(1, self._units))
-
- def __long__(self):
- return long_type(self._REGISTRY.Quantity(1, self._units))
-
- def __float__(self):
- return float(self._REGISTRY.Quantity(1, self._units))
-
- def __complex__(self):
- return complex(self._REGISTRY.Quantity(1, self._units))
-
- __array_priority__ = 17
-
- def __array_prepare__(self, array, context=None):
- return 1
-
- def __array_wrap__(self, array, context=None):
- uf, objs, huh = context
-
- if uf.__name__ in ('true_divide', 'divide', 'floor_divide'):
- return self._REGISTRY.Quantity(array, 1/self._units)
- elif uf.__name__ in ('multiply',):
- return self._REGISTRY.Quantity(array, self._units)
- else:
- raise ValueError('Unsupproted operation for Unit')
-
-
-class UnitRegistry(object):
- """The unit registry stores the definitions and relationships between
- units.
-
- :param filename: path of the units definition file to load.
- Empty to load the default definition file.
- None to leave the UnitRegistry empty.
- :param force_ndarray: convert any input, scalar or not to a numpy.ndarray.
- :param default_as_delta: In the context of a multiplication of units, interpret
- non-multiplicative units as their *delta* counterparts.
- :autoconvert_offset_to_baseunit: If True converts offset units in quantites are
- converted to their base units in multiplicative
- context. If False no conversion happens.
- :param on_redefinition: action to take in case a unit is redefined.
- 'warn', 'raise', 'ignore'
- :type on_redefintion: str
- """
-
- 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)
-
- #: Action to take in case a unit is redefined. 'warn', 'raise', 'ignore'
- self._on_redefinition = on_redefinition
-
- #: Map dimension name (string) to its definition (DimensionDefinition).
- self._dimensions = {}
-
- #: :type: systems.GSManager
- self._gsmanager = systems.GSManager()
-
- #: Map unit name (string) to its definition (UnitDefinition).
- #: Might contain prefixed units.
- self._units = {}
-
- #: Map unit name in lower case (string) to a set of unit names with the right case.
- #: Does not contain prefixed units.
- #: e.g: 'hz' - > set('Hz', )
- self._units_casei = defaultdict(set)
-
- #: Map prefix name (string) to its definition (PrefixDefinition).
- self._prefixes = {'': PrefixDefinition('', '', (), 1)}
-
- #: Map suffix name (string) to canonical , and unit alias to canonical unit name
- self._suffixes = {'': None, 's': ''}
-
- #: Map context name (string) or abbreviation to context.
- self._contexts = {}
-
- #: Stores active contexts.
- self._active_ctx = ContextChain()
-
- #: Maps dimensionality (UnitsContainer) to Units (str)
- self._dimensional_equivalents = dict()
-
- #: Maps dimensionality (UnitsContainer) to Dimensionality (UnitsContainer)
- self._root_units_cache = dict()
-
- #: Maps dimensionality (UnitsContainer) to Dimensionality (UnitsContainer)
- self._base_units_cache = dict()
-
- #: Maps dimensionality (UnitsContainer) to Units (UnitsContainer)
- self._dimensionality_cache = dict()
-
- #: Cache the unit name associated to user input. ('mV' -> 'millivolt')
- self._parse_unit_cache = dict()
-
- #: When performing a multiplication of units, interpret
- #: 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
-
- if filename == '':
- self.load_definitions('default_en.txt', True)
- elif filename is not None:
- self.load_definitions(filename)
-
- self.define(UnitDefinition('pi', 'π', (), ScaleConverter(math.pi)))
-
- self._build_cache()
-
- self.set_default_system(system)
-
- def __name__(self):
- return 'UnitRegistry'
-
- def __getattr__(self, item):
- return self.Unit(item)
-
- def __getitem__(self, item):
- logger.warning('Calling the getitem method from a UnitRegistry is deprecated. '
- 'use `parse_expression` method or use the registry as a callable.')
- return self.parse_expression(item)
-
- def __dir__(self):
- return list(self._units.keys()) + \
- ['define', 'load_definitions', 'get_name', 'get_symbol',
- 'get_dimensionality', 'Quantity', 'wraps',
- 'parse_units', 'parse_expression', 'pi_theorem',
- 'convert', 'get_base_units']
-
- @property
- def default_format(self):
- """Default formatting string for quantities.
- """
- return self.Quantity.default_format
-
- @default_format.setter
- def default_format(self, value):
- self.Unit.default_format = value
- self.Quantity.default_format = value
-
- def get_group(self, name, create_if_needed=True):
- """Return a Group.
-
- :param name: Name of the group to be
- :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)
-
- 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)
-
- 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 = {}
-
- def add_context(self, context):
- """Add a context object to the registry.
-
- The context will be accessible by its name and aliases.
-
- Notice that this method will NOT enable the context. Use `enable_contexts`.
- """
- if context.name in self._contexts:
- logger.warning('The name %s was already registered for another context.',
- context.name)
- self._contexts[context.name] = context
- for alias in context.aliases:
- if alias in self._contexts:
- logger.warning('The name %s was already registered for another context',
- context.name)
- self._contexts[alias] = context
-
- def remove_context(self, name_or_alias):
- """Remove a context from the registry and return it.
-
- Notice that this methods will not disable the context. Use `disable_contexts`.
- """
- context = self._contexts[name_or_alias]
-
- del self._contexts[context.name]
- for alias in context.aliases:
- del self._contexts[alias]
-
- return context
-
- def enable_contexts(self, *names_or_contexts, **kwargs):
- """Enable contexts provided by name or by object.
-
- :param names_or_contexts: sequence of the contexts or contexts names/alias
- :param kwargs: keyword arguments for the context
- """
-
- # If present, copy the defaults from the containing contexts
- if self._active_ctx.defaults:
- kwargs = dict(self._active_ctx.defaults, **kwargs)
-
- # For each name, we first find the corresponding context
- ctxs = tuple((self._contexts[name] if isinstance(name, string_types) else name)
- for name in names_or_contexts)
-
- # Check if the contexts have been checked first, if not we make sure
- # that dimensions are expressed in terms of base dimensions.
- for ctx in ctxs:
- if getattr(ctx, '_checked', False):
- continue
- for (src, dst), func in ctx.funcs.items():
- src_ = self._get_dimensionality(src)
- dst_ = self._get_dimensionality(dst)
- if src != src_ or dst != dst_:
- ctx.remove_transformation(src, dst)
- ctx.add_transformation(src_, dst_, func)
- ctx._checked = True
-
- # and create a new one with the new defaults.
- ctxs = tuple(Context.from_context(ctx, **kwargs)
- for ctx in ctxs)
-
- # Finally we add them to the active context.
- self._active_ctx.insert_contexts(*ctxs)
-
- def disable_contexts(self, n=None):
- """Disable the last n enabled contexts.
- """
- if n is None:
- n = len(self._contexts)
- self._active_ctx.remove_contexts(n)
-
- @contextmanager
- def context(self, *names, **kwargs):
- """Used as a context manager, this function enables to activate a context
- which is removed after usage.
-
- :param names: name of the context.
- :param kwargs: keyword arguments for the contexts.
-
- Context are called by their name::
-
- >>> with ureg.context('one'):
- ... pass
-
- If the context has an argument, you can specify its value as a keyword
- argument::
-
- >>> with ureg.context('one', n=1):
- ... pass
-
- Multiple contexts can be entered in single call:
-
- >>> with ureg.context('one', 'two', n=1):
- ... pass
-
- or nested allowing you to give different values to the same keyword argument::
-
- >>> with ureg.context('one', n=1):
- ... with ureg.context('two', n=2):
- ... pass
-
- A nested context inherits the defaults from the containing context::
-
- >>> with ureg.context('one', n=1):
- ... with ureg.context('two'): # Here n takes the value of the upper context
- ... pass
-
- """
-
- # Enable the contexts.
- self.enable_contexts(*names, **kwargs)
-
- try:
- # After adding the context and rebuilding the graph, the registry
- # is ready to use.
- yield self
- finally:
- # Upon leaving the with statement,
- # the added contexts are removed from the active one.
- self.disable_contexts(len(names))
-
- def define(self, definition):
- """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):
- d, di = self._units, self._units_casei
- if definition.is_base:
- for dimension in definition.reference.keys():
- if dimension in self._dimensions:
- if dimension != '[]':
- raise DefinitionSyntaxError('only one unit per dimension can be a base unit.')
- continue
-
- self.define(DimensionDefinition(dimension, '', (), None, is_base=True))
-
- elif isinstance(definition, PrefixDefinition):
- d, di = self._prefixes, None
- else:
- raise TypeError('{0} is not a valid definition.'.format(definition))
-
- def _adder(key, value, action=self._on_redefinition, selected_dict=d, casei_dict=di):
- if key in selected_dict:
- if action == 'raise':
- raise RedefinitionError(key, type(value))
- elif action == 'warn':
- logger.warning("Redefining '%s' (%s)", key, type(value))
-
- selected_dict[key] = value
- if casei_dict is not None:
- casei_dict[key.lower()].add(key)
-
- _adder(definition.name, definition)
-
- if definition.has_symbol:
- _adder(definition.symbol, definition)
-
- for alias in definition.aliases:
- if ' ' in alias:
- logger.warn('Alias cannot contain a space: ' + alias)
-
- _adder(alias, definition)
-
- # define additional "delta_" units for units with an offset
- if getattr(definition.converter, "offset", 0.0) != 0.0:
- d_name = 'delta_' + definition.name
- if definition.symbol:
- d_symbol = 'Δ' + definition.symbol
- else:
- d_symbol = None
- d_aliases = tuple('Δ' + alias for alias in definition.aliases)
-
- def prep(_name):
- if _name.startswith('['):
- return '[delta_' + _name[1:]
- return 'delta_' + _name
-
- d_reference = UnitsContainer(dict((ref, value)
- for ref, value in definition.reference.items()))
-
- self.define(UnitDefinition(d_name, d_symbol, d_aliases,
- ScaleConverter(definition.converter.scale),
- d_reference, definition.is_base))
-
- def load_definitions(self, file, is_resource=False):
- """Add units and prefixes defined in a definition text file.
- """
- # Permit both filenames and line-iterables
- if isinstance(file, string_types):
- try:
- if is_resource:
- with closing(pkg_resources.resource_stream(__name__, file)) as fp:
- rbytes = fp.read()
- return self.load_definitions(StringIO(rbytes.decode('utf-8')), is_resource)
- else:
- with open(file, encoding='utf-8') as fp:
- return self.load_definitions(fp, is_resource)
- except (RedefinitionError, DefinitionSyntaxError) as e:
- if e.filename is None:
- e.filename = file
- raise e
- except Exception as e:
- msg = getattr(e, 'message', '') or str(e)
- raise ValueError('While opening {0}\n{1}'.format(file, msg))
-
- ifile = enumerate(file, 1)
- 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()
- else:
- try:
- path = os.path.dirname(file.name)
- except AttributeError:
- path = os.getcwd()
- path = os.path.join(path, os.path.normpath(line[7:].strip()))
- self.load_definitions(path, is_resource)
- 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)
- 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)
- else:
- try:
- self.define(Definition.from_string(line))
- except (RedefinitionError, DefinitionSyntaxError) as ex:
- if ex.lineno is None:
- ex.lineno = no
- raise ex
- except Exception as ex:
- logger.error("In line {0}, cannot add '{1}' {2}".format(no, line, ex))
-
- def _build_cache(self):
- """Build a cache of dimensionality and base units.
- """
-
- deps = dict((name, set(definition.reference.keys() if definition.reference else {}))
- for name, definition in self._units.items())
-
- for unit_names in solve_dependencies(deps):
- for unit_name in unit_names:
- prefixed = False
- for p in self._prefixes.keys():
- if p and unit_name.startswith(p):
- prefixed = True
- break
- if '[' in unit_name:
- continue
- try:
- uc = ParserHelper.from_word(unit_name)
-
- bu = self._get_root_units(uc)
- di = self._get_dimensionality(uc)
-
- self._root_units_cache[uc] = bu
- self._dimensionality_cache[uc] = di
-
- if not prefixed:
- if di not in self._dimensional_equivalents:
- self._dimensional_equivalents[di] = set()
-
- self._dimensional_equivalents[di].add(self._units[unit_name]._name)
-
- except Exception as e:
- logger.warning('Could not resolve {0}: {1!r}'.format(unit_name, e))
-
- def get_name(self, name_or_alias, case_sensitive=True):
- """Return the canonical name of a unit.
- """
-
- if name_or_alias == 'dimensionless':
- return ''
-
- try:
- return self._units[name_or_alias]._name
- except KeyError:
- pass
-
- candidates = self._dedup_candidates(self.parse_unit_name(name_or_alias, case_sensitive))
- if not candidates:
- raise UndefinedUnitError(name_or_alias)
- elif len(candidates) == 1:
- prefix, unit_name, _ = candidates[0]
- else:
- logger.warning('Parsing {0} yield multiple results. '
- 'Options are: {1}'.format(name_or_alias, candidates))
- prefix, unit_name, _ = candidates[0]
-
- if prefix:
- name = prefix + unit_name
- symbol = self.get_symbol(name)
- prefix_def = self._prefixes[prefix]
- self._units[name] = UnitDefinition(name, symbol, (), prefix_def.converter,
- UnitsContainer({unit_name: 1}))
- return prefix + unit_name
-
- return unit_name
-
- def get_symbol(self, name_or_alias):
- """Return the preferred alias for a unit
- """
- candidates = self._dedup_candidates(self.parse_unit_name(name_or_alias))
- if not candidates:
- raise UndefinedUnitError(name_or_alias)
- elif len(candidates) == 1:
- prefix, unit_name, _ = candidates[0]
- else:
- logger.warning('Parsing {0} yield multiple results. '
- 'Options are: {1!r}'.format(name_or_alias, candidates))
- prefix, unit_name, _ = candidates[0]
-
- return self._prefixes[prefix].symbol + self._units[unit_name].symbol
-
- def _get_symbol(self, name):
- return self._units[name].symbol
-
- def get_dimensionality(self, input_units):
- """Convert unit or dict of units or dimensions to a dict of base dimensions
- dimensions
-
- :param input_units:
- :return: dimensionality
- """
- input_units = to_units_container(input_units)
-
- return self._get_dimensionality(input_units)
-
- def _get_dimensionality(self, input_units):
- """ Convert a UnitsContainer to base dimensions.
-
- :param input_units:
- :return: dimensionality
- """
- if not input_units:
- return UnitsContainer()
-
- if input_units in self._dimensionality_cache:
- return self._dimensionality_cache[input_units]
-
- accumulator = defaultdict(float)
- self._get_dimensionality_recurse(input_units, 1.0, accumulator)
-
- if '[]' in accumulator:
- del accumulator['[]']
-
- dims = UnitsContainer(dict((k, v) for k, v in accumulator.items()
- if v != 0.0))
-
- self._dimensionality_cache[input_units] = dims
-
- return dims
-
- def _get_dimensionality_recurse(self, ref, exp, accumulator):
- for key in ref:
- exp2 = exp*ref[key]
- if _is_dim(key):
- reg = self._dimensions[key]
- if reg.is_base:
- accumulator[key] += exp2
- elif reg.reference is not None:
- self._get_dimensionality_recurse(reg.reference, exp2, accumulator)
- else:
- reg = self._units[self.get_name(key)]
- if reg.reference is not None:
- self._get_dimensionality_recurse(reg.reference, exp2, accumulator)
-
- def get_root_units(self, input_units, check_nonmult=True):
- """Convert unit or dict of units to the root units.
-
- If any unit is non multiplicative and check_converter is True,
- then None is returned as the multiplicative factor.
-
- :param input_units: units
- :type input_units: UnitsContainer or str
- :param check_nonmult: if True, None will be returned as the
- multiplicative factor if a non-multiplicative
- units is found in the final Units.
- :return: multiplicative factor, base units
- """
- input_units = to_units_container(input_units)
-
- f, units = self._get_root_units(input_units, check_nonmult)
-
- return f, self.Unit(units)
-
- def _get_root_units(self, input_units, check_nonmult=True):
- """Convert unit or dict of units to the root units.
-
- If any unit is non multiplicative and check_converter is True,
- then None is returned as the multiplicative factor.
-
- :param input_units: units
- :type input_units: UnitsContainer or dict
- :param check_nonmult: if True, None will be returned as the
- multiplicative factor if a non-multiplicative
- units is found in the final Units.
- :return: multiplicative factor, base units
- """
- if not input_units:
- return 1., UnitsContainer()
-
- # The cache is only done for check_nonmult=True
- if check_nonmult and input_units in self._root_units_cache:
- return self._root_units_cache[input_units]
-
- accumulators = [1., defaultdict(float)]
- self._get_root_units_recurse(input_units, 1.0, accumulators)
-
- factor = accumulators[0]
- units = UnitsContainer(dict((k, v) for k, v in accumulators[1].items()
- if v != 0.))
-
- # Check if any of the final units is non multiplicative and return None instead.
- if check_nonmult:
- for unit in units.keys():
- if not self._units[unit].converter.is_multiplicative:
- return None, units
-
- if check_nonmult:
- self._root_units_cache[input_units] = factor, units
-
- return factor, units
-
- def get_base_units(self, input_units, check_nonmult=True, system=None):
- """Convert unit or dict of units to the base units.
-
- If any unit is non multiplicative and check_converter is True,
- then None is returned as the multiplicative factor.
-
- :param input_units: units
- :type input_units: UnitsContainer or str
- :param check_nonmult: if True, None will be returned as the
- multiplicative factor if a non-multiplicative
- units is found in the final Units.
- :return: multiplicative factor, base units
- """
- input_units = to_units_container(input_units)
-
- f, units = self._get_base_units(input_units, check_nonmult, system)
-
- return f, self.Unit(units)
-
- def _get_base_units(self, input_units, check_nonmult=True, system=None):
- """
- :param registry:
- :param input_units:
- :param check_nonmult:
- :param system: System
- :return:
- """
-
- # The cache is only done for check_nonmult=True
- if check_nonmult 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
-
- # This will not be necessary after integration with the registry as it has a UnitsContainer intermediate
- units = to_units_container(units, self)
-
- destination_units = UnitsContainer()
-
- bu = self._gsmanager.get_system(system, False).base_units
-
- for unit, value in units.items():
- if unit in bu:
- new_unit = bu[unit]
- new_unit = to_units_container(new_unit, self)
- destination_units *= new_unit ** value
- else:
- destination_units *= UnitsContainer({unit: value})
-
- base_factor = self.convert(factor, units, destination_units)
-
- if check_nonmult:
- self._base_units_cache[input_units] = base_factor, destination_units
-
- return base_factor, destination_units
-
- def _get_root_units_recurse(self, ref, exp, accumulators):
- for key in ref:
- exp2 = exp*ref[key]
- key = self.get_name(key)
- reg = self._units[key]
- if reg.is_base:
- accumulators[1][key] += exp2
- else:
- accumulators[0] *= reg._converter.scale ** exp2
- if reg.reference is not None:
- self._get_root_units_recurse(reg.reference, exp2,
- accumulators)
-
- def get_compatible_units(self, input_units, group_or_system=None):
- """
- """
- input_units = to_units_container(input_units)
-
- 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):
- """
- """
- if not input_units:
- return frozenset()
-
- src_dim = self._get_dimensionality(input_units)
-
- ret = self._dimensional_equivalents[src_dim]
-
- if self._active_ctx:
- nodes = find_connected_nodes(self._active_ctx.graph, src_dim)
- ret = set()
- if nodes:
- for node in nodes:
- ret |= self._dimensional_equivalents[node]
-
- if group_or_system:
- members = self._gsmanager[group_or_system].members
- return frozenset(ret.intersection(members))
-
- return ret
-
- def convert(self, value, src, dst, inplace=False):
- """Convert value from some source to destination units.
-
- :param value: value
- :param src: source units.
- :type src: Quantity or str
- :param dst: destination units.
- :type dst: Quantity or str
-
- :return: converted value
- """
- src = to_units_container(src, self)
-
- dst = to_units_container(dst, self)
-
- return self._convert(value, src, dst, inplace)
-
- def _convert(self, value, src, dst, inplace=False):
- """Convert value from some source to destination units.
-
- :param value: value
- :param src: source units.
- :type src: UnitsContainer
- :param dst: destination units.
- :type dst: UnitsContainer
-
- :return: converted value
- """
- if src == dst:
- return value
-
- src_dim = self._get_dimensionality(src)
- dst_dim = self._get_dimensionality(dst)
-
- # If there is an active context, we look for a path connecting source and
- # destination dimensionality. If it exists, we transform the source value
- # by applying sequentially each transformation of the path.
- if self._active_ctx:
- path = find_shortest_path(self._active_ctx.graph, src_dim, dst_dim)
- if path:
- src = self.Quantity(value, src)
- for a, b in zip(path[:-1], path[1:]):
- src = self._active_ctx.transform(a, b, self, src)
-
- value, src = src._magnitude, src._units
-
- src_dim = self._get_dimensionality(src)
-
- # If the source and destination dimensionality are different,
- # then the conversion cannot be performed.
-
- if src_dim != dst_dim:
- raise DimensionalityError(src, dst, src_dim, dst_dim)
-
- # Conversion needs to consider if non-multiplicative (AKA offset
- # units) are involved. Conversion is only possible if src and dst
- # have at most one offset unit per dimension.
- src_offset_units = [(u, e) for u, e in src.items()
- if not self._units[u].is_multiplicative]
- dst_offset_units = [(u, e) for u, e in dst.items()
- if not self._units[u].is_multiplicative]
-
- # For offset units we need to check if the conversion is allowed.
- if src_offset_units or dst_offset_units:
-
- # Validate that not more than one offset unit is present
- if len(src_offset_units) > 1 or len(dst_offset_units) > 1:
- raise DimensionalityError(
- src, dst, src_dim, dst_dim,
- extra_msg=' - more than one offset unit.')
-
- # validate that offset unit is not used in multiplicative context
- if ((len(src_offset_units) == 1 and len(src) > 1)
- or (len(dst_offset_units) == 1 and len(dst) > 1)
- and not self.autoconvert_offset_to_baseunit):
- raise DimensionalityError(
- src, dst, src_dim, dst_dim,
- extra_msg=' - offset unit used in multiplicative context.')
-
- # Validate that order of offset unit is exactly one.
- if src_offset_units:
- if src_offset_units[0][1] != 1:
- raise DimensionalityError(
- src, dst, src_dim, dst_dim,
- extra_msg=' - offset units in higher order.')
- else:
- if dst_offset_units[0][1] != 1:
- raise DimensionalityError(
- src, dst, src_dim, dst_dim,
- extra_msg=' - offset units in higher order.')
-
- # Here we convert only the offset quantities. Any remaining scaled
- # quantities will be converted later.
-
- # TODO: Shouldn't this (until factor, units) be inside the If above?
-
- # clean src from offset units by converting to reference
- for u, e in src_offset_units:
- value = self._units[u].converter.to_reference(value, inplace)
- src = src.remove([u for u, e in src_offset_units])
-
- # clean dst units from offset units
- dst = dst.remove([u for u, e in dst_offset_units])
-
- # Here src and dst have only multiplicative units left. Thus we can
- # convert with a factor.
- factor, units = self._get_root_units(src / dst)
-
- # factor is type float and if our magnitude is type Decimal then
- # must first convert to Decimal before we can '*' the values
- if isinstance(value, Decimal):
- factor = Decimal(str(factor))
-
- if inplace:
- value *= factor
- else:
- value = value * factor
-
- # Finally convert to offset units specified in destination
- for u, e in dst_offset_units:
- value = self._units[u].converter.from_reference(value, inplace)
-
- return value
-
- def pi_theorem(self, quantities):
- """Builds dimensionless quantities using the Buckingham π theorem
-
- :param quantities: mapping between variable name and units
- :type quantities: dict
- :return: a list of dimensionless quantities expressed as dicts
- """
- return pi_theorem(quantities, self)
-
- def _dedup_candidates(self, candidates):
- """Given a list of units, remove those with different names but equal value.
- """
- candidates = tuple(candidates)
- if len(candidates) < 2:
- return candidates
-
- unique = [candidates[0]]
- for c in candidates[2:]:
- for u in unique:
- if c == u:
- break
- else:
- unique.append(c)
-
- return tuple(unique)
-
- def parse_unit_name(self, unit_name, case_sensitive=True):
- """Parse a unit to identify prefix, unit name and suffix
- by walking the list of prefix and suffix.
- """
- stw = unit_name.startswith
- edw = unit_name.endswith
- for suffix, prefix in itertools.product(self._suffixes, self._prefixes):
- if stw(prefix) and edw(suffix):
- name = unit_name[len(prefix):]
- if suffix:
- name = name[:-len(suffix)]
- if len(name) == 1:
- continue
- if case_sensitive:
- if name in self._units:
- yield (self._prefixes[prefix]._name,
- self._units[name]._name,
- self._suffixes[suffix])
- else:
- for real_name in self._units_casei.get(name.lower(), ()):
- yield (self._prefixes[prefix]._name,
- self._units[real_name]._name,
- self._suffixes[suffix])
-
- def parse_units(self, input_string, as_delta=None):
- """Parse a units expression and returns a UnitContainer with
- the canonical names.
-
- The expression can only contain products, ratios and powers of units.
-
- :param as_delta: if the expression has multiple units, the parser will
- interpret non multiplicative units as their `delta_` counterparts.
-
- :raises:
- :class:`pint.UndefinedUnitError` if a unit is not in the registry
- :class:`ValueError` if the expression is invalid.
- """
- units = self._parse_units(input_string, as_delta)
- return self.Unit(units)
-
- def _parse_units(self, input_string, as_delta=None):
- """
- """
- if input_string in self._parse_unit_cache:
- return self._parse_unit_cache[input_string]
-
- if as_delta is None:
- as_delta = self.default_as_delta
-
- if not input_string:
- return UnitsContainer()
-
- units = ParserHelper.from_string(input_string)
- if units.scale != 1:
- raise ValueError('Unit expression cannot have a scaling factor.')
-
- ret = {}
- many = len(units) > 1
- for name in units:
- cname = self.get_name(name)
- value = units[name]
- if not cname:
- continue
- if as_delta and (many or (not many and value != 1)):
- definition = self._units[cname]
- if not definition.is_multiplicative:
- cname = 'delta_' + cname
- ret[cname] = value
-
- ret = UnitsContainer(ret)
-
- self._parse_unit_cache[input_string] = ret
-
- return ret
-
- def _eval_token(self, token, case_sensitive=True, **values):
- token_type = token[0]
- token_text = token[1]
- if token_type == NAME:
- if token_text == 'pi':
- return self.Quantity(math.pi)
- elif token_text in values:
- return self.Quantity(values[token_text])
- else:
- return self.Quantity(1, UnitsContainer({self.get_name(token_text,
- case_sensitive=case_sensitive) : 1}))
- elif token_type == NUMBER:
- return ParserHelper.eval_token(token)
- else:
- raise Exception('unknown token type')
-
- def parse_expression(self, input_string, case_sensitive=True, **values):
- """Parse a mathematical expression including units and return a quantity object.
-
- Numerical constants can be specified as keyword arguments and will take precedence
- over the names defined in the registry.
- """
-
- if not input_string:
- return self.Quantity(1)
-
- input_string = string_preprocessor(input_string)
- gen = tokenizer(input_string)
-
- return build_eval_tree(gen).evaluate(lambda x : self._eval_token(x, case_sensitive=case_sensitive,
- **values))
-
- __call__ = parse_expression
-
- def wraps(self, ret, args, strict=True):
- """Wraps a function to become pint-aware.
-
- Use it when a function requires a numerical value but in some specific
- units. The wrapper function will take a pint quantity, convert to the units
- specified in `args` and then call the wrapped function with the resulting
- magnitude.
-
- The value returned by the wrapped function will be converted to the units
- specified in `ret`.
-
- Use None to skip argument conversion.
- Set strict to False, to accept also numerical values.
-
- :param ret: output units.
- :param args: iterable of input units.
- :param strict: boolean to indicate that only quantities are accepted.
- :return: the wrapped function.
- :raises:
- :class:`ValueError` if strict and one of the arguments is not a Quantity.
- """
-
- Q_ = self.Quantity
-
- if not isinstance(args, (list, tuple)):
- args = (args, )
-
- units = [to_units_container(arg, self) for arg in args]
-
- if isinstance(ret, (list, tuple)):
- ret = ret.__class__([to_units_container(arg, self) for arg in ret])
- elif isinstance(ret, string_types):
- ret = self.parse_units(ret)
-
- def decorator(func):
- assigned = tuple(attr for attr in functools.WRAPPER_ASSIGNMENTS if hasattr(func, attr))
- updated = tuple(attr for attr in functools.WRAPPER_UPDATES if hasattr(func, attr))
- @functools.wraps(func, assigned=assigned, updated=updated)
- def wrapper(*values, **kw):
- new_args = []
- for unit, value in zip(units, values):
- if unit is None:
- new_args.append(value)
- elif isinstance(value, Q_):
- new_args.append(self._convert(value._magnitude,
- value._units, unit))
- elif not strict:
- new_args.append(value)
- else:
- raise ValueError('A wrapped function using strict=True requires '
- 'quantity for all arguments with not None units. '
- '(error found for {0}, {1})'.format(unit, value))
-
- result = func(*new_args, **kw)
-
- if isinstance(ret, (list, tuple)):
- return ret.__class__(res if unit is None else Q_(res, unit)
- for unit, res in zip(ret, result))
- elif ret is not None:
- return Q_(result, ret)
-
- return result
- return wrapper
- return decorator
-
- def check(self, *args):
- """Decorator to for quantity type checking for function inputs.
-
- Use it to ensure that the decorated function input parameters match
- the expected type of pint quantity.
-
- Use None to skip argument checking.
-
- :param args: iterable of input units.
- :return: the wrapped function.
- :raises:
- :class:`DimensionalityError` if the parameters don't match dimensions
- """
- dimensions = [self.get_dimensionality(dim) for dim in args]
-
- def decorator(func):
- assigned = tuple(attr for attr in functools.WRAPPER_ASSIGNMENTS if hasattr(func, attr))
- updated = tuple(attr for attr in functools.WRAPPER_UPDATES if hasattr(func, attr))
-
- @functools.wraps(func, assigned=assigned, updated=updated)
- def wrapper(*values, **kwargs):
- for dim, value in zip_longest(dimensions, values):
- if dim and value.dimensionality != dim:
- raise DimensionalityError(value, 'a quantity of',
- value.dimensionality, dim)
- return func(*values, **kwargs)
- return wrapper
- return decorator
-
-
-def build_unit_class(registry):
-
- class Unit(_Unit):
- pass
-
- Unit._REGISTRY = registry
- return Unit
-
-
-def build_quantity_class(registry, force_ndarray=False):
- from .quantity import _Quantity
-
- class Quantity(_Quantity):
- pass
-
- Quantity._REGISTRY = registry
- Quantity.force_ndarray = force_ndarray
-
- return Quantity
-
-
-def build_measurement_class(registry, force_ndarray=False):
- from .measurement import _Measurement, ufloat
-
- if ufloat is None:
- class Measurement(object):
-
- def __init__(self, *args):
- raise RuntimeError("Pint requires the 'uncertainties' package to create a Measurement object.")
-
- else:
- class Measurement(_Measurement, registry.Quantity):
- pass
-
- Measurement._REGISTRY = registry
- Measurement.force_ndarray = force_ndarray
-
- return Measurement
-
-
-class LazyRegistry(object):
-
- def __init__(self, args=None, kwargs=None):
- self.__dict__['params'] = args or (), kwargs or {}
-
- def __init(self):
- args, kwargs = self.__dict__['params']
- kwargs['on_redefinition'] = 'raise'
- self.__class__ = UnitRegistry
- self.__init__(*args, **kwargs)
-
- def __getattr__(self, item):
- if item == '_on_redefinition':
- return 'raise'
- self.__init()
- return getattr(self, item)
-
- def __setattr__(self, key, value):
- if key == '__class__':
- super(LazyRegistry, self).__setattr__(key, value)
- else:
- self.__init()
- setattr(self, key, value)
-
- def __getitem__(self, item):
- self.__init()
- return self[item]
-
- def __call__(self, *args, **kwargs):
- self.__init()
- return self(*args, **kwargs)
diff --git a/lib/taurus/external/pint/pint_local/util.py b/lib/taurus/external/pint/pint_local/util.py
deleted file mode 100644
index 7ff28e3..0000000
--- a/lib/taurus/external/pint/pint_local/util.py
+++ /dev/null
@@ -1,643 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- pint.util
- ~~~~~~~~~
-
- Miscellaneous functions for pint.
-
- :copyright: 2013 by Pint Authors, see AUTHORS for more details.
- :license: BSD, see LICENSE for more details.
-"""
-
-from __future__ import division, unicode_literals, print_function, absolute_import
-
-import re
-import operator
-from numbers import Number
-from fractions import Fraction
-from collections import Mapping
-
-import logging
-from token import STRING, NAME, OP, NUMBER
-from tokenize import untokenize
-
-from .compat import string_types, tokenizer, lru_cache, NullHandler, maketrans, NUMERIC_TYPES
-from .formatting import format_unit
-from .pint_eval import build_eval_tree
-
-logger = logging.getLogger(__name__)
-logger.addHandler(NullHandler())
-
-
-def matrix_to_string(matrix, row_headers=None, col_headers=None, fmtfun=lambda x: str(int(x))):
- """Takes a 2D matrix (as nested list) and returns a string.
- """
- ret = []
- if col_headers:
- ret.append(('\t' if row_headers else '') + '\t'.join(col_headers))
- if row_headers:
- ret += [rh + '\t' + '\t'.join(fmtfun(f) for f in row)
- for rh, row in zip(row_headers, matrix)]
- else:
- ret += ['\t'.join(fmtfun(f) for f in row)
- for row in matrix]
-
- return '\n'.join(ret)
-
-
-def transpose(matrix):
- """Takes a 2D matrix (as nested list) and returns the transposed version.
- """
- return [list(val) for val in zip(*matrix)]
-
-
-def column_echelon_form(matrix, ntype=Fraction, transpose_result=False):
- """Calculates the column echelon form using Gaussian elimination.
-
- :param matrix: a 2D matrix as nested list.
- :param ntype: the numerical type to use in the calculation.
- :param transpose_result: indicates if the returned matrix should be transposed.
- :return: column echelon form, transformed identity matrix, swapped rows
- """
- lead = 0
-
- M = transpose(matrix)
-
- _transpose = transpose if transpose_result else lambda x: x
-
- rows, cols = len(M), len(M[0])
-
- new_M = []
- for row in M:
- r = []
- for x in row:
- if isinstance(x, float):
- x = ntype.from_float(x)
- else:
- x = ntype(x)
- r.append(x)
- new_M.append(r)
- M = new_M
-
-# M = [[ntype(x) for x in row] for row in M]
- I = [[ntype(1) if n == nc else ntype(0) for nc in range(rows)] for n in range(rows)]
- swapped = []
-
- for r in range(rows):
- if lead >= cols:
- return _transpose(M), _transpose(I), swapped
- i = r
- while M[i][lead] == 0:
- i += 1
- if i != rows:
- continue
- i = r
- lead += 1
- if cols == lead:
- return _transpose(M), _transpose(I), swapped
-
- M[i], M[r] = M[r], M[i]
- I[i], I[r] = I[r], I[i]
-
- swapped.append(i)
- lv = M[r][lead]
- M[r] = [mrx / lv for mrx in M[r]]
- I[r] = [mrx / lv for mrx in I[r]]
-
- for i in range(rows):
- if i == r:
- continue
- lv = M[i][lead]
- M[i] = [iv - lv*rv for rv, iv in zip(M[r], M[i])]
- I[i] = [iv - lv*rv for rv, iv in zip(I[r], I[i])]
-
- lead += 1
-
- return _transpose(M), _transpose(I), swapped
-
-
-def pi_theorem(quantities, registry=None):
- """Builds dimensionless quantities using the Buckingham π theorem
-
- :param quantities: mapping between variable name and units
- :type quantities: dict
- :return: a list of dimensionless quantities expressed as dicts
- """
-
- # Preprocess input and build the dimensionality Matrix
- quant = []
- dimensions = set()
-
- if registry is None:
- getdim = lambda x: x
- else:
- getdim = registry.get_dimensionality
-
- for name, value in quantities.items():
- if isinstance(value, string_types):
- value = ParserHelper.from_string(value)
- if isinstance(value, dict):
- dims = getdim(UnitsContainer(value))
- elif not hasattr(value, 'dimensionality'):
- dims = getdim(value)
- else:
- dims = value.dimensionality
-
- if not registry and any(not key.startswith('[') for key in dims):
- logger.warning('A non dimension was found and a registry was not provided. '
- 'Assuming that it is a dimension name: {0}.'.format(dims))
-
- quant.append((name, dims))
- dimensions = dimensions.union(dims.keys())
-
- dimensions = list(dimensions)
-
- # Calculate dimensionless quantities
- M = [[dimensionality[dimension] for name, dimensionality in quant]
- for dimension in dimensions]
-
- M, identity, pivot = column_echelon_form(M, transpose_result=False)
-
- # Collect results
- # Make all numbers integers and minimize the number of negative exponents.
- # Remove zeros
- results = []
- for rowm, rowi in zip(M, identity):
- if any(el != 0 for el in rowm):
- continue
- max_den = max(f.denominator for f in rowi)
- neg = -1 if sum(f < 0 for f in rowi) > sum(f > 0 for f in rowi) else 1
- results.append(dict((q[0], neg * f.numerator * max_den / f.denominator)
- for q, f in zip(quant, rowi) if f.numerator != 0))
- return results
-
-
-def solve_dependencies(dependencies):
- """Solve a dependency graph.
-
- :param dependencies: dependency dictionary. For each key, the value is
- an iterable indicating its dependencies.
- :return: list of sets, each containing keys of independents tasks dependent
- only of the previous tasks in the list.
- """
- d = dict((key, set(dependencies[key])) for key in dependencies)
- r = []
- while d:
- # values not in keys (items without dep)
- t = set(i for v in d.values() for i in v) - set(d.keys())
- # and keys without value (items without dep)
- t.update(k for k, v in d.items() if not v)
- # can be done right away
- r.append(t)
- # and cleaned up
- d = dict(((k, v - t) for k, v in d.items() if v))
- return r
-
-
-def find_shortest_path(graph, start, end, path=None):
- path = (path or []) + [start]
- if start == end:
- return path
- if not start in graph:
- return None
- shortest = None
- for node in graph[start]:
- if node not in path:
- newpath = find_shortest_path(graph, node, end, path)
- if newpath:
- if not shortest or len(newpath) < len(shortest):
- shortest = newpath
- return shortest
-
-
-def find_connected_nodes(graph, start, visited=None):
- if not start in graph:
- return None
-
- visited = (visited or set())
- visited.add(start)
-
- for node in graph[start]:
- if node not in visited:
- find_connected_nodes(graph, node, visited)
-
- return visited
-
-
-class udict(dict):
- """ Custom dict implementing __missing__.
-
- """
- def __missing__(self, key):
- return 0.
-
-
-class UnitsContainer(Mapping):
- """The UnitsContainer stores the product of units and their respective
- exponent and implements the corresponding operations.
-
- UnitsContainer is a read-only mapping. All operations (even in place ones)
- return new instances.
-
- """
- __slots__ = ('_d', '_hash')
-
- def __init__(self, *args, **kwargs):
- d = udict(*args, **kwargs)
- self._d = d
- for key, value in d.items():
- if not isinstance(key, string_types):
- raise TypeError('key must be a str, not {0}'.format(type(key)))
- if not isinstance(value, Number):
- raise TypeError('value must be a number, not {0}'.format(type(value)))
- if not isinstance(value, float):
- d[key] = float(value)
- self._hash = hash(frozenset(self._d.items()))
-
- def copy(self):
- return self.__copy__()
-
- def add(self, key, value):
- newval = self._d[key] + value
- new = self.copy()
- if newval:
- new._d[key] = newval
- else:
- del new._d[key]
-
- return new
-
- def remove(self, keys):
- """ Create a new UnitsContainer purged from given keys.
-
- """
- d = udict(self._d)
- return UnitsContainer(((key, d[key]) for key in d if key not in keys))
-
- def rename(self, oldkey, newkey):
- """ Create a new UnitsContainer in which an entry has been renamed.
-
- """
- d = udict(self._d)
- d[newkey] = d.pop(oldkey)
- return UnitsContainer(d)
-
- def __iter__(self):
- return iter(self._d)
-
- def __len__(self):
- return len(self._d)
-
- def __getitem__(self, key):
- return self._d[key]
-
- def __hash__(self):
- return self._hash
-
- def __getstate__(self):
- return {'_d': self._d, '_hash': self._hash}
-
- def __setstate__(self, state):
- self._d = state['_d']
- self._hash = state['_hash']
-
- def __eq__(self, other):
- if isinstance(other, UnitsContainer):
- other = other._d
- elif isinstance(other, string_types):
- other = ParserHelper.from_string(other)
- other = other._d
-
- return dict.__eq__(self._d, other)
-
- def __str__(self):
- return self.__format__('')
-
- def __repr__(self):
- tmp = '{%s}' % ', '.join(["'{0}': {1}".format(key, value)
- for key, value in sorted(self._d.items())])
- return '<UnitsContainer({0})>'.format(tmp)
-
- def __format__(self, spec):
- return format_unit(self, spec)
-
- def __copy__(self):
- return UnitsContainer(self._d)
-
- def __mul__(self, other):
- d = udict(self._d)
- if not isinstance(other, self.__class__):
- err = 'Cannot multiply UnitsContainer by {0}'
- raise TypeError(err.format(type(other)))
- for key, value in other.items():
- d[key] += value
- keys = [key for key, value in d.items() if value == 0]
- for key in keys:
- del d[key]
-
- return UnitsContainer(d)
-
- __rmul__ = __mul__
-
- def __pow__(self, other):
- if not isinstance(other, NUMERIC_TYPES):
- err = 'Cannot power UnitsContainer by {0}'
- raise TypeError(err.format(type(other)))
- d = udict(self._d)
- for key, value in d.items():
- d[key] *= other
- return UnitsContainer(d)
-
- def __truediv__(self, other):
- if not isinstance(other, self.__class__):
- err = 'Cannot divide UnitsContainer by {0}'
- raise TypeError(err.format(type(other)))
-
- d = udict(self._d)
-
- for key, value in other.items():
- d[key] -= value
-
- keys = [key for key, value in d.items() if value == 0]
- for key in keys:
- del d[key]
-
- return UnitsContainer(d)
-
- def __rtruediv__(self, other):
- if not isinstance(other, self.__class__) and other != 1:
- err = 'Cannot divide {0} by UnitsContainer'
- raise TypeError(err.format(type(other)))
-
- return self**-1
-
-
-class ParserHelper(UnitsContainer):
- """ The ParserHelper stores in place the product of variables and
- their respective exponent and implements the corresponding operations.
-
- ParserHelper is a read-only mapping. All operations (even in place ones)
- return new instances.
-
- WARNING : The hash value used does not take into account the scale
- attribute so be careful if you use it as a dict key and then two unequal
- object can have the same hash.
-
- """
-
- __slots__ = ('scale', )
-
- def __init__(self, scale=1, *args, **kwargs):
- super(ParserHelper, self).__init__(*args, **kwargs)
- self.scale = scale
-
- @classmethod
- def from_word(cls, input_word):
- """Creates a ParserHelper object with a single variable with exponent one.
-
- Equivalent to: ParserHelper({'word': 1})
-
- """
- return cls(1, [(input_word, 1)])
-
- @classmethod
- def from_string(cls, input_string):
- return cls._from_string(input_string)
-
- @classmethod
- def eval_token(cls, token, use_decimal=False):
- token_type = token[0]
- token_text = token[1]
- if token_type == NUMBER:
- if '.' in token_text or 'e' in token_text:
- if use_decimal:
- return Decimal(token_text)
- return float(token_text)
- return int(token_text)
- elif token_type == NAME:
- return ParserHelper.from_word(token_text)
- else:
- raise Exception('unknown token type')
-
- @classmethod
- @lru_cache()
- def _from_string(cls, input_string):
- """Parse linear expression mathematical units and return a quantity object.
-
- """
- if not input_string:
- return cls()
-
- input_string = string_preprocessor(input_string)
- if '[' in input_string:
- input_string = input_string.replace('[', '__obra__').replace(']', '__cbra__')
- reps = True
- else:
- reps = False
-
- gen = tokenizer(input_string)
- ret = build_eval_tree(gen).evaluate(cls.eval_token)
-
- if isinstance(ret, Number):
- return ParserHelper(ret)
-
- if not reps:
- return ret
-
- return ParserHelper(ret.scale,
- dict((key.replace('__obra__', '[').replace('__cbra__', ']'), value)
- for key, value in ret.items()))
-
- def __copy__(self):
- # workaround for python2.6 compatibility (cast kwarg keys to str)
- # see http://bugs.python.org/issue2646
- kwargs = dict([(str(k),v) for k,v in self.items()])
- return ParserHelper(scale=self.scale, **kwargs)
-
- def copy(self):
- return self.__copy__()
-
- def __hash__(self):
- if self.scale != 1.0:
- mess = 'Only scale 1.0 ParserHelper instance should be considered hashable'
- raise ValueError(mess)
- return self._hash
-
- def __eq__(self, other):
- if isinstance(other, self.__class__):
- return self.scale == other.scale and\
- super(ParserHelper, self).__eq__(other)
- elif isinstance(other, string_types):
- return self == ParserHelper.from_string(other)
- elif isinstance(other, Number):
- return self.scale == other and not len(self._d)
- else:
- return self.scale == 1. and super(ParserHelper, self).__eq__(other)
-
- def operate(self, items, op=operator.iadd, cleanup=True):
- d = udict(self._d)
- for key, value in items:
- d[key] = op(d[key], value)
-
- if cleanup:
- keys = [key for key, value in d.items() if value == 0]
- for key in keys:
- del d[key]
-
- return self.__class__(self.scale, d)
-
- def __str__(self):
- tmp = '{%s}' % ', '.join(["'{0}': {1}".format(key, value)
- for key, value in sorted(self._d.items())])
- return '{0} {1}'.format(self.scale, tmp)
-
- def __repr__(self):
- tmp = '{%s}' % ', '.join(["'{0}': {1}".format(key, value)
- for key, value in sorted(self._d.items())])
- return '<ParserHelper({0}, {1})>'.format(self.scale, tmp)
-
- def __mul__(self, other):
- if isinstance(other, string_types):
- new = self.add(other, 1)
- elif isinstance(other, Number):
- new = self.copy()
- new.scale *= other
- elif isinstance(other, self.__class__):
- new = self.operate(other.items())
- new.scale *= other.scale
- else:
- new = self.operate(other.items())
- return new
-
- __rmul__ = __mul__
-
- def __pow__(self, other):
- d = self._d.copy()
- for key in self._d:
- d[key] *= other
- return self.__class__(self.scale**other, d)
-
- def __truediv__(self, other):
- if isinstance(other, string_types):
- new = self.add(other, -1)
- elif isinstance(other, Number):
- new = self.copy()
- new.scale /= other
- elif isinstance(other, self.__class__):
- new = self.operate(other.items(), operator.sub)
- new.scale /= other.scale
- else:
- new = self.operate(other.items(), operator.sub)
- return new
-
- __floordiv__ = __truediv__
-
- def __rtruediv__(self, other):
- new = self.__pow__(-1)
- if isinstance(other, string_types):
- new = new.add(other, 1)
- elif isinstance(other, Number):
- new.scale *= other
- elif isinstance(other, self.__class__):
- new = self.operate(other.items(), operator.add)
- new.scale *= other.scale
- else:
- new = new.operate(other.items(), operator.add)
- return new
-
-
-#: List of regex substitution pairs.
-_subs_re = [(r"([\w\.\-\+\*\\\^])\s+", r"\1 "), # merge multiple spaces
- (r"({0}) squared", r"\1**2"), # Handle square and cube
- (r"({0}) cubed", r"\1**3"),
- (r"cubic ({0})", r"\1**3"),
- (r"square ({0})", r"\1**2"),
- (r"sq ({0})", r"\1**2"),
- (r"\b([0-9]+\.?[0-9]*)(?=[e|E][a-zA-Z]|[a-df-zA-DF-Z])", r"\1*"), # Handle numberLetter for multiplication
- (r"([\w\.\-])\s+(?=\w)", r"\1*"), # Handle space for multiplication
- ]
-
-#: Compiles the regex and replace {0} by a regex that matches an identifier.
-_subs_re = [(re.compile(a.format(r"[_a-zA-Z][_a-zA-Z0-9]*")), b) for a, b in _subs_re]
-_pretty_table = maketrans('⁰¹²³⁴⁵⁶⁷⁸⁹·⁻', '0123456789*-')
-_pretty_exp_re = re.compile(r"⁻?[⁰¹²³⁴⁵⁶⁷⁸⁹]+(?:\.[⁰¹²³⁴⁵⁶⁷⁸⁹]*)?")
-
-
-def string_preprocessor(input_string):
-
- input_string = input_string.replace(",", "")
- input_string = input_string.replace(" per ", "/")
-
- for a, b in _subs_re:
- input_string = a.sub(b, input_string)
-
- # Replace pretty format characters
- for pretty_exp in _pretty_exp_re.findall(input_string):
- exp = '**' + pretty_exp.translate(_pretty_table)
- input_string = input_string.replace(pretty_exp, exp)
- input_string = input_string.translate(_pretty_table)
-
- # Handle caret exponentiation
- input_string = input_string.replace("^", "**")
- return input_string
-
-
-def _is_dim(name):
- return name[0] == '[' and name[-1] == ']'
-
-
-class SharedRegistryObject(object):
- """Base class for object keeping a refrence to the registree.
-
- Such object are for now _Quantity and _Unit, in a number of places it is
- that an object from this class has a '_units' attribute.
-
- """
-
- def _check(self, other):
- """Check if the other object use a registry and if so that it is the
- same registry.
-
- Return True is both use a registry and they use the same, False is
- other don't use a registry and raise ValueError if other don't use the
- same unit registry.
-
- """
- if self._REGISTRY is getattr(other, '_REGISTRY', None):
- return True
-
- elif isinstance(other, SharedRegistryObject):
- mess = 'Cannot operate with {0} and {1} of different registries.'
- raise ValueError(mess.format(self.__class__.__name__,
- other.__class__.__name__))
- else:
- return False
-
-def to_units_container(unit_like, registry=None):
- """ Convert a unit compatible type to a UnitsContainer.
-
- """
- mro = type(unit_like).mro()
- if UnitsContainer in mro:
- return unit_like
- elif SharedRegistryObject in mro:
- return unit_like._units
- elif string_types in mro:
- if registry:
- return registry._parse_units(unit_like)
- else:
- return ParserHelper.from_string(unit_like)
- elif dict in mro:
- return UnitsContainer(unit_like)
-
-
-def infer_base_unit(q):
- """Return UnitsContainer of q with all prefixes stripped."""
- d = {}
- parse = q._REGISTRY.parse_unit_name
- for unit_name, power in q._units.items():
- completely_parsed_unit = list(parse(unit_name))[-1]
-
- _, base_unit, __ = completely_parsed_unit
- d[base_unit] = power
- return UnitsContainer(d)
diff --git a/setup.cfg b/setup.cfg
index 8bfd5a1..861a9f5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,4 +1,5 @@
[egg_info]
tag_build =
tag_date = 0
+tag_svn_revision = 0
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/taurus.git
More information about the debian-science-commits
mailing list