Ticket #12164: 13062.diff

File 13062.diff, 142.3 KB (added by Claude Paroz, 15 years ago)

Patch that passes tests

  • django/test/simple.py

     
    185185    # Construct a suite out of the tests that matched.
    186186    return unittest.TestSuite(tests)
    187187
    188 # Python 2.3 compatibility: TestSuites were made iterable in 2.4.
    189 # We need to iterate over them, so we add the missing method when
    190 # necessary.
    191 try:
    192     getattr(unittest.TestSuite, '__iter__')
    193 except AttributeError:
    194     setattr(unittest.TestSuite, '__iter__', lambda s: iter(s._tests))
    195 
    196188def partition_suite(suite, classes, bins):
    197189    """
    198190    Partitions a test suite by test type.
  • django/db/models/options.py

     
    11import re
    22from bisect import bisect
    3 try:
    4     set
    5 except NameError:
    6     from sets import Set as set     # Python 2.3 fallback
    73
    84from django.conf import settings
    95from django.db.models.related import RelatedObject
  • django/db/models/fields/__init__.py

     
    33import re
    44import time
    55import math
     6from itertools import tee
    67
    78import django.utils.copycompat as copy
    89
     
    1415from django.core import exceptions, validators
    1516from django.utils.datastructures import DictWrapper
    1617from django.utils.functional import curry
    17 from django.utils.itercompat import tee
    1818from django.utils.text import capfirst
    1919from django.utils.translation import ugettext_lazy as _
    2020from django.utils.encoding import smart_unicode, force_unicode, smart_str
  • django/db/backends/sqlite3/base.py

     
    11"""
    22SQLite3 backend for django.
    33
    4 Python 2.3 and 2.4 require pysqlite2 (http://pysqlite.org/).
     4Python 2.4 requires pysqlite2 (http://pysqlite.org/).
    55
    66Python 2.5 and later can use a pysqlite2 module or the sqlite3 module in the
    77standard library.
  • django/db/backends/util.py

     
    11import datetime
     2import decimal
    23from time import time
    34
    45from django.utils.hashcompat import md5_constructor
    56
    6 try:
    7     import decimal
    8 except ImportError:
    9     from django.utils import _decimal as decimal    # for Python 2.3
    10 
    117class CursorDebugWrapper(object):
    128    def __init__(self, cursor, db):
    139        self.cursor = cursor
  • django/db/backends/oracle/base.py

     
    99import os
    1010import sys
    1111import time
    12 try:
    13     from decimal import Decimal
    14 except ImportError:
    15     from django.utils._decimal import Decimal
     12from decimal import Decimal
    1613
    1714# Oracle takes client-side character set encoding from the environment.
    1815os.environ['NLS_LANG'] = '.UTF8'
  • django/db/backends/creation.py

     
    11import sys
    22import time
    3 try:
    4     set
    5 except NameError:
    6     # Python 2.3 compat
    7     from sets import Set as set
    83
    94from django.conf import settings
    105from django.core.management import call_command
  • django/db/transaction.py

     
    1919try:
    2020    from functools import wraps
    2121except ImportError:
    22     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     22    from django.utils.functional import wraps  # Python 2.4 fallback.
    2323from django.db import connections, DEFAULT_DB_ALIAS
    2424from django.conf import settings
    2525
  • django/forms/models.py

     
    1818from widgets import media_property
    1919from formsets import BaseFormSet, formset_factory, DELETION_FIELD_NAME
    2020
    21 try:
    22     set
    23 except NameError:
    24     from sets import Set as set     # Python 2.3 fallback
    25 
    2621__all__ = (
    2722    'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model',
    2823    'save_instance', 'form_for_fields', 'ModelChoiceField',
  • django/core/serializers/json.py

     
    33"""
    44
    55import datetime
     6import decimal
    67from StringIO import StringIO
    78
    89from django.core.serializers.python import Serializer as PythonSerializer
     
    1011from django.utils import datetime_safe
    1112from django.utils import simplejson
    1213
    13 try:
    14     import decimal
    15 except ImportError:
    16     from django.utils import _decimal as decimal    # Python 2.3 fallback
    17 
    1814class Serializer(PythonSerializer):
    1915    """
    2016    Convert a queryset to JSON.
  • django/core/urlresolvers.py

     
    1919from django.utils.regex_helper import normalize
    2020from django.utils.thread_support import currentThread
    2121
    22 try:
    23     reversed
    24 except NameError:
    25     from django.utils.itercompat import reversed     # Python 2.3 fallback
    26     from sets import Set as set
    27 
    2822_resolver_cache = {} # Maps URLconf modules to RegexURLResolver instances.
    2923_callable_cache = {} # Maps view and url pattern names to their view functions.
    3024
  • django/core/cache/backends/locmem.py

     
    7777
    7878    def set(self, key, value, timeout=None):
    7979        self._lock.writer_enters()
    80         # Python 2.3 and 2.4 don't allow combined try-except-finally blocks.
     80        # Python 2.4 doesn't allow combined try-except-finally blocks.
    8181        try:
    8282            try:
    8383                self._set(key, pickle.dumps(value), timeout)
  • django/core/management/base.py

     
    1313from django.core.management.color import color_style
    1414from django.utils.encoding import smart_str
    1515
    16 try:
    17     set
    18 except NameError:
    19     from sets import Set as set     # For Python 2.3
    20 
    2116class CommandError(Exception):
    2217    """
    2318    Exception class indicating a problem while executing a management
  • django/core/management/sql.py

     
    99from django.db.models import get_models
    1010from django.db.backends.util import truncate_name
    1111
    12 try:
    13     set
    14 except NameError:
    15     from sets import Set as set   # Python 2.3 fallback
    16 
    1712def sql_create(app, style, connection):
    1813    "Returns a list of the CREATE TABLE SQL statements for the given app."
    1914
  • django/views/decorators/csrf.py

     
    44try:
    55    from functools import wraps
    66except ImportError:
    7     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     7    from django.utils.functional import wraps  # Python 2.4 fallback.
    88
    99csrf_protect = decorator_from_middleware(CsrfViewMiddleware)
    1010csrf_protect.__name__ = "csrf_protect"
  • django/views/decorators/http.py

     
    55try:
    66    from functools import wraps
    77except ImportError:
    8     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     8    from django.utils.functional import wraps  # Python 2.4 fallback.
    99
    1010from calendar import timegm
    1111from datetime import timedelta
  • django/views/decorators/vary.py

     
    11try:
    22    from functools import wraps
    33except ImportError:
    4     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     4    from django.utils.functional import wraps  # Python 2.4 fallback.
    55
    66from django.utils.cache import patch_vary_headers
    77from django.utils.decorators import available_attrs
  • django/views/decorators/cache.py

     
    1414try:
    1515    from functools import wraps
    1616except ImportError:
    17     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     17    from django.utils.functional import wraps  # Python 2.4 fallback.
    1818
    1919from django.utils.decorators import decorator_from_middleware_with_args, available_attrs
    2020from django.utils.cache import patch_cache_control, add_never_cache_headers
  • django/dispatch/dispatcher.py

     
    11import weakref
    2 try:
    3     set
    4 except NameError:
    5     from sets import Set as set # Python 2.3 fallback
    62
    73from django.dispatch import saferef
    84
  • django/utils/_decimal.py

     
    1 # Copyright (c) 2004 Python Software Foundation.
    2 # All rights reserved.
    3 
    4 # Written by Eric Price <eprice at tjhsst.edu>
    5 #    and Facundo Batista <facundo at taniquetil.com.ar>
    6 #    and Raymond Hettinger <python at rcn.com>
    7 #    and Aahz <aahz at pobox.com>
    8 #    and Tim Peters
    9 
    10 # This module is currently Py2.3 compatible and should be kept that way
    11 # unless a major compelling advantage arises.  IOW, 2.3 compatibility is
    12 # strongly preferred, but not guaranteed.
    13 
    14 # Also, this module should be kept in sync with the latest updates of
    15 # the IBM specification as it evolves.  Those updates will be treated
    16 # as bug fixes (deviation from the spec is a compatibility, usability
    17 # bug) and will be backported.  At this point the spec is stabilizing
    18 # and the updates are becoming fewer, smaller, and less significant.
    19 
    20 """
    21 This is a Py2.3 implementation of decimal floating point arithmetic based on
    22 the General Decimal Arithmetic Specification:
    23 
    24     www2.hursley.ibm.com/decimal/decarith.html
    25 
    26 and IEEE standard 854-1987:
    27 
    28     www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
    29 
    30 Decimal floating point has finite precision with arbitrarily large bounds.
    31 
    32 The purpose of the module is to support arithmetic using familiar
    33 "schoolhouse" rules and to avoid the some of tricky representation
    34 issues associated with binary floating point.  The package is especially
    35 useful for financial applications or for contexts where users have
    36 expectations that are at odds with binary floating point (for instance,
    37 in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
    38 of the expected Decimal("0.00") returned by decimal floating point).
    39 
    40 Here are some examples of using the decimal module:
    41 
    42 >>> from decimal import *
    43 >>> setcontext(ExtendedContext)
    44 >>> Decimal(0)
    45 Decimal("0")
    46 >>> Decimal("1")
    47 Decimal("1")
    48 >>> Decimal("-.0123")
    49 Decimal("-0.0123")
    50 >>> Decimal(123456)
    51 Decimal("123456")
    52 >>> Decimal("123.45e12345678901234567890")
    53 Decimal("1.2345E+12345678901234567892")
    54 >>> Decimal("1.33") + Decimal("1.27")
    55 Decimal("2.60")
    56 >>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
    57 Decimal("-2.20")
    58 >>> dig = Decimal(1)
    59 >>> print dig / Decimal(3)
    60 0.333333333
    61 >>> getcontext().prec = 18
    62 >>> print dig / Decimal(3)
    63 0.333333333333333333
    64 >>> print dig.sqrt()
    65 1
    66 >>> print Decimal(3).sqrt()
    67 1.73205080756887729
    68 >>> print Decimal(3) ** 123
    69 4.85192780976896427E+58
    70 >>> inf = Decimal(1) / Decimal(0)
    71 >>> print inf
    72 Infinity
    73 >>> neginf = Decimal(-1) / Decimal(0)
    74 >>> print neginf
    75 -Infinity
    76 >>> print neginf + inf
    77 NaN
    78 >>> print neginf * inf
    79 -Infinity
    80 >>> print dig / 0
    81 Infinity
    82 >>> getcontext().traps[DivisionByZero] = 1
    83 >>> print dig / 0
    84 Traceback (most recent call last):
    85   ...
    86   ...
    87   ...
    88 DivisionByZero: x / 0
    89 >>> c = Context()
    90 >>> c.traps[InvalidOperation] = 0
    91 >>> print c.flags[InvalidOperation]
    92 0
    93 >>> c.divide(Decimal(0), Decimal(0))
    94 Decimal("NaN")
    95 >>> c.traps[InvalidOperation] = 1
    96 >>> print c.flags[InvalidOperation]
    97 1
    98 >>> c.flags[InvalidOperation] = 0
    99 >>> print c.flags[InvalidOperation]
    100 0
    101 >>> print c.divide(Decimal(0), Decimal(0))
    102 Traceback (most recent call last):
    103   ...
    104   ...
    105   ...
    106 InvalidOperation: 0 / 0
    107 >>> print c.flags[InvalidOperation]
    108 1
    109 >>> c.flags[InvalidOperation] = 0
    110 >>> c.traps[InvalidOperation] = 0
    111 >>> print c.divide(Decimal(0), Decimal(0))
    112 NaN
    113 >>> print c.flags[InvalidOperation]
    114 1
    115 >>>
    116 """
    117 
    118 __all__ = [
    119     # Two major classes
    120     'Decimal', 'Context',
    121 
    122     # Contexts
    123     'DefaultContext', 'BasicContext', 'ExtendedContext',
    124 
    125     # Exceptions
    126     'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
    127     'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
    128 
    129     # Constants for use in setting up contexts
    130     'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
    131     'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
    132 
    133     # Functions for manipulating contexts
    134     'setcontext', 'getcontext'
    135 ]
    136 
    137 import django.utils.copycompat as _copy
    138 
    139 #Rounding
    140 ROUND_DOWN = 'ROUND_DOWN'
    141 ROUND_HALF_UP = 'ROUND_HALF_UP'
    142 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
    143 ROUND_CEILING = 'ROUND_CEILING'
    144 ROUND_FLOOR = 'ROUND_FLOOR'
    145 ROUND_UP = 'ROUND_UP'
    146 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
    147 
    148 #Rounding decision (not part of the public API)
    149 NEVER_ROUND = 'NEVER_ROUND'    # Round in division (non-divmod), sqrt ONLY
    150 ALWAYS_ROUND = 'ALWAYS_ROUND'  # Every operation rounds at end.
    151 
    152 #Errors
    153 
    154 class DecimalException(ArithmeticError):
    155     """Base exception class.
    156 
    157     Used exceptions derive from this.
    158     If an exception derives from another exception besides this (such as
    159     Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
    160     called if the others are present.  This isn't actually used for
    161     anything, though.
    162 
    163     handle  -- Called when context._raise_error is called and the
    164                trap_enabler is set.  First argument is self, second is the
    165                context.  More arguments can be given, those being after
    166                the explanation in _raise_error (For example,
    167                context._raise_error(NewError, '(-x)!', self._sign) would
    168                call NewError().handle(context, self._sign).)
    169 
    170     To define a new exception, it should be sufficient to have it derive
    171     from DecimalException.
    172     """
    173     def handle(self, context, *args):
    174         pass
    175 
    176 
    177 class Clamped(DecimalException):
    178     """Exponent of a 0 changed to fit bounds.
    179 
    180     This occurs and signals clamped if the exponent of a result has been
    181     altered in order to fit the constraints of a specific concrete
    182     representation. This may occur when the exponent of a zero result would
    183     be outside the bounds of a representation, or  when a large normal
    184     number would have an encoded exponent that cannot be represented. In
    185     this latter case, the exponent is reduced to fit and the corresponding
    186     number of zero digits are appended to the coefficient ("fold-down").
    187     """
    188 
    189 
    190 class InvalidOperation(DecimalException):
    191     """An invalid operation was performed.
    192 
    193     Various bad things cause this:
    194 
    195     Something creates a signaling NaN
    196     -INF + INF
    197      0 * (+-)INF
    198      (+-)INF / (+-)INF
    199     x % 0
    200     (+-)INF % x
    201     x._rescale( non-integer )
    202     sqrt(-x) , x > 0
    203     0 ** 0
    204     x ** (non-integer)
    205     x ** (+-)INF
    206     An operand is invalid
    207     """
    208     def handle(self, context, *args):
    209         if args:
    210             if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
    211                 return Decimal( (args[1]._sign, args[1]._int, 'n') )
    212         return NaN
    213 
    214 class ConversionSyntax(InvalidOperation):
    215     """Trying to convert badly formed string.
    216 
    217     This occurs and signals invalid-operation if an string is being
    218     converted to a number and it does not conform to the numeric string
    219     syntax. The result is [0,qNaN].
    220     """
    221 
    222     def handle(self, context, *args):
    223         return (0, (0,), 'n') #Passed to something which uses a tuple.
    224 
    225 class DivisionByZero(DecimalException, ZeroDivisionError):
    226     """Division by 0.
    227 
    228     This occurs and signals division-by-zero if division of a finite number
    229     by zero was attempted (during a divide-integer or divide operation, or a
    230     power operation with negative right-hand operand), and the dividend was
    231     not zero.
    232 
    233     The result of the operation is [sign,inf], where sign is the exclusive
    234     or of the signs of the operands for divide, or is 1 for an odd power of
    235     -0, for power.
    236     """
    237 
    238     def handle(self, context, sign, double = None, *args):
    239         if double is not None:
    240             return (Infsign[sign],)*2
    241         return Infsign[sign]
    242 
    243 class DivisionImpossible(InvalidOperation):
    244     """Cannot perform the division adequately.
    245 
    246     This occurs and signals invalid-operation if the integer result of a
    247     divide-integer or remainder operation had too many digits (would be
    248     longer than precision). The result is [0,qNaN].
    249     """
    250 
    251     def handle(self, context, *args):
    252         return (NaN, NaN)
    253 
    254 class DivisionUndefined(InvalidOperation, ZeroDivisionError):
    255     """Undefined result of division.
    256 
    257     This occurs and signals invalid-operation if division by zero was
    258     attempted (during a divide-integer, divide, or remainder operation), and
    259     the dividend is also zero. The result is [0,qNaN].
    260     """
    261 
    262     def handle(self, context, tup=None, *args):
    263         if tup is not None:
    264             return (NaN, NaN) #for 0 %0, 0 // 0
    265         return NaN
    266 
    267 class Inexact(DecimalException):
    268     """Had to round, losing information.
    269 
    270     This occurs and signals inexact whenever the result of an operation is
    271     not exact (that is, it needed to be rounded and any discarded digits
    272     were non-zero), or if an overflow or underflow condition occurs. The
    273     result in all cases is unchanged.
    274 
    275     The inexact signal may be tested (or trapped) to determine if a given
    276     operation (or sequence of operations) was inexact.
    277     """
    278     pass
    279 
    280 class InvalidContext(InvalidOperation):
    281     """Invalid context.  Unknown rounding, for example.
    282 
    283     This occurs and signals invalid-operation if an invalid context was
    284     detected during an operation. This can occur if contexts are not checked
    285     on creation and either the precision exceeds the capability of the
    286     underlying concrete representation or an unknown or unsupported rounding
    287     was specified. These aspects of the context need only be checked when
    288     the values are required to be used. The result is [0,qNaN].
    289     """
    290 
    291     def handle(self, context, *args):
    292         return NaN
    293 
    294 class Rounded(DecimalException):
    295     """Number got rounded (not  necessarily changed during rounding).
    296 
    297     This occurs and signals rounded whenever the result of an operation is
    298     rounded (that is, some zero or non-zero digits were discarded from the
    299     coefficient), or if an overflow or underflow condition occurs. The
    300     result in all cases is unchanged.
    301 
    302     The rounded signal may be tested (or trapped) to determine if a given
    303     operation (or sequence of operations) caused a loss of precision.
    304     """
    305     pass
    306 
    307 class Subnormal(DecimalException):
    308     """Exponent < Emin before rounding.
    309 
    310     This occurs and signals subnormal whenever the result of a conversion or
    311     operation is subnormal (that is, its adjusted exponent is less than
    312     Emin, before any rounding). The result in all cases is unchanged.
    313 
    314     The subnormal signal may be tested (or trapped) to determine if a given
    315     or operation (or sequence of operations) yielded a subnormal result.
    316     """
    317     pass
    318 
    319 class Overflow(Inexact, Rounded):
    320     """Numerical overflow.
    321 
    322     This occurs and signals overflow if the adjusted exponent of a result
    323     (from a conversion or from an operation that is not an attempt to divide
    324     by zero), after rounding, would be greater than the largest value that
    325     can be handled by the implementation (the value Emax).
    326 
    327     The result depends on the rounding mode:
    328 
    329     For round-half-up and round-half-even (and for round-half-down and
    330     round-up, if implemented), the result of the operation is [sign,inf],
    331     where sign is the sign of the intermediate result. For round-down, the
    332     result is the largest finite number that can be represented in the
    333     current precision, with the sign of the intermediate result. For
    334     round-ceiling, the result is the same as for round-down if the sign of
    335     the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
    336     the result is the same as for round-down if the sign of the intermediate
    337     result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
    338     will also be raised.
    339    """
    340 
    341     def handle(self, context, sign, *args):
    342         if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
    343                                      ROUND_HALF_DOWN, ROUND_UP):
    344             return Infsign[sign]
    345         if sign == 0:
    346             if context.rounding == ROUND_CEILING:
    347                 return Infsign[sign]
    348             return Decimal((sign, (9,)*context.prec,
    349                             context.Emax-context.prec+1))
    350         if sign == 1:
    351             if context.rounding == ROUND_FLOOR:
    352                 return Infsign[sign]
    353             return Decimal( (sign, (9,)*context.prec,
    354                              context.Emax-context.prec+1))
    355 
    356 
    357 class Underflow(Inexact, Rounded, Subnormal):
    358     """Numerical underflow with result rounded to 0.
    359 
    360     This occurs and signals underflow if a result is inexact and the
    361     adjusted exponent of the result would be smaller (more negative) than
    362     the smallest value that can be handled by the implementation (the value
    363     Emin). That is, the result is both inexact and subnormal.
    364 
    365     The result after an underflow will be a subnormal number rounded, if
    366     necessary, so that its exponent is not less than Etiny. This may result
    367     in 0 with the sign of the intermediate result and an exponent of Etiny.
    368 
    369     In all cases, Inexact, Rounded, and Subnormal will also be raised.
    370     """
    371 
    372 # List of public traps and flags
    373 _signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
    374            Underflow, InvalidOperation, Subnormal]
    375 
    376 # Map conditions (per the spec) to signals
    377 _condition_map = {ConversionSyntax:InvalidOperation,
    378                   DivisionImpossible:InvalidOperation,
    379                   DivisionUndefined:InvalidOperation,
    380                   InvalidContext:InvalidOperation}
    381 
    382 ##### Context Functions #######################################
    383 
    384 # The getcontext() and setcontext() function manage access to a thread-local
    385 # current context.  Py2.4 offers direct support for thread locals.  If that
    386 # is not available, use threading.currentThread() which is slower but will
    387 # work for older Pythons.  If threads are not part of the build, create a
    388 # mock threading object with threading.local() returning the module namespace.
    389 
    390 try:
    391     import threading
    392 except ImportError:
    393     # Python was compiled without threads; create a mock object instead
    394     import sys
    395     class MockThreading:
    396         def local(self, sys=sys):
    397             return sys.modules[__name__]
    398     threading = MockThreading()
    399     del sys, MockThreading
    400 
    401 try:
    402     threading.local
    403 
    404 except AttributeError:
    405 
    406     #To fix reloading, force it to create a new context
    407     #Old contexts have different exceptions in their dicts, making problems.
    408     if hasattr(threading.currentThread(), '__decimal_context__'):
    409         del threading.currentThread().__decimal_context__
    410 
    411     def setcontext(context):
    412         """Set this thread's context to context."""
    413         if context in (DefaultContext, BasicContext, ExtendedContext):
    414             context = context.copy()
    415             context.clear_flags()
    416         threading.currentThread().__decimal_context__ = context
    417 
    418     def getcontext():
    419         """Returns this thread's context.
    420 
    421         If this thread does not yet have a context, returns
    422         a new context and sets this thread's context.
    423         New contexts are copies of DefaultContext.
    424         """
    425         try:
    426             return threading.currentThread().__decimal_context__
    427         except AttributeError:
    428             context = Context()
    429             threading.currentThread().__decimal_context__ = context
    430             return context
    431 
    432 else:
    433 
    434     local = threading.local()
    435     if hasattr(local, '__decimal_context__'):
    436         del local.__decimal_context__
    437 
    438     def getcontext(_local=local):
    439         """Returns this thread's context.
    440 
    441         If this thread does not yet have a context, returns
    442         a new context and sets this thread's context.
    443         New contexts are copies of DefaultContext.
    444         """
    445         try:
    446             return _local.__decimal_context__
    447         except AttributeError:
    448             context = Context()
    449             _local.__decimal_context__ = context
    450             return context
    451 
    452     def setcontext(context, _local=local):
    453         """Set this thread's context to context."""
    454         if context in (DefaultContext, BasicContext, ExtendedContext):
    455             context = context.copy()
    456             context.clear_flags()
    457         _local.__decimal_context__ = context
    458 
    459     del threading, local        # Don't contaminate the namespace
    460 
    461 
    462 ##### Decimal class ###########################################
    463 
    464 class Decimal(object):
    465     """Floating point class for decimal arithmetic."""
    466 
    467     __slots__ = ('_exp','_int','_sign', '_is_special')
    468     # Generally, the value of the Decimal instance is given by
    469     #  (-1)**_sign * _int * 10**_exp
    470     # Special values are signified by _is_special == True
    471 
    472     # We're immutable, so use __new__ not __init__
    473     def __new__(cls, value="0", context=None):
    474         """Create a decimal point instance.
    475 
    476         >>> Decimal('3.14')              # string input
    477         Decimal("3.14")
    478         >>> Decimal((0, (3, 1, 4), -2))  # tuple input (sign, digit_tuple, exponent)
    479         Decimal("3.14")
    480         >>> Decimal(314)                 # int or long
    481         Decimal("314")
    482         >>> Decimal(Decimal(314))        # another decimal instance
    483         Decimal("314")
    484         """
    485 
    486         self = object.__new__(cls)
    487         self._is_special = False
    488 
    489         # From an internal working value
    490         if isinstance(value, _WorkRep):
    491             self._sign = value.sign
    492             self._int = tuple(map(int, str(value.int)))
    493             self._exp = int(value.exp)
    494             return self
    495 
    496         # From another decimal
    497         if isinstance(value, Decimal):
    498             self._exp  = value._exp
    499             self._sign = value._sign
    500             self._int  = value._int
    501             self._is_special  = value._is_special
    502             return self
    503 
    504         # From an integer
    505         if isinstance(value, (int,long)):
    506             if value >= 0:
    507                 self._sign = 0
    508             else:
    509                 self._sign = 1
    510             self._exp = 0
    511             self._int = tuple(map(int, str(abs(value))))
    512             return self
    513 
    514         # tuple/list conversion (possibly from as_tuple())
    515         if isinstance(value, (list,tuple)):
    516             if len(value) != 3:
    517                 raise ValueError, 'Invalid arguments'
    518             if value[0] not in (0,1):
    519                 raise ValueError, 'Invalid sign'
    520             for digit in value[1]:
    521                 if not isinstance(digit, (int,long)) or digit < 0:
    522                     raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
    523 
    524             self._sign = value[0]
    525             self._int  = tuple(value[1])
    526             if value[2] in ('F','n','N'):
    527                 self._exp = value[2]
    528                 self._is_special = True
    529             else:
    530                 self._exp  = int(value[2])
    531             return self
    532 
    533         if isinstance(value, float):
    534             raise TypeError("Cannot convert float to Decimal.  " +
    535                             "First convert the float to a string")
    536 
    537         # Other argument types may require the context during interpretation
    538         if context is None:
    539             context = getcontext()
    540 
    541         # From a string
    542         # REs insist on real strings, so we can too.
    543         if isinstance(value, basestring):
    544             if _isinfinity(value):
    545                 self._exp = 'F'
    546                 self._int = (0,)
    547                 self._is_special = True
    548                 if _isinfinity(value) == 1:
    549                     self._sign = 0
    550                 else:
    551                     self._sign = 1
    552                 return self
    553             if _isnan(value):
    554                 sig, sign, diag = _isnan(value)
    555                 self._is_special = True
    556                 if len(diag) > context.prec: #Diagnostic info too long
    557                     self._sign, self._int, self._exp = \
    558                                 context._raise_error(ConversionSyntax)
    559                     return self
    560                 if sig == 1:
    561                     self._exp = 'n' #qNaN
    562                 else: #sig == 2
    563                     self._exp = 'N' #sNaN
    564                 self._sign = sign
    565                 self._int = tuple(map(int, diag)) #Diagnostic info
    566                 return self
    567             try:
    568                 self._sign, self._int, self._exp = _string2exact(value)
    569             except ValueError:
    570                 self._is_special = True
    571                 self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
    572             return self
    573 
    574         raise TypeError("Cannot convert %r to Decimal" % value)
    575 
    576     def _isnan(self):
    577         """Returns whether the number is not actually one.
    578 
    579         0 if a number
    580         1 if NaN
    581         2 if sNaN
    582         """
    583         if self._is_special:
    584             exp = self._exp
    585             if exp == 'n':
    586                 return 1
    587             elif exp == 'N':
    588                 return 2
    589         return 0
    590 
    591     def _isinfinity(self):
    592         """Returns whether the number is infinite
    593 
    594         0 if finite or not a number
    595         1 if +INF
    596         -1 if -INF
    597         """
    598         if self._exp == 'F':
    599             if self._sign:
    600                 return -1
    601             return 1
    602         return 0
    603 
    604     def _check_nans(self, other = None, context=None):
    605         """Returns whether the number is not actually one.
    606 
    607         if self, other are sNaN, signal
    608         if self, other are NaN return nan
    609         return 0
    610 
    611         Done before operations.
    612         """
    613 
    614         self_is_nan = self._isnan()
    615         if other is None:
    616             other_is_nan = False
    617         else:
    618             other_is_nan = other._isnan()
    619 
    620         if self_is_nan or other_is_nan:
    621             if context is None:
    622                 context = getcontext()
    623 
    624             if self_is_nan == 2:
    625                 return context._raise_error(InvalidOperation, 'sNaN',
    626                                         1, self)
    627             if other_is_nan == 2:
    628                 return context._raise_error(InvalidOperation, 'sNaN',
    629                                         1, other)
    630             if self_is_nan:
    631                 return self
    632 
    633             return other
    634         return 0
    635 
    636     def __nonzero__(self):
    637         """Is the number non-zero?
    638 
    639         0 if self == 0
    640         1 if self != 0
    641         """
    642         if self._is_special:
    643             return 1
    644         return sum(self._int) != 0
    645 
    646     def __cmp__(self, other, context=None):
    647         other = _convert_other(other)
    648         if other is NotImplemented:
    649             return other
    650 
    651         if self._is_special or other._is_special:
    652             ans = self._check_nans(other, context)
    653             if ans:
    654                 return 1 # Comparison involving NaN's always reports self > other
    655 
    656             # INF = INF
    657             return cmp(self._isinfinity(), other._isinfinity())
    658 
    659         if not self and not other:
    660             return 0 #If both 0, sign comparison isn't certain.
    661 
    662         #If different signs, neg one is less
    663         if other._sign < self._sign:
    664             return -1
    665         if self._sign < other._sign:
    666             return 1
    667 
    668         self_adjusted = self.adjusted()
    669         other_adjusted = other.adjusted()
    670         if self_adjusted == other_adjusted and \
    671            self._int + (0,)*(self._exp - other._exp) == \
    672            other._int + (0,)*(other._exp - self._exp):
    673             return 0 #equal, except in precision. ([0]*(-x) = [])
    674         elif self_adjusted > other_adjusted and self._int[0] != 0:
    675             return (-1)**self._sign
    676         elif self_adjusted < other_adjusted and other._int[0] != 0:
    677             return -((-1)**self._sign)
    678 
    679         # Need to round, so make sure we have a valid context
    680         if context is None:
    681             context = getcontext()
    682 
    683         context = context._shallow_copy()
    684         rounding = context._set_rounding(ROUND_UP) #round away from 0
    685 
    686         flags = context._ignore_all_flags()
    687         res = self.__sub__(other, context=context)
    688 
    689         context._regard_flags(*flags)
    690 
    691         context.rounding = rounding
    692 
    693         if not res:
    694             return 0
    695         elif res._sign:
    696             return -1
    697         return 1
    698 
    699     def __eq__(self, other):
    700         if not isinstance(other, (Decimal, int, long)):
    701             return NotImplemented
    702         return self.__cmp__(other) == 0
    703 
    704     def __ne__(self, other):
    705         if not isinstance(other, (Decimal, int, long)):
    706             return NotImplemented
    707         return self.__cmp__(other) != 0
    708 
    709     def compare(self, other, context=None):
    710         """Compares one to another.
    711 
    712         -1 => a < b
    713         0  => a = b
    714         1  => a > b
    715         NaN => one is NaN
    716         Like __cmp__, but returns Decimal instances.
    717         """
    718         other = _convert_other(other)
    719         if other is NotImplemented:
    720             return other
    721 
    722         #compare(NaN, NaN) = NaN
    723         if (self._is_special or other and other._is_special):
    724             ans = self._check_nans(other, context)
    725             if ans:
    726                 return ans
    727 
    728         return Decimal(self.__cmp__(other, context))
    729 
    730     def __hash__(self):
    731         """x.__hash__() <==> hash(x)"""
    732         # Decimal integers must hash the same as the ints
    733         # Non-integer decimals are normalized and hashed as strings
    734         # Normalization assures that hast(100E-1) == hash(10)
    735         if self._is_special:
    736             if self._isnan():
    737                 raise TypeError('Cannot hash a NaN value.')
    738             return hash(str(self))
    739         i = int(self)
    740         if self == Decimal(i):
    741             return hash(i)
    742         assert self.__nonzero__()   # '-0' handled by integer case
    743         return hash(str(self.normalize()))
    744 
    745     def as_tuple(self):
    746         """Represents the number as a triple tuple.
    747 
    748         To show the internals exactly as they are.
    749         """
    750         return (self._sign, self._int, self._exp)
    751 
    752     def __repr__(self):
    753         """Represents the number as an instance of Decimal."""
    754         # Invariant:  eval(repr(d)) == d
    755         return 'Decimal("%s")' % str(self)
    756 
    757     def __str__(self, eng = 0, context=None):
    758         """Return string representation of the number in scientific notation.
    759 
    760         Captures all of the information in the underlying representation.
    761         """
    762 
    763         if self._is_special:
    764             if self._isnan():
    765                 minus = '-'*self._sign
    766                 if self._int == (0,):
    767                     info = ''
    768                 else:
    769                     info = ''.join(map(str, self._int))
    770                 if self._isnan() == 2:
    771                     return minus + 'sNaN' + info
    772                 return minus + 'NaN' + info
    773             if self._isinfinity():
    774                 minus = '-'*self._sign
    775                 return minus + 'Infinity'
    776 
    777         if context is None:
    778             context = getcontext()
    779 
    780         tmp = map(str, self._int)
    781         numdigits = len(self._int)
    782         leftdigits = self._exp + numdigits
    783         if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
    784             if self._exp < 0 and self._exp >= -6: #short, no need for e/E
    785                 s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
    786                 return s
    787             #exp is closest mult. of 3 >= self._exp
    788             exp = ((self._exp - 1)// 3 + 1) * 3
    789             if exp != self._exp:
    790                 s = '0.'+'0'*(exp - self._exp)
    791             else:
    792                 s = '0'
    793             if exp != 0:
    794                 if context.capitals:
    795                     s += 'E'
    796                 else:
    797                     s += 'e'
    798                 if exp > 0:
    799                     s += '+' #0.0e+3, not 0.0e3
    800                 s += str(exp)
    801             s = '-'*self._sign + s
    802             return s
    803         if eng:
    804             dotplace = (leftdigits-1)%3+1
    805             adjexp = leftdigits -1 - (leftdigits-1)%3
    806         else:
    807             adjexp = leftdigits-1
    808             dotplace = 1
    809         if self._exp == 0:
    810             pass
    811         elif self._exp < 0 and adjexp >= 0:
    812             tmp.insert(leftdigits, '.')
    813         elif self._exp < 0 and adjexp >= -6:
    814             tmp[0:0] = ['0'] * int(-leftdigits)
    815             tmp.insert(0, '0.')
    816         else:
    817             if numdigits > dotplace:
    818                 tmp.insert(dotplace, '.')
    819             elif numdigits < dotplace:
    820                 tmp.extend(['0']*(dotplace-numdigits))
    821             if adjexp:
    822                 if not context.capitals:
    823                     tmp.append('e')
    824                 else:
    825                     tmp.append('E')
    826                     if adjexp > 0:
    827                         tmp.append('+')
    828                 tmp.append(str(adjexp))
    829         if eng:
    830             while tmp[0:1] == ['0']:
    831                 tmp[0:1] = []
    832             if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
    833                 tmp[0:0] = ['0']
    834         if self._sign:
    835             tmp.insert(0, '-')
    836 
    837         return ''.join(tmp)
    838 
    839     def to_eng_string(self, context=None):
    840         """Convert to engineering-type string.
    841 
    842         Engineering notation has an exponent which is a multiple of 3, so there
    843         are up to 3 digits left of the decimal place.
    844 
    845         Same rules for when in exponential and when as a value as in __str__.
    846         """
    847         return self.__str__(eng=1, context=context)
    848 
    849     def __neg__(self, context=None):
    850         """Returns a copy with the sign switched.
    851 
    852         Rounds, if it has reason.
    853         """
    854         if self._is_special:
    855             ans = self._check_nans(context=context)
    856             if ans:
    857                 return ans
    858 
    859         if not self:
    860             # -Decimal('0') is Decimal('0'), not Decimal('-0')
    861             sign = 0
    862         elif self._sign:
    863             sign = 0
    864         else:
    865             sign = 1
    866 
    867         if context is None:
    868             context = getcontext()
    869         if context._rounding_decision == ALWAYS_ROUND:
    870             return Decimal((sign, self._int, self._exp))._fix(context)
    871         return Decimal( (sign, self._int, self._exp))
    872 
    873     def __pos__(self, context=None):
    874         """Returns a copy, unless it is a sNaN.
    875 
    876         Rounds the number (if more then precision digits)
    877         """
    878         if self._is_special:
    879             ans = self._check_nans(context=context)
    880             if ans:
    881                 return ans
    882 
    883         sign = self._sign
    884         if not self:
    885             # + (-0) = 0
    886             sign = 0
    887 
    888         if context is None:
    889             context = getcontext()
    890 
    891         if context._rounding_decision == ALWAYS_ROUND:
    892             ans = self._fix(context)
    893         else:
    894             ans = Decimal(self)
    895         ans._sign = sign
    896         return ans
    897 
    898     def __abs__(self, round=1, context=None):
    899         """Returns the absolute value of self.
    900 
    901         If the second argument is 0, do not round.
    902         """
    903         if self._is_special:
    904             ans = self._check_nans(context=context)
    905             if ans:
    906                 return ans
    907 
    908         if not round:
    909             if context is None:
    910                 context = getcontext()
    911             context = context._shallow_copy()
    912             context._set_rounding_decision(NEVER_ROUND)
    913 
    914         if self._sign:
    915             ans = self.__neg__(context=context)
    916         else:
    917             ans = self.__pos__(context=context)
    918 
    919         return ans
    920 
    921     def __add__(self, other, context=None):
    922         """Returns self + other.
    923 
    924         -INF + INF (or the reverse) cause InvalidOperation errors.
    925         """
    926         other = _convert_other(other)
    927         if other is NotImplemented:
    928             return other
    929 
    930         if context is None:
    931             context = getcontext()
    932 
    933         if self._is_special or other._is_special:
    934             ans = self._check_nans(other, context)
    935             if ans:
    936                 return ans
    937 
    938             if self._isinfinity():
    939                 #If both INF, same sign => same as both, opposite => error.
    940                 if self._sign != other._sign and other._isinfinity():
    941                     return context._raise_error(InvalidOperation, '-INF + INF')
    942                 return Decimal(self)
    943             if other._isinfinity():
    944                 return Decimal(other)  #Can't both be infinity here
    945 
    946         shouldround = context._rounding_decision == ALWAYS_ROUND
    947 
    948         exp = min(self._exp, other._exp)
    949         negativezero = 0
    950         if context.rounding == ROUND_FLOOR and self._sign != other._sign:
    951             #If the answer is 0, the sign should be negative, in this case.
    952             negativezero = 1
    953 
    954         if not self and not other:
    955             sign = min(self._sign, other._sign)
    956             if negativezero:
    957                 sign = 1
    958             return Decimal( (sign, (0,), exp))
    959         if not self:
    960             exp = max(exp, other._exp - context.prec-1)
    961             ans = other._rescale(exp, watchexp=0, context=context)
    962             if shouldround:
    963                 ans = ans._fix(context)
    964             return ans
    965         if not other:
    966             exp = max(exp, self._exp - context.prec-1)
    967             ans = self._rescale(exp, watchexp=0, context=context)
    968             if shouldround:
    969                 ans = ans._fix(context)
    970             return ans
    971 
    972         op1 = _WorkRep(self)
    973         op2 = _WorkRep(other)
    974         op1, op2 = _normalize(op1, op2, shouldround, context.prec)
    975 
    976         result = _WorkRep()
    977         if op1.sign != op2.sign:
    978             # Equal and opposite
    979             if op1.int == op2.int:
    980                 if exp < context.Etiny():
    981                     exp = context.Etiny()
    982                     context._raise_error(Clamped)
    983                 return Decimal((negativezero, (0,), exp))
    984             if op1.int < op2.int:
    985                 op1, op2 = op2, op1
    986                 #OK, now abs(op1) > abs(op2)
    987             if op1.sign == 1:
    988                 result.sign = 1
    989                 op1.sign, op2.sign = op2.sign, op1.sign
    990             else:
    991                 result.sign = 0
    992                 #So we know the sign, and op1 > 0.
    993         elif op1.sign == 1:
    994             result.sign = 1
    995             op1.sign, op2.sign = (0, 0)
    996         else:
    997             result.sign = 0
    998         #Now, op1 > abs(op2) > 0
    999 
    1000         if op2.sign == 0:
    1001             result.int = op1.int + op2.int
    1002         else:
    1003             result.int = op1.int - op2.int
    1004 
    1005         result.exp = op1.exp
    1006         ans = Decimal(result)
    1007         if shouldround:
    1008             ans = ans._fix(context)
    1009         return ans
    1010 
    1011     __radd__ = __add__
    1012 
    1013     def __sub__(self, other, context=None):
    1014         """Return self + (-other)"""
    1015         other = _convert_other(other)
    1016         if other is NotImplemented:
    1017             return other
    1018 
    1019         if self._is_special or other._is_special:
    1020             ans = self._check_nans(other, context=context)
    1021             if ans:
    1022                 return ans
    1023 
    1024         # -Decimal(0) = Decimal(0), which we don't want since
    1025         # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
    1026         # so we change the sign directly to a copy
    1027         tmp = Decimal(other)
    1028         tmp._sign = 1-tmp._sign
    1029 
    1030         return self.__add__(tmp, context=context)
    1031 
    1032     def __rsub__(self, other, context=None):
    1033         """Return other + (-self)"""
    1034         other = _convert_other(other)
    1035         if other is NotImplemented:
    1036             return other
    1037 
    1038         tmp = Decimal(self)
    1039         tmp._sign = 1 - tmp._sign
    1040         return other.__add__(tmp, context=context)
    1041 
    1042     def _increment(self, round=1, context=None):
    1043         """Special case of add, adding 1eExponent
    1044 
    1045         Since it is common, (rounding, for example) this adds
    1046         (sign)*one E self._exp to the number more efficiently than add.
    1047 
    1048         For example:
    1049         Decimal('5.624e10')._increment() == Decimal('5.625e10')
    1050         """
    1051         if self._is_special:
    1052             ans = self._check_nans(context=context)
    1053             if ans:
    1054                 return ans
    1055 
    1056             return Decimal(self) # Must be infinite, and incrementing makes no difference
    1057 
    1058         L = list(self._int)
    1059         L[-1] += 1
    1060         spot = len(L)-1
    1061         while L[spot] == 10:
    1062             L[spot] = 0
    1063             if spot == 0:
    1064                 L[0:0] = [1]
    1065                 break
    1066             L[spot-1] += 1
    1067             spot -= 1
    1068         ans = Decimal((self._sign, L, self._exp))
    1069 
    1070         if context is None:
    1071             context = getcontext()
    1072         if round and context._rounding_decision == ALWAYS_ROUND:
    1073             ans = ans._fix(context)
    1074         return ans
    1075 
    1076     def __mul__(self, other, context=None):
    1077         """Return self * other.
    1078 
    1079         (+-) INF * 0 (or its reverse) raise InvalidOperation.
    1080         """
    1081         other = _convert_other(other)
    1082         if other is NotImplemented:
    1083             return other
    1084 
    1085         if context is None:
    1086             context = getcontext()
    1087 
    1088         resultsign = self._sign ^ other._sign
    1089 
    1090         if self._is_special or other._is_special:
    1091             ans = self._check_nans(other, context)
    1092             if ans:
    1093                 return ans
    1094 
    1095             if self._isinfinity():
    1096                 if not other:
    1097                     return context._raise_error(InvalidOperation, '(+-)INF * 0')
    1098                 return Infsign[resultsign]
    1099 
    1100             if other._isinfinity():
    1101                 if not self:
    1102                     return context._raise_error(InvalidOperation, '0 * (+-)INF')
    1103                 return Infsign[resultsign]
    1104 
    1105         resultexp = self._exp + other._exp
    1106         shouldround = context._rounding_decision == ALWAYS_ROUND
    1107 
    1108         # Special case for multiplying by zero
    1109         if not self or not other:
    1110             ans = Decimal((resultsign, (0,), resultexp))
    1111             if shouldround:
    1112                 #Fixing in case the exponent is out of bounds
    1113                 ans = ans._fix(context)
    1114             return ans
    1115 
    1116         # Special case for multiplying by power of 10
    1117         if self._int == (1,):
    1118             ans = Decimal((resultsign, other._int, resultexp))
    1119             if shouldround:
    1120                 ans = ans._fix(context)
    1121             return ans
    1122         if other._int == (1,):
    1123             ans = Decimal((resultsign, self._int, resultexp))
    1124             if shouldround:
    1125                 ans = ans._fix(context)
    1126             return ans
    1127 
    1128         op1 = _WorkRep(self)
    1129         op2 = _WorkRep(other)
    1130 
    1131         ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
    1132         if shouldround:
    1133             ans = ans._fix(context)
    1134 
    1135         return ans
    1136     __rmul__ = __mul__
    1137 
    1138     def __div__(self, other, context=None):
    1139         """Return self / other."""
    1140         return self._divide(other, context=context)
    1141     __truediv__ = __div__
    1142 
    1143     def _divide(self, other, divmod = 0, context=None):
    1144         """Return a / b, to context.prec precision.
    1145 
    1146         divmod:
    1147         0 => true division
    1148         1 => (a //b, a%b)
    1149         2 => a //b
    1150         3 => a%b
    1151 
    1152         Actually, if divmod is 2 or 3 a tuple is returned, but errors for
    1153         computing the other value are not raised.
    1154         """
    1155         other = _convert_other(other)
    1156         if other is NotImplemented:
    1157             if divmod in (0, 1):
    1158                 return NotImplemented
    1159             return (NotImplemented, NotImplemented)
    1160 
    1161         if context is None:
    1162             context = getcontext()
    1163 
    1164         sign = self._sign ^ other._sign
    1165 
    1166         if self._is_special or other._is_special:
    1167             ans = self._check_nans(other, context)
    1168             if ans:
    1169                 if divmod:
    1170                     return (ans, ans)
    1171                 return ans
    1172 
    1173             if self._isinfinity() and other._isinfinity():
    1174                 if divmod:
    1175                     return (context._raise_error(InvalidOperation,
    1176                                             '(+-)INF // (+-)INF'),
    1177                             context._raise_error(InvalidOperation,
    1178                                             '(+-)INF % (+-)INF'))
    1179                 return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
    1180 
    1181             if self._isinfinity():
    1182                 if divmod == 1:
    1183                     return (Infsign[sign],
    1184                             context._raise_error(InvalidOperation, 'INF % x'))
    1185                 elif divmod == 2:
    1186                     return (Infsign[sign], NaN)
    1187                 elif divmod == 3:
    1188                     return (Infsign[sign],
    1189                             context._raise_error(InvalidOperation, 'INF % x'))
    1190                 return Infsign[sign]
    1191 
    1192             if other._isinfinity():
    1193                 if divmod:
    1194                     return (Decimal((sign, (0,), 0)), Decimal(self))
    1195                 context._raise_error(Clamped, 'Division by infinity')
    1196                 return Decimal((sign, (0,), context.Etiny()))
    1197 
    1198         # Special cases for zeroes
    1199         if not self and not other:
    1200             if divmod:
    1201                 return context._raise_error(DivisionUndefined, '0 / 0', 1)
    1202             return context._raise_error(DivisionUndefined, '0 / 0')
    1203 
    1204         if not self:
    1205             if divmod:
    1206                 otherside = Decimal(self)
    1207                 otherside._exp = min(self._exp, other._exp)
    1208                 return (Decimal((sign, (0,), 0)),  otherside)
    1209             exp = self._exp - other._exp
    1210             if exp < context.Etiny():
    1211                 exp = context.Etiny()
    1212                 context._raise_error(Clamped, '0e-x / y')
    1213             if exp > context.Emax:
    1214                 exp = context.Emax
    1215                 context._raise_error(Clamped, '0e+x / y')
    1216             return Decimal( (sign, (0,), exp) )
    1217 
    1218         if not other:
    1219             if divmod:
    1220                 return context._raise_error(DivisionByZero, 'divmod(x,0)',
    1221                                            sign, 1)
    1222             return context._raise_error(DivisionByZero, 'x / 0', sign)
    1223 
    1224         #OK, so neither = 0, INF or NaN
    1225 
    1226         shouldround = context._rounding_decision == ALWAYS_ROUND
    1227 
    1228         #If we're dividing into ints, and self < other, stop.
    1229         #self.__abs__(0) does not round.
    1230         if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
    1231 
    1232             if divmod == 1 or divmod == 3:
    1233                 exp = min(self._exp, other._exp)
    1234                 ans2 = self._rescale(exp, context=context, watchexp=0)
    1235                 if shouldround:
    1236                     ans2 = ans2._fix(context)
    1237                 return (Decimal( (sign, (0,), 0) ),
    1238                         ans2)
    1239 
    1240             elif divmod == 2:
    1241                 #Don't round the mod part, if we don't need it.
    1242                 return (Decimal( (sign, (0,), 0) ), Decimal(self))
    1243 
    1244         op1 = _WorkRep(self)
    1245         op2 = _WorkRep(other)
    1246         op1, op2, adjust = _adjust_coefficients(op1, op2)
    1247         res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
    1248         if divmod and res.exp > context.prec + 1:
    1249             return context._raise_error(DivisionImpossible)
    1250 
    1251         prec_limit = 10 ** context.prec
    1252         while 1:
    1253             while op2.int <= op1.int:
    1254                 res.int += 1
    1255                 op1.int -= op2.int
    1256             if res.exp == 0 and divmod:
    1257                 if res.int >= prec_limit and shouldround:
    1258                     return context._raise_error(DivisionImpossible)
    1259                 otherside = Decimal(op1)
    1260                 frozen = context._ignore_all_flags()
    1261 
    1262                 exp = min(self._exp, other._exp)
    1263                 otherside = otherside._rescale(exp, context=context, watchexp=0)
    1264                 context._regard_flags(*frozen)
    1265                 if shouldround:
    1266                     otherside = otherside._fix(context)
    1267                 return (Decimal(res), otherside)
    1268 
    1269             if op1.int == 0 and adjust >= 0 and not divmod:
    1270                 break
    1271             if res.int >= prec_limit and shouldround:
    1272                 if divmod:
    1273                     return context._raise_error(DivisionImpossible)
    1274                 shouldround=1
    1275                 # Really, the answer is a bit higher, so adding a one to
    1276                 # the end will make sure the rounding is right.
    1277                 if op1.int != 0:
    1278                     res.int *= 10
    1279                     res.int += 1
    1280                     res.exp -= 1
    1281 
    1282                 break
    1283             res.int *= 10
    1284             res.exp -= 1
    1285             adjust += 1
    1286             op1.int *= 10
    1287             op1.exp -= 1
    1288 
    1289             if res.exp == 0 and divmod and op2.int > op1.int:
    1290                 #Solves an error in precision.  Same as a previous block.
    1291 
    1292                 if res.int >= prec_limit and shouldround:
    1293                     return context._raise_error(DivisionImpossible)
    1294                 otherside = Decimal(op1)
    1295                 frozen = context._ignore_all_flags()
    1296 
    1297                 exp = min(self._exp, other._exp)
    1298                 otherside = otherside._rescale(exp, context=context)
    1299 
    1300                 context._regard_flags(*frozen)
    1301 
    1302                 return (Decimal(res), otherside)
    1303 
    1304         ans = Decimal(res)
    1305         if shouldround:
    1306             ans = ans._fix(context)
    1307         return ans
    1308 
    1309     def __rdiv__(self, other, context=None):
    1310         """Swaps self/other and returns __div__."""
    1311         other = _convert_other(other)
    1312         if other is NotImplemented:
    1313             return other
    1314         return other.__div__(self, context=context)
    1315     __rtruediv__ = __rdiv__
    1316 
    1317     def __divmod__(self, other, context=None):
    1318         """
    1319         (self // other, self % other)
    1320         """
    1321         return self._divide(other, 1, context)
    1322 
    1323     def __rdivmod__(self, other, context=None):
    1324         """Swaps self/other and returns __divmod__."""
    1325         other = _convert_other(other)
    1326         if other is NotImplemented:
    1327             return other
    1328         return other.__divmod__(self, context=context)
    1329 
    1330     def __mod__(self, other, context=None):
    1331         """
    1332         self % other
    1333         """
    1334         other = _convert_other(other)
    1335         if other is NotImplemented:
    1336             return other
    1337 
    1338         if self._is_special or other._is_special:
    1339             ans = self._check_nans(other, context)
    1340             if ans:
    1341                 return ans
    1342 
    1343         if self and not other:
    1344             return context._raise_error(InvalidOperation, 'x % 0')
    1345 
    1346         return self._divide(other, 3, context)[1]
    1347 
    1348     def __rmod__(self, other, context=None):
    1349         """Swaps self/other and returns __mod__."""
    1350         other = _convert_other(other)
    1351         if other is NotImplemented:
    1352             return other
    1353         return other.__mod__(self, context=context)
    1354 
    1355     def remainder_near(self, other, context=None):
    1356         """
    1357         Remainder nearest to 0-  abs(remainder-near) <= other/2
    1358         """
    1359         other = _convert_other(other)
    1360         if other is NotImplemented:
    1361             return other
    1362 
    1363         if self._is_special or other._is_special:
    1364             ans = self._check_nans(other, context)
    1365             if ans:
    1366                 return ans
    1367         if self and not other:
    1368             return context._raise_error(InvalidOperation, 'x % 0')
    1369 
    1370         if context is None:
    1371             context = getcontext()
    1372         # If DivisionImpossible causes an error, do not leave Rounded/Inexact
    1373         # ignored in the calling function.
    1374         context = context._shallow_copy()
    1375         flags = context._ignore_flags(Rounded, Inexact)
    1376         #keep DivisionImpossible flags
    1377         (side, r) = self.__divmod__(other, context=context)
    1378 
    1379         if r._isnan():
    1380             context._regard_flags(*flags)
    1381             return r
    1382 
    1383         context = context._shallow_copy()
    1384         rounding = context._set_rounding_decision(NEVER_ROUND)
    1385 
    1386         if other._sign:
    1387             comparison = other.__div__(Decimal(-2), context=context)
    1388         else:
    1389             comparison = other.__div__(Decimal(2), context=context)
    1390 
    1391         context._set_rounding_decision(rounding)
    1392         context._regard_flags(*flags)
    1393 
    1394         s1, s2 = r._sign, comparison._sign
    1395         r._sign, comparison._sign = 0, 0
    1396 
    1397         if r < comparison:
    1398             r._sign, comparison._sign = s1, s2
    1399             #Get flags now
    1400             self.__divmod__(other, context=context)
    1401             return r._fix(context)
    1402         r._sign, comparison._sign = s1, s2
    1403 
    1404         rounding = context._set_rounding_decision(NEVER_ROUND)
    1405 
    1406         (side, r) = self.__divmod__(other, context=context)
    1407         context._set_rounding_decision(rounding)
    1408         if r._isnan():
    1409             return r
    1410 
    1411         decrease = not side._iseven()
    1412         rounding = context._set_rounding_decision(NEVER_ROUND)
    1413         side = side.__abs__(context=context)
    1414         context._set_rounding_decision(rounding)
    1415 
    1416         s1, s2 = r._sign, comparison._sign
    1417         r._sign, comparison._sign = 0, 0
    1418         if r > comparison or decrease and r == comparison:
    1419             r._sign, comparison._sign = s1, s2
    1420             context.prec += 1
    1421             if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
    1422                 context.prec -= 1
    1423                 return context._raise_error(DivisionImpossible)[1]
    1424             context.prec -= 1
    1425             if self._sign == other._sign:
    1426                 r = r.__sub__(other, context=context)
    1427             else:
    1428                 r = r.__add__(other, context=context)
    1429         else:
    1430             r._sign, comparison._sign = s1, s2
    1431 
    1432         return r._fix(context)
    1433 
    1434     def __floordiv__(self, other, context=None):
    1435         """self // other"""
    1436         return self._divide(other, 2, context)[0]
    1437 
    1438     def __rfloordiv__(self, other, context=None):
    1439         """Swaps self/other and returns __floordiv__."""
    1440         other = _convert_other(other)
    1441         if other is NotImplemented:
    1442             return other
    1443         return other.__floordiv__(self, context=context)
    1444 
    1445     def __float__(self):
    1446         """Float representation."""
    1447         return float(str(self))
    1448 
    1449     def __int__(self):
    1450         """Converts self to an int, truncating if necessary."""
    1451         if self._is_special:
    1452             if self._isnan():
    1453                 context = getcontext()
    1454                 return context._raise_error(InvalidContext)
    1455             elif self._isinfinity():
    1456                 raise OverflowError, "Cannot convert infinity to long"
    1457         if self._exp >= 0:
    1458             s = ''.join(map(str, self._int)) + '0'*self._exp
    1459         else:
    1460             s = ''.join(map(str, self._int))[:self._exp]
    1461         if s == '':
    1462             s = '0'
    1463         sign = '-'*self._sign
    1464         return int(sign + s)
    1465 
    1466     def __long__(self):
    1467         """Converts to a long.
    1468 
    1469         Equivalent to long(int(self))
    1470         """
    1471         return long(self.__int__())
    1472 
    1473     def _fix(self, context):
    1474         """Round if it is necessary to keep self within prec precision.
    1475 
    1476         Rounds and fixes the exponent.  Does not raise on a sNaN.
    1477 
    1478         Arguments:
    1479         self - Decimal instance
    1480         context - context used.
    1481         """
    1482         if self._is_special:
    1483             return self
    1484         if context is None:
    1485             context = getcontext()
    1486         prec = context.prec
    1487         ans = self._fixexponents(context)
    1488         if len(ans._int) > prec:
    1489             ans = ans._round(prec, context=context)
    1490             ans = ans._fixexponents(context)
    1491         return ans
    1492 
    1493     def _fixexponents(self, context):
    1494         """Fix the exponents and return a copy with the exponent in bounds.
    1495         Only call if known to not be a special value.
    1496         """
    1497         folddown = context._clamp
    1498         Emin = context.Emin
    1499         ans = self
    1500         ans_adjusted = ans.adjusted()
    1501         if ans_adjusted < Emin:
    1502             Etiny = context.Etiny()
    1503             if ans._exp < Etiny:
    1504                 if not ans:
    1505                     ans = Decimal(self)
    1506                     ans._exp = Etiny
    1507                     context._raise_error(Clamped)
    1508                     return ans
    1509                 ans = ans._rescale(Etiny, context=context)
    1510                 #It isn't zero, and exp < Emin => subnormal
    1511                 context._raise_error(Subnormal)
    1512                 if context.flags[Inexact]:
    1513                     context._raise_error(Underflow)
    1514             else:
    1515                 if ans:
    1516                     #Only raise subnormal if non-zero.
    1517                     context._raise_error(Subnormal)
    1518         else:
    1519             Etop = context.Etop()
    1520             if folddown and ans._exp > Etop:
    1521                 context._raise_error(Clamped)
    1522                 ans = ans._rescale(Etop, context=context)
    1523             else:
    1524                 Emax = context.Emax
    1525                 if ans_adjusted > Emax:
    1526                     if not ans:
    1527                         ans = Decimal(self)
    1528                         ans._exp = Emax
    1529                         context._raise_error(Clamped)
    1530                         return ans
    1531                     context._raise_error(Inexact)
    1532                     context._raise_error(Rounded)
    1533                     return context._raise_error(Overflow, 'above Emax', ans._sign)
    1534         return ans
    1535 
    1536     def _round(self, prec=None, rounding=None, context=None):
    1537         """Returns a rounded version of self.
    1538 
    1539         You can specify the precision or rounding method.  Otherwise, the
    1540         context determines it.
    1541         """
    1542 
    1543         if self._is_special:
    1544             ans = self._check_nans(context=context)
    1545             if ans:
    1546                 return ans
    1547 
    1548             if self._isinfinity():
    1549                 return Decimal(self)
    1550 
    1551         if context is None:
    1552             context = getcontext()
    1553 
    1554         if rounding is None:
    1555             rounding = context.rounding
    1556         if prec is None:
    1557             prec = context.prec
    1558 
    1559         if not self:
    1560             if prec <= 0:
    1561                 dig = (0,)
    1562                 exp = len(self._int) - prec + self._exp
    1563             else:
    1564                 dig = (0,) * prec
    1565                 exp = len(self._int) + self._exp - prec
    1566             ans = Decimal((self._sign, dig, exp))
    1567             context._raise_error(Rounded)
    1568             return ans
    1569 
    1570         if prec == 0:
    1571             temp = Decimal(self)
    1572             temp._int = (0,)+temp._int
    1573             prec = 1
    1574         elif prec < 0:
    1575             exp = self._exp + len(self._int) - prec - 1
    1576             temp = Decimal( (self._sign, (0, 1), exp))
    1577             prec = 1
    1578         else:
    1579             temp = Decimal(self)
    1580 
    1581         numdigits = len(temp._int)
    1582         if prec == numdigits:
    1583             return temp
    1584 
    1585         # See if we need to extend precision
    1586         expdiff = prec - numdigits
    1587         if expdiff > 0:
    1588             tmp = list(temp._int)
    1589             tmp.extend([0] * expdiff)
    1590             ans =  Decimal( (temp._sign, tmp, temp._exp - expdiff))
    1591             return ans
    1592 
    1593         #OK, but maybe all the lost digits are 0.
    1594         lostdigits = self._int[expdiff:]
    1595         if lostdigits == (0,) * len(lostdigits):
    1596             ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
    1597             #Rounded, but not Inexact
    1598             context._raise_error(Rounded)
    1599             return ans
    1600 
    1601         # Okay, let's round and lose data
    1602 
    1603         this_function = getattr(temp, self._pick_rounding_function[rounding])
    1604         #Now we've got the rounding function
    1605 
    1606         if prec != context.prec:
    1607             context = context._shallow_copy()
    1608             context.prec = prec
    1609         ans = this_function(prec, expdiff, context)
    1610         context._raise_error(Rounded)
    1611         context._raise_error(Inexact, 'Changed in rounding')
    1612 
    1613         return ans
    1614 
    1615     _pick_rounding_function = {}
    1616 
    1617     def _round_down(self, prec, expdiff, context):
    1618         """Also known as round-towards-0, truncate."""
    1619         return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
    1620 
    1621     def _round_half_up(self, prec, expdiff, context, tmp = None):
    1622         """Rounds 5 up (away from 0)"""
    1623 
    1624         if tmp is None:
    1625             tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
    1626         if self._int[prec] >= 5:
    1627             tmp = tmp._increment(round=0, context=context)
    1628             if len(tmp._int) > prec:
    1629                 return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
    1630         return tmp
    1631 
    1632     def _round_half_even(self, prec, expdiff, context):
    1633         """Round 5 to even, rest to nearest."""
    1634 
    1635         tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
    1636         half = (self._int[prec] == 5)
    1637         if half:
    1638             for digit in self._int[prec+1:]:
    1639                 if digit != 0:
    1640                     half = 0
    1641                     break
    1642         if half:
    1643             if self._int[prec-1] & 1 == 0:
    1644                 return tmp
    1645         return self._round_half_up(prec, expdiff, context, tmp)
    1646 
    1647     def _round_half_down(self, prec, expdiff, context):
    1648         """Round 5 down"""
    1649 
    1650         tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
    1651         half = (self._int[prec] == 5)
    1652         if half:
    1653             for digit in self._int[prec+1:]:
    1654                 if digit != 0:
    1655                     half = 0
    1656                     break
    1657         if half:
    1658             return tmp
    1659         return self._round_half_up(prec, expdiff, context, tmp)
    1660 
    1661     def _round_up(self, prec, expdiff, context):
    1662         """Rounds away from 0."""
    1663         tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
    1664         for digit in self._int[prec:]:
    1665             if digit != 0:
    1666                 tmp = tmp._increment(round=1, context=context)
    1667                 if len(tmp._int) > prec:
    1668                     return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
    1669                 else:
    1670                     return tmp
    1671         return tmp
    1672 
    1673     def _round_ceiling(self, prec, expdiff, context):
    1674         """Rounds up (not away from 0 if negative.)"""
    1675         if self._sign:
    1676             return self._round_down(prec, expdiff, context)
    1677         else:
    1678             return self._round_up(prec, expdiff, context)
    1679 
    1680     def _round_floor(self, prec, expdiff, context):
    1681         """Rounds down (not towards 0 if negative)"""
    1682         if not self._sign:
    1683             return self._round_down(prec, expdiff, context)
    1684         else:
    1685             return self._round_up(prec, expdiff, context)
    1686 
    1687     def __pow__(self, n, modulo = None, context=None):
    1688         """Return self ** n (mod modulo)
    1689 
    1690         If modulo is None (default), don't take it mod modulo.
    1691         """
    1692         n = _convert_other(n)
    1693         if n is NotImplemented:
    1694             return n
    1695 
    1696         if context is None:
    1697             context = getcontext()
    1698 
    1699         if self._is_special or n._is_special or n.adjusted() > 8:
    1700             #Because the spot << doesn't work with really big exponents
    1701             if n._isinfinity() or n.adjusted() > 8:
    1702                 return context._raise_error(InvalidOperation, 'x ** INF')
    1703 
    1704             ans = self._check_nans(n, context)
    1705             if ans:
    1706                 return ans
    1707 
    1708         if not n._isinteger():
    1709             return context._raise_error(InvalidOperation, 'x ** (non-integer)')
    1710 
    1711         if not self and not n:
    1712             return context._raise_error(InvalidOperation, '0 ** 0')
    1713 
    1714         if not n:
    1715             return Decimal(1)
    1716 
    1717         if self == Decimal(1):
    1718             return Decimal(1)
    1719 
    1720         sign = self._sign and not n._iseven()
    1721         n = int(n)
    1722 
    1723         if self._isinfinity():
    1724             if modulo:
    1725                 return context._raise_error(InvalidOperation, 'INF % x')
    1726             if n > 0:
    1727                 return Infsign[sign]
    1728             return Decimal( (sign, (0,), 0) )
    1729 
    1730         #with ludicrously large exponent, just raise an overflow and return inf.
    1731         if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
    1732            and self:
    1733 
    1734             tmp = Decimal('inf')
    1735             tmp._sign = sign
    1736             context._raise_error(Rounded)
    1737             context._raise_error(Inexact)
    1738             context._raise_error(Overflow, 'Big power', sign)
    1739             return tmp
    1740 
    1741         elength = len(str(abs(n)))
    1742         firstprec = context.prec
    1743 
    1744         if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
    1745             return context._raise_error(Overflow, 'Too much precision.', sign)
    1746 
    1747         mul = Decimal(self)
    1748         val = Decimal(1)
    1749         context = context._shallow_copy()
    1750         context.prec = firstprec + elength + 1
    1751         if n < 0:
    1752             #n is a long now, not Decimal instance
    1753             n = -n
    1754             mul = Decimal(1).__div__(mul, context=context)
    1755 
    1756         spot = 1
    1757         while spot <= n:
    1758             spot <<= 1
    1759 
    1760         spot >>= 1
    1761         #Spot is the highest power of 2 less than n
    1762         while spot:
    1763             val = val.__mul__(val, context=context)
    1764             if val._isinfinity():
    1765                 val = Infsign[sign]
    1766                 break
    1767             if spot & n:
    1768                 val = val.__mul__(mul, context=context)
    1769             if modulo is not None:
    1770                 val = val.__mod__(modulo, context=context)
    1771             spot >>= 1
    1772         context.prec = firstprec
    1773 
    1774         if context._rounding_decision == ALWAYS_ROUND:
    1775             return val._fix(context)
    1776         return val
    1777 
    1778     def __rpow__(self, other, context=None):
    1779         """Swaps self/other and returns __pow__."""
    1780         other = _convert_other(other)
    1781         if other is NotImplemented:
    1782             return other
    1783         return other.__pow__(self, context=context)
    1784 
    1785     def normalize(self, context=None):
    1786         """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
    1787 
    1788         if self._is_special:
    1789             ans = self._check_nans(context=context)
    1790             if ans:
    1791                 return ans
    1792 
    1793         dup = self._fix(context)
    1794         if dup._isinfinity():
    1795             return dup
    1796 
    1797         if not dup:
    1798             return Decimal( (dup._sign, (0,), 0) )
    1799         end = len(dup._int)
    1800         exp = dup._exp
    1801         while dup._int[end-1] == 0:
    1802             exp += 1
    1803             end -= 1
    1804         return Decimal( (dup._sign, dup._int[:end], exp) )
    1805 
    1806 
    1807     def quantize(self, exp, rounding=None, context=None, watchexp=1):
    1808         """Quantize self so its exponent is the same as that of exp.
    1809 
    1810         Similar to self._rescale(exp._exp) but with error checking.
    1811         """
    1812         if self._is_special or exp._is_special:
    1813             ans = self._check_nans(exp, context)
    1814             if ans:
    1815                 return ans
    1816 
    1817             if exp._isinfinity() or self._isinfinity():
    1818                 if exp._isinfinity() and self._isinfinity():
    1819                     return self  #if both are inf, it is OK
    1820                 if context is None:
    1821                     context = getcontext()
    1822                 return context._raise_error(InvalidOperation,
    1823                                         'quantize with one INF')
    1824         return self._rescale(exp._exp, rounding, context, watchexp)
    1825 
    1826     def same_quantum(self, other):
    1827         """Test whether self and other have the same exponent.
    1828 
    1829         same as self._exp == other._exp, except NaN == sNaN
    1830         """
    1831         if self._is_special or other._is_special:
    1832             if self._isnan() or other._isnan():
    1833                 return self._isnan() and other._isnan() and True
    1834             if self._isinfinity() or other._isinfinity():
    1835                 return self._isinfinity() and other._isinfinity() and True
    1836         return self._exp == other._exp
    1837 
    1838     def _rescale(self, exp, rounding=None, context=None, watchexp=1):
    1839         """Rescales so that the exponent is exp.
    1840 
    1841         exp = exp to scale to (an integer)
    1842         rounding = rounding version
    1843         watchexp: if set (default) an error is returned if exp is greater
    1844         than Emax or less than Etiny.
    1845         """
    1846         if context is None:
    1847             context = getcontext()
    1848 
    1849         if self._is_special:
    1850             if self._isinfinity():
    1851                 return context._raise_error(InvalidOperation, 'rescale with an INF')
    1852 
    1853             ans = self._check_nans(context=context)
    1854             if ans:
    1855                 return ans
    1856 
    1857         if watchexp and (context.Emax  < exp or context.Etiny() > exp):
    1858             return context._raise_error(InvalidOperation, 'rescale(a, INF)')
    1859 
    1860         if not self:
    1861             ans = Decimal(self)
    1862             ans._int = (0,)
    1863             ans._exp = exp
    1864             return ans
    1865 
    1866         diff = self._exp - exp
    1867         digits = len(self._int) + diff
    1868 
    1869         if watchexp and digits > context.prec:
    1870             return context._raise_error(InvalidOperation, 'Rescale > prec')
    1871 
    1872         tmp = Decimal(self)
    1873         tmp._int = (0,) + tmp._int
    1874         digits += 1
    1875 
    1876         if digits < 0:
    1877             tmp._exp = -digits + tmp._exp
    1878             tmp._int = (0,1)
    1879             digits = 1
    1880         tmp = tmp._round(digits, rounding, context=context)
    1881 
    1882         if tmp._int[0] == 0 and len(tmp._int) > 1:
    1883             tmp._int = tmp._int[1:]
    1884         tmp._exp = exp
    1885 
    1886         tmp_adjusted = tmp.adjusted()
    1887         if tmp and tmp_adjusted < context.Emin:
    1888             context._raise_error(Subnormal)
    1889         elif tmp and tmp_adjusted > context.Emax:
    1890             return context._raise_error(InvalidOperation, 'rescale(a, INF)')
    1891         return tmp
    1892 
    1893     def to_integral(self, rounding=None, context=None):
    1894         """Rounds to the nearest integer, without raising inexact, rounded."""
    1895         if self._is_special:
    1896             ans = self._check_nans(context=context)
    1897             if ans:
    1898                 return ans
    1899         if self._exp >= 0:
    1900             return self
    1901         if context is None:
    1902             context = getcontext()
    1903         flags = context._ignore_flags(Rounded, Inexact)
    1904         ans = self._rescale(0, rounding, context=context)
    1905         context._regard_flags(flags)
    1906         return ans
    1907 
    1908     def sqrt(self, context=None):
    1909         """Return the square root of self.
    1910 
    1911         Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
    1912         Should quadratically approach the right answer.
    1913         """
    1914         if self._is_special:
    1915             ans = self._check_nans(context=context)
    1916             if ans:
    1917                 return ans
    1918 
    1919             if self._isinfinity() and self._sign == 0:
    1920                 return Decimal(self)
    1921 
    1922         if not self:
    1923             #exponent = self._exp / 2, using round_down.
    1924             #if self._exp < 0:
    1925             #    exp = (self._exp+1) // 2
    1926             #else:
    1927             exp = (self._exp) // 2
    1928             if self._sign == 1:
    1929                 #sqrt(-0) = -0
    1930                 return Decimal( (1, (0,), exp))
    1931             else:
    1932                 return Decimal( (0, (0,), exp))
    1933 
    1934         if context is None:
    1935             context = getcontext()
    1936 
    1937         if self._sign == 1:
    1938             return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
    1939 
    1940         tmp = Decimal(self)
    1941 
    1942         expadd = tmp._exp // 2
    1943         if tmp._exp & 1:
    1944             tmp._int += (0,)
    1945             tmp._exp = 0
    1946         else:
    1947             tmp._exp = 0
    1948 
    1949         context = context._shallow_copy()
    1950         flags = context._ignore_all_flags()
    1951         firstprec = context.prec
    1952         context.prec = 3
    1953         if tmp.adjusted() & 1 == 0:
    1954             ans = Decimal( (0, (8,1,9), tmp.adjusted()  - 2) )
    1955             ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
    1956                                           context=context), context=context)
    1957             ans._exp -= 1 + tmp.adjusted() // 2
    1958         else:
    1959             ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
    1960             ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
    1961                                           context=context), context=context)
    1962             ans._exp -= 1 + tmp.adjusted()  // 2
    1963 
    1964         #ans is now a linear approximation.
    1965 
    1966         Emax, Emin = context.Emax, context.Emin
    1967         context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
    1968 
    1969         half = Decimal('0.5')
    1970 
    1971         maxp = firstprec + 2
    1972         rounding = context._set_rounding(ROUND_HALF_EVEN)
    1973         while 1:
    1974             context.prec = min(2*context.prec - 2, maxp)
    1975             ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
    1976                                            context=context), context=context)
    1977             if context.prec == maxp:
    1978                 break
    1979 
    1980         #round to the answer's precision-- the only error can be 1 ulp.
    1981         context.prec = firstprec
    1982         prevexp = ans.adjusted()
    1983         ans = ans._round(context=context)
    1984 
    1985         #Now, check if the other last digits are better.
    1986         context.prec = firstprec + 1
    1987         # In case we rounded up another digit and we should actually go lower.
    1988         if prevexp != ans.adjusted():
    1989             ans._int += (0,)
    1990             ans._exp -= 1
    1991 
    1992 
    1993         lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
    1994         context._set_rounding(ROUND_UP)
    1995         if lower.__mul__(lower, context=context) > (tmp):
    1996             ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
    1997 
    1998         else:
    1999             upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
    2000             context._set_rounding(ROUND_DOWN)
    2001             if upper.__mul__(upper, context=context) < tmp:
    2002                 ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
    2003 
    2004         ans._exp += expadd
    2005 
    2006         context.prec = firstprec
    2007         context.rounding = rounding
    2008         ans = ans._fix(context)
    2009 
    2010         rounding = context._set_rounding_decision(NEVER_ROUND)
    2011         if not ans.__mul__(ans, context=context) == self:
    2012             # Only rounded/inexact if here.
    2013             context._regard_flags(flags)
    2014             context._raise_error(Rounded)
    2015             context._raise_error(Inexact)
    2016         else:
    2017             #Exact answer, so let's set the exponent right.
    2018             #if self._exp < 0:
    2019             #    exp = (self._exp +1)// 2
    2020             #else:
    2021             exp = self._exp // 2
    2022             context.prec += ans._exp - exp
    2023             ans = ans._rescale(exp, context=context)
    2024             context.prec = firstprec
    2025             context._regard_flags(flags)
    2026         context.Emax, context.Emin = Emax, Emin
    2027 
    2028         return ans._fix(context)
    2029 
    2030     def max(self, other, context=None):
    2031         """Returns the larger value.
    2032 
    2033         like max(self, other) except if one is not a number, returns
    2034         NaN (and signals if one is sNaN).  Also rounds.
    2035         """
    2036         other = _convert_other(other)
    2037         if other is NotImplemented:
    2038             return other
    2039 
    2040         if self._is_special or other._is_special:
    2041             # if one operand is a quiet NaN and the other is number, then the
    2042             # number is always returned
    2043             sn = self._isnan()
    2044             on = other._isnan()
    2045             if sn or on:
    2046                 if on == 1 and sn != 2:
    2047                     return self
    2048                 if sn == 1 and on != 2:
    2049                     return other
    2050                 return self._check_nans(other, context)
    2051 
    2052         ans = self
    2053         c = self.__cmp__(other)
    2054         if c == 0:
    2055             # if both operands are finite and equal in numerical value
    2056             # then an ordering is applied:
    2057             #
    2058             # if the signs differ then max returns the operand with the
    2059             # positive sign and min returns the operand with the negative sign
    2060             #
    2061             # if the signs are the same then the exponent is used to select
    2062             # the result.
    2063             if self._sign != other._sign:
    2064                 if self._sign:
    2065                     ans = other
    2066             elif self._exp < other._exp and not self._sign:
    2067                 ans = other
    2068             elif self._exp > other._exp and self._sign:
    2069                 ans = other
    2070         elif c == -1:
    2071             ans = other
    2072 
    2073         if context is None:
    2074             context = getcontext()
    2075         if context._rounding_decision == ALWAYS_ROUND:
    2076             return ans._fix(context)
    2077         return ans
    2078 
    2079     def min(self, other, context=None):
    2080         """Returns the smaller value.
    2081 
    2082         like min(self, other) except if one is not a number, returns
    2083         NaN (and signals if one is sNaN).  Also rounds.
    2084         """
    2085         other = _convert_other(other)
    2086         if other is NotImplemented:
    2087             return other
    2088 
    2089         if self._is_special or other._is_special:
    2090             # if one operand is a quiet NaN and the other is number, then the
    2091             # number is always returned
    2092             sn = self._isnan()
    2093             on = other._isnan()
    2094             if sn or on:
    2095                 if on == 1 and sn != 2:
    2096                     return self
    2097                 if sn == 1 and on != 2:
    2098                     return other
    2099                 return self._check_nans(other, context)
    2100 
    2101         ans = self
    2102         c = self.__cmp__(other)
    2103         if c == 0:
    2104             # if both operands are finite and equal in numerical value
    2105             # then an ordering is applied:
    2106             #
    2107             # if the signs differ then max returns the operand with the
    2108             # positive sign and min returns the operand with the negative sign
    2109             #
    2110             # if the signs are the same then the exponent is used to select
    2111             # the result.
    2112             if self._sign != other._sign:
    2113                 if other._sign:
    2114                     ans = other
    2115             elif self._exp > other._exp and not self._sign:
    2116                 ans = other
    2117             elif self._exp < other._exp and self._sign:
    2118                 ans = other
    2119         elif c == 1:
    2120             ans = other
    2121 
    2122         if context is None:
    2123             context = getcontext()
    2124         if context._rounding_decision == ALWAYS_ROUND:
    2125             return ans._fix(context)
    2126         return ans
    2127 
    2128     def _isinteger(self):
    2129         """Returns whether self is an integer"""
    2130         if self._exp >= 0:
    2131             return True
    2132         rest = self._int[self._exp:]
    2133         return rest == (0,)*len(rest)
    2134 
    2135     def _iseven(self):
    2136         """Returns 1 if self is even.  Assumes self is an integer."""
    2137         if self._exp > 0:
    2138             return 1
    2139         return self._int[-1+self._exp] & 1 == 0
    2140 
    2141     def adjusted(self):
    2142         """Return the adjusted exponent of self"""
    2143         try:
    2144             return self._exp + len(self._int) - 1
    2145         #If NaN or Infinity, self._exp is string
    2146         except TypeError:
    2147             return 0
    2148 
    2149     # support for pickling, copy, and deepcopy
    2150     def __reduce__(self):
    2151         return (self.__class__, (str(self),))
    2152 
    2153     def __copy__(self):
    2154         if type(self) == Decimal:
    2155             return self     # I'm immutable; therefore I am my own clone
    2156         return self.__class__(str(self))
    2157 
    2158     def __deepcopy__(self, memo):
    2159         if type(self) == Decimal:
    2160             return self     # My components are also immutable
    2161         return self.__class__(str(self))
    2162 
    2163 ##### Context class ###########################################
    2164 
    2165 
    2166 # get rounding method function:
    2167 rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
    2168 for name in rounding_functions:
    2169     #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
    2170     globalname = name[1:].upper()
    2171     val = globals()[globalname]
    2172     Decimal._pick_rounding_function[val] = name
    2173 
    2174 del name, val, globalname, rounding_functions
    2175 
    2176 class Context(object):
    2177     """Contains the context for a Decimal instance.
    2178 
    2179     Contains:
    2180     prec - precision (for use in rounding, division, square roots..)
    2181     rounding - rounding type. (how you round)
    2182     _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
    2183     traps - If traps[exception] = 1, then the exception is
    2184                     raised when it is caused.  Otherwise, a value is
    2185                     substituted in.
    2186     flags  - When an exception is caused, flags[exception] is incremented.
    2187              (Whether or not the trap_enabler is set)
    2188              Should be reset by user of Decimal instance.
    2189     Emin -   Minimum exponent
    2190     Emax -   Maximum exponent
    2191     capitals -      If 1, 1*10^1 is printed as 1E+1.
    2192                     If 0, printed as 1e1
    2193     _clamp - If 1, change exponents if too high (Default 0)
    2194     """
    2195 
    2196     def __init__(self, prec=None, rounding=None,
    2197                  traps=None, flags=None,
    2198                  _rounding_decision=None,
    2199                  Emin=None, Emax=None,
    2200                  capitals=None, _clamp=0,
    2201                  _ignored_flags=None):
    2202         if flags is None:
    2203             flags = []
    2204         if _ignored_flags is None:
    2205             _ignored_flags = []
    2206         if not isinstance(flags, dict):
    2207             flags = dict([(s,s in flags) for s in _signals])
    2208             del s
    2209         if traps is not None and not isinstance(traps, dict):
    2210             traps = dict([(s,s in traps) for s in _signals])
    2211             del s
    2212         for name, val in locals().items():
    2213             if val is None:
    2214                 setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
    2215             else:
    2216                 setattr(self, name, val)
    2217         del self.self
    2218 
    2219     def __repr__(self):
    2220         """Show the current context."""
    2221         s = []
    2222         s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
    2223         s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
    2224         s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
    2225         return ', '.join(s) + ')'
    2226 
    2227     def clear_flags(self):
    2228         """Reset all flags to zero"""
    2229         for flag in self.flags:
    2230             self.flags[flag] = 0
    2231 
    2232     def _shallow_copy(self):
    2233         """Returns a shallow copy from self."""
    2234         nc = Context(self.prec, self.rounding, self.traps, self.flags,
    2235                          self._rounding_decision, self.Emin, self.Emax,
    2236                          self.capitals, self._clamp, self._ignored_flags)
    2237         return nc
    2238 
    2239     def copy(self):
    2240         """Returns a deep copy from self."""
    2241         nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
    2242                          self._rounding_decision, self.Emin, self.Emax,
    2243                          self.capitals, self._clamp, self._ignored_flags)
    2244         return nc
    2245     __copy__ = copy
    2246 
    2247     def _raise_error(self, condition, explanation = None, *args):
    2248         """Handles an error
    2249 
    2250         If the flag is in _ignored_flags, returns the default response.
    2251         Otherwise, it increments the flag, then, if the corresponding
    2252         trap_enabler is set, it reaises the exception.  Otherwise, it returns
    2253         the default value after incrementing the flag.
    2254         """
    2255         error = _condition_map.get(condition, condition)
    2256         if error in self._ignored_flags:
    2257             #Don't touch the flag
    2258             return error().handle(self, *args)
    2259 
    2260         self.flags[error] += 1
    2261         if not self.traps[error]:
    2262             #The errors define how to handle themselves.
    2263             return condition().handle(self, *args)
    2264 
    2265         # Errors should only be risked on copies of the context
    2266         #self._ignored_flags = []
    2267         raise error, explanation
    2268 
    2269     def _ignore_all_flags(self):
    2270         """Ignore all flags, if they are raised"""
    2271         return self._ignore_flags(*_signals)
    2272 
    2273     def _ignore_flags(self, *flags):
    2274         """Ignore the flags, if they are raised"""
    2275         # Do not mutate-- This way, copies of a context leave the original
    2276         # alone.
    2277         self._ignored_flags = (self._ignored_flags + list(flags))
    2278         return list(flags)
    2279 
    2280     def _regard_flags(self, *flags):
    2281         """Stop ignoring the flags, if they are raised"""
    2282         if flags and isinstance(flags[0], (tuple,list)):
    2283             flags = flags[0]
    2284         for flag in flags:
    2285             self._ignored_flags.remove(flag)
    2286 
    2287     def __hash__(self):
    2288         """A Context cannot be hashed."""
    2289         # We inherit object.__hash__, so we must deny this explicitly
    2290         raise TypeError, "Cannot hash a Context."
    2291 
    2292     def Etiny(self):
    2293         """Returns Etiny (= Emin - prec + 1)"""
    2294         return int(self.Emin - self.prec + 1)
    2295 
    2296     def Etop(self):
    2297         """Returns maximum exponent (= Emax - prec + 1)"""
    2298         return int(self.Emax - self.prec + 1)
    2299 
    2300     def _set_rounding_decision(self, type):
    2301         """Sets the rounding decision.
    2302 
    2303         Sets the rounding decision, and returns the current (previous)
    2304         rounding decision.  Often used like:
    2305 
    2306         context = context._shallow_copy()
    2307         # That so you don't change the calling context
    2308         # if an error occurs in the middle (say DivisionImpossible is raised).
    2309 
    2310         rounding = context._set_rounding_decision(NEVER_ROUND)
    2311         instance = instance / Decimal(2)
    2312         context._set_rounding_decision(rounding)
    2313 
    2314         This will make it not round for that operation.
    2315         """
    2316 
    2317         rounding = self._rounding_decision
    2318         self._rounding_decision = type
    2319         return rounding
    2320 
    2321     def _set_rounding(self, type):
    2322         """Sets the rounding type.
    2323 
    2324         Sets the rounding type, and returns the current (previous)
    2325         rounding type.  Often used like:
    2326 
    2327         context = context.copy()
    2328         # so you don't change the calling context
    2329         # if an error occurs in the middle.
    2330         rounding = context._set_rounding(ROUND_UP)
    2331         val = self.__sub__(other, context=context)
    2332         context._set_rounding(rounding)
    2333 
    2334         This will make it round up for that operation.
    2335         """
    2336         rounding = self.rounding
    2337         self.rounding= type
    2338         return rounding
    2339 
    2340     def create_decimal(self, num='0'):
    2341         """Creates a new Decimal instance but using self as context."""
    2342         d = Decimal(num, context=self)
    2343         return d._fix(self)
    2344 
    2345     #Methods
    2346     def abs(self, a):
    2347         """Returns the absolute value of the operand.
    2348 
    2349         If the operand is negative, the result is the same as using the minus
    2350         operation on the operand. Otherwise, the result is the same as using
    2351         the plus operation on the operand.
    2352 
    2353         >>> ExtendedContext.abs(Decimal('2.1'))
    2354         Decimal("2.1")
    2355         >>> ExtendedContext.abs(Decimal('-100'))
    2356         Decimal("100")
    2357         >>> ExtendedContext.abs(Decimal('101.5'))
    2358         Decimal("101.5")
    2359         >>> ExtendedContext.abs(Decimal('-101.5'))
    2360         Decimal("101.5")
    2361         """
    2362         return a.__abs__(context=self)
    2363 
    2364     def add(self, a, b):
    2365         """Return the sum of the two operands.
    2366 
    2367         >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
    2368         Decimal("19.00")
    2369         >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
    2370         Decimal("1.02E+4")
    2371         """
    2372         return a.__add__(b, context=self)
    2373 
    2374     def _apply(self, a):
    2375         return str(a._fix(self))
    2376 
    2377     def compare(self, a, b):
    2378         """Compares values numerically.
    2379 
    2380         If the signs of the operands differ, a value representing each operand
    2381         ('-1' if the operand is less than zero, '0' if the operand is zero or
    2382         negative zero, or '1' if the operand is greater than zero) is used in
    2383         place of that operand for the comparison instead of the actual
    2384         operand.
    2385 
    2386         The comparison is then effected by subtracting the second operand from
    2387         the first and then returning a value according to the result of the
    2388         subtraction: '-1' if the result is less than zero, '0' if the result is
    2389         zero or negative zero, or '1' if the result is greater than zero.
    2390 
    2391         >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
    2392         Decimal("-1")
    2393         >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
    2394         Decimal("0")
    2395         >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
    2396         Decimal("0")
    2397         >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
    2398         Decimal("1")
    2399         >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
    2400         Decimal("1")
    2401         >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
    2402         Decimal("-1")
    2403         """
    2404         return a.compare(b, context=self)
    2405 
    2406     def divide(self, a, b):
    2407         """Decimal division in a specified context.
    2408 
    2409         >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
    2410         Decimal("0.333333333")
    2411         >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
    2412         Decimal("0.666666667")
    2413         >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
    2414         Decimal("2.5")
    2415         >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
    2416         Decimal("0.1")
    2417         >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
    2418         Decimal("1")
    2419         >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
    2420         Decimal("4.00")
    2421         >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
    2422         Decimal("1.20")
    2423         >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
    2424         Decimal("10")
    2425         >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
    2426         Decimal("1000")
    2427         >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
    2428         Decimal("1.20E+6")
    2429         """
    2430         return a.__div__(b, context=self)
    2431 
    2432     def divide_int(self, a, b):
    2433         """Divides two numbers and returns the integer part of the result.
    2434 
    2435         >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
    2436         Decimal("0")
    2437         >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
    2438         Decimal("3")
    2439         >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
    2440         Decimal("3")
    2441         """
    2442         return a.__floordiv__(b, context=self)
    2443 
    2444     def divmod(self, a, b):
    2445         return a.__divmod__(b, context=self)
    2446 
    2447     def max(self, a,b):
    2448         """max compares two values numerically and returns the maximum.
    2449 
    2450         If either operand is a NaN then the general rules apply.
    2451         Otherwise, the operands are compared as as though by the compare
    2452         operation. If they are numerically equal then the left-hand operand
    2453         is chosen as the result. Otherwise the maximum (closer to positive
    2454         infinity) of the two operands is chosen as the result.
    2455 
    2456         >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
    2457         Decimal("3")
    2458         >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
    2459         Decimal("3")
    2460         >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
    2461         Decimal("1")
    2462         >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
    2463         Decimal("7")
    2464         """
    2465         return a.max(b, context=self)
    2466 
    2467     def min(self, a,b):
    2468         """min compares two values numerically and returns the minimum.
    2469 
    2470         If either operand is a NaN then the general rules apply.
    2471         Otherwise, the operands are compared as as though by the compare
    2472         operation. If they are numerically equal then the left-hand operand
    2473         is chosen as the result. Otherwise the minimum (closer to negative
    2474         infinity) of the two operands is chosen as the result.
    2475 
    2476         >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
    2477         Decimal("2")
    2478         >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
    2479         Decimal("-10")
    2480         >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
    2481         Decimal("1.0")
    2482         >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
    2483         Decimal("7")
    2484         """
    2485         return a.min(b, context=self)
    2486 
    2487     def minus(self, a):
    2488         """Minus corresponds to unary prefix minus in Python.
    2489 
    2490         The operation is evaluated using the same rules as subtract; the
    2491         operation minus(a) is calculated as subtract('0', a) where the '0'
    2492         has the same exponent as the operand.
    2493 
    2494         >>> ExtendedContext.minus(Decimal('1.3'))
    2495         Decimal("-1.3")
    2496         >>> ExtendedContext.minus(Decimal('-1.3'))
    2497         Decimal("1.3")
    2498         """
    2499         return a.__neg__(context=self)
    2500 
    2501     def multiply(self, a, b):
    2502         """multiply multiplies two operands.
    2503 
    2504         If either operand is a special value then the general rules apply.
    2505         Otherwise, the operands are multiplied together ('long multiplication'),
    2506         resulting in a number which may be as long as the sum of the lengths
    2507         of the two operands.
    2508 
    2509         >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
    2510         Decimal("3.60")
    2511         >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
    2512         Decimal("21")
    2513         >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
    2514         Decimal("0.72")
    2515         >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
    2516         Decimal("-0.0")
    2517         >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
    2518         Decimal("4.28135971E+11")
    2519         """
    2520         return a.__mul__(b, context=self)
    2521 
    2522     def normalize(self, a):
    2523         """normalize reduces an operand to its simplest form.
    2524 
    2525         Essentially a plus operation with all trailing zeros removed from the
    2526         result.
    2527 
    2528         >>> ExtendedContext.normalize(Decimal('2.1'))
    2529         Decimal("2.1")
    2530         >>> ExtendedContext.normalize(Decimal('-2.0'))
    2531         Decimal("-2")
    2532         >>> ExtendedContext.normalize(Decimal('1.200'))
    2533         Decimal("1.2")
    2534         >>> ExtendedContext.normalize(Decimal('-120'))
    2535         Decimal("-1.2E+2")
    2536         >>> ExtendedContext.normalize(Decimal('120.00'))
    2537         Decimal("1.2E+2")
    2538         >>> ExtendedContext.normalize(Decimal('0.00'))
    2539         Decimal("0")
    2540         """
    2541         return a.normalize(context=self)
    2542 
    2543     def plus(self, a):
    2544         """Plus corresponds to unary prefix plus in Python.
    2545 
    2546         The operation is evaluated using the same rules as add; the
    2547         operation plus(a) is calculated as add('0', a) where the '0'
    2548         has the same exponent as the operand.
    2549 
    2550         >>> ExtendedContext.plus(Decimal('1.3'))
    2551         Decimal("1.3")
    2552         >>> ExtendedContext.plus(Decimal('-1.3'))
    2553         Decimal("-1.3")
    2554         """
    2555         return a.__pos__(context=self)
    2556 
    2557     def power(self, a, b, modulo=None):
    2558         """Raises a to the power of b, to modulo if given.
    2559 
    2560         The right-hand operand must be a whole number whose integer part (after
    2561         any exponent has been applied) has no more than 9 digits and whose
    2562         fractional part (if any) is all zeros before any rounding. The operand
    2563         may be positive, negative, or zero; if negative, the absolute value of
    2564         the power is used, and the left-hand operand is inverted (divided into
    2565         1) before use.
    2566 
    2567         If the increased precision needed for the intermediate calculations
    2568         exceeds the capabilities of the implementation then an Invalid operation
    2569         condition is raised.
    2570 
    2571         If, when raising to a negative power, an underflow occurs during the
    2572         division into 1, the operation is not halted at that point but
    2573         continues.
    2574 
    2575         >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
    2576         Decimal("8")
    2577         >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
    2578         Decimal("0.125")
    2579         >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
    2580         Decimal("69.7575744")
    2581         >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
    2582         Decimal("0")
    2583         >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
    2584         Decimal("0")
    2585         >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
    2586         Decimal("1")
    2587         >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
    2588         Decimal("Infinity")
    2589         >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
    2590         Decimal("Infinity")
    2591         >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
    2592         Decimal("0")
    2593         >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
    2594         Decimal("-0")
    2595         >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
    2596         Decimal("1")
    2597         >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
    2598         Decimal("-Infinity")
    2599         >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
    2600         Decimal("Infinity")
    2601         >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
    2602         Decimal("NaN")
    2603         """
    2604         return a.__pow__(b, modulo, context=self)
    2605 
    2606     def quantize(self, a, b):
    2607         """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
    2608 
    2609         The coefficient of the result is derived from that of the left-hand
    2610         operand. It may be rounded using the current rounding setting (if the
    2611         exponent is being increased), multiplied by a positive power of ten (if
    2612         the exponent is being decreased), or is unchanged (if the exponent is
    2613         already equal to that of the right-hand operand).
    2614 
    2615         Unlike other operations, if the length of the coefficient after the
    2616         quantize operation would be greater than precision then an Invalid
    2617         operation condition is raised. This guarantees that, unless there is an
    2618         error condition, the exponent of the result of a quantize is always
    2619         equal to that of the right-hand operand.
    2620 
    2621         Also unlike other operations, quantize will never raise Underflow, even
    2622         if the result is subnormal and inexact.
    2623 
    2624         >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
    2625         Decimal("2.170")
    2626         >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
    2627         Decimal("2.17")
    2628         >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
    2629         Decimal("2.2")
    2630         >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
    2631         Decimal("2")
    2632         >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
    2633         Decimal("0E+1")
    2634         >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
    2635         Decimal("-Infinity")
    2636         >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
    2637         Decimal("NaN")
    2638         >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
    2639         Decimal("-0")
    2640         >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
    2641         Decimal("-0E+5")
    2642         >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
    2643         Decimal("NaN")
    2644         >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
    2645         Decimal("NaN")
    2646         >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
    2647         Decimal("217.0")
    2648         >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
    2649         Decimal("217")
    2650         >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
    2651         Decimal("2.2E+2")
    2652         >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
    2653         Decimal("2E+2")
    2654         """
    2655         return a.quantize(b, context=self)
    2656 
    2657     def remainder(self, a, b):
    2658         """Returns the remainder from integer division.
    2659 
    2660         The result is the residue of the dividend after the operation of
    2661         calculating integer division as described for divide-integer, rounded to
    2662         precision digits if necessary. The sign of the result, if non-zero, is
    2663         the same as that of the original dividend.
    2664 
    2665         This operation will fail under the same conditions as integer division
    2666         (that is, if integer division on the same two operands would fail, the
    2667         remainder cannot be calculated).
    2668 
    2669         >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
    2670         Decimal("2.1")
    2671         >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
    2672         Decimal("1")
    2673         >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
    2674         Decimal("-1")
    2675         >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
    2676         Decimal("0.2")
    2677         >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
    2678         Decimal("0.1")
    2679         >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
    2680         Decimal("1.0")
    2681         """
    2682         return a.__mod__(b, context=self)
    2683 
    2684     def remainder_near(self, a, b):
    2685         """Returns to be "a - b * n", where n is the integer nearest the exact
    2686         value of "x / b" (if two integers are equally near then the even one
    2687         is chosen). If the result is equal to 0 then its sign will be the
    2688         sign of a.
    2689 
    2690         This operation will fail under the same conditions as integer division
    2691         (that is, if integer division on the same two operands would fail, the
    2692         remainder cannot be calculated).
    2693 
    2694         >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
    2695         Decimal("-0.9")
    2696         >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
    2697         Decimal("-2")
    2698         >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
    2699         Decimal("1")
    2700         >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
    2701         Decimal("-1")
    2702         >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
    2703         Decimal("0.2")
    2704         >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
    2705         Decimal("0.1")
    2706         >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
    2707         Decimal("-0.3")
    2708         """
    2709         return a.remainder_near(b, context=self)
    2710 
    2711     def same_quantum(self, a, b):
    2712         """Returns True if the two operands have the same exponent.
    2713 
    2714         The result is never affected by either the sign or the coefficient of
    2715         either operand.
    2716 
    2717         >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
    2718         False
    2719         >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
    2720         True
    2721         >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
    2722         False
    2723         >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
    2724         True
    2725         """
    2726         return a.same_quantum(b)
    2727 
    2728     def sqrt(self, a):
    2729         """Returns the square root of a non-negative number to context precision.
    2730 
    2731         If the result must be inexact, it is rounded using the round-half-even
    2732         algorithm.
    2733 
    2734         >>> ExtendedContext.sqrt(Decimal('0'))
    2735         Decimal("0")
    2736         >>> ExtendedContext.sqrt(Decimal('-0'))
    2737         Decimal("-0")
    2738         >>> ExtendedContext.sqrt(Decimal('0.39'))
    2739         Decimal("0.624499800")
    2740         >>> ExtendedContext.sqrt(Decimal('100'))
    2741         Decimal("10")
    2742         >>> ExtendedContext.sqrt(Decimal('1'))
    2743         Decimal("1")
    2744         >>> ExtendedContext.sqrt(Decimal('1.0'))
    2745         Decimal("1.0")
    2746         >>> ExtendedContext.sqrt(Decimal('1.00'))
    2747         Decimal("1.0")
    2748         >>> ExtendedContext.sqrt(Decimal('7'))
    2749         Decimal("2.64575131")
    2750         >>> ExtendedContext.sqrt(Decimal('10'))
    2751         Decimal("3.16227766")
    2752         >>> ExtendedContext.prec
    2753         9
    2754         """
    2755         return a.sqrt(context=self)
    2756 
    2757     def subtract(self, a, b):
    2758         """Return the difference between the two operands.
    2759 
    2760         >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
    2761         Decimal("0.23")
    2762         >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
    2763         Decimal("0.00")
    2764         >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
    2765         Decimal("-0.77")
    2766         """
    2767         return a.__sub__(b, context=self)
    2768 
    2769     def to_eng_string(self, a):
    2770         """Converts a number to a string, using scientific notation.
    2771 
    2772         The operation is not affected by the context.
    2773         """
    2774         return a.to_eng_string(context=self)
    2775 
    2776     def to_sci_string(self, a):
    2777         """Converts a number to a string, using scientific notation.
    2778 
    2779         The operation is not affected by the context.
    2780         """
    2781         return a.__str__(context=self)
    2782 
    2783     def to_integral(self, a):
    2784         """Rounds to an integer.
    2785 
    2786         When the operand has a negative exponent, the result is the same
    2787         as using the quantize() operation using the given operand as the
    2788         left-hand-operand, 1E+0 as the right-hand-operand, and the precision
    2789         of the operand as the precision setting, except that no flags will
    2790         be set. The rounding mode is taken from the context.
    2791 
    2792         >>> ExtendedContext.to_integral(Decimal('2.1'))
    2793         Decimal("2")
    2794         >>> ExtendedContext.to_integral(Decimal('100'))
    2795         Decimal("100")
    2796         >>> ExtendedContext.to_integral(Decimal('100.0'))
    2797         Decimal("100")
    2798         >>> ExtendedContext.to_integral(Decimal('101.5'))
    2799         Decimal("102")
    2800         >>> ExtendedContext.to_integral(Decimal('-101.5'))
    2801         Decimal("-102")
    2802         >>> ExtendedContext.to_integral(Decimal('10E+5'))
    2803         Decimal("1.0E+6")
    2804         >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
    2805         Decimal("7.89E+77")
    2806         >>> ExtendedContext.to_integral(Decimal('-Inf'))
    2807         Decimal("-Infinity")
    2808         """
    2809         return a.to_integral(context=self)
    2810 
    2811 class _WorkRep(object):
    2812     __slots__ = ('sign','int','exp')
    2813     # sign: 0 or 1
    2814     # int:  int or long
    2815     # exp:  None, int, or string
    2816 
    2817     def __init__(self, value=None):
    2818         if value is None:
    2819             self.sign = None
    2820             self.int = 0
    2821             self.exp = None
    2822         elif isinstance(value, Decimal):
    2823             self.sign = value._sign
    2824             cum = 0
    2825             for digit  in value._int:
    2826                 cum = cum * 10 + digit
    2827             self.int = cum
    2828             self.exp = value._exp
    2829         else:
    2830             # assert isinstance(value, tuple)
    2831             self.sign = value[0]
    2832             self.int = value[1]
    2833             self.exp = value[2]
    2834 
    2835     def __repr__(self):
    2836         return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
    2837 
    2838     __str__ = __repr__
    2839 
    2840 
    2841 
    2842 def _normalize(op1, op2, shouldround = 0, prec = 0):
    2843     """Normalizes op1, op2 to have the same exp and length of coefficient.
    2844 
    2845     Done during addition.
    2846     """
    2847     # Yes, the exponent is a long, but the difference between exponents
    2848     # must be an int-- otherwise you'd get a big memory problem.
    2849     numdigits = int(op1.exp - op2.exp)
    2850     if numdigits < 0:
    2851         numdigits = -numdigits
    2852         tmp = op2
    2853         other = op1
    2854     else:
    2855         tmp = op1
    2856         other = op2
    2857 
    2858 
    2859     if shouldround and numdigits > prec + 1:
    2860         # Big difference in exponents - check the adjusted exponents
    2861         tmp_len = len(str(tmp.int))
    2862         other_len = len(str(other.int))
    2863         if numdigits > (other_len + prec + 1 - tmp_len):
    2864             # If the difference in adjusted exps is > prec+1, we know
    2865             # other is insignificant, so might as well put a 1 after the precision.
    2866             # (since this is only for addition.)  Also stops use of massive longs.
    2867 
    2868             extend = prec + 2 - tmp_len
    2869             if extend <= 0:
    2870                 extend = 1
    2871             tmp.int *= 10 ** extend
    2872             tmp.exp -= extend
    2873             other.int = 1
    2874             other.exp = tmp.exp
    2875             return op1, op2
    2876 
    2877     tmp.int *= 10 ** numdigits
    2878     tmp.exp -= numdigits
    2879     return op1, op2
    2880 
    2881 def _adjust_coefficients(op1, op2):
    2882     """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
    2883 
    2884     Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
    2885 
    2886     Used on _WorkRep instances during division.
    2887     """
    2888     adjust = 0
    2889     #If op1 is smaller, make it larger
    2890     while op2.int > op1.int:
    2891         op1.int *= 10
    2892         op1.exp -= 1
    2893         adjust += 1
    2894 
    2895     #If op2 is too small, make it larger
    2896     while op1.int >= (10 * op2.int):
    2897         op2.int *= 10
    2898         op2.exp -= 1
    2899         adjust -= 1
    2900 
    2901     return op1, op2, adjust
    2902 
    2903 ##### Helper Functions ########################################
    2904 
    2905 def _convert_other(other):
    2906     """Convert other to Decimal.
    2907 
    2908     Verifies that it's ok to use in an implicit construction.
    2909     """
    2910     if isinstance(other, Decimal):
    2911         return other
    2912     if isinstance(other, (int, long)):
    2913         return Decimal(other)
    2914     return NotImplemented
    2915 
    2916 _infinity_map = {
    2917     'inf' : 1,
    2918     'infinity' : 1,
    2919     '+inf' : 1,
    2920     '+infinity' : 1,
    2921     '-inf' : -1,
    2922     '-infinity' : -1
    2923 }
    2924 
    2925 def _isinfinity(num):
    2926     """Determines whether a string or float is infinity.
    2927 
    2928     +1 for negative infinity; 0 for finite ; +1 for positive infinity
    2929     """
    2930     num = str(num).lower()
    2931     return _infinity_map.get(num, 0)
    2932 
    2933 def _isnan(num):
    2934     """Determines whether a string or float is NaN
    2935 
    2936     (1, sign, diagnostic info as string) => NaN
    2937     (2, sign, diagnostic info as string) => sNaN
    2938     0 => not a NaN
    2939     """
    2940     num = str(num).lower()
    2941     if not num:
    2942         return 0
    2943 
    2944     #get the sign, get rid of trailing [+-]
    2945     sign = 0
    2946     if num[0] == '+':
    2947         num = num[1:]
    2948     elif num[0] == '-':  #elif avoids '+-nan'
    2949         num = num[1:]
    2950         sign = 1
    2951 
    2952     if num.startswith('nan'):
    2953         if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
    2954             return 0
    2955         return (1, sign, num[3:].lstrip('0'))
    2956     if num.startswith('snan'):
    2957         if len(num) > 4 and not num[4:].isdigit():
    2958             return 0
    2959         return (2, sign, num[4:].lstrip('0'))
    2960     return 0
    2961 
    2962 
    2963 ##### Setup Specific Contexts ################################
    2964 
    2965 # The default context prototype used by Context()
    2966 # Is mutable, so that new contexts can have different default values
    2967 
    2968 DefaultContext = Context(
    2969         prec=28, rounding=ROUND_HALF_EVEN,
    2970         traps=[DivisionByZero, Overflow, InvalidOperation],
    2971         flags=[],
    2972         _rounding_decision=ALWAYS_ROUND,
    2973         Emax=999999999,
    2974         Emin=-999999999,
    2975         capitals=1
    2976 )
    2977 
    2978 # Pre-made alternate contexts offered by the specification
    2979 # Don't change these; the user should be able to select these
    2980 # contexts and be able to reproduce results from other implementations
    2981 # of the spec.
    2982 
    2983 BasicContext = Context(
    2984         prec=9, rounding=ROUND_HALF_UP,
    2985         traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
    2986         flags=[],
    2987 )
    2988 
    2989 ExtendedContext = Context(
    2990         prec=9, rounding=ROUND_HALF_EVEN,
    2991         traps=[],
    2992         flags=[],
    2993 )
    2994 
    2995 
    2996 ##### Useful Constants (internal use only) ####################
    2997 
    2998 #Reusable defaults
    2999 Inf = Decimal('Inf')
    3000 negInf = Decimal('-Inf')
    3001 
    3002 #Infsign[sign] is infinity w/ that sign
    3003 Infsign = (Inf, negInf)
    3004 
    3005 NaN = Decimal('NaN')
    3006 
    3007 
    3008 ##### crud for parsing strings #################################
    3009 import re
    3010 
    3011 # There's an optional sign at the start, and an optional exponent
    3012 # at the end.  The exponent has an optional sign and at least one
    3013 # digit.  In between, must have either at least one digit followed
    3014 # by an optional fraction, or a decimal point followed by at least
    3015 # one digit.  Yuck.
    3016 
    3017 _parser = re.compile(r"""
    3018 #    \s*
    3019     (?P<sign>[-+])?
    3020     (
    3021         (?P<int>\d+) (\. (?P<frac>\d*))?
    3022     |
    3023         \. (?P<onlyfrac>\d+)
    3024     )
    3025     ([eE](?P<exp>[-+]? \d+))?
    3026 #    \s*
    3027     $
    3028 """, re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
    3029 
    3030 del re
    3031 
    3032 # return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
    3033 
    3034 def _string2exact(s):
    3035     m = _parser(s)
    3036     if m is None:
    3037         raise ValueError("invalid literal for Decimal: %r" % s)
    3038 
    3039     if m.group('sign') == "-":
    3040         sign = 1
    3041     else:
    3042         sign = 0
    3043 
    3044     exp = m.group('exp')
    3045     if exp is None:
    3046         exp = 0
    3047     else:
    3048         exp = int(exp)
    3049 
    3050     intpart = m.group('int')
    3051     if intpart is None:
    3052         intpart = ""
    3053         fracpart = m.group('onlyfrac')
    3054     else:
    3055         fracpart = m.group('frac')
    3056         if fracpart is None:
    3057             fracpart = ""
    3058 
    3059     exp -= len(fracpart)
    3060 
    3061     mantissa = intpart + fracpart
    3062     tmp = map(int, mantissa)
    3063     backup = tmp
    3064     while tmp and tmp[0] == 0:
    3065         del tmp[0]
    3066 
    3067     # It's a zero
    3068     if not tmp:
    3069         if backup:
    3070             return (sign, tuple(backup), exp)
    3071         return (sign, (0,), exp)
    3072     mantissa = tuple(tmp)
    3073 
    3074     return (sign, mantissa, exp)
    3075 
    3076 
    3077 if __name__ == '__main__':
    3078     import doctest, sys
    3079     doctest.testmod(sys.modules[__name__])
  • django/utils/functional.py

     
    6060# Summary of changes made to the Python 2.5 code below:
    6161#   * swapped ``partial`` for ``curry`` to maintain backwards-compatibility
    6262#     in Django.
    63 #   * Wrapped the ``setattr`` call in ``update_wrapper`` with a try-except
    64 #     block to make it compatible with Python 2.3, which doesn't allow
    65 #     assigning to ``__name__``.
    6663
    6764# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation.
    6865# All Rights Reserved.
     
    9087       function (defaults to functools.WRAPPER_UPDATES)
    9188    """
    9289    for attr in assigned:
    93         try:
    94             setattr(wrapper, attr, getattr(wrapped, attr))
    95         except TypeError: # Python 2.3 doesn't allow assigning to __name__.
    96             pass
     90        setattr(wrapper, attr, getattr(wrapped, attr))
    9791    for attr in updated:
    9892        getattr(wrapper, attr).update(getattr(wrapped, attr))
    9993    # Return the wrapper so this can be used as a decorator via curry()
  • django/utils/decorators.py

     
    44try:
    55    from functools import wraps, update_wrapper, WRAPPER_ASSIGNMENTS
    66except ImportError:
    7     from django.utils.functional import wraps, update_wrapper, WRAPPER_ASSIGNMENTS  # Python 2.3, 2.4 fallback.
     7    from django.utils.functional import wraps, update_wrapper, WRAPPER_ASSIGNMENTS  # Python 2.4 fallback.
    88
    99
    1010def method_decorator(decorator):
  • django/utils/itercompat.py

     
    66
    77import itertools
    88
    9 def compat_tee(iterable):
    10     """
    11     Return two independent iterators from a single iterable.
    12 
    13     Based on http://www.python.org/doc/2.3.5/lib/itertools-example.html
    14     """
    15     # Note: Using a dictionary and a list as the default arguments here is
    16     # deliberate and safe in this instance.
    17     def gen(next, data={}, cnt=[0]):
    18         dpop = data.pop
    19         for i in itertools.count():
    20             if i == cnt[0]:
    21                 item = data[i] = next()
    22                 cnt[0] += 1
    23             else:
    24                 item = dpop(i)
    25             yield item
    26     next = iter(iterable).next
    27     return gen(next), gen(next)
    28 
    29 def groupby(iterable, keyfunc=None):
    30     """
    31     Taken from http://docs.python.org/lib/itertools-functions.html
    32     """
    33     if keyfunc is None:
    34         keyfunc = lambda x:x
    35     iterable = iter(iterable)
    36     l = [iterable.next()]
    37     lastkey = keyfunc(l[0])
    38     for item in iterable:
    39         key = keyfunc(item)
    40         if key != lastkey:
    41             yield lastkey, l
    42             lastkey = key
    43             l = [item]
    44         else:
    45             l.append(item)
    46     yield lastkey, l
    47 
     9# Fallback for Python 2.4, Python 2.5
    4810def product(*args, **kwds):
    4911    """
    5012    Taken from http://docs.python.org/library/itertools.html#itertools.product
     
    5820    for prod in result:
    5921        yield tuple(prod)
    6022
    61 # Not really in itertools, since it's a builtin in Python 2.4 and later, but it
    62 # does operate as an iterator.
    63 def reversed(data):
    64     for index in xrange(len(data)-1, -1, -1):
    65         yield data[index]
    66 
    67 if hasattr(itertools, 'tee'):
    68     tee = itertools.tee
    69 else:
    70     tee = compat_tee
    71 if hasattr(itertools, 'groupby'):
    72     groupby = itertools.groupby
    7323if hasattr(itertools, 'product'):
    7424    product = itertools.product
    7525
     
    8232    else:
    8333        return True
    8434
    85 def sorted(in_value):
    86     "A naive implementation of sorted"
    87     out_value = in_value[:]
    88     out_value.sort()
    89     return out_value
    90 
    9135def all(iterable):
    9236    for item in iterable:
    9337        if not item:
  • django/utils/encoding.py

     
    33import locale
    44import datetime
    55import codecs
     6from decimal import Decimal
    67
    78from django.utils.functional import Promise
    89
    9 try:
    10     from decimal import Decimal
    11 except ImportError:
    12     from django.utils._decimal import Decimal # Python 2.3 fallback
    13 
    14 
    1510class DjangoUnicodeDecodeError(UnicodeDecodeError):
    1611    def __init__(self, obj, *args):
    1712        self.obj = obj
  • django/contrib/formtools/utils.py

     
    3232    data.append(settings.SECRET_KEY)
    3333
    3434    # Use HIGHEST_PROTOCOL because it's the most efficient. It requires
    35     # Python 2.3, but Django requires 2.3 anyway, so that's OK.
     35    # Python 2.3, but Django requires 2.4 anyway, so that's OK.
    3636    pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
    3737
    3838    return md5_constructor(pickled).hexdigest()
  • django/contrib/admin/options.py

     
    2323from django.utils.translation import ugettext as _
    2424from django.utils.translation import ungettext, ugettext_lazy
    2525from django.utils.encoding import force_unicode
    26 try:
    27     set
    28 except NameError:
    29     from sets import Set as set     # Python 2.3 fallback
    3026
    3127HORIZONTAL, VERTICAL = 1, 2
    3228# returns the <ul> class for a given radio_admin field
  • django/contrib/admin/actions.py

     
    1212from django.utils.safestring import mark_safe
    1313from django.utils.text import capfirst
    1414from django.utils.translation import ugettext_lazy, ugettext as _
    15 try:
    16     set
    17 except NameError:
    18     from sets import Set as set     # Python 2.3 fallback
    1915
    2016def delete_selected(modeladmin, request, queryset):
    2117    """
  • django/contrib/admin/views/main.py

     
    99from django.utils.http import urlencode
    1010import operator
    1111
    12 try:
    13     set
    14 except NameError:
    15     from sets import Set as set   # Python 2.3 fallback
    16 
    1712# The system will display a "Show all" link on the change list only if the
    1813# total result count is less than or equal to this setting.
    1914MAX_SHOW_ALL_ALLOWED = 200
  • django/contrib/admin/views/decorators.py

     
    22try:
    33    from functools import wraps
    44except ImportError:
    5     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     5    from django.utils.functional import wraps  # Python 2.4 fallback.
    66
    77from django import http, template
    88from django.conf import settings
  • django/contrib/admin/sites.py

     
    1414from django.utils.translation import ugettext_lazy, ugettext as _
    1515from django.views.decorators.cache import never_cache
    1616from django.conf import settings
    17 try:
    18     set
    19 except NameError:
    20     from sets import Set as set     # Python 2.3 fallback
    2117
    2218ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
    2319LOGIN_FORM_KEY = 'this_is_the_login_form'
  • django/contrib/auth/decorators.py

     
    11try:
    22    from functools import update_wrapper, wraps
    33except ImportError:
    4     from django.utils.functional import update_wrapper, wraps  # Python 2.3, 2.4 fallback.
     4    from django.utils.functional import update_wrapper, wraps  # Python 2.4 fallback.
    55
    66from django.contrib.auth import REDIRECT_FIELD_NAME
    77from django.http import HttpResponseRedirect
  • django/contrib/auth/backends.py

     
    1 try:
    2     set
    3 except NameError:
    4     from sets import Set as set # Python 2.3 fallback
    5 
    61from django.db import connection
    72from django.contrib.auth.models import User, Permission
    83
  • django/contrib/localflavor/br/forms.py

     
    1010from django.utils.translation import ugettext_lazy as _
    1111import re
    1212
    13 try:
    14     set
    15 except NameError:
    16     from sets import Set as set     # For Python 2.3
    17 
    1813phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
    1914
    2015class BRZipCodeField(RegexField):
  • django/contrib/messages/storage/fallback.py

     
    11from django.contrib.messages.storage.base import BaseStorage
    22from django.contrib.messages.storage.cookie import CookieStorage
    33from django.contrib.messages.storage.session import SessionStorage
    4 try:
    5     set
    6 except NameError:
    7     from sets import Set as set   # Python 2.3
    84
    9 
    105class FallbackStorage(BaseStorage):
    116    """
    127    Tries to store all messages in the first backend, storing any unstored
  • django/template/defaultfilters.py

     
    11"""Default variable filters."""
    22
    33import 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 
     4from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
    105import random as random_module
    116try:
    127    from functools import wraps
    138except ImportError:
    14     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     9    from django.utils.functional import wraps  # Python 2.4 fallback.
    1510
    1611from django.template import Variable, Library
    1712from django.conf import settings
  • django/template/defaulttags.py

     
    22
    33import sys
    44import re
    5 from itertools import cycle as itertools_cycle
     5from itertools import groupby, cycle as itertools_cycle
    66
    77from django.template import Node, NodeList, Template, Context, Variable
    88from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END
     
    1010from django.template.smartif import IfParser, Literal
    1111from django.conf import settings
    1212from django.utils.encoding import smart_str, smart_unicode
    13 from django.utils.itercompat import groupby
    1413from django.utils.safestring import mark_safe
    1514
    1615register = Library()
  • tests/modeltests/or_lookups/models.py

     
    88clauses using the variable ``django.db.models.Q`` (or any object with an
    99``add_to_query`` method).
    1010"""
    11 # Python 2.3 doesn't have sorted()
    12 try:
    13     sorted
    14 except NameError:
    15     from django.utils.itercompat import sorted
    1611
    1712from django.db import models
    1813
  • tests/modeltests/aggregation/models.py

     
    11# coding: utf-8
    22from django.db import models
    33
    4 try:
    5     sorted
    6 except NameError:
    7     from django.utils.itercompat import sorted      # For Python 2.3
    8 
    94class Author(models.Model):
    105    name = models.CharField(max_length=100)
    116    age = models.IntegerField()
     
    4843# Different backends and numbers.
    4944__test__ = {'API_TESTS': """
    5045>>> from django.core import management
    51 >>> try:
    52 ...     from decimal import Decimal
    53 ... except:
    54 ...     from django.utils._decimal import Decimal
     46>>> from decimal import Decimal
    5547>>> from datetime import date
    5648
    5749# Reset the database representation of this app.
  • tests/modeltests/basic/models.py

     
    44
    55This is a basic model with only two non-primary-key fields.
    66"""
    7 # Python 2.3 doesn't have set as a builtin
    8 try:
    9     set
    10 except NameError:
    11     from sets import Set as set
    12 
    13 # Python 2.3 doesn't have sorted()
    14 try:
    15     sorted
    16 except NameError:
    17     from django.utils.itercompat import sorted
    18 
    197from django.db import models, DEFAULT_DB_ALIAS
    208
    219class Article(models.Model):
  • tests/modeltests/model_formsets/models.py

     
    22from django import forms
    33from django.db import models
    44
    5 try:
    6     sorted
    7 except NameError:
    8     from django.utils.itercompat import sorted
    9 
    105class Author(models.Model):
    116    name = models.CharField(max_length=100)
    127
  • tests/modeltests/serializers/models.py

     
    66``QuerySet`` objects to and from "flat" data (i.e. strings).
    77"""
    88
    9 try:
    10     from decimal import Decimal
    11 except ImportError:
    12     from django.utils._decimal import Decimal # Python 2.3 fallback
    13 
     9from decimal import Decimal
    1410from django.db import models
    1511
    1612class Category(models.Model):
  • tests/regressiontests/model_inheritance_regress/models.py

     
    66
    77from django.db import models
    88
    9 # Python 2.3 doesn't have sorted()
    10 try:
    11     sorted
    12 except NameError:
    13     from django.utils.itercompat import sorted
    14 
    159class Place(models.Model):
    1610    name = models.CharField(max_length=50)
    1711    address = models.CharField(max_length=80)
  • tests/regressiontests/defaultfilters/tests.py

     
    580580from django.template.defaultfilters import *
    581581import datetime
    582582
    583 # Python 2.3 doesn't have sorted()
    584 try:
    585     sorted
    586 except NameError:
    587     from django.utils.itercompat import sorted
    588 
    589583if __name__ == '__main__':
    590584    import doctest
    591585    doctest.testmod()
  • tests/regressiontests/aggregation_regress/models.py

     
    44from django.db import connection, models, DEFAULT_DB_ALIAS
    55from django.conf import settings
    66
    7 try:
    8     sorted
    9 except NameError:
    10     from django.utils.itercompat import sorted      # For Python 2.3
    11 
    127class Author(models.Model):
    138    name = models.CharField(max_length=100)
    149    age = models.IntegerField()
  • tests/regressiontests/decorators/tests.py

     
    33try:
    44    from functools import wraps
    55except ImportError:
    6     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     6    from django.utils.functional import wraps  # Python 2.4 fallback.
    77
    88from django.http import HttpResponse, HttpRequest
    99from django.utils.functional import allow_lazy, lazy, memoize
  • tests/regressiontests/forms/extra.py

     
    55>>> import datetime
    66>>> import time
    77>>> import re
    8 >>> try:
    9 ...     from decimal import Decimal
    10 ... except ImportError:
    11 ...     from django.utils._decimal import Decimal
     8>>> from decimal import Decimal
    129
    1310###############
    1411# Extra stuff #
  • tests/regressiontests/forms/fields.py

     
    2828import time
    2929import re
    3030import os
     31from decimal import Decimal
    3132
    3233from unittest import TestCase
    3334
     
    3536from django.forms import *
    3637from django.forms.widgets import RadioFieldRenderer
    3738
    38 try:
    39     from decimal import Decimal
    40 except ImportError:
    41     from django.utils._decimal import Decimal
    4239
    43 
    4440def fix_os_paths(x):
    4541    if isinstance(x, basestring):
    4642        return x.replace('\\', '/')
  • tests/regressiontests/forms/forms.py

     
    55>>> import datetime
    66>>> import time
    77>>> import re
    8 >>> try:
    9 ...     from decimal import Decimal
    10 ... except ImportError:
    11 ...     from django.utils._decimal import Decimal
     8>>> from decimal import Decimal
    129
    1310#########
    1411# Forms #
  • tests/regressiontests/forms/widgets.py

     
    77>>> import datetime
    88>>> import time
    99>>> import re
    10 >>> try:
    11 ...     from decimal import Decimal
    12 ... except ImportError:
    13 ...     from django.utils._decimal import Decimal
     10>>> from decimal import Decimal
    1411>>> from django.utils.translation import activate, deactivate
    1512>>> from django.conf import settings
    1613
  • tests/regressiontests/model_fields/tests.py

     
    11import datetime
    22import unittest
     3from decimal import Decimal
    34
    45import django.test
    56from django import forms
     
    89
    910from models import Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post, NullBooleanModel, BooleanModel
    1011
    11 try:
    12     from decimal import Decimal
    13 except ImportError:
    14     from django.utils._decimal import Decimal
    15 
    16 
    1712# If PIL available, do these tests.
    1813if Image:
    1914    from imagefield import \
  • tests/regressiontests/model_fields/models.py

     
    11import os
    22import tempfile
    33
    4 try:
    5     import decimal
    6 except ImportError:
    7     from django.utils import _decimal as decimal    # Python 2.3 fallback
    8 
    94# Try to import PIL in either of the two ways it can end up installed.
    105# Checking for the existence of Image is enough for CPython, but for PyPy,
    116# you need to check for the underlying modules.
  • tests/regressiontests/admin_scripts/management/commands/base_command.py

     
    11from django.core.management.base import BaseCommand
    22from optparse import make_option
    3 # Python 2.3 doesn't have sorted()
    4 try:
    5     sorted
    6 except NameError:
    7     from django.utils.itercompat import sorted
    83
    94class Command(BaseCommand):
    105    option_list = BaseCommand.option_list + (
  • tests/regressiontests/admin_scripts/management/commands/label_command.py

     
    11from django.core.management.base import LabelCommand
    2 # Python 2.3 doesn't have sorted()
    3 try:
    4     sorted
    5 except NameError:
    6     from django.utils.itercompat import sorted
    72
    83class Command(LabelCommand):
    94    help = "Test Label-based commands"
  • tests/regressiontests/admin_scripts/management/commands/app_command.py

     
    11from django.core.management.base import AppCommand
    2 # Python 2.3 doesn't have sorted()
    3 try:
    4     sorted
    5 except NameError:
    6     from django.utils.itercompat import sorted
    72
    83class Command(AppCommand):
    94    help = 'Test Application-based commands'
  • tests/regressiontests/admin_scripts/management/commands/noargs_command.py

     
    11from django.core.management.base import NoArgsCommand
    2 # Python 2.3 doesn't have sorted()
    3 try:
    4     sorted
    5 except NameError:
    6     from django.utils.itercompat import sorted
    72
    83class Command(NoArgsCommand):
    94    help = "Test No-args commands"
  • tests/regressiontests/utils/tests.py

     
    1010import timesince
    1111import datastructures
    1212import datetime_safe
    13 import itercompat
    1413import tzinfo
    1514
    1615from decorators import DecoratorFromMiddlewareTests
    1716from functional import FunctionalTestCase
    1817
    19 # We need this because "datastructures" uses sorted() and the tests are run in
    20 # the scope of this module.
    21 try:
    22     sorted
    23 except NameError:
    24     from django.utils.itercompat import sorted  # For Python 2.3
    25 
    2618# Extra tests
    2719__test__ = {
    2820    'timesince': timesince,
    2921    'datastructures': datastructures,
    3022    'datetime_safe': datetime_safe,
    31     'itercompat': itercompat,
    3223    'tzinfo': tzinfo,
    3324}
    3425
  • tests/regressiontests/utils/itercompat.py

     
    1 """
    2 # Tests of the utils itercompat library.
    3 
    4 >>> from django.utils.itercompat import sorted as compat_sorted
    5 
    6 # Check the replacement version of sorted
    7 >>> x = [5,1,4,2,3]
    8 >>> y = compat_sorted(x)
    9 >>> print y
    10 [1, 2, 3, 4, 5]
    11 
    12 >>> print x
    13 [5, 1, 4, 2, 3]
    14 
    15 """
    16  No newline at end of file
  • tests/regressiontests/queries/models.py

     
    1212from django.db.models import Count
    1313from django.db.models.query import Q, ITER_CHUNK_SIZE, EmptyQuerySet
    1414
    15 # Python 2.3 doesn't have sorted()
    16 try:
    17     sorted
    18 except NameError:
    19     from django.utils.itercompat import sorted
    20 
    2115class DumbCategory(models.Model):
    2216    pass
    2317
     
    12791273
    12801274"""}
    12811275
    1282 # In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__
     1276# In Python 2.6 beta releases, exceptions raised in __len__
    12831277# are swallowed (Python issue 1242657), so these cases return an empty list,
    12841278# rather than raising an exception. Not a lot we can do about that,
    12851279# unfortunately, due to the way Python handles list() calls internally. Thus,
    1286 # we skip the tests for Python 2.3 and 2.6.
    1287 if (2, 4) <= sys.version_info < (2, 6):
     1280# we skip the tests for Python 2.6.
     1281if sys.version_info < (2, 6):
    12881282    __test__["API_TESTS"] += """
    12891283# If you're not careful, it's possible to introduce infinite loops via default
    12901284# ordering on foreign keys in a cycle. We detect that.
  • tests/runtests.py

     
    55
    66import django.contrib as contrib
    77
    8 try:
    9     set
    10 except NameError:
    11     from sets import Set as set     # For Python 2.3
    12 
    13 
    148CONTRIB_DIR_NAME = 'django.contrib'
    159MODEL_TESTS_DIR_NAME = 'modeltests'
    1610REGRESSION_TESTS_DIR_NAME = 'regressiontests'
Back to Top