Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[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
Justin Bronn authored December 17, 2009
50  django/contrib/gis/measure.py
@@ -27,7 +27,7 @@
27 27
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
 #
29 29
 """
30  
-Distance and Area objects to allow for sensible and convienient calculation 
  30
+Distance and Area objects to allow for sensible and convienient calculation
31 31
 and conversions.
32 32
 
33 33
 Authors: Robert Coup, Justin Bronn
@@ -70,7 +70,7 @@ def default_units(self, kwargs):
70 70
     @classmethod
71 71
     def unit_attname(cls, unit_str):
72 72
         """
73  
-        Retrieves the unit attribute name for the given unit string.  
  73
+        Retrieves the unit attribute name for the given unit string.
74 74
         For example, if the given unit string is 'metre', 'm' would be returned.
75 75
         An exception is raised if an attribute cannot be found.
76 76
         """
@@ -165,51 +165,51 @@ def __init__(self, default_unit=None, **kwargs):
165 165
         self.m, self._default_unit = self.default_units(kwargs)
166 166
         if default_unit and isinstance(default_unit, str):
167 167
             self._default_unit = default_unit
168  
-    
  168
+
169 169
     def __getattr__(self, name):
170 170
         if name in self.UNITS:
171 171
             return self.m / self.UNITS[name]
172 172
         else:
173 173
             raise AttributeError('Unknown unit type: %s' % name)
174  
-    
  174
+
175 175
     def __repr__(self):
176 176
         return 'Distance(%s=%s)' % (self._default_unit, getattr(self, self._default_unit))
177 177
 
178 178
     def __str__(self):
179 179
         return '%s %s' % (getattr(self, self._default_unit), self._default_unit)
180  
-        
  180
+
181 181
     def __cmp__(self, other):
182 182
         if isinstance(other, Distance):
183 183
             return cmp(self.m, other.m)
184 184
         else:
185 185
             return NotImplemented
186  
-        
  186
+
187 187
     def __add__(self, other):
188 188
         if isinstance(other, Distance):
189 189
             return Distance(default_unit=self._default_unit, m=(self.m + other.m))
190 190
         else:
191 191
             raise TypeError('Distance must be added with Distance')
192  
-    
  192
+
193 193
     def __iadd__(self, other):
194 194
         if isinstance(other, Distance):
195 195
             self.m += other.m
196 196
             return self
197 197
         else:
198 198
             raise TypeError('Distance must be added with Distance')
199  
-    
  199
+
200 200
     def __sub__(self, other):
201 201
         if isinstance(other, Distance):
202 202
             return Distance(default_unit=self._default_unit, m=(self.m - other.m))
203 203
         else:
204 204
             raise TypeError('Distance must be subtracted from Distance')
205  
-    
  205
+
206 206
     def __isub__(self, other):
207 207
         if isinstance(other, Distance):
208 208
             self.m -= other.m
209 209
             return self
210 210
         else:
211 211
             raise TypeError('Distance must be subtracted from Distance')
212  
-    
  212
+
213 213
     def __mul__(self, other):
214 214
         if isinstance(other, (int, float, long, Decimal)):
215 215
             return Distance(default_unit=self._default_unit, m=(self.m * float(other)))
@@ -217,14 +217,17 @@ def __mul__(self, other):
217 217
             return Area(default_unit='sq_' + self._default_unit, sq_m=(self.m * other.m))
218 218
         else:
219 219
             raise TypeError('Distance must be multiplied with number or Distance')
220  
-    
  220
+
221 221
     def __imul__(self, other):
222 222
         if isinstance(other, (int, float, long, Decimal)):
223 223
             self.m *= float(other)
224 224
             return self
225 225
         else:
226 226
             raise TypeError('Distance must be multiplied with number')
227  
-    
  227
+
  228
+    def __rmul__(self, other):
  229
+        return self * other
  230
+
228 231
     def __div__(self, other):
229 232
         if isinstance(other, (int, float, long, Decimal)):
230 233
             return Distance(default_unit=self._default_unit, m=(self.m / float(other)))
@@ -251,13 +254,13 @@ def __init__(self, default_unit=None, **kwargs):
251 254
         self.sq_m, self._default_unit = self.default_units(kwargs)
252 255
         if default_unit and isinstance(default_unit, str):
253 256
             self._default_unit = default_unit
254  
-    
  257
+
255 258
     def __getattr__(self, name):
256 259
         if name in self.UNITS:
257 260
             return self.sq_m / self.UNITS[name]
258 261
         else:
259 262
             raise AttributeError('Unknown unit type: ' + name)
260  
-    
  263
+
261 264
     def __repr__(self):
262 265
         return 'Area(%s=%s)' % (self._default_unit, getattr(self, self._default_unit))
263 266
 
@@ -269,46 +272,49 @@ def __cmp__(self, other):
269 272
             return cmp(self.sq_m, other.sq_m)
270 273
         else:
271 274
             return NotImplemented
272  
-        
  275
+
273 276
     def __add__(self, other):
274 277
         if isinstance(other, Area):
275 278
             return Area(default_unit=self._default_unit, sq_m=(self.sq_m + other.sq_m))
276 279
         else:
277 280
             raise TypeError('Area must be added with Area')
278  
-    
  281
+
279 282
     def __iadd__(self, other):
280 283
         if isinstance(other, Area):
281 284
             self.sq_m += other.sq_m
282 285
             return self
283 286
         else:
284 287
             raise TypeError('Area must be added with Area')
285  
-    
  288
+
286 289
     def __sub__(self, other):
287 290
         if isinstance(other, Area):
288 291
             return Area(default_unit=self._default_unit, sq_m=(self.sq_m - other.sq_m))
289 292
         else:
290 293
             raise TypeError('Area must be subtracted from Area')
291  
-    
  294
+
292 295
     def __isub__(self, other):
293 296
         if isinstance(other, Area):
294 297
             self.sq_m -= other.sq_m
295 298
             return self
296 299
         else:
297 300
             raise TypeError('Area must be subtracted from Area')
298  
-    
  301
+
299 302
     def __mul__(self, other):
300 303
         if isinstance(other, (int, float, long, Decimal)):
301 304
             return Area(default_unit=self._default_unit, sq_m=(self.sq_m * float(other)))
302 305
         else:
303 306
             raise TypeError('Area must be multiplied with number')
304  
-    
  307
+
305 308
     def __imul__(self, other):
306 309
         if isinstance(other, (int, float, long, Decimal)):
307 310
             self.sq_m *= float(other)
308 311
             return self
309 312
         else:
310 313
             raise TypeError('Area must be multiplied with number')
311  
-    
  314
+
  315
+    def __rmul__(self, other):
  316
+        return self * other
  317
+
312 318
     def __div__(self, other):
313 319
         if isinstance(other, (int, float, long, Decimal)):
314 320
             return Area(default_unit=self._default_unit, sq_m=(self.sq_m / float(other)))
@@ -324,7 +330,7 @@ def __idiv__(self, other):
324 330
 
325 331
     def __nonzero__(self):
326 332
         return bool(self.sq_m)
327  
-        
  333
+
328 334
 # Shortcuts
329 335
 D = Distance
330 336
 A = Area
5  django/contrib/gis/tests/test_measure.py
@@ -95,6 +95,8 @@ def testMultiplication(self):
95 95
 
96 96
         d3 = d1 * 2
97 97
         self.assertEqual(d3.m, 200)
  98
+        d3 = 2 * d1
  99
+        self.assertEqual(d3.m, 200)
98 100
         d3 *= 5
99 101
         self.assertEqual(d3.m, 1000)
100 102
         
@@ -248,6 +250,8 @@ def testMultiplication(self):
248 250
 
249 251
         a3 = a1 * 2
250 252
         self.assertEqual(a3.sq_m, 200)
  253
+        a3 = 2 * a1
  254
+        self.assertEqual(a3.sq_m, 200)
251 255
         a3 *= 5
252 256
         self.assertEqual(a3.sq_m, 1000)
253 257
         
@@ -319,7 +323,6 @@ def testUnitsStr(self):
319 323
         self.assertEqual(repr(a1), 'Area(sq_m=100.0)')
320 324
         self.assertEqual(repr(a2), 'Area(sq_km=3.5)')
321 325
 
322  
-        
323 326
 def suite():
324 327
     s = unittest.TestSuite()
325 328
     s.addTest(unittest.makeSuite(DistanceTest))

0 notes on commit de2c7d9

Please sign in to comment.
Something went wrong with that request. Please try again.