summaryrefslogtreecommitdiff
path: root/scss/types.py
diff options
context:
space:
mode:
Diffstat (limited to 'scss/types.py')
-rw-r--r--scss/types.py17
1 files changed, 16 insertions, 1 deletions
diff --git a/scss/types.py b/scss/types.py
index e733377..c35905a 100644
--- a/scss/types.py
+++ b/scss/types.py
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
from collections import Iterable
import colorsys
+from fractions import Fraction
import operator
import re
import string
@@ -255,7 +256,21 @@ class Number(Value):
self.unit_denom = amount.unit_denom
return
- if not isinstance(amount, (int, float)):
+ # Numbers with units are stored internally as a "base" unit, which can
+ # involve float division, which can lead to precision errors in obscure
+ # cases. Storing the original units would only partially solve this
+ # problem, because there'd still be a possible loss of precision when
+ # converting in Sass-land. Almost all of the conversion factors are
+ # simple ratios of small whole numbers, so using Fraction across the
+ # board preserves as much precision as possible.
+ # TODO in fact, i wouldn't mind parsing Sass values as fractions of a
+ # power of ten!
+ # TODO this slowed the test suite down by about 10%, ha
+ if isinstance(amount, (int, float)):
+ amount = Fraction.from_float(amount)
+ elif isinstance(amount, Fraction):
+ pass
+ else:
raise TypeError("Expected number, got %r" % (amount,))
if unit is not None: