mirror of https://github.com/scrapy/scrapy.git
warn XPathSelector deprecation on subclassing and direct instance
This commit is contained in:
parent
3e42646ce1
commit
b3be6e210d
|
|
@ -1,47 +1,50 @@
|
|||
"""
|
||||
XPath selectors based on lxml
|
||||
"""
|
||||
from scrapy.utils.deprecate import create_deprecated_class
|
||||
from .unified import Selector, SelectorList
|
||||
|
||||
|
||||
__all__ = ['HtmlXPathSelector', 'XmlXPathSelector', 'XPathSelector',
|
||||
'XPathSelectorList']
|
||||
|
||||
def _xpathselector_css(self, *a, **kw):
|
||||
raise RuntimeError('.css() method not available for %s, '
|
||||
'instantiate scrapy.selector.Selector '
|
||||
'instead' % type(self).__name__)
|
||||
|
||||
class XPathSelector(Selector):
|
||||
__slots__ = ()
|
||||
_default_type = 'html'
|
||||
XPathSelector = create_deprecated_class(
|
||||
'XPathSelector',
|
||||
Selector,
|
||||
{
|
||||
'__slots__': (),
|
||||
'_default_type': 'html',
|
||||
'css': _xpathselector_css,
|
||||
},
|
||||
new_class_path='scrapy.selector.Selector',
|
||||
old_class_path='scrapy.selector.XPathSelector',
|
||||
)
|
||||
|
||||
def __init__(self, *a, **kw):
|
||||
import warnings
|
||||
from scrapy.exceptions import ScrapyDeprecationWarning
|
||||
warnings.warn('%s is deprecated, instantiate scrapy.selector.Selector '
|
||||
'instead' % type(self).__name__,
|
||||
category=ScrapyDeprecationWarning, stacklevel=1)
|
||||
super(XPathSelector, self).__init__(*a, **kw)
|
||||
XmlXPathSelector = create_deprecated_class(
|
||||
'XmlXPathSelector',
|
||||
XPathSelector,
|
||||
clsdict={
|
||||
'__slots__': (),
|
||||
'_default_type': 'xml',
|
||||
},
|
||||
new_class_path='scrapy.selector.Selector',
|
||||
old_class_path='scrapy.selector.XmlXPathSelector',
|
||||
)
|
||||
|
||||
def css(self, *a, **kw):
|
||||
raise RuntimeError('.css() method not available for %s, '
|
||||
'instantiate scrapy.selector.Selector '
|
||||
'instead' % type(self).__name__)
|
||||
HtmlXPathSelector = create_deprecated_class(
|
||||
'HtmlXPathSelector',
|
||||
XPathSelector,
|
||||
clsdict={
|
||||
'__slots__': (),
|
||||
'_default_type': 'html',
|
||||
},
|
||||
new_class_path='scrapy.selector.Selector',
|
||||
old_class_path='scrapy.selector.HtmlXPathSelector',
|
||||
)
|
||||
|
||||
|
||||
class XmlXPathSelector(XPathSelector):
|
||||
__slots__ = ()
|
||||
_default_type = 'xml'
|
||||
|
||||
|
||||
class HtmlXPathSelector(XPathSelector):
|
||||
__slots__ = ()
|
||||
_default_type = 'html'
|
||||
|
||||
|
||||
class XPathSelectorList(SelectorList):
|
||||
|
||||
def __init__(self, *a, **kw):
|
||||
import warnings
|
||||
from scrapy.exceptions import ScrapyDeprecationWarning
|
||||
warnings.warn('XPathSelectorList is deprecated, instantiate '
|
||||
'scrapy.selector.SelectorList instead',
|
||||
category=ScrapyDeprecationWarning, stacklevel=1)
|
||||
super(XPathSelectorList, self).__init__(*a, **kw)
|
||||
XPathSelectorList = create_deprecated_class('XPathSelectorList', SelectorList)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import re
|
||||
import inspect
|
||||
import warnings
|
||||
import weakref
|
||||
from twisted.trial import unittest
|
||||
|
|
@ -301,17 +302,83 @@ class DeprecatedXpathSelectorTest(unittest.TestCase):
|
|||
|
||||
text = '<div><img src="a.jpg"><p>Hello</div>'
|
||||
|
||||
def test_warnings(self):
|
||||
for cls in XPathSelector, HtmlXPathSelector, XPathSelector:
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('always')
|
||||
hs = cls(text=self.text)
|
||||
assert len(w) == 1, w
|
||||
assert issubclass(w[0].category, ScrapyDeprecationWarning)
|
||||
assert 'deprecated' in str(w[-1].message)
|
||||
hs.select("//div").extract()
|
||||
assert issubclass(w[1].category, ScrapyDeprecationWarning)
|
||||
assert 'deprecated' in str(w[-1].message)
|
||||
def test_warnings_xpathselector(self):
|
||||
cls = XPathSelector
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
class UserClass(cls):
|
||||
pass
|
||||
|
||||
# subclassing must issue a warning
|
||||
self.assertEqual(len(w), 1, str(cls))
|
||||
self.assertIn('scrapy.selector.Selector', str(w[0].message))
|
||||
|
||||
# subclass instance doesn't issue a warning
|
||||
usel = UserClass(text=self.text)
|
||||
self.assertEqual(len(w), 1)
|
||||
|
||||
# class instance must issue a warning
|
||||
sel = cls(text=self.text)
|
||||
self.assertEqual(len(w), 2, str((cls, [x.message for x in w])))
|
||||
self.assertIn('scrapy.selector.Selector', str(w[1].message))
|
||||
|
||||
# subclass and instance checks
|
||||
self.assertTrue(issubclass(cls, Selector))
|
||||
self.assertTrue(isinstance(sel, Selector))
|
||||
self.assertTrue(isinstance(usel, Selector))
|
||||
|
||||
def test_warnings_xmlxpathselector(self):
|
||||
cls = XmlXPathSelector
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
class UserClass(cls):
|
||||
pass
|
||||
|
||||
# subclassing must issue a warning
|
||||
self.assertEqual(len(w), 1, str(cls))
|
||||
self.assertIn('scrapy.selector.Selector', str(w[0].message))
|
||||
|
||||
# subclass instance doesn't issue a warning
|
||||
usel = UserClass(text=self.text)
|
||||
self.assertEqual(len(w), 1)
|
||||
|
||||
# class instance must issue a warning
|
||||
sel = cls(text=self.text)
|
||||
self.assertEqual(len(w), 2, str((cls, [x.message for x in w])))
|
||||
self.assertIn('scrapy.selector.Selector', str(w[1].message))
|
||||
|
||||
# subclass and instance checks
|
||||
self.assertTrue(issubclass(cls, Selector))
|
||||
self.assertTrue(issubclass(cls, XPathSelector))
|
||||
self.assertTrue(isinstance(sel, Selector))
|
||||
self.assertTrue(isinstance(usel, Selector))
|
||||
self.assertTrue(isinstance(sel, XPathSelector))
|
||||
self.assertTrue(isinstance(usel, XPathSelector))
|
||||
|
||||
def test_warnings_htmlxpathselector(self):
|
||||
cls = HtmlXPathSelector
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
class UserClass(cls):
|
||||
pass
|
||||
|
||||
# subclassing must issue a warning
|
||||
self.assertEqual(len(w), 1, str(cls))
|
||||
self.assertIn('scrapy.selector.Selector', str(w[0].message))
|
||||
|
||||
# subclass instance doesn't issue a warning
|
||||
usel = UserClass(text=self.text)
|
||||
self.assertEqual(len(w), 1)
|
||||
|
||||
# class instance must issue a warning
|
||||
sel = cls(text=self.text)
|
||||
self.assertEqual(len(w), 2, str((cls, [x.message for x in w])))
|
||||
self.assertIn('scrapy.selector.Selector', str(w[1].message))
|
||||
|
||||
# subclass and instance checks
|
||||
self.assertTrue(issubclass(cls, Selector))
|
||||
self.assertTrue(issubclass(cls, XPathSelector))
|
||||
self.assertTrue(isinstance(sel, Selector))
|
||||
self.assertTrue(isinstance(usel, Selector))
|
||||
self.assertTrue(isinstance(sel, XPathSelector))
|
||||
self.assertTrue(isinstance(usel, XPathSelector))
|
||||
|
||||
def test_xpathselector(self):
|
||||
with warnings.catch_warnings(record=True):
|
||||
|
|
|
|||
Loading…
Reference in New Issue