From fa4b5c1b9360dc4c6abe913e86d3d36793d8826a Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Tue, 2 Aug 2016 09:32:00 -0400
Subject: [PATCH] [1.10.x] Fixed #26988 -- Improved/clarified
 User.is_authenticated/anonymous compatibility.

Thanks marktranchant for the report and review.

Backport of 54afa960d1ee8c63635225a0f0a2489971b5aab5 from master
---
 django/utils/deprecation.py           |  6 ++++++
 docs/releases/1.10.1.txt              |  3 +++
 docs/releases/1.10.txt                |  8 ++++++++
 tests/utils_tests/test_deprecation.py | 16 ++++++++++++++++
 4 files changed, 33 insertions(+)
 create mode 100644 tests/utils_tests/test_deprecation.py

diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py
index 351bd1d27d..0a0dd216da 100644
--- a/django/utils/deprecation.py
+++ b/django/utils/deprecation.py
@@ -107,6 +107,12 @@ class CallableBool:
     def __repr__(self):
         return 'CallableBool(%r)' % self.value
 
+    def __eq__(self, other):
+        return self.value == other
+
+    def __ne__(self, other):
+        return self.value != other
+
 CallableFalse = CallableBool(False)
 CallableTrue = CallableBool(True)
 
diff --git a/docs/releases/1.10.1.txt b/docs/releases/1.10.1.txt
index 2f4fd581b9..86cd087bdf 100644
--- a/docs/releases/1.10.1.txt
+++ b/docs/releases/1.10.1.txt
@@ -11,3 +11,6 @@ Bugfixes
 
 * Fixed a crash in MySQL connections where ``SELECT @@SQL_AUTO_IS_NULL``
   doesn't return a result (:ticket:`26991`).
+
+* Allowed ``User.is_authenticated`` and ``User.is_anonymous`` properties to be
+  compared using ``==`` and ``!=`` (:ticket:`26988`).
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index 1f6ebc3a7e..88209cb1cf 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -1061,6 +1061,14 @@ method, e.g.::
 If you override these methods in a custom user model, you must change them to
 properties or attributes.
 
+Django uses a ``CallableBool`` object to allow these attributes to work as both
+a property and a method. Thus, until the deprecation period ends, you cannot
+compare these properties using the ``is`` operator. That is, the following
+won't work::
+
+    if request.user.is_authenticated is True:
+        ...
+
 Custom manager classes available through ``prefetch_related`` must define a ``_apply_rel_filters()`` method
 -----------------------------------------------------------------------------------------------------------
 
diff --git a/tests/utils_tests/test_deprecation.py b/tests/utils_tests/test_deprecation.py
new file mode 100644
index 0000000000..41627ce1b3
--- /dev/null
+++ b/tests/utils_tests/test_deprecation.py
@@ -0,0 +1,16 @@
+from django.test import SimpleTestCase
+from django.utils.deprecation import CallableFalse, CallableTrue
+
+
+class TestCallableBool(SimpleTestCase):
+    def test_true(self):
+        self.assertTrue(CallableTrue)
+        self.assertEqual(CallableTrue, True)
+        self.assertFalse(CallableTrue != True)  # noqa: E712
+        self.assertNotEqual(CallableTrue, False)
+
+    def test_false(self):
+        self.assertFalse(CallableFalse)
+        self.assertEqual(CallableFalse, False)
+        self.assertFalse(CallableFalse != False)  # noqa: E712
+        self.assertNotEqual(CallableFalse, True)