Your message dated Fri, 08 Mar 2024 18:06:11 +0000
with message-id <e1riebj-001orx...@fasolo.debian.org>
and subject line Bug#1064736: fixed in urlwatch 2.28-2
has caused the Debian Bug report #1064736,
regarding urlwatch: FTBFS: dh_auto_test: error: pybuild --test --test-pytest -i 
python{version} -p "3.12 3.11" returned exit code 13
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
1064736: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064736
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
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.

--- End Message ---
--- Begin Message ---
Source: urlwatch
Source-Version: 2.28-2
Done: Maxime Werlen <max...@werlen.fr>

We believe that the bug you reported is fixed in the latest version of
urlwatch, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 1064...@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Maxime Werlen <max...@werlen.fr> (supplier of updated urlwatch package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmas...@ftp-master.debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Format: 1.8
Date: Tue, 27 Feb 2024 09:59:34 +0100
Source: urlwatch
Architecture: source
Version: 2.28-2
Distribution: unstable
Urgency: medium
Maintainer: Maxime Werlen <max...@werlen.fr>
Changed-By: Maxime Werlen <max...@werlen.fr>
Closes: 1064736
Changes:
 urlwatch (2.28-2) unstable; urgency=medium
 .
   * Backport upstream fix on LXML 5 (Closes: #1064736)
Checksums-Sha1:
 fbd31330b346a70b699503a45aa5e536d80110a6 2173 urlwatch_2.28-2.dsc
 d70885e3d7c1b15a87705fde1ec06348994228a9 174071 urlwatch_2.28.orig.tar.gz
 36212b63429ac41645083888d88635e49f34267d 9216 urlwatch_2.28-2.debian.tar.xz
 a03356355071856cd6c8e3cfc21005e418b3714e 7913 urlwatch_2.28-2_amd64.buildinfo
Checksums-Sha256:
 d00b2e9cf5f725b5a82e1024f7dca5ae9703bf0ae22c696974742fb10fdda49e 2173 
urlwatch_2.28-2.dsc
 940d82f75b1358e40ea6244d79989de3fd474e0ddeacef378e59cabb7f5ebbe8 174071 
urlwatch_2.28.orig.tar.gz
 6ec6ac43d94941b224f5b2c1c08b848f69259f2be24b1e480fd7783d27632a9f 9216 
urlwatch_2.28-2.debian.tar.xz
 cd7ccffcd16c368ac2f10c83f0ec813f70c2bac9ac3e5bde6ffb60a095077115 7913 
urlwatch_2.28-2_amd64.buildinfo
Files:
 fa5dc2563ea472550ae7a1398ae9c0f8 2173 web optional urlwatch_2.28-2.dsc
 7bc0e1b8193751657227c707c30ac998 174071 web optional urlwatch_2.28.orig.tar.gz
 fb87dac0f3f409862463f3866cde01c5 9216 web optional 
urlwatch_2.28-2.debian.tar.xz
 2316d3be11237e56752ac7faef41c57c 7913 web optional 
urlwatch_2.28-2_amd64.buildinfo

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEfncpR22H1vEdkazLwpPntGGCWs4FAmXrTeQACgkQwpPntGGC
Ws5NTA/+LS04cSDFkG3NVad/GOBNKOUp4wJPqF+8ywzj6ehDKxjI20XiIlYqZJ00
89VAxBSdStuoFMBoZb66f1UFnA1Rk7msDmM8co9Wcs4AJ+EHMHU+7yyWEmdJpk8y
ldx+c5uXmDojAFWqvN5v/C7uTrXY78x50s6EtXcoTbDEa85ZFEas+OhFGYcMoycj
I/kO8pJVQVqzXlm/Gl/twYCazTpXynCQRpT6rskX1+iOseZcxTGPaboMJcWee4LO
linT5OHV5l+CO8bmm49D9n/7wDAgzNa0XHQjnljTyVdNJxDR/n0MmfaDqMB1NgPq
CksXIypnlVGIV97sY9Uxf+F62lNh7iS/OrUCXgrpUMc5kJNmGlJZ3bdkT6CDAQz7
OtZHwW/Rj9t28RSf2S55O9X+UAcF8qqKsbWjGtHov8tLoVNdDLFvBY4hxmcavuSZ
h1MM/WFCesgkL0lqlZ4I2jSQxkfD+/bJXLH8Ozj57iTJPMrWJSHWZGPOXCHNp+nu
mw4rawvljM6q+p6f8Fx1iOiTBDYXwIlh0aEg2Z4AZTHm2kIQcWefiHzSUZU1Ro57
vL9Eoup3y2zBlz2idMeugb40eXapGDSJo1IRXdDFYzaR3OsetatOZwBjwC7iKN8o
FhfbaUB+cQZ4bozAv37pvB6/H1B7KO9oNvmtCExbaPGV8qnreQQ=
=ghLH
-----END PGP SIGNATURE-----

Attachment: pgpL0tFzbX_ru.pgp
Description: PGP signature


--- End Message ---

Reply via email to