Changeset 9369
- Timestamp:
- 11/07/08 19:44:46 (2 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/template/defaultfilters.py
r9291 r9369 2 2 3 3 import re 4 5 try: 6 from decimal import Decimal, InvalidOperation, ROUND_HALF_UP 7 except ImportError: 8 from django.utils._decimal import Decimal, InvalidOperation, ROUND_HALF_UP 9 4 10 import random as random_module 5 11 try: … … 45 51 # STRINGS # 46 52 ################### 47 48 53 49 54 def addslashes(value): … … 93 98 fix_ampersands = stringfilter(fix_ampersands) 94 99 100 # Values for testing floatformat input against infinity and NaN representations, 101 # which differ across platforms and Python versions. Some (i.e. old Windows 102 # ones) are not recognized by Decimal but we want to return them unchanged vs. 103 # returning an empty string as we do for completley invalid input. Note these 104 # need to be built up from values that are not inf/nan, since inf/nan values do 105 # not reload properly from .pyc files on Windows prior to some level of Python 2.5 106 # (see Python Issue757815 and Issue1080440). 107 pos_inf = 1e200 * 1e200 108 neg_inf = -1e200 * 1e200 109 nan = (1e200 * 1e200) / (1e200 * 1e200) 110 special_floats = [str(pos_inf), str(neg_inf), str(nan)] 111 95 112 def floatformat(text, arg=-1): 96 113 """ … … 120 137 * {{ num2|floatformat:"-3" }} displays "34" 121 138 * {{ num3|floatformat:"-3" }} displays "34.260" 122 """ 123 try: 124 f = float(text) 125 except (ValueError, TypeError): 126 return u'' 127 try: 128 d = int(arg) 139 140 If the input float is infinity or NaN, the (platform-dependent) string 141 representation of that value will be displayed. 142 """ 143 144 try: 145 input_val = force_unicode(text) 146 d = Decimal(input_val) 147 except UnicodeEncodeError: 148 return u'' 149 except InvalidOperation: 150 if input_val in special_floats: 151 return input_val 152 else: 153 return u'' 154 try: 155 p = int(arg) 129 156 except ValueError: 130 return force_unicode(f) 131 try: 132 m = f - int(f) 133 except OverflowError: 134 return force_unicode(f) 135 if not m and d < 0: 136 return mark_safe(u'%d' % int(f)) 157 return input_val 158 159 try: 160 m = int(d) - d 161 except (OverflowError, InvalidOperation): 162 return input_val 163 164 if not m and p < 0: 165 return mark_safe(u'%d' % (int(d))) 166 167 if p == 0: 168 exp = Decimal(1) 137 169 else: 138 formatstr = u'%%.%df' % abs(d) 139 return mark_safe(formatstr % f) 170 exp = Decimal('1.0') / (Decimal(10) ** abs(p)) 171 try: 172 return mark_safe(u'%s' % str(d.quantize(exp, ROUND_HALF_UP))) 173 except InvalidOperation: 174 return input_val 140 175 floatformat.is_safe = True 141 176 django/trunk/tests/regressiontests/defaultfilters/tests.py
r8599 r9369 14 14 >>> floatformat(0.0) 15 15 u'0' 16 >>> floatformat(7.7, 3)16 >>> floatformat(7.7, 3) 17 17 u'7.700' 18 >>> floatformat(6.000000, 3)18 >>> floatformat(6.000000, 3) 19 19 u'6.000' 20 20 >>> floatformat(6.200000, 3) … … 22 22 >>> floatformat(6.200000, -3) 23 23 u'6.200' 24 >>> floatformat(13.1031, -3)24 >>> floatformat(13.1031, -3) 25 25 u'13.103' 26 26 >>> floatformat(11.1197, -2) … … 36 36 >>> floatformat(13.1031, u'bar') 37 37 u'13.1031' 38 >>> floatformat(18.125, 2) 39 u'18.13' 38 40 >>> floatformat(u'foo', u'bar') 39 41 u'' 42 >>> floatformat(u'¿Cómo esta usted?') 43 u'' 40 44 >>> floatformat(None) 41 45 u'' 46 >>> pos_inf = float(1e30000) 47 >>> floatformat(pos_inf) == unicode(pos_inf) 48 True 49 >>> neg_inf = float(-1e30000) 50 >>> floatformat(neg_inf) == unicode(neg_inf) 51 True 52 >>> nan = pos_inf / pos_inf 53 >>> floatformat(nan) == unicode(nan) 54 True 42 55 43 56 >>> addslashes(u'"double quotes" and \'single quotes\'')
