From cdbd8745f6c550422170a6ae5928c0b679fab0df Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Mon, 22 Feb 2016 13:25:01 -0500
Subject: [PATCH] Fixed #26263 -- Deprecated Context.has_key()

---
 django/template/context.py           | 15 +++++++++++----
 docs/internals/deprecation.txt       |  2 ++
 docs/releases/1.10.txt               |  2 ++
 tests/template_tests/test_context.py | 24 +++++++++++++++++++++++-
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/django/template/context.py b/django/template/context.py
index 04d0e2f5f4..361f3503ca 100644
--- a/django/template/context.py
+++ b/django/template/context.py
@@ -1,6 +1,9 @@
+import warnings
 from contextlib import contextmanager
 from copy import copy
 
+from django.utils.deprecation import RemovedInDjango20Warning
+
 # Hard-coded processor for easier use of CSRF protection.
 _builtin_context_processors = ('django.template.context_processors.csrf',)
 
@@ -76,14 +79,18 @@ class BaseContext(object):
         del self.dicts[-1][key]
 
     def has_key(self, key):
+        warnings.warn(
+            "%s.has_key() is deprecated in favor of the 'in' operator." % self.__class__.__name__,
+            RemovedInDjango20Warning
+        )
+        return key in self
+
+    def __contains__(self, key):
         for d in self.dicts:
             if key in d:
                 return True
         return False
 
-    def __contains__(self, key):
-        return self.has_key(key)
-
     def get(self, key, otherwise=None):
         for d in reversed(self.dicts):
             if key in d:
@@ -184,7 +191,7 @@ class RenderContext(BaseContext):
         for d in self.dicts[-1]:
             yield d
 
-    def has_key(self, key):
+    def __contains__(self, key):
         return key in self.dicts[-1]
 
     def get(self, key, otherwise=None):
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 13d9305658..d1f877aa06 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -133,6 +133,8 @@ details on these changes.
 * The model ``CommaSeparatedIntegerField`` will be removed. A stub field will
   remain for compatibility with historical migrations.
 
+* Support for the template ``Context.has_key()`` method will be removed.
+
 .. _deprecation-removed-in-1.10:
 
 1.10
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index 658a3646bd..fc7b03d2a7 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -678,6 +678,8 @@ Miscellaneous
 * Importing from the ``django.core.urlresolvers`` module is deprecated in
   favor of its new location, :mod:`django.urls`.
 
+* The template ``Context.has_key()`` method is deprecated in favor of ``in``.
+
 .. _removed-features-1.10:
 
 Features removed in 1.10
diff --git a/tests/template_tests/test_context.py b/tests/template_tests/test_context.py
index 87b2016aa5..2fa7715d27 100644
--- a/tests/template_tests/test_context.py
+++ b/tests/template_tests/test_context.py
@@ -1,11 +1,13 @@
 # -*- coding: utf-8 -*-
+import warnings
 
 from django.http import HttpRequest
 from django.template import (
     Context, Engine, RequestContext, Template, Variable, VariableDoesNotExist,
 )
 from django.template.context import RenderContext
-from django.test import RequestFactory, SimpleTestCase
+from django.test import RequestFactory, SimpleTestCase, ignore_warnings
+from django.utils.deprecation import RemovedInDjango20Warning
 
 
 class ContextTests(SimpleTestCase):
@@ -182,6 +184,26 @@ class ContextTests(SimpleTestCase):
         """
         RequestContext(HttpRequest()).new().new()
 
+    @ignore_warnings(category=RemovedInDjango20Warning)
+    def test_has_key(self):
+        a = Context({'a': 1})
+        b = RequestContext(HttpRequest(), {'a': 1})
+        msg = "Context.has_key() is deprecated in favor of the 'in' operator."
+        msg2 = "RequestContext.has_key() is deprecated in favor of the 'in' operator."
+
+        with warnings.catch_warnings(record=True) as warns:
+            warnings.simplefilter('always')
+            self.assertEqual(a.has_key('a'), True)
+            self.assertEqual(a.has_key('b'), False)
+            self.assertEqual(b.has_key('a'), True)
+            self.assertEqual(b.has_key('b'), False)
+
+        self.assertEqual(len(warns), 4)
+        self.assertEqual(str(warns[0].message), msg)
+        self.assertEqual(str(warns[1].message), msg)
+        self.assertEqual(str(warns[2].message), msg2)
+        self.assertEqual(str(warns[3].message), msg2)
+
 
 class RequestContextTests(SimpleTestCase):