~ubuntu-branches/debian/sid/python-django/sid

« back to all changes in this revision

Viewing changes to django/utils/functional.py

  • Committer: Package Import Robot
  • Author(s): Luke Faraone
  • Date: 2013-11-07 15:33:49 UTC
  • mfrom: (1.3.12)
  • Revision ID: package-import@ubuntu.com-20131107153349-e31sc149l2szs3jb
Tags: 1.6-1
* New upstream version. Closes: #557474, #724637.
* python-django now also suggests the installation of ipython,
  bpython, python-django-doc, and libgdal1.
  Closes: #636511, #686333, #704203
* Set package maintainer to Debian Python Modules Team.
* Bump standards version to 3.9.5, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
import copy
2
2
import operator
3
 
from functools import wraps, update_wrapper
 
3
from functools import wraps
4
4
import sys
5
5
 
6
6
from django.utils import six
7
7
from django.utils.six.moves import copyreg
8
8
 
9
9
 
10
 
# You can't trivially replace this `functools.partial` because this binds to
11
 
# classes and returns bound instances, whereas functools.partial (on CPython)
12
 
# is a type and its instances don't bind.
 
10
# You can't trivially replace this with `functools.partial` because this binds
 
11
# to classes and returns bound instances, whereas functools.partial (on
 
12
# CPython) is a type and its instances don't bind.
13
13
def curry(_curried_func, *args, **kwargs):
14
14
    def _curried(*moreargs, **morekwargs):
15
 
        return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
 
15
        return _curried_func(*(args + moreargs), **dict(kwargs, **morekwargs))
16
16
    return _curried
17
17
 
 
18
 
18
19
def memoize(func, cache, num_args):
19
20
    """
20
21
    Wrap a function so that results for any argument tuple are stored in
33
34
        return result
34
35
    return wrapper
35
36
 
 
37
 
36
38
class cached_property(object):
37
39
    """
38
 
    Decorator that creates converts a method with a single
39
 
    self argument into a property cached on the instance.
 
40
    Decorator that converts a method with a single self argument into a
 
41
    property cached on the instance.
40
42
    """
41
43
    def __init__(self, func):
42
44
        self.func = func
43
45
 
44
 
    def __get__(self, instance, type):
 
46
    def __get__(self, instance, type=None):
 
47
        if instance is None:
 
48
            return self
45
49
        res = instance.__dict__[self.func.__name__] = self.func(instance)
46
50
        return res
47
51
 
 
52
 
48
53
class Promise(object):
49
54
    """
50
55
    This is just a base class for the proxy class created in
53
58
    """
54
59
    pass
55
60
 
 
61
 
56
62
def lazy(func, *resultclasses):
57
63
    """
58
64
    Turns any callable into a lazy evaluated callable. You need to give result
88
94
                cls.__dispatch[resultclass] = {}
89
95
                for type_ in reversed(resultclass.mro()):
90
96
                    for (k, v) in type_.__dict__.items():
91
 
                        # All __promise__ return the same wrapper method, but they
92
 
                        # also do setup, inserting the method into the dispatch
93
 
                        # dict.
 
97
                        # All __promise__ return the same wrapper method, but
 
98
                        # they also do setup, inserting the method into the
 
99
                        # dispatch dict.
94
100
                        meth = cls.__promise__(resultclass, k, v)
95
101
                        if hasattr(cls, k):
96
102
                            continue
111
117
        __prepare_class__ = classmethod(__prepare_class__)
112
118
 
113
119
        def __promise__(cls, klass, funcname, method):
114
 
            # Builds a wrapper around some magic method and registers that magic
115
 
            # method for the given type and method name.
 
120
            # Builds a wrapper around some magic method and registers that
 
121
            # magic method for the given type and method name.
116
122
            def __wrapper__(self, *args, **kw):
117
123
                # Automatically triggers the evaluation of a lazy value and
118
124
                # applies the given magic method of the result type.
156
162
            return hash(self.__cast())
157
163
 
158
164
        def __mod__(self, rhs):
159
 
            if self._delegate_bytes and not six.PY3:
 
165
            if self._delegate_bytes and six.PY2:
160
166
                return bytes(self) % rhs
161
167
            elif self._delegate_text:
162
168
                return six.text_type(self) % rhs
163
 
            else:
164
 
                raise AssertionError('__mod__ not supported for non-string types')
 
169
            return self.__cast() % rhs
165
170
 
166
171
        def __deepcopy__(self, memo):
167
172
            # Instances of this class are effectively immutable. It's just a
177
182
 
178
183
    return __wrapper__
179
184
 
 
185
 
180
186
def _lazy_proxy_unpickle(func, args, kwargs, *resultclasses):
181
187
    return lazy(func, *resultclasses)(*args, **kwargs)
182
188
 
 
189
 
183
190
def allow_lazy(func, *resultclasses):
184
191
    """
185
192
    A decorator that allows a function to be called with one or more lazy
198
205
    return wrapper
199
206
 
200
207
empty = object()
 
208
 
 
209
 
201
210
def new_method_proxy(func):
202
211
    def inner(self, *args):
203
212
        if self._wrapped is empty:
205
214
        return func(self._wrapped, *args)
206
215
    return inner
207
216
 
 
217
 
208
218
class LazyObject(object):
209
219
    """
210
220
    A wrapper for another class that can be used to delay instantiation of the
213
223
    By subclassing, you have the opportunity to intercept and alter the
214
224
    instantiation. If you don't need to do that, use SimpleLazyObject.
215
225
    """
 
226
 
 
227
    # Avoid infinite recursion when tracing __init__ (#19456).
 
228
    _wrapped = None
 
229
 
216
230
    def __init__(self):
217
231
        self._wrapped = empty
218
232
 
240
254
        """
241
255
        raise NotImplementedError
242
256
 
243
 
    # introspection support:
 
257
    # Introspection support
244
258
    __dir__ = new_method_proxy(dir)
245
259
 
 
260
    # Dictionary methods support
 
261
    @new_method_proxy
 
262
    def __getitem__(self, key):
 
263
        return self[key]
 
264
 
 
265
    @new_method_proxy
 
266
    def __setitem__(self, key, value):
 
267
        self[key] = value
 
268
 
 
269
    @new_method_proxy
 
270
    def __delitem__(self, key):
 
271
        del self[key]
 
272
 
246
273
 
247
274
# Workaround for http://bugs.python.org/issue12370
248
275
_super = super
249
276
 
 
277
 
250
278
class SimpleLazyObject(LazyObject):
251
279
    """
252
280
    A lazy object initialised from any function.
289
317
    # Because we have messed with __class__ below, we confuse pickle as to what
290
318
    # class we are pickling. It also appears to stop __reduce__ from being
291
319
    # called. So, we define __getstate__ in a way that cooperates with the way
292
 
    # that pickle interprets this class.  This fails when the wrapped class is a
293
 
    # builtin, but it is better than nothing.
 
320
    # that pickle interprets this class.  This fails when the wrapped class is
 
321
    # a builtin, but it is better than nothing.
294
322
    def __getstate__(self):
295
323
        if self._wrapped is empty:
296
324
            self._setup()
314
342
            # all.
315
343
            return (copyreg._reconstructor, (self.__class__, object, None), self.__getstate__())
316
344
 
317
 
    # Need to pretend to be the wrapped class, for the sake of objects that care
318
 
    # about this (especially in equality tests)
 
345
    # Return a meaningful representation of the lazy object for debugging
 
346
    # without evaluating the wrapped object.
 
347
    def __repr__(self):
 
348
        if self._wrapped is empty:
 
349
            repr_attr = self._setupfunc
 
350
        else:
 
351
            repr_attr = self._wrapped
 
352
        return '<SimpleLazyObject: %r>' % repr_attr
 
353
 
 
354
    # Need to pretend to be the wrapped class, for the sake of objects that
 
355
    # care about this (especially in equality tests)
319
356
    __class__ = property(new_method_proxy(operator.attrgetter("__class__")))
320
357
    __eq__ = new_method_proxy(operator.eq)
 
358
    __ne__ = new_method_proxy(operator.ne)
321
359
    __hash__ = new_method_proxy(hash)
322
360
    __bool__ = new_method_proxy(bool)       # Python 3
323
361
    __nonzero__ = __bool__                  # Python 2
343
381
                return getattr(instance, name)()
344
382
        return property(fget, fset, fdel, doc)
345
383
 
 
384
 
346
385
def partition(predicate, values):
347
386
    """
348
387
    Splits the values into two sets, based on the return value of the function
356
395
        results[predicate(item)].append(item)
357
396
    return results
358
397
 
359
 
if sys.version_info >= (2,7,2):
 
398
if sys.version_info >= (2, 7, 2):
360
399
    from functools import total_ordering
361
400
else:
362
401
    # For Python < 2.7.2. Python 2.6 does not have total_ordering, and