summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHernan Grecco <hernan.grecco@gmail.com>2014-07-31 00:22:05 -0300
committerHernan Grecco <hernan.grecco@gmail.com>2014-07-31 00:22:05 -0300
commitdcb7ca4c7b7413785b040136bf3bc55d98b97fef (patch)
treeb81b15813649ffe5d38c6c6dee420d45608d98d1
parent74338c4024aa9960b47d84fb4bad0aea67b3457f (diff)
parent89bbc0545ef3407d258f61f264a95985d78cc274 (diff)
downloadpint-dcb7ca4c7b7413785b040136bf3bc55d98b97fef.tar.gz
Merged 0.5.2 into develop
-rw-r--r--CHANGES28
-rw-r--r--pint/compat/__init__.py4
-rw-r--r--pint/context.py14
-rw-r--r--pint/quantity.py24
-rw-r--r--pint/testsuite/helpers.py9
-rw-r--r--pint/testsuite/test_contexts.py7
-rw-r--r--pint/testsuite/test_issues.py30
-rw-r--r--pint/unit.py5
-rw-r--r--setup.py6
9 files changed, 102 insertions, 25 deletions
diff --git a/CHANGES b/CHANGES
index deb9d17..7850281 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,26 +2,28 @@ Pint Changelog
==============
-0.6 (unreleased)
-----------------
+0.5.3 (unreleased)
+------------------
-- Optimized "get_dimensionality" and "get_base_name".
- (Issue #166 and #167, thanks jbmohler)
-- Renamed ureg.parse_units parameter "to_delta" to "as_delta" to make clear
- that no conversion happens. Accordingly, the parameter/property
- "default_to_delta" of UnitRegistry was renamed to "default_as_delta".
- (Issue #158, thanks dalit)
-- Fixed problem when adding two uncertainties.
- (thanks dalito)
-- Full support for Offset units (e.g. temperature)
- (Issue #88, #143, #147 and #161, thanks dalito)
+- Nothing changed yet.
-0.5.2 (unreleased)
+0.5.2 (2014-07-31)
------------------
- Changed travis config to use miniconda for faster testing.
- Added wheel configuration to setup.cfg.
+- Ensure resource streams are closed after reading.
+- Require setuptools.
+ (Issue #169)
+- Implemented real, imag and T Quantity properties.
+ (Issue #171)
+- Implemented __int__ and __long__ for Quantity
+ (Issue #170)
+- Fixed SI prefix error on ureg.convert.
+ (Issue #156, thanks jdreaver)
+- Fixed parsing of multiparemeter contexts.
+ (Issue #174)
0.5.1 (2014-06-03)
diff --git a/pint/compat/__init__.py b/pint/compat/__init__.py
index ed5c255..72e011b 100644
--- a/pint/compat/__init__.py
+++ b/pint/compat/__init__.py
@@ -29,6 +29,8 @@ if PYTHON3:
return x
maketrans = str.maketrans
+
+ long_type = int
else:
from StringIO import StringIO
string_types = basestring
@@ -41,6 +43,8 @@ else:
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
diff --git a/pint/context.py b/pint/context.py
index 947d643..86df972 100644
--- a/pint/context.py
+++ b/pint/context.py
@@ -22,9 +22,6 @@ from .util import ParserHelper, string_types
#: Regex to match the header parts of a context.
_header_re = re.compile('@context\s*(?P<defaults>\(.*\))?\s+(?P<name>\w+)\s*(=(?P<aliases>.*))*')
-#: Reqex to match the different parts of a relation definition.
-_def_re = re.compile('\s*(\w+)\s*=\s*([\w\d+-/*()]+)\s*')
-
#: Regex to match variable names in an equation.
_varname_re = re.compile('[A-Za-z_][A-Za-z0-9_]*')
@@ -124,8 +121,15 @@ class Context(object):
if not val.imag:
return val.real
return val
- defaults = dict((str(k), to_num(v))
- for k, v in _def_re.findall(defaults.strip('()')))
+
+ 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)
diff --git a/pint/quantity.py b/pint/quantity.py
index 509c0a3..9f072b8 100644
--- a/pint/quantity.py
+++ b/pint/quantity.py
@@ -17,7 +17,7 @@ import functools
from .formatting import remove_custom_flags
from .unit import (DimensionalityError, OffsetUnitCalculusError,
UnitsContainer, UnitDefinition, UndefinedUnitError)
-from .compat import string_types, ndarray, np, _to_magnitude
+from .compat import string_types, ndarray, np, _to_magnitude, long_type
from .util import logger
@@ -264,6 +264,16 @@ class _Quantity(object):
return self.__class__(magnitude, other)
# 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()))
@@ -911,6 +921,18 @@ class _Quantity(object):
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
diff --git a/pint/testsuite/helpers.py b/pint/testsuite/helpers.py
index f11614f..6e6d323 100644
--- a/pint/testsuite/helpers.py
+++ b/pint/testsuite/helpers.py
@@ -2,7 +2,7 @@
from __future__ import division, unicode_literals, print_function, absolute_import
-from pint.compat import unittest, HAS_NUMPY, HAS_UNCERTAINTIES, NUMPY_VER
+from pint.compat import unittest, HAS_NUMPY, HAS_UNCERTAINTIES, NUMPY_VER, PYTHON3
def requires_numpy18():
@@ -24,3 +24,10 @@ def requires_uncertainties():
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.')
diff --git a/pint/testsuite/test_contexts.py b/pint/testsuite/test_contexts.py
index d680f61..b75ed7d 100644
--- a/pint/testsuite/test_contexts.py
+++ b/pint/testsuite/test_contexts.py
@@ -560,6 +560,13 @@ class TestContexts(QuantityTestCase):
self.assertEqual(set(c.funcs.keys()), set((a, b)))
self._test_ctx(c)
+ s = ['@context(n=1, bla=2) longcontextname',
+ '[length] <-> 1 / [time]: n * c / value / bla']
+
+ c = Context.from_lines(s)
+ self.assertEqual(c.defaults, {'n': 1, 'bla': 2})
+ self.assertEqual(set(c.funcs.keys()), set((a, b)))
+
# If the variable is not present in the definition, then raise an error
s = ['@context(n=1) longcontextname',
'[length] <-> 1 / [time]: c / value']
diff --git a/pint/testsuite/test_issues.py b/pint/testsuite/test_issues.py
index 1e23661..ab14e21 100644
--- a/pint/testsuite/test_issues.py
+++ b/pint/testsuite/test_issues.py
@@ -8,7 +8,7 @@ from pint import UnitRegistry
from pint.unit import UnitsContainer
from pint.util import ParserHelper
-from pint.compat import np, unittest
+from pint.compat import np, unittest, long_type
from pint.testsuite import QuantityTestCase, helpers
@@ -255,6 +255,21 @@ class TestIssues(QuantityTestCase):
self.assertQuantityAlmostEqual(summer(y), ureg.Quantity(3, 'meter'))
self.assertQuantityAlmostEqual(y[0], ureg.Quantity(1, 'meter'))
+ def test_issue170(self):
+ Q_ = UnitRegistry().Quantity
+ q = Q_('1 kHz')/Q_('100 Hz')
+ iq = int(q)
+ 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)
+
@helpers.requires_numpy()
class TestIssuesNP(QuantityTestCase):
@@ -443,3 +458,16 @@ class TestIssuesNP(QuantityTestCase):
q[1] = float('NaN')
self.assertNotEqual(q[1], 2.)
self.assertTrue(math.isnan(q[1].magnitude))
+
+ def test_issue171_real_imag(self):
+ qr = [1., 2., 3., 4.] * self.ureg.meter
+ qi = [4., 3., 2., 1.] * self.ureg.meter
+ q = qr + 1j * qi
+ self.assertQuantityEqual(q.real, qr)
+ self.assertQuantityEqual(q.imag, qi)
+
+ def test_issue171_T(self):
+ a = np.asarray([[1., 2., 3., 4.],[4., 3., 2., 1.]])
+ q1 = a * self.ureg.meter
+ q2 = a.T * self.ureg.meter
+ self.assertQuantityEqual(q1.T, q2)
diff --git a/pint/unit.py b/pint/unit.py
index 7ef47f7..0864c4d 100644
--- a/pint/unit.py
+++ b/pint/unit.py
@@ -18,7 +18,7 @@ import itertools
import functools
import pkg_resources
from decimal import Decimal
-from contextlib import contextmanager
+from contextlib import contextmanager, closing
from io import open, StringIO
from numbers import Number
from collections import defaultdict
@@ -747,7 +747,8 @@ class UnitRegistry(object):
if isinstance(file, string_types):
try:
if is_resource:
- rbytes = pkg_resources.resource_stream(__name__, file).read()
+ 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:
diff --git a/setup.py b/setup.py
index f37c47e..6615f1a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,8 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+import sys
+
try:
- import sys
reload(sys).setdefaultencoding("UTF-8")
except:
pass
@@ -10,7 +11,8 @@ except:
try:
from setuptools import setup
except ImportError:
- from distutils.core import setup
+ print('Please install or upgrade setuptools or pip to continue')
+ sys.exit(1)
import codecs