Browse Source

Fixed #25466 -- Added backwards compatibility aliases for LoaderOrigin and StringOrigin.

Thanks Simon Charette for the DeprecationInstanceCheck class.
Tim Graham 9 years ago
parent
commit
8d1a001ef6

+ 2 - 1
django/template/__init__.py

@@ -58,7 +58,8 @@ from .exceptions import TemplateDoesNotExist, TemplateSyntaxError       # NOQA i
 
 # Template parts
 from .base import (                                                     # NOQA isort:skip
-    Context, Node, NodeList, Origin, RequestContext, Template, Variable,
+    Context, Node, NodeList, Origin, RequestContext, StringOrigin, Template,
+    Variable,
 )
 
 # Library management

+ 8 - 0
django/template/base.py

@@ -59,6 +59,9 @@ from django.template.context import (  # NOQA: imported for backwards compatibil
     BaseContext, Context, ContextPopException, RequestContext,
 )
 from django.utils import six
+from django.utils.deprecation import (
+    DeprecationInstanceCheck, RemovedInDjango20Warning,
+)
 from django.utils.encoding import (
     force_str, force_text, python_2_unicode_compatible,
 )
@@ -156,6 +159,11 @@ class Origin(object):
             )
 
 
+class StringOrigin(six.with_metaclass(DeprecationInstanceCheck, Origin)):
+    alternative = 'django.template.Origin'
+    deprecation_warning = RemovedInDjango20Warning
+
+
 class Template(object):
     def __init__(self, template_string, origin=None, name=None, engine=None):
         try:

+ 11 - 0
django/template/loader.py

@@ -1,4 +1,10 @@
+from django.utils import six
+from django.utils.deprecation import (
+    DeprecationInstanceCheck, RemovedInDjango20Warning,
+)
+
 from . import engines
+from .base import Origin
 from .exceptions import TemplateDoesNotExist
 
 
@@ -57,3 +63,8 @@ def render_to_string(template_name, context=None, request=None, using=None):
 
 def _engine_list(using=None):
     return engines.all() if using is None else [engines[using]]
+
+
+class LoaderOrigin(six.with_metaclass(DeprecationInstanceCheck, Origin)):
+    alternative = 'django.template.Origin'
+    deprecation_warning = RemovedInDjango20Warning

+ 11 - 1
django/utils/deprecation.py

@@ -8,7 +8,8 @@ class RemovedInDjango20Warning(PendingDeprecationWarning):
     pass
 
 
-RemovedInNextVersionWarning = DeprecationWarning
+class RemovedInNextVersionWarning(DeprecationWarning):
+    pass
 
 
 class warn_about_renamed_method(object):
@@ -69,3 +70,12 @@ class RenameMethodsBase(type):
                     setattr(base, old_method_name, wrapper(new_method))
 
         return new_class
+
+
+class DeprecationInstanceCheck(type):
+    def __instancecheck__(self, instance):
+        warnings.warn(
+            "`%s` is deprecated, use `%s` instead." % (self.__name__, self.alternative),
+            self.deprecation_warning, 2
+        )
+        return super(DeprecationInstanceCheck, self).__instancecheck__(instance)

+ 4 - 0
docs/internals/deprecation.txt

@@ -100,6 +100,10 @@ details on these changes.
 * The ``enclosure`` keyword argument to ``SyndicationFeed.add_item()`` will be
   removed.
 
+* The ``django.template.loader.LoaderOrigin`` and
+  ``django.template.base.StringOrigin`` aliases for
+  ``django.template.base.Origin`` will be removed.
+
 .. _deprecation-removed-in-1.10:
 
 1.10

+ 7 - 1
docs/releases/1.9.txt

@@ -818,7 +818,9 @@ debug as ``True``, an instance of ``django.template.loader.LoaderOrigin`` or
 ``django.template.base.StringOrigin`` was set as the origin attribute on the
 template object. These classes have been combined into
 :class:`~django.template.base.Origin` and is now always set regardless of the
-engine debug setting.
+engine debug setting. For a minimal level of backwards compatibility, the old
+class names will be kept as aliases to the new ``Origin`` class until
+Django 2.0.
 
 .. _default-logging-changes-19:
 
@@ -1335,6 +1337,10 @@ Miscellaneous
   deprecated. Use the new ``enclosures`` argument which accepts a list of
   ``Enclosure`` objects instead of a single one.
 
+* The ``django.template.loader.LoaderOrigin`` and
+  ``django.template.base.StringOrigin`` aliases for
+  ``django.template.base.Origin`` are deprecated.
+
 .. _removed-features-1.9:
 
 Features removed in 1.9

+ 16 - 1
tests/deprecation/tests.py

@@ -5,7 +5,9 @@ import warnings
 from django.test import SimpleTestCase
 from django.test.utils import reset_warning_registry
 from django.utils import six
-from django.utils.deprecation import RenameMethodsBase
+from django.utils.deprecation import (
+    DeprecationInstanceCheck, RemovedInNextVersionWarning, RenameMethodsBase,
+)
 
 
 class RenameManagerMethods(RenameMethodsBase):
@@ -170,3 +172,16 @@ class RenameMethodsTests(SimpleTestCase):
                 '`DeprecatedMixin.old` is deprecated, use `new` instead.',
                 '`RenamedMixin.old` is deprecated, use `new` instead.',
             ])
+
+
+class DeprecationInstanceCheckTest(SimpleTestCase):
+    def test_warning(self):
+        class Manager(six.with_metaclass(DeprecationInstanceCheck)):
+            alternative = 'fake.path.Foo'
+            deprecation_warning = RemovedInNextVersionWarning
+
+        msg = '`Manager` is deprecated, use `fake.path.Foo` instead.'
+        with warnings.catch_warnings():
+            warnings.simplefilter('error', category=RemovedInNextVersionWarning)
+            with self.assertRaisesMessage(RemovedInNextVersionWarning, msg):
+                isinstance(object, Manager)

+ 3 - 3
tests/test_runner/tests.py

@@ -352,9 +352,9 @@ class DeprecationDisplayTest(AdminScriptTestCase):
         args = ['test', '--settings=test_project.settings', 'test_runner_deprecation_app']
         out, err = self.run_django_admin(args)
         self.assertIn("Ran 1 test", force_text(err))
-        # change "Deprecation" to "RemovedInDjango\d+" in Django 1.11.
-        six.assertRegex(self, err, r"DeprecationWarning: warning from test")
-        six.assertRegex(self, err, r"DeprecationWarning: module-level warning from deprecation_app")
+        # change "NextVersion" to "RemovedInDjango\d+" in Django 1.11.
+        six.assertRegex(self, err, r"RemovedInNextVersionWarning: warning from test")
+        six.assertRegex(self, err, r"RemovedInNextVersionWarning: module-level warning from deprecation_app")
 
     def test_runner_deprecation_verbosity_zero(self):
         args = ['test', '--settings=test_project.settings', '--verbosity=0', 'test_runner_deprecation_app']