improved deprecation code; add some test

This commit is contained in:
Mikhail Korobov 2013-12-29 01:54:24 +06:00
parent a27d91f0a6
commit 04788673e7
4 changed files with 61 additions and 6 deletions

View File

@ -67,9 +67,8 @@ class Spider(object_ref):
class BaseSpider(Spider):
__metaclass__ = warn_when_subclassed(
4, # == len([object, object_ref, Spider, BaseSpider])
"scrapy.spider.BaseSpider was deprecated. "
"Please inherit from scrapy.spider.Spider."
superclass=Spider,
message="scrapy.spider.BaseSpider was deprecated. Please inherit from scrapy.spider.Spider."
)

View File

@ -5,10 +5,11 @@ from cStringIO import StringIO
from twisted.trial import unittest
from scrapy.spider import Spider
from scrapy.spider import Spider, BaseSpider
from scrapy.http import Response, TextResponse, XmlResponse, HtmlResponse
from scrapy.contrib.spiders.init import InitSpider
from scrapy.contrib.spiders import CrawlSpider, XMLFeedSpider, CSVFeedSpider, SitemapSpider
from scrapy.exceptions import ScrapyDeprecationWarning
class SpiderTest(unittest.TestCase):
@ -134,5 +135,19 @@ class SitemapSpiderTest(SpiderTest):
r = Response(url="http://www.example.com/sitemap.xml.gz", body=self.GZBODY)
self.assertEqual(spider._get_sitemap_body(r), self.BODY)
class BaseSpiderDeprecationTest(unittest.TestCase):
def test_basespider_is_deprecated(self):
with warnings.catch_warnings(record=True) as w:
class MySpider(BaseSpider):
pass
self.assertEqual(len(w), 1)
self.assertEqual(w[0].category, ScrapyDeprecationWarning)
self.assertEqual(w[0].lineno, inspect.getsourcelines(MySpider)[1])
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import inspect
import unittest
import warnings
from scrapy.utils.deprecate import warn_when_subclassed
class MyWarning(UserWarning):
pass
class SomeBaseClass(object):
pass
class NewName(SomeBaseClass):
pass
class WarnWhenSubclassedTest(unittest.TestCase):
def test_no_warning_on_definition(self):
with warnings.catch_warnings(record=True) as w:
class Deprecated(NewName):
__metaclass__ = warn_when_subclassed(NewName, "message")
self.assertEqual(w, [])
def test_warning_on_subclassing(self):
with warnings.catch_warnings(record=True) as w:
class Deprecated(NewName):
__metaclass__ = warn_when_subclassed(NewName, "message", MyWarning)
class UserClass(Deprecated):
pass
self.assertEqual(len(w), 1)
msg = w[0]
assert issubclass(msg.category, MyWarning)
self.assertEqual(str(msg.message), "message")
self.assertEqual(msg.lineno, inspect.getsourcelines(UserClass)[1])

View File

@ -11,14 +11,14 @@ def attribute(obj, oldattr, newattr, version='0.12'):
(cname, oldattr, version, cname, newattr), ScrapyDeprecationWarning, stacklevel=3)
def warn_when_subclassed(mro_len, message, category=ScrapyDeprecationWarning):
def warn_when_subclassed(superclass, message, category=ScrapyDeprecationWarning):
"""
Return a metaclass that causes classes to
issue a warning when they are subclassed.
"""
class Metaclass(type):
def __init__(cls, name, bases, clsdict):
if len(cls.mro()) > mro_len:
if len(cls.mro()) > len(superclass.mro()) + 1:
warnings.warn(message, category, stacklevel=2)
super(Metaclass, cls).__init__(name, bases, clsdict)
return Metaclass