From b88abd684041ffa66bfe445e1ac26164e803d488 Mon Sep 17 00:00:00 2001
From: Tomek Paczkowski <tomek@hauru.eu>
Date: Sat, 23 Feb 2013 23:20:00 +0100
Subject: [PATCH] Fixed #19872

Made cached_property to behave as property when accessed via class.
---
 django/utils/functional.py                |  4 +++-
 tests/regressiontests/utils/functional.py | 29 ++++++++++++++++++++++-
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/django/utils/functional.py b/django/utils/functional.py
index 1b5200c98c..51001ea655 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -39,7 +39,9 @@ class cached_property(object):
     def __init__(self, func):
         self.func = func
 
-    def __get__(self, instance, type):
+    def __get__(self, instance, type=None):
+        if instance is None:
+            return self
         res = instance.__dict__[self.func.__name__] = self.func(instance)
         return res
 
diff --git a/tests/regressiontests/utils/functional.py b/tests/regressiontests/utils/functional.py
index 90a6f08630..3bb50007c6 100644
--- a/tests/regressiontests/utils/functional.py
+++ b/tests/regressiontests/utils/functional.py
@@ -1,5 +1,5 @@
 from django.utils import unittest
-from django.utils.functional import lazy, lazy_property
+from django.utils.functional import lazy, lazy_property, cached_property
 
 
 class FunctionalTestCase(unittest.TestCase):
@@ -37,3 +37,30 @@ class FunctionalTestCase(unittest.TestCase):
 
         self.assertRaises(NotImplementedError, lambda: A().do)
         self.assertEqual(B().do, 'DO IT')
+
+    def test_cached_property(self):
+        """
+        Test that cached_property caches its value,
+        and that it behaves like a property
+        """
+
+        class A(object):
+
+            @cached_property
+            def value(self):
+                return 1, object()
+
+        a = A()
+
+        # check that it is cached
+        self.assertEqual(a.value, a.value)
+
+        # check that it returns the right thing
+        self.assertEqual(a.value[0], 1)
+
+        # check that state isn't shared between instances
+        a2 = A()
+        self.assertNotEqual(a.value, a2.value)
+
+        # check that it behaves like a property when there's no instance
+        self.assertIsInstance(A.value, cached_property)