Fixed #30876 -- Moved classproperty() decorator to the django.utils.functional.

This commit is contained in:
André Ericson 2019-10-18 21:00:34 +02:00 committed by Mariusz Felisiak
parent 31174031f1
commit 3120490912
8 changed files with 56 additions and 55 deletions

View File

@ -1,7 +1,7 @@
from django.apps.registry import Apps
from django.db import models
from django.db.utils import DatabaseError
from django.utils.decorators import classproperty
from django.utils.functional import classproperty
from django.utils.timezone import now
from .exceptions import MigrationSchemaMissing

View File

@ -3,7 +3,7 @@ import unittest
from contextlib import contextmanager
from django.test import LiveServerTestCase, tag
from django.utils.decorators import classproperty
from django.utils.functional import classproperty
from django.utils.module_loading import import_string
from django.utils.text import capfirst

View File

@ -37,7 +37,7 @@ from django.test.utils import (
CaptureQueriesContext, ContextList, compare_xml, modify_settings,
override_settings,
)
from django.utils.decorators import classproperty
from django.utils.functional import classproperty
from django.views.static import serve
__all__ = ('TestCase', 'TransactionTestCase',

View File

@ -150,15 +150,3 @@ def make_middleware_decorator(middleware_class):
return _wrapped_view
return _decorator
return _make_decorator
class classproperty:
def __init__(self, method=None):
self.fget = method
def __get__(self, instance, cls=None):
return self.fget(cls)
def getter(self, method):
self.fget = method
return self

View File

@ -49,6 +49,18 @@ class cached_property:
return res
class classproperty:
def __init__(self, method=None):
self.fget = method
def __get__(self, instance, cls=None):
return self.fget(cls)
def getter(self, method):
self.fget = method
return self
class Promise:
"""
Base class for the proxy class created in the closure of the lazy function.

View File

@ -263,6 +263,9 @@ Miscellaneous
``ETag`` header to responses with an empty
:attr:`~django.http.HttpResponse.content`.
* ``django.utils.decorators.classproperty()`` decorator is moved to
``django.utils.functional.classproperty()``.
.. _deprecated-features-3.1:
Features deprecated in 3.1

View File

@ -2,7 +2,7 @@ from django.http import HttpResponse
from django.template import engines
from django.template.response import TemplateResponse
from django.test import RequestFactory, SimpleTestCase
from django.utils.decorators import classproperty, decorator_from_middleware
from django.utils.decorators import decorator_from_middleware
class ProcessViewMiddleware:
@ -108,41 +108,3 @@ class DecoratorFromMiddlewareTests(SimpleTestCase):
self.assertTrue(getattr(request, 'process_response_reached', False))
# process_response saw the rendered content
self.assertEqual(request.process_response_content, b"Hello world")
class ClassPropertyTest(SimpleTestCase):
def test_getter(self):
class Foo:
foo_attr = 123
def __init__(self):
self.foo_attr = 456
@classproperty
def foo(cls):
return cls.foo_attr
class Bar:
bar = classproperty()
@bar.getter
def bar(cls):
return 123
self.assertEqual(Foo.foo, 123)
self.assertEqual(Foo().foo, 123)
self.assertEqual(Bar.bar, 123)
self.assertEqual(Bar().bar, 123)
def test_override_getter(self):
class Foo:
@classproperty
def foo(cls):
return 123
@foo.getter
def foo(cls):
return 456
self.assertEqual(Foo.foo, 456)
self.assertEqual(Foo().foo, 456)

View File

@ -1,7 +1,7 @@
from unittest import mock
from django.test import SimpleTestCase
from django.utils.functional import cached_property, lazy
from django.utils.functional import cached_property, classproperty, lazy
class FunctionalTests(SimpleTestCase):
@ -218,3 +218,39 @@ class FunctionalTests(SimpleTestCase):
with mock.patch.object(__proxy__, '__prepare_class__') as mocked:
lazified()
mocked.assert_not_called()
def test_classproperty_getter(self):
class Foo:
foo_attr = 123
def __init__(self):
self.foo_attr = 456
@classproperty
def foo(cls):
return cls.foo_attr
class Bar:
bar = classproperty()
@bar.getter
def bar(cls):
return 123
self.assertEqual(Foo.foo, 123)
self.assertEqual(Foo().foo, 123)
self.assertEqual(Bar.bar, 123)
self.assertEqual(Bar().bar, 123)
def test_classproperty_override_getter(self):
class Foo:
@classproperty
def foo(cls):
return 123
@foo.getter
def foo(cls):
return 456
self.assertEqual(Foo.foo, 456)
self.assertEqual(Foo().foo, 456)