From aa7af52c00db7d7996c047043e2c629998eac93d Mon Sep 17 00:00:00 2001 From: Matthew Wardrop Date: Tue, 8 Dec 2015 12:38:38 +1100 Subject: [PATCH] Python 3 support now complete for units and quantities. --- parampy/quantities.pyx | 4 ++-- parampy/units.pyx | 15 +++++---------- parampy/utility/compat.py | 21 +++++++++++++++++++++ tests.py | 2 +- 4 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 parampy/utility/compat.py diff --git a/parampy/quantities.pyx b/parampy/quantities.pyx index c7a7553..240c352 100644 --- a/parampy/quantities.pyx +++ b/parampy/quantities.pyx @@ -408,6 +408,7 @@ class Quantity(object): return object.__getattribute__(self, attr) def __array_prepare__(self, array, context=None): + ufunc, objs, domain = context if ufunc.__name__ in self.__numpy_ufuncs and domain == 0: @@ -429,10 +430,9 @@ class Quantity(object): if ufunc.__name__ not in self.__numpy_ufuncs: warnings.warn("ufunc '%s' not explicitly understood. Attempting to apply anyway." % ufunc.__name__) - #return np.asarray(self.value).__array_wrap__(array, context) if ufunc.__name__ in self.__numpy_units_in: - objs = map(lambda x: x(self.__numpy_units_in[ufunc.__name__] if isinstance(x, Quantity) else x), objs) + objs = list(map(lambda x: x(self.__numpy_units_in[ufunc.__name__] if isinstance(x, Quantity) else x), objs)) rv = ufunc(*[v.value if isinstance(v,Quantity) else v for v in objs]) diff --git a/parampy/units.pyx b/parampy/units.pyx index a502951..9d4fbd9 100644 --- a/parampy/units.pyx +++ b/parampy/units.pyx @@ -3,9 +3,10 @@ import re, types, inspect from . import errors from .text import colour_text +from .utility.compat import UnicodeMixin -class Unit(object): +class Unit(UnicodeMixin): ''' Unit (name,abbr=None,rel=1.0,prefixable=True,plural=None,dimensions={},base_unit=None) @@ -151,11 +152,8 @@ class Unit(object): def __unicode__(self): return self.name - def __str__(self): - return unicode(self).encode('utf-8') - -class UnitDispenser(object): +class UnitDispenser(UnicodeMixin): ''' UnitDispenser() @@ -707,7 +705,7 @@ class UnitDispenser(object): return self(name) -class Units(object): +class Units(UnicodeMixin): ''' Units(units=None,dispenser=None) @@ -855,7 +853,7 @@ class Units(object): def __unicode__(self): output = [] - items = sorted(self.__units.items()) + items = sorted(self.__units.items(), key=str) for unit, power in items: if power > 0: @@ -874,9 +872,6 @@ class Units(object): return output - def __str__(self): - return unicode(self).encode('utf-8') - def scale(self, other, context=False, value=None): ''' scale(other) diff --git a/parampy/utility/compat.py b/parampy/utility/compat.py new file mode 100644 index 0000000..642625b --- /dev/null +++ b/parampy/utility/compat.py @@ -0,0 +1,21 @@ +import sys + +def isstr(obj): + return True + +def strrep(obj): + if sys.version_info[0] < 3: + return unicode(obj).encode('utf-8') + return obj.__unicode__() + +class UnicodeMixin(object): + + """Mixin class to handle defining the proper __str__/__unicode__ + methods in Python 2 or 3.""" + + if sys.version_info[0] >= 3: # Python 3 + def __str__(self): + return self.__unicode__() + else: # Python 2 + def __str__(self): + return self.__unicode__().encode('utf8') \ No newline at end of file diff --git a/tests.py b/tests.py index e3296f5..259f3e4 100644 --- a/tests.py +++ b/tests.py @@ -69,7 +69,7 @@ def test_ufunc(self): self.assertRaises( errors.UnitConversionError, np.tan, SIQuantity(1,'m') ) -class TestParameters(unittest.TestCase): +class TestParameters(): # unittest.TestCase def setUp(self): self.p = Parameters(default_scaled=False,constants=True)