Source: urlwatch
Version: 2.28-1
Severity: serious
Justification: FTBFS
Tags: trixie sid ftbfs
User: lu...@debian.org
Usertags: ftbfs-20240224 ftbfs-trixie

Hi,

During a rebuild of all packages in sid, your package failed to build
on amd64.


Relevant part (hopefully):
>  debian/rules binary
> dh binary --with python3,sphinxdoc --buildsystem=pybuild
>    dh_update_autotools_config -O--buildsystem=pybuild
>    dh_autoreconf -O--buildsystem=pybuild
>    dh_auto_configure -O--buildsystem=pybuild
> I: pybuild base:305: python3.12 setup.py config 
> running config
> I: pybuild base:305: python3.11 setup.py config 
> running config
>    dh_auto_build -O--buildsystem=pybuild
> I: pybuild base:305: /usr/bin/python3.12 setup.py build 
> running build
> running build_py
> creating /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/__init__.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/mailer.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/main.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/filters.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/storage.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/reporters.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/html2txt.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/command.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/migration.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/cli.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/worker.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/jobs.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/config.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/util.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/handler.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/xmpp.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> copying lib/urlwatch/ical2txt.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch
> I: pybuild base:305: /usr/bin/python3 setup.py build 
> running build
> running build_py
> creating /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/__init__.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/mailer.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/main.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/filters.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/storage.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/reporters.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/html2txt.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/command.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/migration.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/cli.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/worker.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/jobs.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/config.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/util.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/handler.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/xmpp.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
> copying lib/urlwatch/ical2txt.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch
>    dh_auto_test -O--buildsystem=pybuild
> I: pybuild pybuild:310: cp -r /<<PKGBUILDDIR>>/docs 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/../; cp -r 
> /<<PKGBUILDDIR>>/lib/urlwatch/tests 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/urlwatch/; cp -r 
> /<<PKGBUILDDIR>>/share 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build/../
> I: pybuild base:305: cd 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build; python3.12 -m pytest 
> ============================= test session starts 
> ==============================
> platform linux -- Python 3.12.2, pytest-7.4.4, pluggy-1.4.0
> rootdir: /<<PKGBUILDDIR>>
> collected 88 items
> 
> urlwatch/tests/test_filter_documentation.py .....F.F.FFFF..............  [ 
> 30%]
> urlwatch/tests/test_filters.py ...................FFF................... [ 
> 77%]
> ...                                                                      [ 
> 80%]
> urlwatch/tests/test_handler.py .............                             [ 
> 95%]
> urlwatch/tests/test_util.py ....                                         
> [100%]
> 
> =================================== FAILURES 
> ===================================
> ____________________ test_url[https://example.net/css.html] 
> ____________________
> 
> url = 'https://example.net/css.html'
> job = {'filter': [{'css': 'ul#groceries > li.unchecked'}], 'url': 
> 'https://example.net/css.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd43011760>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _______________ test_url[http://example.com/blog/css-index.rss] 
> ________________
> 
> url = 'http://example.com/blog/css-index.rss'
> job = {'filter': [{'css': {'method': 'xml', 'selector': 'item > title, item > 
> pubDate'}}, {'html2text': 're'}], 'url': 
> 'http://example.com/blog/css-index.rss'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd43012450>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _____________ test_url[http://example.org/feed/css-namespace.xml] 
> ______________
> 
> url = 'http://example.org/feed/css-namespace.xml'
> job = {'filter': [{'css': {'method': 'xml', 'namespaces': {'media': 
> 'http://search.yahoo.com/mrss/'}, 'selector': 'item > media|keywords'}}, 
> 'html2text'], 'url': 'http://example.org/feed/css-namespace.xml'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd43010230>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ________________ test_url[https://example.org/css-exclude.html] 
> ________________
> 
> url = 'https://example.org/css-exclude.html'
> job = {'filter': [{'css': {'exclude': 'a', 'selector': 'body'}}], 'url': 
> 'https://example.org/css-exclude.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd4302f320>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _____________ test_url[https://example.net/css-skip-maxitems.html] 
> _____________
> 
> url = 'https://example.net/css-skip-maxitems.html'
> job = {'filter': [{'css': {'maxitems': 2, 'selector': 'div.cpu', 'skip': 
> 1}}], 'url': 'https://example.net/css-skip-maxitems.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd43034320>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ____________ test_url[https://example.org/items-random-order.html] 
> _____________
> 
> url = 'https://example.org/items-random-order.html'
> job = {'filter': [{'css': {'selector': 'span.item', 'sort': True}}], 'url': 
> 'https://example.org/items-random-order.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd4302d880>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ______________________________ test_filters[css] 
> _______________________________
> 
> test_name = 'css'
> test_data = {'data': 
> '<html><head></head><body>\n<div>foo</div>\n<div>bar</div>\n</body></html>\n',
>  'expected_result': '<div>foo</div>\n\n<div>bar</div>\n', 'filter': 'css:div'}
> 
>     @pytest.mark.parametrize('test_name, test_data', FILTER_TESTS, ids=[d[0] 
> for d in FILTER_TESTS])
>     def test_filters(test_name, test_data):
>         filter = test_data['filter']
>         data = test_data['data']
>         expected_result = test_data['expected_result']
>     
>         result = data
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(filter):
>             logger.info('filter kind: %s, subfilter: %s', filter_kind, 
> subfilter)
>             filtercls = FilterBase.__subclasses__.get(filter_kind)
>             if filtercls is None:
>                 raise ValueError('Unknown filter kind: %s:%s' % (filter_kind, 
> subfilter))
> >           result = filtercls(None, None).filter(result, subfilter)
> 
> urlwatch/tests/test_filters.py:55: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd43011af0>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ------------------------------ Captured log call 
> -------------------------------
> WARNING  urlwatch.filters:filters.py:163 String-based filter definitions 
> (css:div) are deprecated, please convert to dict-style (see 
> https://urlwatch.readthedocs.io/en/latest/deprecated.html):
> 
> - css: div
> __________________________ test_filters[css_exclude] 
> ___________________________
> 
> test_name = 'css_exclude'
> test_data = {'data': '<html><head></head><body>\n<div class="excl">you don\'t 
> want to see me</div>\n<div class="foo">f<span class=... 'expected_result': 
> '<div class="foo">foo</div>\n', 'filter': [{'css': {'exclude': '.excl, #bar', 
> 'selector': 'div'}}]}
> 
>     @pytest.mark.parametrize('test_name, test_data', FILTER_TESTS, ids=[d[0] 
> for d in FILTER_TESTS])
>     def test_filters(test_name, test_data):
>         filter = test_data['filter']
>         data = test_data['data']
>         expected_result = test_data['expected_result']
>     
>         result = data
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(filter):
>             logger.info('filter kind: %s, subfilter: %s', filter_kind, 
> subfilter)
>             filtercls = FilterBase.__subclasses__.get(filter_kind)
>             if filtercls is None:
>                 raise ValueError('Unknown filter kind: %s:%s' % (filter_kind, 
> subfilter))
> >           result = filtercls(None, None).filter(result, subfilter)
> 
> urlwatch/tests/test_filters.py:55: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd43013140>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _______________________ test_filters[css_xml_namespaces] 
> _______________________
> 
> test_name = 'css_xml_namespaces'
> test_data = {'data': '<feed 
> xmlns:f="foo">\n<item>\n<f:year>2017</f:year>\n<author>Tom</author>\n<data>abc</data>\n</item>\n<f:ite...er':
>  [{'css': {'exclude': 'f|year, author', 'method': 'xml', 'namespaces': {'f': 
> 'foo'}, 'selector': 'item, f|item'}}]}
> 
>     @pytest.mark.parametrize('test_name, test_data', FILTER_TESTS, ids=[d[0] 
> for d in FILTER_TESTS])
>     def test_filters(test_name, test_data):
>         filter = test_data['filter']
>         data = test_data['data']
>         expected_result = test_data['expected_result']
>     
>         result = data
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(filter):
>             logger.info('filter kind: %s, subfilter: %s', filter_kind, 
> subfilter)
>             filtercls = FilterBase.__subclasses__.get(filter_kind)
>             if filtercls is None:
>                 raise ValueError('Unknown filter kind: %s:%s' % (filter_kind, 
> subfilter))
> >           result = filtercls(None, None).filter(result, subfilter)
> 
> urlwatch/tests/test_filters.py:55: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7fbd430120f0>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> =========================== short test summary info 
> ============================
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.net/css.html]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[http:/example.com/blog/css-index.rss]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[http:/example.org/feed/css-namespace.xml]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.org/css-exclude.html]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.net/css-skip-maxitems.html]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.org/items-random-order.html]
> FAILED urlwatch/tests/test_filters.py::test_filters[css] - AttributeError: 
> 'C...
> FAILED urlwatch/tests/test_filters.py::test_filters[css_exclude] - 
> AttributeE...
> FAILED urlwatch/tests/test_filters.py::test_filters[css_xml_namespaces] - 
> Att...
> ========================= 9 failed, 79 passed in 2.16s 
> =========================
> E: pybuild pybuild:391: test: plugin distutils failed with: exit code=1: cd 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_urlwatch/build; python3.12 -m pytest 
> I: pybuild pybuild:310: cp -r /<<PKGBUILDDIR>>/docs 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/../; cp -r 
> /<<PKGBUILDDIR>>/lib/urlwatch/tests 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/urlwatch/; cp -r 
> /<<PKGBUILDDIR>>/share 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build/../
> I: pybuild base:305: cd 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build; python3.11 -m pytest 
> ============================= test session starts 
> ==============================
> platform linux -- Python 3.11.8, pytest-7.4.4, pluggy-1.4.0
> rootdir: /<<PKGBUILDDIR>>
> collected 88 items
> 
> urlwatch/tests/test_filter_documentation.py .....F.F.FFFF..............  [ 
> 30%]
> urlwatch/tests/test_filters.py ...................FFF................... [ 
> 77%]
> ...                                                                      [ 
> 80%]
> urlwatch/tests/test_handler.py .............                             [ 
> 95%]
> urlwatch/tests/test_util.py ....                                         
> [100%]
> 
> =================================== FAILURES 
> ===================================
> ____________________ test_url[https://example.net/css.html] 
> ____________________
> 
> url = 'https://example.net/css.html'
> job = {'filter': [{'css': 'ul#groceries > li.unchecked'}], 'url': 
> 'https://example.net/css.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448ddc5d50>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _______________ test_url[http://example.com/blog/css-index.rss] 
> ________________
> 
> url = 'http://example.com/blog/css-index.rss'
> job = {'filter': [{'css': {'method': 'xml', 'selector': 'item > title, item > 
> pubDate'}}, {'html2text': 're'}], 'url': 
> 'http://example.com/blog/css-index.rss'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d3bc550>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _____________ test_url[http://example.org/feed/css-namespace.xml] 
> ______________
> 
> url = 'http://example.org/feed/css-namespace.xml'
> job = {'filter': [{'css': {'method': 'xml', 'namespaces': {'media': 
> 'http://search.yahoo.com/mrss/'}, 'selector': 'item > media|keywords'}}, 
> 'html2text'], 'url': 'http://example.org/feed/css-namespace.xml'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d3be090>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ________________ test_url[https://example.org/css-exclude.html] 
> ________________
> 
> url = 'https://example.org/css-exclude.html'
> job = {'filter': [{'css': {'exclude': 'a', 'selector': 'body'}}], 'url': 
> 'https://example.org/css-exclude.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d3e9510>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _____________ test_url[https://example.net/css-skip-maxitems.html] 
> _____________
> 
> url = 'https://example.net/css-skip-maxitems.html'
> job = {'filter': [{'css': {'maxitems': 2, 'selector': 'div.cpu', 'skip': 
> 1}}], 'url': 'https://example.net/css-skip-maxitems.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d3a5b50>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ____________ test_url[https://example.org/items-random-order.html] 
> _____________
> 
> url = 'https://example.org/items-random-order.html'
> job = {'filter': [{'css': {'selector': 'span.item', 'sort': True}}], 'url': 
> 'https://example.org/items-random-order.html'}
> 
>     @pytest.mark.parametrize('url, job', FILTER_DOC_URLS, ids=[v[0] for v in 
> FILTER_DOC_URLS])
>     def test_url(url, job):
>         with open(os.path.join(here, 
> 'data/filter_documentation_testdata.yaml')) as f:
>             testdata = yaml.safe_load(f)
>         d = testdata[url]
>         if 'filename' in d:
>             with open(os.path.join(here, 'data', d['filename']), 'rb') as f:
>                 input_data = f.read()
>         else:
>             input_data = d['input']
>     
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(job['filter']):
>             filtercls = FilterBase.__subclasses__[filter_kind]
> >           input_data = filtercls(None, None).filter(input_data, subfilter)
> 
> urlwatch/tests/test_filter_documentation.py:76: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d3e9950>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ______________________________ test_filters[css] 
> _______________________________
> 
> test_name = 'css'
> test_data = {'data': 
> '<html><head></head><body>\n<div>foo</div>\n<div>bar</div>\n</body></html>\n',
>  'expected_result': '<div>foo</div>\n\n<div>bar</div>\n', 'filter': 'css:div'}
> 
>     @pytest.mark.parametrize('test_name, test_data', FILTER_TESTS, ids=[d[0] 
> for d in FILTER_TESTS])
>     def test_filters(test_name, test_data):
>         filter = test_data['filter']
>         data = test_data['data']
>         expected_result = test_data['expected_result']
>     
>         result = data
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(filter):
>             logger.info('filter kind: %s, subfilter: %s', filter_kind, 
> subfilter)
>             filtercls = FilterBase.__subclasses__.get(filter_kind)
>             if filtercls is None:
>                 raise ValueError('Unknown filter kind: %s:%s' % (filter_kind, 
> subfilter))
> >           result = filtercls(None, None).filter(result, subfilter)
> 
> urlwatch/tests/test_filters.py:55: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d3e9010>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> ------------------------------ Captured log call 
> -------------------------------
> WARNING  urlwatch.filters:filters.py:163 String-based filter definitions 
> (css:div) are deprecated, please convert to dict-style (see 
> https://urlwatch.readthedocs.io/en/latest/deprecated.html):
> 
> - css: div
> __________________________ test_filters[css_exclude] 
> ___________________________
> 
> test_name = 'css_exclude'
> test_data = {'data': '<html><head></head><body>\n<div class="excl">you don\'t 
> want to see me</div>\n<div class="foo">f<span class=... 'expected_result': 
> '<div class="foo">foo</div>\n', 'filter': [{'css': {'exclude': '.excl, #bar', 
> 'selector': 'div'}}]}
> 
>     @pytest.mark.parametrize('test_name, test_data', FILTER_TESTS, ids=[d[0] 
> for d in FILTER_TESTS])
>     def test_filters(test_name, test_data):
>         filter = test_data['filter']
>         data = test_data['data']
>         expected_result = test_data['expected_result']
>     
>         result = data
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(filter):
>             logger.info('filter kind: %s, subfilter: %s', filter_kind, 
> subfilter)
>             filtercls = FilterBase.__subclasses__.get(filter_kind)
>             if filtercls is None:
>                 raise ValueError('Unknown filter kind: %s:%s' % (filter_kind, 
> subfilter))
> >           result = filtercls(None, None).filter(result, subfilter)
> 
> urlwatch/tests/test_filters.py:55: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d3a6cd0>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> _______________________ test_filters[css_xml_namespaces] 
> _______________________
> 
> test_name = 'css_xml_namespaces'
> test_data = {'data': '<feed 
> xmlns:f="foo">\n<item>\n<f:year>2017</f:year>\n<author>Tom</author>\n<data>abc</data>\n</item>\n<f:ite...er':
>  [{'css': {'exclude': 'f|year, author', 'method': 'xml', 'namespaces': {'f': 
> 'foo'}, 'selector': 'item, f|item'}}]}
> 
>     @pytest.mark.parametrize('test_name, test_data', FILTER_TESTS, ids=[d[0] 
> for d in FILTER_TESTS])
>     def test_filters(test_name, test_data):
>         filter = test_data['filter']
>         data = test_data['data']
>         expected_result = test_data['expected_result']
>     
>         result = data
>         for filter_kind, subfilter in 
> FilterBase.normalize_filter_list(filter):
>             logger.info('filter kind: %s, subfilter: %s', filter_kind, 
> subfilter)
>             filtercls = FilterBase.__subclasses__.get(filter_kind)
>             if filtercls is None:
>                 raise ValueError('Unknown filter kind: %s:%s' % (filter_kind, 
> subfilter))
> >           result = filtercls(None, None).filter(result, subfilter)
> 
> urlwatch/tests/test_filters.py:55: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> urlwatch/filters.py:810: in filter
>     return lxml_parser.get_filtered_data()
> urlwatch/filters.py:776: in get_filtered_data
>     elements = list(self._get_filtered_elements())
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <urlwatch.filters.LxmlParser object at 0x7f448d459410>
> 
>     def _get_filtered_elements(self):
>         try:
>             root = etree.fromstring(self.data, self.parser)
>         except ValueError:
>             # Strip XML declaration, for example: '<?xml version="1.0" 
> encoding="utf-8"?>'
>             # for https://heronebag.com/blog/index.xml, an error happens, as 
> we get a
>             # a (Unicode) string, but the XML contains its own "encoding" 
> declaration
>             self.data = re.sub(r'^<[?]xml[^>]*[?]>', '', self.data)
>             # Retry parsing with XML declaration removed (Fixes #281)
>             root = etree.fromstring(self.data, self.parser)
>         if root is None:
>             return []
>         excluded_elems = None
>         if self.filter_kind == 'css':
>             selected_elems = CSSSelector(self.expression,
> >                                        
> > namespaces=self.namespaces).evaluate(root)
> E           AttributeError: 'CSSSelector' object has no attribute 'evaluate'
> 
> urlwatch/filters.py:764: AttributeError
> =========================== short test summary info 
> ============================
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.net/css.html]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[http:/example.com/blog/css-index.rss]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[http:/example.org/feed/css-namespace.xml]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.org/css-exclude.html]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.net/css-skip-maxitems.html]
> FAILED 
> urlwatch/tests/test_filter_documentation.py::test_url[https:/example.org/items-random-order.html]
> FAILED urlwatch/tests/test_filters.py::test_filters[css] - AttributeError: 
> 'C...
> FAILED urlwatch/tests/test_filters.py::test_filters[css_exclude] - 
> AttributeE...
> FAILED urlwatch/tests/test_filters.py::test_filters[css_xml_namespaces] - 
> Att...
> ========================= 9 failed, 79 passed in 1.98s 
> =========================
> E: pybuild pybuild:391: test: plugin distutils failed with: exit code=1: cd 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11_urlwatch/build; python3.11 -m pytest 
> dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.12 
> 3.11" returned exit code 13


The full build log is available from:
http://qa-logs.debian.net/2024/02/24/urlwatch_2.28-1_unstable.log

All bugs filed during this archive rebuild are listed at:
https://bugs.debian.org/cgi-bin/pkgreport.cgi?tag=ftbfs-20240224;users=lu...@debian.org
or:
https://udd.debian.org/bugs/?release=na&merged=ign&fnewerval=7&flastmodval=7&fusertag=only&fusertagtag=ftbfs-20240224&fusertaguser=lu...@debian.org&allbugs=1&cseverity=1&ctags=1&caffected=1#results

A list of current common problems and possible solutions is available at
http://wiki.debian.org/qa.debian.org/FTBFS . You're welcome to contribute!

If you reassign this bug to another package, please mark it as 'affects'-ing
this package. See https://www.debian.org/Bugs/server-control#affects

If you fail to reproduce this, please provide a build log and diff it with mine
so that we can identify if something relevant changed in the meantime.

Reply via email to