From 0d157a0154140dc6dcd491d62df3a2b66367be15 Mon Sep 17 00:00:00 2001 From: Facundo Batista Date: Fri, 30 Nov 2007 17:15:25 +0000 Subject: [PATCH] Reordering of __new__ to minimize isinstance() calls to most used types. Thanks Mark Dickinson. --- Lib/decimal.py | 111 +++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/Lib/decimal.py b/Lib/decimal.py index 6a3ee8494ef..6baa838e9ea 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -540,21 +540,47 @@ class Decimal(object): # digits. self = object.__new__(cls) - self._is_special = False - # From an internal working value - if isinstance(value, _WorkRep): - self._sign = value.sign - self._int = str(value.int) - self._exp = int(value.exp) - return self + # From a string + # REs insist on real strings, so we can too. + if isinstance(value, basestring): + m = _parser(value) + if m is None: + if context is None: + context = getcontext() + return context._raise_error(ConversionSyntax, + "Invalid literal for Decimal: %r" % value) - # From another decimal - if isinstance(value, Decimal): - self._exp = value._exp - self._sign = value._sign - self._int = value._int - self._is_special = value._is_special + if m.group('sign') == "-": + self._sign = 1 + else: + self._sign = 0 + intpart = m.group('int') + if intpart is not None: + # finite number + fracpart = m.group('frac') + exp = int(m.group('exp') or '0') + if fracpart is not None: + self._int = (intpart+fracpart).lstrip('0') or '0' + self._exp = exp - len(fracpart) + else: + self._int = intpart.lstrip('0') or '0' + self._exp = exp + self._is_special = False + else: + diag = m.group('diag') + if diag is not None: + # NaN + self._int = diag.lstrip('0') + if m.group('signal'): + self._exp = 'N' + else: + self._exp = 'n' + else: + # infinity + self._int = '0' + self._exp = 'F' + self._is_special = True return self # From an integer @@ -565,6 +591,23 @@ class Decimal(object): self._sign = 1 self._exp = 0 self._int = str(abs(value)) + self._is_special = False + return self + + # From another decimal + if isinstance(value, Decimal): + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + # From an internal working value + if isinstance(value, _WorkRep): + self._sign = value.sign + self._int = str(value.int) + self._exp = int(value.exp) + self._is_special = False return self # tuple/list conversion (possibly from as_tuple()) @@ -616,48 +659,6 @@ class Decimal(object): raise TypeError("Cannot convert float to Decimal. " + "First convert the float to a string") - # From a string - # REs insist on real strings, so we can too. - if isinstance(value, basestring): - m = _parser(value) - if m is None: - if context is None: - context = getcontext() - return context._raise_error(ConversionSyntax, - "Invalid literal for Decimal: %r" % value) - - if m.group('sign') == "-": - self._sign = 1 - else: - self._sign = 0 - intpart = m.group('int') - if intpart is not None: - # finite number - fracpart = m.group('frac') - exp = int(m.group('exp') or '0') - if fracpart is not None: - self._int = (intpart+fracpart).lstrip('0') or '0' - self._exp = exp - len(fracpart) - else: - self._int = intpart.lstrip('0') or '0' - self._exp = exp - self._is_special = False - else: - diag = m.group('diag') - if diag is not None: - # NaN - self._int = diag.lstrip('0') - if m.group('signal'): - self._exp = 'N' - else: - self._exp = 'n' - else: - # infinity - self._int = '0' - self._exp = 'F' - self._is_special = True - return self - raise TypeError("Cannot convert %r to Decimal" % value) def _isnan(self):