diff --git a/scrapy/tests/test_utils_deprecate.py b/scrapy/tests/test_utils_deprecate.py index 2afb780ef..8cc3a26f1 100644 --- a/scrapy/tests/test_utils_deprecate.py +++ b/scrapy/tests/test_utils_deprecate.py @@ -46,6 +46,25 @@ class WarnWhenSubclassedTest(unittest.TestCase): ) self.assertEqual(w[0].lineno, inspect.getsourcelines(UserClass)[1]) + def test_custom_class_paths(self): + Deprecated = create_deprecated_class('Deprecated', NewName, + new_class_path='foo.NewClass', + old_class_path='bar.OldClass', + warn_category=MyWarning) + + with warnings.catch_warnings(record=True) as w: + class UserClass(Deprecated): + pass + + _ = Deprecated() + + w = self._mywarnings(w) + self.assertEqual(len(w), 2) + self.assertIn('foo.NewClass', str(w[0].message)) + self.assertIn('bar.OldClass', str(w[0].message)) + self.assertIn('foo.NewClass', str(w[1].message)) + self.assertIn('bar.OldClass', str(w[1].message)) + def test_subclassing_warns_only_on_direct_childs(self): Deprecated = create_deprecated_class('Deprecated', NewName, warn_once=False, diff --git a/scrapy/utils/deprecate.py b/scrapy/utils/deprecate.py index 6130ad800..47d97e9cb 100644 --- a/scrapy/utils/deprecate.py +++ b/scrapy/utils/deprecate.py @@ -15,6 +15,8 @@ def attribute(obj, oldattr, newattr, version='0.12'): def create_deprecated_class(name, new_class, clsdict=None, warn_category=ScrapyDeprecationWarning, warn_once=True, + old_class_path=None, + new_class_path=None, subclass_warn_message="{cls} inherits from "\ "deprecated class {old}, please inherit "\ "from {new}.", @@ -62,8 +64,8 @@ def create_deprecated_class(name, new_class, clsdict=None, if old in bases and not (warn_once and meta.warned_on_subclass): meta.warned_on_subclass = True msg = subclass_warn_message.format(cls=_clspath(cls), - old=_clspath(old), - new=_clspath(new_class)) + old=_clspath(old, old_class_path), + new=_clspath(new_class, new_class_path)) if warn_once: msg += ' (warning only on first subclass, there may be others)' warnings.warn(msg, warn_category, stacklevel=2) @@ -88,8 +90,8 @@ def create_deprecated_class(name, new_class, clsdict=None, meta = cls.__class__ old = meta.deprecated_class if cls is old: - msg = instance_warn_message.format(cls=_clspath(cls), - new=_clspath(new_class)) + msg = instance_warn_message.format(cls=_clspath(cls, old_class_path), + new=_clspath(new_class, new_class_path)) warnings.warn(msg, warn_category, stacklevel=2) return super(DeprecatedClass, cls).__call__(*args, **kwargs) @@ -102,5 +104,7 @@ def create_deprecated_class(name, new_class, clsdict=None, return deprecated_cls -def _clspath(cls): +def _clspath(cls, forced=None): + if forced is not None: + return forced return '{}.{}'.format(cls.__module__, cls.__name__)