#30949: Use functools.cached_property instead of
django.utils.functional.cached_property.
-------------------------------------+-------------------------------------
     Reporter:  Thomas Grainger      |                    Owner:  David
         Type:                       |  Smith
  Cleanup/optimization               |                   Status:  assigned
    Component:  Utilities            |                  Version:  dev
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:
                                     |  Someday/Maybe
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Filip Sedlák):

 One thing to note is that the `@functools.cached_property` supports a use
 case that Django's doesn't. If you define a subclass with plain
 `@property`, the caching doesn't happen because the `@property` is a "data
 descriptor" so it gets precedence before the cached value. It's still not
 clear to me why `super().count` also avoids the cached value in
 `self.__dict__` but it clearly does.

 {{{#!python
 In [8]: class A:
    ...:     @django.utils.functional.cached_property
    ...:     def count(self):
    ...:         print('Computing... A.count')
    ...:         return 15
    ...:
    ...:
    ...: class B(A):
    ...:     @property
    ...:     def count(self):
    ...:         print('B.count')
    ...:         return super().count
    ...:
    ...:

 In [9]: b = B()

 In [10]: b.count
 B.count
 Computing... A.count                          <===== expected
 Out[10]: 15

 In [11]: b.count
 B.count
 Computing... A.count                          <===== should not happen
 Out[11]: 15
 }}}

 The difference with `functools` is that `functools.cached_property` still
 explicitly looks into `instance.__dict__` if it's called.

 It's a corner case but I expected `super().count` to be cached. It hit us
 when overriding `Paginator.count`. The lack of caching led to four count
 queries. Small impact, easy workaround, but surprising behaviour.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30949#comment:13>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701815d89988f-b702735f-b19a-4557-be52-ad16868ad96b-000000%40eu-central-1.amazonses.com.

Reply via email to