diff options
| author | Ran Benita <ran234@gmail.com> | 2019-05-03 13:24:43 +0300 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-06-12 05:33:02 +0200 |
| commit | b214845f0f8d973e527e41730ca5770fad51ec5d (patch) | |
| tree | 0bccce475a629832d4a529a0ed025b232dd04bf7 | |
| parent | e0e0204477e47a9f8c3302236a31a42514b94c25 (diff) | |
Improved order of methods in proxy class in lazy().
This order reads more naturally and puts methods into three groups:
1. The methods required to support the implementation of __proxy__, e.g.
__deepcopy__ doesn't come from `object` and __reduce__ is
overridden to support behavior required explicitly for pickling of
lazy objects.
2. Methods that are specifically overridden from `object` which we
don't want to inherit from the provided resultclasses. These will be
skipped later when we add methods from the resultclasses.
3. Additional methods - that is _add__, __radd__, and __mod__ - don't
come from `object`, but typically from `str` and `int` which are the
most common use cases.
Co-authored-by: Nick Pope <nick@nickpope.me.uk>
| -rw-r--r-- | django/utils/functional.py | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/django/utils/functional.py b/django/utils/functional.py index 6ee630c021..e3be672282 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -104,8 +104,12 @@ def lazy(func, *resultclasses): (func, self.__args, self.__kw) + resultclasses, ) - def __repr__(self): - return repr(self.__cast()) + def __deepcopy__(self, memo): + # Instances of this class are effectively immutable. It's just a + # collection of functions. So we don't need to do anything + # complicated for copying. + memo[id(self)] = self + return self @classmethod def __prepare_class__(cls): @@ -133,6 +137,12 @@ def lazy(func, *resultclasses): def __cast(self): return func(*self.__args, **self.__kw) + # Explicitly wrap methods which are defined on object and hence would + # not have been overloaded by the loop over resultclasses below. + + def __repr__(self): + return repr(self.__cast()) + def __str__(self): # object defines __str__(), so __prepare_class__() won't overload # a __str__() method from the proxied class. @@ -171,8 +181,8 @@ def lazy(func, *resultclasses): def __hash__(self): return hash(self.__cast()) - def __mod__(self, rhs): - return self.__cast() % rhs + # Explicitly wrap methods which are required for certain operations on + # int/str objects to function correctly. def __add__(self, other): return self.__cast() + other @@ -180,12 +190,8 @@ def lazy(func, *resultclasses): def __radd__(self, other): return other + self.__cast() - def __deepcopy__(self, memo): - # Instances of this class are effectively immutable. It's just a - # collection of functions. So we don't need to do anything - # complicated for copying. - memo[id(self)] = self - return self + def __mod__(self, other): + return self.__cast() % other @wraps(func) def __wrapper__(*args, **kw): |
