diff options
author | Guido Imperiale <crusaderky@gmail.com> | 2019-12-03 17:29:46 +0000 |
---|---|---|
committer | Guido Imperiale <crusaderky@gmail.com> | 2019-12-03 17:29:46 +0000 |
commit | 31a01bf568ec55b9ecd2862ff9daf9dbae703170 (patch) | |
tree | d84d1c0985001fba67f4de001b1d30f53d18b536 /pint | |
parent | cf05eb8ddb74895a01986bb77d6aef64429cabf5 (diff) | |
download | pint-31a01bf568ec55b9ecd2862ff9daf9dbae703170.tar.gz |
Remove 2.7 support from codebase
Diffstat (limited to 'pint')
40 files changed, 147 insertions, 675 deletions
diff --git a/pint/__init__.py b/pint/__init__.py index 0189f08..55486b2 100644 --- a/pint/__init__.py +++ b/pint/__init__.py @@ -11,8 +11,6 @@ :copyright: 2016 by Pint Authors, see AUTHORS for more details. :license: BSD, see LICENSE for more details. """ -from __future__ import with_statement - import pkg_resources diff --git a/pint/babel_names.py b/pint/babel_names.py index 05b5509..25037ae 100644 --- a/pint/babel_names.py +++ b/pint/babel_names.py @@ -138,7 +138,7 @@ _babel_units = dict( ) if not HAS_PROPER_BABEL: - _babel_units = dict() + _babel_units = {} _babel_systems = dict( mks='metric', diff --git a/pint/compat/__init__.py b/pint/compat/__init__.py index 1fc438d..255dc9c 100644 --- a/pint/compat/__init__.py +++ b/pint/compat/__init__.py @@ -9,10 +9,6 @@ :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 @@ -21,7 +17,6 @@ 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): @@ -30,42 +25,6 @@ def tokenizer(input_string): 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 - -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 itertools import zip_longest -except ImportError: - from itertools import izip_longest as zip_longest - try: import numpy as np from numpy import ndarray @@ -77,7 +36,7 @@ try: 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 == '': + elif isinstance(value, str) and value == '': raise ValueError('Quantity magnitude cannot be an empty string.') elif isinstance(value, (list, tuple)): return np.asarray(value) @@ -89,7 +48,7 @@ except ImportError: np = None - class ndarray(object): + class ndarray: pass HAS_NUMPY = False @@ -99,7 +58,7 @@ except ImportError: 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 == '': + elif isinstance(value, str) 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 ' diff --git a/pint/compat/chainmap.py b/pint/compat/chainmap.py deleted file mode 100644 index 8a0ad14..0000000 --- a/pint/compat/chainmap.py +++ /dev/null @@ -1,155 +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 - -if sys.version_info < (3, 3): - from collections import MutableMapping -else: - from collections.abc import MutableMapping - -if sys.version_info < (3, 0): - 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/pint/compat/lrucache.py b/pint/compat/lrucache.py deleted file mode 100644 index 868b598..0000000 --- a/pint/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/pint/compat/meta.py b/pint/compat/meta.py deleted file mode 100644 index 0036870..0000000 --- a/pint/compat/meta.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -""" - pint.compat.meta - ~~~~~~~~~~~~~~~~ - - Compatibility layer. - - :copyright: 2016 by Pint Authors, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - # This requires a bit of explanation: the basic idea is to make a dummy - # metaclass for one level of class instantiation that replaces itself with - # the actual metaclass. - - # Taken from six - - class metaclass(meta): - - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {})
\ No newline at end of file diff --git a/pint/compat/tokenize.py b/pint/compat/tokenize.py index 8d28b4f..a285a6b 100644 --- a/pint/compat/tokenize.py +++ b/pint/compat/tokenize.py @@ -31,29 +31,11 @@ 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) +cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) +blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) COMMENT = N_TOKENS tok_name[COMMENT] = 'COMMENT' @@ -108,6 +90,7 @@ EXACT_TOKEN_TYPES = { '@': AT } + class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')): def __repr__(self): annotated_type = '%d (%s)' % (self.type, tok_name[self.type]) @@ -121,9 +104,18 @@ class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line' else: return self.type -def group(*choices): return '(' + '|'.join(choices) + ')' -def any(*choices): return group(*choices) + '*' -def maybe(*choices): return group(*choices) + '?' + +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. @@ -182,9 +174,11 @@ ContStr = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\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, @@ -230,9 +224,13 @@ for t in ("'", '"', tabsize = 8 -class TokenError(Exception): pass -class StopTokenizing(Exception): pass +class TokenError(Exception): + pass + + +class StopTokenizing(Exception): + pass class Untokenizer: @@ -351,6 +349,7 @@ def _get_normal_name(orig_enc): return "iso-8859-1" return orig_enc + def detect_encoding(readline): """ The detect_encoding() function is used to detect the encoding that should @@ -375,6 +374,7 @@ def detect_encoding(readline): bom_found = False encoding = None default = 'utf-8' + def read_or_stop(): try: return readline() @@ -486,7 +486,7 @@ def tokenize(readline): try: return _tokenize(chain(consumed, rl_gen, empty).__next__, encoding) except AttributeError: - return _tokenize(chain(consumed, rl_gen, empty).next, encoding) + return _tokenize(chain(consumed, rl_gen, empty).__next__, encoding) def _tokenize(readline, encoding): @@ -621,7 +621,7 @@ def _tokenize(readline, encoding): break else: # ordinary string yield TokenInfo(STRING, token, spos, epos, line) - elif isidentifier(initial): # ordinary name + elif initial.isidentifier(): # ordinary name yield TokenInfo(NAME, token, spos, epos, line) elif initial == '\\': # continued stmt continued = 1 @@ -636,6 +636,6 @@ def _tokenize(readline, encoding): (lnum, pos), (lnum, pos+1), line) pos += 1 - for indent in indents[1:]: # pop remaining indent levels + for _ in indents[1:]: # pop remaining indent levels yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '') yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '') diff --git a/pint/context.py b/pint/context.py index 6bd7335..d4d27b9 100644 --- a/pint/context.py +++ b/pint/context.py @@ -9,15 +9,11 @@ :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 collections import ChainMap, defaultdict -from .compat import ChainMap -from .util import (ParserHelper, UnitsContainer, string_types, +from .util import (ParserHelper, UnitsContainer, to_units_container, SourceIterator) from .errors import DefinitionSyntaxError @@ -34,7 +30,7 @@ def _expression_to_function(eq): return func -class Context(object): +class Context: """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. diff --git a/pint/converters.py b/pint/converters.py index 6dbf4b4..62572f8 100644 --- a/pint/converters.py +++ b/pint/converters.py @@ -8,11 +8,9 @@ :copyright: 2016 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): +class Converter: """Base class for value converters. """ diff --git a/pint/definitions.py b/pint/definitions.py index 428aeae..f180f7c 100644 --- a/pint/definitions.py +++ b/pint/definitions.py @@ -9,16 +9,11 @@ :license: BSD, see LICENSE for more details. """ -from __future__ import (division, unicode_literals, print_function, - absolute_import) -import sys - from .converters import ScaleConverter, OffsetConverter from .util import UnitsContainer, _is_dim, ParserHelper -from .compat import string_types -class Definition(object): +class Definition: """Base class for definitions. :param name: name. @@ -45,13 +40,6 @@ class Definition(object): name = name.strip() result = [res.strip() for res in definition.split('=')] - # For python 2.7, remove unsupported unicode character - if (sys.version_info < (3, 0)): - for value in result: - try: - value.decode('utf-8') - except UnicodeEncodeError: - result.remove(value) # @alias name = alias1 = alias2 = ... if name.startswith("@alias "): @@ -106,7 +94,7 @@ class PrefixDefinition(Definition): """ def __init__(self, name, symbol, aliases, converter): - if isinstance(converter, string_types): + if isinstance(converter, str): converter = ScaleConverter(eval(converter)) aliases = tuple(alias.strip('-') for alias in aliases) if symbol: @@ -126,7 +114,7 @@ class UnitDefinition(Definition): reference=None, is_base=False): self.reference = reference self.is_base = is_base - if isinstance(converter, string_types): + if isinstance(converter, str): if ';' in converter: [converter, modifiers] = converter.split(';', 2) modifiers = dict((key.strip(), eval(value)) for key, value in @@ -162,7 +150,7 @@ class DimensionDefinition(Definition): reference=None, is_base=False): self.reference = reference self.is_base = is_base - if isinstance(converter, string_types): + if isinstance(converter, str): converter = ParserHelper.from_string(converter) if not converter: self.is_base = True diff --git a/pint/errors.py b/pint/errors.py index 700d79c..1939dce 100644 --- a/pint/errors.py +++ b/pint/errors.py @@ -8,10 +8,6 @@ :copyright: 2016 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): @@ -60,7 +56,7 @@ class UndefinedUnitError(AttributeError): def __str__(self): mess = "'{}' is not defined in the unit registry" mess_plural = "'{}' are not defined in the unit registry" - if isinstance(self.unit_names, string_types): + if isinstance(self.unit_names, str): return mess.format(self.unit_names) elif isinstance(self.unit_names, (list, tuple))\ and len(self.unit_names) == 1: diff --git a/pint/formatting.py b/pint/formatting.py index efd68f7..24a44d5 100644 --- a/pint/formatting.py +++ b/pint/formatting.py @@ -9,12 +9,10 @@ :license: BSD, see LICENSE for more details. """ -from __future__ import division, unicode_literals, print_function, absolute_import - import re from .babel_names import _babel_units, _babel_lengths -from pint.compat import babel_units, Loc, string_types +from .compat import Loc __JOIN_REG_EXP = re.compile("\{\d*\}") @@ -291,7 +289,7 @@ def matrix_to_latex(matrix, fmtfun=lambda x: format(x, '.2f')): def ndarray_to_latex_parts(ndarr, fmtfun=lambda x: format(x, '.2f'), dim=()): - if isinstance(fmtfun, string_types): + if isinstance(fmtfun, str): fmt = fmtfun fmtfun = lambda x: format(x, fmt) diff --git a/pint/matplotlib.py b/pint/matplotlib.py index 4c8af68..67ffef8 100644 --- a/pint/matplotlib.py +++ b/pint/matplotlib.py @@ -9,7 +9,6 @@ :copyright: 2017 by Pint Authors, see AUTHORS for more details. :license: BSD, see LICENSE for more details. """ -from __future__ import absolute_import import matplotlib.units diff --git a/pint/measurement.py b/pint/measurement.py index 3fc40e1..63f8744 100644 --- a/pint/measurement.py +++ b/pint/measurement.py @@ -7,8 +7,6 @@ :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, siunitx_format_unit from .quantity import Quantity @@ -140,7 +138,7 @@ _Measurement = Measurement def build_measurement_class(registry): if ufloat is None: - class Measurement(object): + class Measurement: _REGISTRY = registry def __init__(self, *args): diff --git a/pint/pint_eval.py b/pint/pint_eval.py index 751e496..b198a40 100644 --- a/pint/pint_eval.py +++ b/pint/pint_eval.py @@ -44,7 +44,7 @@ _UNARY_OPERATOR_MAP = { } -class EvalTreeNode(object): +class EvalTreeNode: def __init__(self, left, operator=None, right=None): """ diff --git a/pint/quantity.py b/pint/quantity.py index f093d08..9fe1b45 100644 --- a/pint/quantity.py +++ b/pint/quantity.py @@ -7,8 +7,6 @@ :license: BSD, see LICENSE for more details. """ -from __future__ import division, unicode_literals, print_function, absolute_import - import contextlib import copy import datetime @@ -25,7 +23,7 @@ from .formatting import (remove_custom_flags, siunitx_format_unit, ndarray_to_la from .errors import (DimensionalityError, OffsetUnitCalculusError, UndefinedUnitError, UnitStrippedWarning) from .definitions import UnitDefinition -from .compat import string_types, ndarray, np, _to_magnitude, long_type +from .compat import ndarray, np, _to_magnitude from .util import (PrettyIPython, logger, UnitsContainer, SharedRegistryObject, to_units_container, infer_base_unit, fix_str_conversions) @@ -125,7 +123,7 @@ class Quantity(PrettyIPython, SharedRegistryObject): def __new__(cls, value, units=None): if units is None: - if isinstance(value, string_types): + if isinstance(value, str): if value == '': raise ValueError('Expression to parse as Quantity cannot ' 'be an empty string.') @@ -142,7 +140,7 @@ class Quantity(PrettyIPython, SharedRegistryObject): inst = SharedRegistryObject.__new__(cls) inst._magnitude = _to_magnitude(value, inst.force_ndarray) inst._units = units - elif isinstance(units, string_types): + elif isinstance(units, str): inst = SharedRegistryObject.__new__(cls) inst._magnitude = _to_magnitude(value, inst.force_ndarray) inst._units = inst._REGISTRY.parse_units(units)._units @@ -577,7 +575,7 @@ class Quantity(PrettyIPython, SharedRegistryObject): magnitude = q_base.magnitude units = list(q_base._units.items()) - units_numerator = list(filter(lambda a: a[1]>0, units)) + units_numerator = [a for a in units if a[1] > 0] if len(units_numerator) > 0: unit_str, unit_power = units_numerator[0] @@ -602,11 +600,6 @@ class Quantity(PrettyIPython, SharedRegistryObject): 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())) diff --git a/pint/registry.py b/pint/registry.py index 4324c7d..f6be018 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -32,8 +32,6 @@ :license: BSD, see LICENSE for more details. """ -from __future__ import division, unicode_literals, print_function, absolute_import - import copy import os import re @@ -56,7 +54,7 @@ from .util import (getattr_maybe_raise, find_shortest_path, UnitsContainer, _is_dim, to_units_container, SourceIterator) -from .compat import tokenizer, string_types, meta +from .compat import tokenizer from .definitions import (Definition, UnitDefinition, PrefixDefinition, DimensionDefinition, AliasDefinition) from .converters import ScaleConverter @@ -69,18 +67,18 @@ from . import systems _BLOCK_RE = re.compile(r' |\(') -class _Meta(type): +class RegistryMeta(type): """This is just to call after_init at the right time instead of asking the developer to do it when subclassing. """ def __call__(self, *args, **kwargs): - obj = super(_Meta, self).__call__(*args, **kwargs) + obj = super().__call__(*args, **kwargs) obj._after_init() return obj -class BaseRegistry(meta.with_metaclass(_Meta)): +class BaseRegistry(metaclass=RegistryMeta): """Base class for all registries. Capabilities: @@ -239,7 +237,7 @@ class BaseRegistry(meta.with_metaclass(_Meta)): :type definition: str or Definition """ - if isinstance(definition, string_types): + if isinstance(definition, str): for line in definition.split('\n'): self._define(Definition.from_string(line)) else: @@ -301,8 +299,9 @@ class BaseRegistry(meta.with_metaclass(_Meta)): d_aliases = tuple('Δ' + alias for alias in definition.aliases) + \ tuple('delta_' + alias for alias in definition.aliases) - d_reference = UnitsContainer(dict((ref, value) - for ref, value in definition.reference.items())) + d_reference = UnitsContainer( + {ref: value for ref, value in definition.reference.items()} + ) d_def = UnitDefinition(d_name, d_symbol, d_aliases, ScaleConverter(definition.converter.scale), @@ -359,7 +358,7 @@ class BaseRegistry(meta.with_metaclass(_Meta)): :type parserfunc: SourceIterator -> None """ if self._parsers is None: - self._parsers = dict() + self._parsers = {} if prefix and prefix[0] == '@': self._parsers[prefix] = parserfunc @@ -374,7 +373,7 @@ class BaseRegistry(meta.with_metaclass(_Meta)): and therefore should be loaded from the package. """ # Permit both filenames and line-iterables - if isinstance(file, string_types): + if isinstance(file, str): try: if is_resource: with closing(pkg_resources.resource_stream(__name__, file)) as fp: @@ -564,8 +563,7 @@ class BaseRegistry(meta.with_metaclass(_Meta)): if '[]' in accumulator: del accumulator['[]'] - dims = UnitsContainer(dict((k, v) for k, v in accumulator.items() - if v != 0.0)) + dims = UnitsContainer({k: v for k, v in accumulator.items() if v != 0.0}) self._dimensionality_cache[input_units] = dims @@ -650,12 +648,11 @@ class BaseRegistry(meta.with_metaclass(_Meta)): 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.)) + units = UnitsContainer({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(): + for unit in units: if not self._units[unit].converter.is_multiplicative: return None, units @@ -1122,8 +1119,10 @@ class ContextRegistry(BaseRegistry): kwargs = dict(self._active_ctx.defaults, **kwargs) # For each name, we first find the corresponding context - ctxs = list((self._contexts[name] if isinstance(name, string_types) else name) - for name in names_or_contexts) + ctxs = [ + self._contexts[name] if isinstance(name, str) 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. @@ -1550,7 +1549,7 @@ class UnitRegistry(SystemRegistry, ContextRegistry, NonMultiplicativeRegistry): check = registry_helpers.check -class LazyRegistry(object): +class LazyRegistry: def __init__(self, args=None, kwargs=None): self.__dict__['params'] = args or (), kwargs or {} diff --git a/pint/registry_helpers.py b/pint/registry_helpers.py index 74f16d3..7733c49 100644 --- a/pint/registry_helpers.py +++ b/pint/registry_helpers.py @@ -10,17 +10,12 @@ """ import functools +from inspect import signature +from itertools import zip_longest -from .compat import string_types, zip_longest from .errors import DimensionalityError from .util import to_units_container, UnitsContainer -try: - from inspect import signature -except ImportError: - # Python2 does not have the inspect library. Import the backport. - from funcsigs import signature - def _replace_units(original_units, values_by_name): """Convert a unit compatible type to a UnitsContainer. @@ -42,7 +37,7 @@ def _to_units_container(a, registry=None): Return a tuple with the unit container and a boolean indicating if it was a reference. """ - if isinstance(a, string_types) and '=' in a: + if isinstance(a, str) and '=' in a: return to_units_container(a.split('=', 1)[1]), True return to_units_container(a, registry), False @@ -130,6 +125,7 @@ def _parse_wrap_args(args, registry=None): return _converter + def _apply_defaults(func, args, kwargs): """Apply default keyword arguments. @@ -145,6 +141,7 @@ def _apply_defaults(func, args, kwargs): args = [bound_arguments.arguments[key] for key in sig.parameters.keys()] return args, {} + def wraps(ureg, ret, args, strict=True): """Wraps a function to become pint-aware. diff --git a/pint/systems.py b/pint/systems.py index 3c56660..3daf527 100644 --- a/pint/systems.py +++ b/pint/systems.py @@ -9,8 +9,6 @@ :license: BSD, see LICENSE for more details. """ -from __future__ import division, unicode_literals, print_function, absolute_import - import re from .definitions import Definition, UnitDefinition @@ -401,9 +399,11 @@ class System(SharedRegistryObject): # 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./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 @@ -432,7 +432,7 @@ class System(SharedRegistryObject): return system -class Lister(object): +class Lister: def __init__(self, d): self.d = d diff --git a/pint/testsuite/__init__.py b/pint/testsuite/__init__.py index 2f50544..b46d86f 100644 --- a/pint/testsuite/__init__.py +++ b/pint/testsuite/__init__.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - import doctest import logging import os diff --git a/pint/testsuite/helpers.py b/pint/testsuite/helpers.py index 1f58d21..bf638bd 100644 --- a/pint/testsuite/helpers.py +++ b/pint/testsuite/helpers.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - - import doctest from distutils.version import StrictVersion import re import unittest -from pint.compat import HAS_NUMPY, HAS_PROPER_BABEL, HAS_UNCERTAINTIES, NUMPY_VER, PYTHON3 +from ..compat import HAS_NUMPY, HAS_PROPER_BABEL, HAS_UNCERTAINTIES, NUMPY_VER def requires_numpy18(): @@ -43,14 +40,6 @@ def requires_not_uncertainties(): return unittest.skipIf(HAS_UNCERTAINTIES, 'Requires Uncertainties is not installed.') -def requires_python2(): - return unittest.skipIf(PYTHON3, 'Requires Python 2.X.') - - -def requires_python3(): - return unittest.skipUnless(PYTHON3, 'Requires Python 3.X.') - - _number_re = '([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)' _q_re = re.compile('<Quantity\(' + '\s*' + '(?P<magnitude>%s)' % _number_re + '\s*,\s*' + "'(?P<unit>.*)'" + '\s*' + '\)>') diff --git a/pint/testsuite/parameterized.py b/pint/testsuite/parameterized.py index 7c45915..37575fd 100644 --- a/pint/testsuite/parameterized.py +++ b/pint/testsuite/parameterized.py @@ -121,7 +121,7 @@ class ParameterizedTestCaseMetaClass(type): return new_method @add_metaclass(ParameterizedTestCaseMetaClass) -class ParameterizedTestMixin(object): +class ParameterizedTestMixin: @classmethod def parameterize(cls, param_names, data, func_name_format='{func_name}_{case_num:05d}'): diff --git a/pint/testsuite/test_babel.py b/pint/testsuite/test_babel.py index 0194977..d9f7433 100644 --- a/pint/testsuite/test_babel.py +++ b/pint/testsuite/test_babel.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import from pint.testsuite import helpers, BaseTestCase from pint import UnitRegistry import os + class TestBabel(BaseTestCase): @helpers.requires_proper_babel() diff --git a/pint/testsuite/test_contexts.py b/pint/testsuite/test_contexts.py index 7766aa7..10c5037 100644 --- a/pint/testsuite/test_contexts.py +++ b/pint/testsuite/test_contexts.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - import itertools from collections import defaultdict diff --git a/pint/testsuite/test_converters.py b/pint/testsuite/test_converters.py index 962242e..30a7eaa 100644 --- a/pint/testsuite/test_converters.py +++ b/pint/testsuite/test_converters.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import import itertools @@ -7,6 +6,7 @@ from pint.compat import np from pint.converters import (ScaleConverter, OffsetConverter, Converter) from pint.testsuite import helpers, BaseTestCase + class TestConverter(BaseTestCase): def test_converter(self): diff --git a/pint/testsuite/test_definitions.py b/pint/testsuite/test_definitions.py index 8a66a4e..0181f5a 100644 --- a/pint/testsuite/test_definitions.py +++ b/pint/testsuite/test_definitions.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - from pint.util import (UnitsContainer) from pint.converters import (ScaleConverter, OffsetConverter) from pint.definitions import (Definition, PrefixDefinition, UnitDefinition, @@ -9,6 +7,7 @@ from pint.definitions import (Definition, PrefixDefinition, UnitDefinition, from pint.testsuite import BaseTestCase + class TestDefinition(BaseTestCase): def test_invalid(self): diff --git a/pint/testsuite/test_errors.py b/pint/testsuite/test_errors.py index b6537c1..0158861 100644 --- a/pint/testsuite/test_errors.py +++ b/pint/testsuite/test_errors.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - from pint import DimensionalityError, UndefinedUnitError from pint.testsuite import BaseTestCase diff --git a/pint/testsuite/test_formatter.py b/pint/testsuite/test_formatter.py index 9f2015b..b471a1c 100644 --- a/pint/testsuite/test_formatter.py +++ b/pint/testsuite/test_formatter.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - from pint import formatting as fmt from pint.testsuite import QuantityTestCase @@ -14,7 +12,6 @@ class TestFormatter(QuantityTestCase): self.assertEqual(fmt._join('*', '1 2 3'.split()), '1*2*3') self.assertEqual(fmt._join('{0}*{1}', '1 2 3'.split()), '1*2*3') - def test_formatter(self): self.assertEqual(fmt.formatter(dict().items()), '') self.assertEqual(fmt.formatter(dict(meter=1).items()), 'meter') diff --git a/pint/testsuite/test_issues.py b/pint/testsuite/test_issues.py index eea527b..7cc0f9c 100644 --- a/pint/testsuite/test_issues.py +++ b/pint/testsuite/test_issues.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - -import math import copy +import math import unittest import sys @@ -430,49 +428,17 @@ class TestIssues(QuantityTestCase): self.assertEqual(iq, 10) self.assertIsInstance(iq, int) - @helpers.requires_python2() - def test_issue170b(self): - Q_ = UnitRegistry().Quantity - q = Q_('1 kHz')/Q_('100 Hz') - iq = long(q) - self.assertEqual(iq, long(10)) - self.assertIsInstance(iq, long) - def test_angstrom_creation(self): ureg = UnitRegistry() - try: - # Check if the install supports unicode, travis python27 seems to - # support it... - if (sys.version_info < (3, 0)): - 'Å'.decode('utf-8') - except UnicodeEncodeError: - self.assertRaises(UndefinedUnitError, ureg.Quantity, 2, 'Å') - else: - ureg.Quantity(2, 'Å') + ureg.Quantity(2, 'Å') def test_alternative_angstrom_definition(self): ureg = UnitRegistry() - try: - # Check if the install supports unicode, travis python27 seems to - # support it... - if (sys.version_info < (3, 0)): - 'Å'.decode('utf-8') - except UnicodeEncodeError: - self.assertRaises(UndefinedUnitError, ureg.Quantity, 2, '\u212B') - else: - ureg.Quantity(2, '\u212B') + ureg.Quantity(2, '\u212B') def test_micro_creation(self): ureg = UnitRegistry() - try: - # Check if the install supports unicode, travis python27 seems to - # support it... - if (sys.version_info < (3, 0)): - 'µ'.decode('utf-8') - except UnicodeEncodeError: - self.assertRaises(UndefinedUnitError, ureg.Quantity, 2, 'µm') - else: - ureg.Quantity(2, 'µm') + ureg.Quantity(2, 'µm') @helpers.requires_numpy() def test_issue171_real_imag(self): @@ -537,7 +503,7 @@ class TestIssues(QuantityTestCase): x = ureg.Quantity(1., 'meter') y = f(x) z = x * y - self.assertEquals(z, ureg.Quantity(1., 'meter * kilogram')) + self.assertEqual(z, ureg.Quantity(1., 'meter * kilogram')) @helpers.requires_numpy() def test_issue482(self): diff --git a/pint/testsuite/test_measurement.py b/pint/testsuite/test_measurement.py index eff666a..389cd20 100644 --- a/pint/testsuite/test_measurement.py +++ b/pint/testsuite/test_measurement.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - from pint.testsuite import QuantityTestCase, helpers diff --git a/pint/testsuite/test_numpy.py b/pint/testsuite/test_numpy.py index 996195c..f821315 100644 --- a/pint/testsuite/test_numpy.py +++ b/pint/testsuite/test_numpy.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - import copy import operator as op import unittest diff --git a/pint/testsuite/test_pint_eval.py b/pint/testsuite/test_pint_eval.py index c01975f..1f61310 100644 --- a/pint/testsuite/test_pint_eval.py +++ b/pint/testsuite/test_pint_eval.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import import unittest from pint.compat import tokenizer diff --git a/pint/testsuite/test_pitheorem.py b/pint/testsuite/test_pitheorem.py index 47f3790..ce2026f 100644 --- a/pint/testsuite/test_pitheorem.py +++ b/pint/testsuite/test_pitheorem.py @@ -1,11 +1,8 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - import itertools from pint import pi_theorem - from pint.testsuite import QuantityTestCase diff --git a/pint/testsuite/test_quantity.py b/pint/testsuite/test_quantity.py index e5fc076..e15923d 100644 --- a/pint/testsuite/test_quantity.py +++ b/pint/testsuite/test_quantity.py @@ -1,16 +1,13 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - import copy import datetime import math import operator as op -import warnings from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry from pint.unit import UnitsContainer -from pint.compat import string_types, PYTHON3, np +from pint.compat import np from pint.testsuite import QuantityTestCase, helpers from pint.testsuite.parameterized import ParameterizedTestCase @@ -191,7 +188,7 @@ class TestQuantity(QuantityTestCase): def test_ipython(self): alltext = [] - class Pretty(object): + class Pretty: @staticmethod def text(text): alltext.append(text) @@ -467,22 +464,20 @@ class TestQuantityToCompact(QuantityTestCase): def test_nonnumeric_magnitudes(self): ureg = self.ureg x = "some string"*ureg.m - if PYTHON3: - with self.assertWarns(RuntimeWarning): - self.compareQuantity_compact(x,x) - else: - self.assertRaises(RuntimeError, self.compareQuantity_compact(x,x)) + with self.assertWarns(RuntimeWarning): + self.compareQuantity_compact(x, x) + class TestQuantityBasicMath(QuantityTestCase): FORCE_NDARRAY = False def _test_inplace(self, operator, value1, value2, expected_result, unit=None): - if isinstance(value1, string_types): + if isinstance(value1, str): value1 = self.Q_(value1) - if isinstance(value2, string_types): + if isinstance(value2, str): value2 = self.Q_(value2) - if isinstance(expected_result, string_types): + if isinstance(expected_result, str): expected_result = self.Q_(expected_result) if not unit is None: @@ -502,11 +497,11 @@ class TestQuantityBasicMath(QuantityTestCase): self.assertEqual(id2, id(value2)) def _test_not_inplace(self, operator, value1, value2, expected_result, unit=None): - if isinstance(value1, string_types): + if isinstance(value1, str): value1 = self.Q_(value1) - if isinstance(value2, string_types): + if isinstance(value2, str): value2 = self.Q_(value2) - if isinstance(expected_result, string_types): + if isinstance(expected_result, str): expected_result = self.Q_(expected_result) if not unit is None: @@ -616,9 +611,9 @@ class TestQuantityBasicMath(QuantityTestCase): func(op.ifloordiv, '10*meter', '4.2*inch', 93, unit) def _test_quantity_divmod_one(self, a, b): - if isinstance(a, string_types): + if isinstance(a, str): a = self.Q_(a) - if isinstance(b, string_types): + if isinstance(b, str): b = self.Q_(b) q, r = divmod(a, b) @@ -685,9 +680,8 @@ class TestQuantityBasicMath(QuantityTestCase): x = self.Q_(-4.2, 'meter') y = self.Q_(4.2, 'meter') - # In Python 3+ round of x is delegated to x.__round__, instead of round(x.__float__) - # and therefore it can be properly implemented by Pint - for fun in (abs, op.pos, op.neg) + (round, ) if PYTHON3 else (): + + for fun in (abs, round, op.pos, op.neg): zx = self.Q_(fun(x.magnitude), 'meter') zy = self.Q_(fun(y.magnitude), 'meter') rx = fun(x) diff --git a/pint/testsuite/test_systems.py b/pint/testsuite/test_systems.py index 734bb73..ba5c9e4 100644 --- a/pint/testsuite/test_systems.py +++ b/pint/testsuite/test_systems.py @@ -1,10 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - - from pint import UnitRegistry - from pint.testsuite import QuantityTestCase diff --git a/pint/testsuite/test_umath.py b/pint/testsuite/test_umath.py index 589aaa4..d4fa9c6 100644 --- a/pint/testsuite/test_umath.py +++ b/pint/testsuite/test_umath.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - from pint.compat import np from pint.testsuite import QuantityTestCase, helpers diff --git a/pint/testsuite/test_unit.py b/pint/testsuite/test_unit.py index 9c6bf51..8bbe54c 100644 --- a/pint/testsuite/test_unit.py +++ b/pint/testsuite/test_unit.py @@ -1,16 +1,14 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - import copy import math -from pint.registry import (UnitRegistry, LazyRegistry) -from pint.util import (UnitsContainer, ParserHelper) from pint import DimensionalityError, UndefinedUnitError -from pint.compat import u, np, string_types +from pint.compat import np +from pint.registry import (UnitRegistry, LazyRegistry) from pint.testsuite import QuantityTestCase, helpers from pint.testsuite.parameterized import ParameterizedTestCase +from pint.util import (UnitsContainer, ParserHelper) class TestUnit(QuantityTestCase): @@ -66,7 +64,7 @@ class TestUnit(QuantityTestCase): def test_ipython(self): alltext = [] - class Pretty(object): + class Pretty: @staticmethod def text(text): alltext.append(text) @@ -231,7 +229,7 @@ class TestRegistry(QuantityTestCase): def test_str_errors(self): self.assertEqual(str(UndefinedUnitError('rabbits')), "'{0!s}' is not defined in the unit registry".format('rabbits')) self.assertEqual(str(UndefinedUnitError(('rabbits', 'horses'))), "'{0!s}' are not defined in the unit registry".format(('rabbits', 'horses'))) - self.assertEqual(u(str(DimensionalityError('meter', 'second'))), + self.assertEqual(str(DimensionalityError('meter', 'second')), "Cannot convert from 'meter' to 'second'") self.assertEqual(str(DimensionalityError('meter', 'second', 'length', 'time')), "Cannot convert from 'meter' (length) to 'second' (time)") @@ -638,7 +636,7 @@ class TestConvertWithOffset(QuantityTestCase, ParameterizedTestCase): src, dst = UnitsContainer(src), UnitsContainer(dst) value = 10. convert = self.ureg.convert - if isinstance(expected, string_types): + if isinstance(expected, str): self.assertRaises(DimensionalityError, convert, value, src, dst) if src != dst: self.assertRaises(DimensionalityError, convert, value, dst, src) diff --git a/pint/testsuite/test_util.py b/pint/testsuite/test_util.py index 30d0bf9..b10b047 100644 --- a/pint/testsuite/test_util.py +++ b/pint/testsuite/test_util.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division, unicode_literals, print_function, absolute_import - import collections import copy import operator as op diff --git a/pint/unit.py b/pint/unit.py index 24c9e0b..5d194a5 100644 --- a/pint/unit.py +++ b/pint/unit.py @@ -9,8 +9,6 @@ :license: BSD, see LICENSE for more details. """ -from __future__ import division, unicode_literals, print_function, absolute_import - import copy import operator from numbers import Number @@ -18,7 +16,7 @@ from numbers import Number from .util import ( PrettyIPython, UnitsContainer, SharedRegistryObject, fix_str_conversions) -from .compat import string_types, NUMERIC_TYPES, long_type +from .compat import NUMERIC_TYPES from .formatting import siunitx_format_unit from .definitions import UnitDefinition @@ -44,7 +42,7 @@ class Unit(PrettyIPython, SharedRegistryObject): super(Unit, self).__init__() if isinstance(units, (UnitsContainer, UnitDefinition)): self._units = units - elif isinstance(units, string_types): + elif isinstance(units, str): self._units = self._REGISTRY.parse_units(units)._units elif isinstance(units, Unit): self._units = units._units @@ -224,9 +222,6 @@ class Unit(PrettyIPython, SharedRegistryObject): 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)) diff --git a/pint/util.py b/pint/util.py index e447264..ec3170d 100644 --- a/pint/util.py +++ b/pint/util.py @@ -9,29 +9,22 @@ :license: BSD, see LICENSE for more details. """ -from __future__ import division, unicode_literals, print_function, absolute_import - -from decimal import Decimal import locale +import logging +from logging import NullHandler import sys import re import operator +from collections.abc import Mapping +from decimal import Decimal from numbers import Number from fractions import Fraction +from functools import lru_cache -try: - from collections.abc import Mapping -except ImportError: - from collections import Mapping - -from logging import NullHandler +from token import NAME, NUMBER -import logging -from token import STRING, NAME, OP, NUMBER -from tokenize import untokenize - -from .compat import string_types, tokenizer, lru_cache, maketrans, NUMERIC_TYPES -from .formatting import format_unit,siunitx_format_unit +from .compat import tokenizer, NUMERIC_TYPES +from .formatting import format_unit from .pint_eval import build_eval_tree from .errors import DefinitionSyntaxError @@ -144,7 +137,7 @@ def pi_theorem(quantities, registry=None): getdim = registry.get_dimensionality for name, value in quantities.items(): - if isinstance(value, string_types): + if isinstance(value, str): value = ParserHelper.from_string(value) if isinstance(value, dict): dims = getdim(UnitsContainer(value)) @@ -194,15 +187,18 @@ def solve_dependencies(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()) + t = {i for v in d.values() for i in v} - 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 if not t: - raise ValueError('Cyclic dependencies exist among these items: {}'.format(', '.join(repr(x) for x in d.items()))) + raise ValueError( + 'Cyclic dependencies exist among these items: {}' + .format(', '.join(repr(x) for x in d.items())) + ) r.append(t) # and cleaned up - d = dict(((k, v - t) for k, v in d.items() if v)) + d = {k: v - t for k, v in d.items() if v} return r @@ -261,7 +257,7 @@ class UnitsContainer(Mapping): d = udict(*args, **kwargs) self._d = d for key, value in d.items(): - if not isinstance(key, string_types): + if not isinstance(key, str): raise TypeError('key must be a str, not {}'.format(type(key))) if not isinstance(value, Number): raise TypeError('value must be a number, not {}'.format(type(value))) @@ -318,10 +314,6 @@ class UnitsContainer(Mapping): self._hash = hash(frozenset(self._d.items())) return self._hash - # Only needed by Python 2.7 - def __getstate__(self): - return self._d, self._hash - def __setstate__(self, state): self._d, self._hash = state @@ -336,7 +328,7 @@ class UnitsContainer(Mapping): return False other = other._d - elif isinstance(other, string_types): + elif isinstance(other, str): other = ParserHelper.from_string(other) other = other._d @@ -485,9 +477,13 @@ class ParserHelper(UnitsContainer): if not reps: return ret - return ParserHelper(ret.scale, - dict((key.replace('__obra__', '[').replace('__cbra__', ']'), value) - for key, value in ret.items())) + return ParserHelper( + ret.scale, + { + key.replace('__obra__', '[').replace('__cbra__', ']'): value + for key, value in ret.items() + } + ) def __copy__(self): new = super(ParserHelper, self).__copy__() @@ -503,10 +499,6 @@ class ParserHelper(UnitsContainer): raise ValueError(mess) return super(ParserHelper, self).__hash__() - # Only needed by Python 2.7 - def __getstate__(self): - return self._d, self._hash, self.scale - def __setstate__(self, state): self._d, self._hash, self.scale = state @@ -516,7 +508,7 @@ class ParserHelper(UnitsContainer): self.scale == other.scale and super(ParserHelper, self).__eq__(other) ) - elif isinstance(other, string_types): + elif isinstance(other, str): return self == ParserHelper.from_string(other) elif isinstance(other, Number): return self.scale == other and not len(self._d) @@ -546,7 +538,7 @@ class ParserHelper(UnitsContainer): return '<ParserHelper({}, {})>'.format(self.scale, tmp) def __mul__(self, other): - if isinstance(other, string_types): + if isinstance(other, str): new = self.add(other, 1) elif isinstance(other, Number): new = self.copy() @@ -567,7 +559,7 @@ class ParserHelper(UnitsContainer): return self.__class__(self.scale**other, d) def __truediv__(self, other): - if isinstance(other, string_types): + if isinstance(other, str): new = self.add(other, -1) elif isinstance(other, Number): new = self.copy() @@ -583,7 +575,7 @@ class ParserHelper(UnitsContainer): def __rtruediv__(self, other): new = self.__pow__(-1) - if isinstance(other, string_types): + if isinstance(other, str): new = new.add(other, 1) elif isinstance(other, Number): new.scale *= other @@ -609,7 +601,7 @@ _subs_re = [('\N{DEGREE SIGN}', " degree"), #: Compiles the regex and replace {} 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_table = str.maketrans('⁰¹²³⁴⁵⁶⁷⁸⁹·⁻', '0123456789*-') _pretty_exp_re = re.compile(r"⁻?[⁰¹²³⁴⁵⁶⁷⁸⁹]+(?:\.[⁰¹²³⁴⁵⁶⁷⁸⁹]*)?") @@ -636,7 +628,7 @@ def _is_dim(name): return name[0] == '[' and name[-1] == ']' -class SharedRegistryObject(object): +class SharedRegistryObject: """Base class for object keeping a reference to the registree. Such object are for now Quantity and Unit, in a number of places it is @@ -673,7 +665,7 @@ class SharedRegistryObject(object): return False -class PrettyIPython(object): +class PrettyIPython: """Mixin to add pretty-printers for IPython""" def _repr_html_(self): @@ -704,7 +696,7 @@ def to_units_container(unit_like, registry=None): return unit_like elif SharedRegistryObject in mro: return unit_like._units - elif string_types in mro: + elif str in mro: if registry: return registry._parse_units(unit_like) else: @@ -722,7 +714,9 @@ def infer_base_unit(q): _, base_unit, __ = completely_parsed_unit d[base_unit] += power - return UnitsContainer(dict((k, v) for k, v in d.items() if v != 0)) # remove values that resulted in a power of 0 + + # remove values that resulted in a power of 0 + return UnitsContainer({k: v for k, v in d.items() if v != 0}) def fix_str_conversions(cls): @@ -748,7 +742,7 @@ def getattr_maybe_raise(self, item): raise AttributeError("%r object has no attribute %r" % (self, item)) -class SourceIterator(object): +class SourceIterator: """Iterator to facilitate reading the definition files. Accepts any sequence (like a list of lines, a file or another SourceIterator) |