--
Ticket URL: <https://code.djangoproject.com/ticket/30864>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
Comment (by Claude Paroz):
Personally, I'd love having `cached_classproperty`…
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:1>
Comment (by Simon Charette):
> Personally, I'd love having `cached_classproperty`…
That would be hard to implement without some metaclass mockery or relying
on some naive `if not hasattr(cls, '_cached_foo')` constructs.
`cached_property` is efficient because it relies on the descriptor
protocol to cache its return value into `__dict__` and avoid class level
attribute lookups. We can't achieve similar things without defining the
attribute on the class of the class (metaclass) and use the class's
`__dict__` as a cache store.
I guess the following could work.
{{{#!python
class cached_classproperty:
NOT_SET = object()
def __init__(self, method):
self.method = method
self.cached_value = self.NOT_SET
def __get__(self, instance, owner):
if self.cached_value is not self.NOT_SET:
return self.cached_value
self.cached_value = self.method(owner)
return self.cached_value
def __set__(self, instance, value):
self.cached_value = value
def __delete__(self, instance):
self.cached_value = self.NOT_SET
}}}
But this wouldn't be as efficient as `cached_property` because `__get__`
would always be called.
Anyway the `cached_classproperty` case should probably be discussed in
another ticket or on the mailing list.
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:2>
* stage: Unreviewed => Accepted
Comment:
I don't see any harm in promoting this to ''public''.
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:3>
Comment (by felixxm):
I can only add that it's already tested
`utils_tests.test_decorators.ClassPropertyTest`. Documentation should land
in `docs/ref/utils.txt`.
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:4>
Comment (by Claude Paroz):
Shouldn't it be moved to `django.utils.functional`?
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:5>
Comment (by felixxm):
Yes, good idea.
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:6>
Comment (by André Ericson):
Replying to [comment:5 Claude Paroz]:
> Shouldn't it be moved to `django.utils.functional`?
I've created a ticket for that https://code.djangoproject.com/ticket/30876
I think it makes more sense to address it first. I will go ahead and do it
once it's accepted.
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:7>
* owner: nobody => André Ericson
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:8>
* owner: André Ericson => (none)
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:9>
* owner: (none) => sumitpatra6
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:10>
* owner: sumitpatra6 => (none)
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:11>
* owner: (none) => Deep Sukhwani
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:12>
* has_patch: 0 => 1
Comment:
[https://github.com/django/django/pull/12637 PR#12637]
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:13>
Comment (by Deep Sukhwani):
For reviewers: Slightly confused since this is my first trac ticket in
Django project. Please guide.
**Three questions:**
- The version on this ticket says 2.2 however the change, i.e. move from
`django.utils.decorators` to `django.utils.functional` was made in Django
3.1 (current ongoing development version) as a result of which, I added
`versionchanged` text to the submitted code change. Should I remove
`versionchanged`?
- If the answer for above question is **yes**, does this mean this change
needs to be backported to 2.2?
- If the answer for above question is **yes**, then does this also need to
be backported to every other version release since 2.2? i.e. all Versions:
in 2.x.y series and versions in 3.0.x series?
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:14>
* version: 2.2 => master
Comment:
Replying to [comment:14 Deep Sukhwani]:
> - The version on this ticket says 2.2 however the change, i.e. move from
`django.utils.decorators` to `django.utils.functional` was made in Django
3.1 (current ongoing development version) as a result of which, I added
`versionchanged` text to the submitted code change. Should I remove
`versionchanged`?
This is a new feature so it goes only to the current master and should be
targeted to the Django 3.1. `versionchanged` annotation is not necessary,
you should add `versionadded` instead.
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:15>
Comment (by Deep Sukhwani):
Replying to [comment:15 felixxm]:
> This is a new feature so it goes only to the current master and should
be targeted to the Django 3.1. `versionchanged` annotation is not
necessary, you should add `versionadded` instead.
This feature (`classproperty` decorator) did exist in previous version,
however it was part of a different module `django.utils.decorators` and in
version 3.1 it is moved to `django.utils.functional`
Ref: https://docs.djangoproject.com/en/dev/releases/3.1/#id1, it says
> `django.utils.decorators.classproperty()` decorator is moved to
`django.utils.functional.classproperty()`
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:16>
Comment (by felixxm):
I know that, but it doesn't change anything, IMO. We've added this note in
case someone uses this unsupported API. `classproperty` docs doesn't need
to contain it.
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:17>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:18>
* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:19>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"4b146e0c83891fc67a422aa22f846bb7654c4d38" 4b146e0c]:
{{{
#!CommitTicketReference repository=""
revision="4b146e0c83891fc67a422aa22f846bb7654c4d38"
Fixed #30864 -- Doc'd classproperty decorator.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/30864#comment:20>