Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[1.1.X] Fixed #12390 -- `Distance` and `Area` objects now support mul…

…tiplication when they are the right-hand side.

Backport of r11898 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@11899 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit de2c7d9fddc17e7eae36fe1bc11b8a64e2aca081 1 parent de64970
@jbronn jbronn authored
View
50 django/contrib/gis/measure.py
@@ -27,7 +27,7 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""
-Distance and Area objects to allow for sensible and convienient calculation
+Distance and Area objects to allow for sensible and convienient calculation
and conversions.
Authors: Robert Coup, Justin Bronn
@@ -70,7 +70,7 @@ def default_units(self, kwargs):
@classmethod
def unit_attname(cls, unit_str):
"""
- Retrieves the unit attribute name for the given unit string.
+ Retrieves the unit attribute name for the given unit string.
For example, if the given unit string is 'metre', 'm' would be returned.
An exception is raised if an attribute cannot be found.
"""
@@ -165,51 +165,51 @@ def __init__(self, default_unit=None, **kwargs):
self.m, self._default_unit = self.default_units(kwargs)
if default_unit and isinstance(default_unit, str):
self._default_unit = default_unit
-
+
def __getattr__(self, name):
if name in self.UNITS:
return self.m / self.UNITS[name]
else:
raise AttributeError('Unknown unit type: %s' % name)
-
+
def __repr__(self):
return 'Distance(%s=%s)' % (self._default_unit, getattr(self, self._default_unit))
def __str__(self):
return '%s %s' % (getattr(self, self._default_unit), self._default_unit)
-
+
def __cmp__(self, other):
if isinstance(other, Distance):
return cmp(self.m, other.m)
else:
return NotImplemented
-
+
def __add__(self, other):
if isinstance(other, Distance):
return Distance(default_unit=self._default_unit, m=(self.m + other.m))
else:
raise TypeError('Distance must be added with Distance')
-
+
def __iadd__(self, other):
if isinstance(other, Distance):
self.m += other.m
return self
else:
raise TypeError('Distance must be added with Distance')
-
+
def __sub__(self, other):
if isinstance(other, Distance):
return Distance(default_unit=self._default_unit, m=(self.m - other.m))
else:
raise TypeError('Distance must be subtracted from Distance')
-
+
def __isub__(self, other):
if isinstance(other, Distance):
self.m -= other.m
return self
else:
raise TypeError('Distance must be subtracted from Distance')
-
+
def __mul__(self, other):
if isinstance(other, (int, float, long, Decimal)):
return Distance(default_unit=self._default_unit, m=(self.m * float(other)))
@@ -217,14 +217,17 @@ def __mul__(self, other):
return Area(default_unit='sq_' + self._default_unit, sq_m=(self.m * other.m))
else:
raise TypeError('Distance must be multiplied with number or Distance')
-
+
def __imul__(self, other):
if isinstance(other, (int, float, long, Decimal)):
self.m *= float(other)
return self
else:
raise TypeError('Distance must be multiplied with number')
-
+
+ def __rmul__(self, other):
+ return self * other
+
def __div__(self, other):
if isinstance(other, (int, float, long, Decimal)):
return Distance(default_unit=self._default_unit, m=(self.m / float(other)))
@@ -251,13 +254,13 @@ def __init__(self, default_unit=None, **kwargs):
self.sq_m, self._default_unit = self.default_units(kwargs)
if default_unit and isinstance(default_unit, str):
self._default_unit = default_unit
-
+
def __getattr__(self, name):
if name in self.UNITS:
return self.sq_m / self.UNITS[name]
else:
raise AttributeError('Unknown unit type: ' + name)
-
+
def __repr__(self):
return 'Area(%s=%s)' % (self._default_unit, getattr(self, self._default_unit))
@@ -269,46 +272,49 @@ def __cmp__(self, other):
return cmp(self.sq_m, other.sq_m)
else:
return NotImplemented
-
+
def __add__(self, other):
if isinstance(other, Area):
return Area(default_unit=self._default_unit, sq_m=(self.sq_m + other.sq_m))
else:
raise TypeError('Area must be added with Area')
-
+
def __iadd__(self, other):
if isinstance(other, Area):
self.sq_m += other.sq_m
return self
else:
raise TypeError('Area must be added with Area')
-
+
def __sub__(self, other):
if isinstance(other, Area):
return Area(default_unit=self._default_unit, sq_m=(self.sq_m - other.sq_m))
else:
raise TypeError('Area must be subtracted from Area')
-
+
def __isub__(self, other):
if isinstance(other, Area):
self.sq_m -= other.sq_m
return self
else:
raise TypeError('Area must be subtracted from Area')
-
+
def __mul__(self, other):
if isinstance(other, (int, float, long, Decimal)):
return Area(default_unit=self._default_unit, sq_m=(self.sq_m * float(other)))
else:
raise TypeError('Area must be multiplied with number')
-
+
def __imul__(self, other):
if isinstance(other, (int, float, long, Decimal)):
self.sq_m *= float(other)
return self
else:
raise TypeError('Area must be multiplied with number')
-
+
+ def __rmul__(self, other):
+ return self * other
+
def __div__(self, other):
if isinstance(other, (int, float, long, Decimal)):
return Area(default_unit=self._default_unit, sq_m=(self.sq_m / float(other)))
@@ -324,7 +330,7 @@ def __idiv__(self, other):
def __nonzero__(self):
return bool(self.sq_m)
-
+
# Shortcuts
D = Distance
A = Area
View
5 django/contrib/gis/tests/test_measure.py
@@ -95,6 +95,8 @@ def testMultiplication(self):
d3 = d1 * 2
self.assertEqual(d3.m, 200)
+ d3 = 2 * d1
+ self.assertEqual(d3.m, 200)
d3 *= 5
self.assertEqual(d3.m, 1000)
@@ -248,6 +250,8 @@ def testMultiplication(self):
a3 = a1 * 2
self.assertEqual(a3.sq_m, 200)
+ a3 = 2 * a1
+ self.assertEqual(a3.sq_m, 200)
a3 *= 5
self.assertEqual(a3.sq_m, 1000)
@@ -319,7 +323,6 @@ def testUnitsStr(self):
self.assertEqual(repr(a1), 'Area(sq_m=100.0)')
self.assertEqual(repr(a2), 'Area(sq_km=3.5)')
-
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(DistanceTest))
Please sign in to comment.
Something went wrong with that request. Please try again.