prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Deprecated class inheritance check bug
  ``` python
  >>> from scrapy.spider import BaseSpider
  >>> class A(BaseSpider):
  ...     pass
  ... 
  >>> class B(BaseSpider):
  ...     pass
  ... 
  >>> isinstance(A('foo'), B)
  True
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `scrapy/utils/deprecate.py`
  Content:
  ```
  1 """Some helpers for deprecation messages"""
  2 
  3 import warnings
  4 import inspect
  5 from scrapy.exceptions import ScrapyDeprecationWarning
  6 
  7 
  8 def attribute(obj, oldattr, newattr, version='0.12'):
  9     cname = obj.__class__.__name__
  10     warnings.warn("%s.%s attribute is deprecated and will be no longer supported "
  11         "in Scrapy %s, use %s.%s attribute instead" % \
  12         (cname, oldattr, version, cname, newattr), ScrapyDeprecationWarning, stacklevel=3)
  13 
  14 
  15 def create_deprecated_class(name, new_class, clsdict=None,
  16                             warn_category=ScrapyDeprecationWarning,
  17                             warn_once=True,
  18                             old_class_path=None,
  19                             new_class_path=None,
  20                             subclass_warn_message="{cls} inherits from "\
  21                                     "deprecated class {old}, please inherit "\
  22                                     "from {new}.",
  23                             instance_warn_message="{cls} is deprecated, "\
  24                                     "instantiate {new} instead."):
  25     """
  26     Return a "deprecated" class that causes its subclasses to issue a warning.
  27     Subclasses of ``new_class`` are considered subclasses of this class.
  28     It also warns when the deprecated class is instantiated, but do not when
  29     its subclasses are instantiated.
  30 
  31     It can be used to rename a base class in a library. For example, if we
  32     have
  33 
  34         class OldName(SomeClass):
  35             # ...
  36 
  37     and we want to rename it to NewName, we can do the following::
  38 
  39         class NewName(SomeClass):
  40             # ...
  41 
  42         OldName = create_deprecated_class('OldName', NewName)
  43 
  44     Then, if user class inherits from OldName, warning is issued. Also, if
  45     some code uses ``issubclass(sub, OldName)`` or ``isinstance(sub(), OldName)``
  46     checks they'll still return True if sub is a subclass of NewName instead of
  47     OldName.
  48     """
  49 
  50     class DeprecatedClass(new_class.__class__):
  51 
  52         deprecated_class = None
  53         warned_on_subclass = False
  54 
  55         def __new__(metacls, name, bases, clsdict_):
  56             cls = super(DeprecatedClass, metacls).__new__(metacls, name, bases, clsdict_)
  57             if metacls.deprecated_class is None:
  58                 metacls.deprecated_class = cls
  59             return cls
  60 
  61         def __init__(cls, name, bases, clsdict_):
  62             meta = cls.__class__
  63             old = meta.deprecated_class
  64             if old in bases and not (warn_once and meta.warned_on_subclass):
  65                 meta.warned_on_subclass = True
  66                 msg = subclass_warn_message.format(cls=_clspath(cls),
  67                                                    old=_clspath(old, old_class_path),
  68                                                    new=_clspath(new_class, new_class_path))
  69                 if warn_once:
  70                     msg += ' (warning only on first subclass, there may be others)'
  71                 warnings.warn(msg, warn_category, stacklevel=2)
  72             super(DeprecatedClass, cls).__init__(name, bases, clsdict_)
  73 
  74         # see http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass
  75         # and http://docs.python.org/2/reference/datamodel.html#customizing-instance-and-subclass-checks
  76         # for implementation details
  77         def __instancecheck__(cls, inst):
  78             return any(cls.__subclasscheck__(c)
  79                        for c in {type(inst), inst.__class__})
  80 
  81         def __subclasscheck__(cls, sub):
  82             if not inspect.isclass(sub):
  83                 raise TypeError("issubclass() arg 1 must be a class")
  84 
  85             mro = getattr(sub, '__mro__', ())
  86             candidates = {cls, new_class}
  87             return any(c in candidates for c in mro)
  88 
  89         def __call__(cls, *args, **kwargs):
  90             old = DeprecatedClass.deprecated_class
  91             if cls is old:
  92                 msg = instance_warn_message.format(cls=_clspath(cls, old_class_path),
  93                                                    new=_clspath(new_class, new_class_path))
  94                 warnings.warn(msg, warn_category, stacklevel=2)
  95             return super(DeprecatedClass, cls).__call__(*args, **kwargs)
  96 
  97     deprecated_cls = DeprecatedClass(name, (new_class,), clsdict or {})
  98     frm = inspect.stack()[1]
  99     parent_module = inspect.getmodule(frm[0])
  100     if parent_module is not None:
  101         deprecated_cls.__module__ = parent_module.__name__
  102 
  103     return deprecated_cls
  104 
  105 
  106 def _clspath(cls, forced=None):
  107     if forced is not None:
  108         return forced
  109     return '{}.{}'.format(cls.__module__, cls.__name__)
  110
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/scrapy/utils/deprecate.py b/scrapy/utils/deprecate.py
  --- a/scrapy/utils/deprecate.py
  +++ b/scrapy/utils/deprecate.py
  @@ -79,12 +79,18 @@
                          for c in {type(inst), inst.__class__})
   
           def __subclasscheck__(cls, sub):
  +            if cls is not DeprecatedClass.deprecated_class:
  +                # we should do the magic only if second `issubclass` argument
  +                # is the deprecated class itself - subclasses of the
  +                # deprecated class should not use custom `__subclasscheck__`
  +                # method.
  +                return super(DeprecatedClass, cls).__subclasscheck__(sub)
  +
               if not inspect.isclass(sub):
                   raise TypeError("issubclass() arg 1 must be a class")
   
               mro = getattr(sub, '__mro__', ())
  -            candidates = {cls, new_class}
  -            return any(c in candidates for c in mro)
  +            return any(c in {cls, new_class} for c in mro)
   
           def __call__(cls, *args, **kwargs):
               old = DeprecatedClass.deprecated_class
  
verification_info: {"golden_diff": "diff --git a/scrapy/utils/deprecate.py b/scrapy/utils/deprecate.py\n--- a/scrapy/utils/deprecate.py\n+++ b/scrapy/utils/deprecate.py\n@@ -79,12 +79,18 @@\n                        for c in {type(inst), inst.__class__})\n \n         def __subclasscheck__(cls, sub):\n+            if cls is not DeprecatedClass.deprecated_class:\n+                # we should do the magic only if second `issubclass` argument\n+                # is the deprecated class itself - subclasses of the\n+                # deprecated class should not use custom `__subclasscheck__`\n+                # method.\n+                return super(DeprecatedClass, cls).__subclasscheck__(sub)\n+\n             if not inspect.isclass(sub):\n                 raise TypeError(\"issubclass() arg 1 must be a class\")\n \n             mro = getattr(sub, '__mro__', ())\n-            candidates = {cls, new_class}\n-            return any(c in candidates for c in mro)\n+            return any(c in {cls, new_class} for c in mro)\n \n         def __call__(cls, *args, **kwargs):\n             old = DeprecatedClass.deprecated_class\n", "issue": "Deprecated class inheritance check bug\n``` python\n>>> from scrapy.spider import BaseSpider\n>>> class A(BaseSpider):\n...     pass\n... \n>>> class B(BaseSpider):\n...     pass\n... \n>>> isinstance(A('foo'), B)\nTrue\n```\n\n", "before_files": [{"content": "\"\"\"Some helpers for deprecation messages\"\"\"\n\nimport warnings\nimport inspect\nfrom scrapy.exceptions import ScrapyDeprecationWarning\n\n\ndef attribute(obj, oldattr, newattr, version='0.12'):\n    cname = obj.__class__.__name__\n    warnings.warn(\"%s.%s attribute is deprecated and will be no longer supported \"\n        \"in Scrapy %s, use %s.%s attribute instead\" % \\\n        (cname, oldattr, version, cname, newattr), ScrapyDeprecationWarning, stacklevel=3)\n\n\ndef create_deprecated_class(name, new_class, clsdict=None,\n                            warn_category=ScrapyDeprecationWarning,\n                            warn_once=True,\n                            old_class_path=None,\n                            new_class_path=None,\n                            subclass_warn_message=\"{cls} inherits from \"\\\n                                    \"deprecated class {old}, please inherit \"\\\n                                    \"from {new}.\",\n                            instance_warn_message=\"{cls} is deprecated, \"\\\n                                    \"instantiate {new} instead.\"):\n    \"\"\"\n    Return a \"deprecated\" class that causes its subclasses to issue a warning.\n    Subclasses of ``new_class`` are considered subclasses of this class.\n    It also warns when the deprecated class is instantiated, but do not when\n    its subclasses are instantiated.\n\n    It can be used to rename a base class in a library. For example, if we\n    have\n\n        class OldName(SomeClass):\n            # ...\n\n    and we want to rename it to NewName, we can do the following::\n\n        class NewName(SomeClass):\n            # ...\n\n        OldName = create_deprecated_class('OldName', NewName)\n\n    Then, if user class inherits from OldName, warning is issued. Also, if\n    some code uses ``issubclass(sub, OldName)`` or ``isinstance(sub(), OldName)``\n    checks they'll still return True if sub is a subclass of NewName instead of\n    OldName.\n    \"\"\"\n\n    class DeprecatedClass(new_class.__class__):\n\n        deprecated_class = None\n        warned_on_subclass = False\n\n        def __new__(metacls, name, bases, clsdict_):\n            cls = super(DeprecatedClass, metacls).__new__(metacls, name, bases, clsdict_)\n            if metacls.deprecated_class is None:\n                metacls.deprecated_class = cls\n            return cls\n\n        def __init__(cls, name, bases, clsdict_):\n            meta = cls.__class__\n            old = meta.deprecated_class\n            if old in bases and not (warn_once and meta.warned_on_subclass):\n                meta.warned_on_subclass = True\n                msg = subclass_warn_message.format(cls=_clspath(cls),\n                                                   old=_clspath(old, old_class_path),\n                                                   new=_clspath(new_class, new_class_path))\n                if warn_once:\n                    msg += ' (warning only on first subclass, there may be others)'\n                warnings.warn(msg, warn_category, stacklevel=2)\n            super(DeprecatedClass, cls).__init__(name, bases, clsdict_)\n\n        # see http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass\n        # and http://docs.python.org/2/reference/datamodel.html#customizing-instance-and-subclass-checks\n        # for implementation details\n        def __instancecheck__(cls, inst):\n            return any(cls.__subclasscheck__(c)\n                       for c in {type(inst), inst.__class__})\n\n        def __subclasscheck__(cls, sub):\n            if not inspect.isclass(sub):\n                raise TypeError(\"issubclass() arg 1 must be a class\")\n\n            mro = getattr(sub, '__mro__', ())\n            candidates = {cls, new_class}\n            return any(c in candidates for c in mro)\n\n        def __call__(cls, *args, **kwargs):\n            old = DeprecatedClass.deprecated_class\n            if cls is old:\n                msg = instance_warn_message.format(cls=_clspath(cls, old_class_path),\n                                                   new=_clspath(new_class, new_class_path))\n                warnings.warn(msg, warn_category, stacklevel=2)\n            return super(DeprecatedClass, cls).__call__(*args, **kwargs)\n\n    deprecated_cls = DeprecatedClass(name, (new_class,), clsdict or {})\n    frm = inspect.stack()[1]\n    parent_module = inspect.getmodule(frm[0])\n    if parent_module is not None:\n        deprecated_cls.__module__ = parent_module.__name__\n\n    return deprecated_cls\n\n\ndef _clspath(cls, forced=None):\n    if forced is not None:\n        return forced\n    return '{}.{}'.format(cls.__module__, cls.__name__)\n", "path": "scrapy/utils/deprecate.py"}], "after_files": [{"content": "\"\"\"Some helpers for deprecation messages\"\"\"\n\nimport warnings\nimport inspect\nfrom scrapy.exceptions import ScrapyDeprecationWarning\n\n\ndef attribute(obj, oldattr, newattr, version='0.12'):\n    cname = obj.__class__.__name__\n    warnings.warn(\"%s.%s attribute is deprecated and will be no longer supported \"\n        \"in Scrapy %s, use %s.%s attribute instead\" % \\\n        (cname, oldattr, version, cname, newattr), ScrapyDeprecationWarning, stacklevel=3)\n\n\ndef create_deprecated_class(name, new_class, clsdict=None,\n                            warn_category=ScrapyDeprecationWarning,\n                            warn_once=True,\n                            old_class_path=None,\n                            new_class_path=None,\n                            subclass_warn_message=\"{cls} inherits from \"\\\n                                    \"deprecated class {old}, please inherit \"\\\n                                    \"from {new}.\",\n                            instance_warn_message=\"{cls} is deprecated, \"\\\n                                    \"instantiate {new} instead.\"):\n    \"\"\"\n    Return a \"deprecated\" class that causes its subclasses to issue a warning.\n    Subclasses of ``new_class`` are considered subclasses of this class.\n    It also warns when the deprecated class is instantiated, but do not when\n    its subclasses are instantiated.\n\n    It can be used to rename a base class in a library. For example, if we\n    have\n\n        class OldName(SomeClass):\n            # ...\n\n    and we want to rename it to NewName, we can do the following::\n\n        class NewName(SomeClass):\n            # ...\n\n        OldName = create_deprecated_class('OldName', NewName)\n\n    Then, if user class inherits from OldName, warning is issued. Also, if\n    some code uses ``issubclass(sub, OldName)`` or ``isinstance(sub(), OldName)``\n    checks they'll still return True if sub is a subclass of NewName instead of\n    OldName.\n    \"\"\"\n\n    class DeprecatedClass(new_class.__class__):\n\n        deprecated_class = None\n        warned_on_subclass = False\n\n        def __new__(metacls, name, bases, clsdict_):\n            cls = super(DeprecatedClass, metacls).__new__(metacls, name, bases, clsdict_)\n            if metacls.deprecated_class is None:\n                metacls.deprecated_class = cls\n            return cls\n\n        def __init__(cls, name, bases, clsdict_):\n            meta = cls.__class__\n            old = meta.deprecated_class\n            if old in bases and not (warn_once and meta.warned_on_subclass):\n                meta.warned_on_subclass = True\n                msg = subclass_warn_message.format(cls=_clspath(cls),\n                                                   old=_clspath(old, old_class_path),\n                                                   new=_clspath(new_class, new_class_path))\n                if warn_once:\n                    msg += ' (warning only on first subclass, there may be others)'\n                warnings.warn(msg, warn_category, stacklevel=2)\n            super(DeprecatedClass, cls).__init__(name, bases, clsdict_)\n\n        # see http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass\n        # and http://docs.python.org/2/reference/datamodel.html#customizing-instance-and-subclass-checks\n        # for implementation details\n        def __instancecheck__(cls, inst):\n            return any(cls.__subclasscheck__(c)\n                       for c in {type(inst), inst.__class__})\n\n        def __subclasscheck__(cls, sub):\n            if cls is not DeprecatedClass.deprecated_class:\n                # we should do the magic only if second `issubclass` argument\n                # is the deprecated class itself - subclasses of the\n                # deprecated class should not use custom `__subclasscheck__`\n                # method.\n                return super(DeprecatedClass, cls).__subclasscheck__(sub)\n\n            if not inspect.isclass(sub):\n                raise TypeError(\"issubclass() arg 1 must be a class\")\n\n            mro = getattr(sub, '__mro__', ())\n            return any(c in {cls, new_class} for c in mro)\n\n        def __call__(cls, *args, **kwargs):\n            old = DeprecatedClass.deprecated_class\n            if cls is old:\n                msg = instance_warn_message.format(cls=_clspath(cls, old_class_path),\n                                                   new=_clspath(new_class, new_class_path))\n                warnings.warn(msg, warn_category, stacklevel=2)\n            return super(DeprecatedClass, cls).__call__(*args, **kwargs)\n\n    deprecated_cls = DeprecatedClass(name, (new_class,), clsdict or {})\n    frm = inspect.stack()[1]\n    parent_module = inspect.getmodule(frm[0])\n    if parent_module is not None:\n        deprecated_cls.__module__ = parent_module.__name__\n\n    return deprecated_cls\n\n\ndef _clspath(cls, forced=None):\n    if forced is not None:\n        return forced\n    return '{}.{}'.format(cls.__module__, cls.__name__)\n", "path": "scrapy/utils/deprecate.py"}]}