Skip to content

Commit

Permalink
Allow lines to be a bit longer
Browse files Browse the repository at this point in the history
  • Loading branch information
liZe committed Jul 18, 2024
1 parent 9d60aed commit cb92103
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 47 deletions.
19 changes: 7 additions & 12 deletions cssselect2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,17 @@ def add_selector(self, selector, payload):
return

entry = (
selector.test, selector.specificity, self.order,
selector.pseudo_element, payload)
selector.test, selector.specificity, self.order, selector.pseudo_element,
payload)
if selector.id is not None:
self.id_selectors.setdefault(selector.id, []).append(entry)
elif selector.class_name is not None:
self.class_selectors.setdefault(
selector.class_name, []).append(entry)
self.class_selectors.setdefault(selector.class_name, []).append(entry)
elif selector.local_name is not None:
self.lower_local_name_selectors.setdefault(
selector.lower_local_name, []).append(entry)
elif selector.namespace is not None:
self.namespace_selectors.setdefault(
selector.namespace, []).append(entry)
self.namespace_selectors.setdefault(selector.namespace, []).append(entry)
elif selector.requires_lang_attr:
self.lang_attr_selectors.append(entry)
else:
Expand Down Expand Up @@ -87,8 +85,7 @@ def match(self, element):
for class_name in element.classes:
if class_name in self.class_selectors:
self.add_relevant_selectors(
element, self.class_selectors[class_name],
relevant_selectors)
element, self.class_selectors[class_name], relevant_selectors)

lower_name = ascii_lower(element.local_name)
if lower_name in self.lower_local_name_selectors:
Expand All @@ -104,8 +101,7 @@ def match(self, element):
self.add_relevant_selectors(
element, self.lang_attr_selectors, relevant_selectors)

self.add_relevant_selectors(
element, self.other_selectors, relevant_selectors)
self.add_relevant_selectors(element, self.other_selectors, relevant_selectors)

relevant_selectors.sort()
return relevant_selectors
Expand All @@ -114,5 +110,4 @@ def match(self, element):
def add_relevant_selectors(element, selectors, relevant_selectors):
for test, specificity, order, pseudo, payload in selectors:
if test(element):
relevant_selectors.append(
(specificity, order, pseudo, payload))
relevant_selectors.append((specificity, order, pseudo, payload))
7 changes: 2 additions & 5 deletions cssselect2/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ def compile_selector_list(input, namespaces=None):
A list of opaque :class:`compiler.CompiledSelector` objects.
"""
return [
CompiledSelector(selector)
for selector in parser.parse(input, namespaces)]
return [CompiledSelector(selector) for selector in parser.parse(input, namespaces)]


class CompiledSelector:
Expand Down Expand Up @@ -239,8 +237,7 @@ def _compile_node(selector):
elif selector.operator == '*=':
return f'{value!r} in {attribute_value}' if value else '0'
else:
raise SelectorError(
'Unknown attribute operator', selector.operator)
raise SelectorError('Unknown attribute operator', selector.operator)
else: # In any namespace
raise NotImplementedError # TODO

Expand Down
29 changes: 9 additions & 20 deletions cssselect2/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ def parse_simple_selector(tokens, namespaces):
if next == ':':
next = tokens.next()
if next is None or next.type != 'ident':
raise SelectorError(
next, f'Expected a pseudo-element name, got {next}')
raise SelectorError(next, f'Expected a pseudo-element name, got {next}')
value = next.lower_value
if value not in SUPPORTED_PSEUDO_ELEMENTS:
raise SelectorError(
Expand All @@ -154,8 +153,7 @@ def parse_simple_selector(tokens, namespaces):
if name in ('is', 'where', 'not', 'has'):
return parse_logical_combination(next, namespaces, name), None
else:
return (
FunctionalPseudoClassSelector(name, next.arguments), None)
return (FunctionalPseudoClassSelector(name, next.arguments), None)
else:
raise SelectorError(next, f'unexpected {next} token.')
else:
Expand Down Expand Up @@ -185,8 +183,7 @@ def parse_logical_combination(matches_any_token, namespaces, name):

def parse_attribute_selector(tokens, namespaces):
tokens.skip_whitespace()
qualified_name = parse_qualified_name(
tokens, namespaces, is_attribute=True)
qualified_name = parse_qualified_name(tokens, namespaces, is_attribute=True)
if qualified_name is None:
next = tokens.next()
raise SelectorError(next, f'expected attribute name, got {next}')
Expand All @@ -204,12 +201,10 @@ def parse_attribute_selector(tokens, namespaces):
next = tokens.next()
if next is None or next.type not in ('ident', 'string'):
next_type = 'None' if next is None else next.type
raise SelectorError(
next, f'expected attribute value, got {next_type}')
raise SelectorError(next, f'expected attribute value, got {next_type}')
value = next.value
else:
raise SelectorError(
peek, f'expected attribute selector operator, got {peek}')
raise SelectorError(peek, f'expected attribute selector operator, got {peek}')

tokens.skip_whitespace()
next = tokens.next()
Expand All @@ -221,8 +216,7 @@ def parse_attribute_selector(tokens, namespaces):
case_sensitive = True
else:
raise SelectorError(next, f'expected ], got {next.type}')
return AttributeSelector(
namespace, local_name, operator, value, case_sensitive)
return AttributeSelector(namespace, local_name, operator, value, case_sensitive)


def parse_qualified_name(tokens, namespaces, is_attribute=False):
Expand All @@ -246,15 +240,13 @@ def parse_qualified_name(tokens, namespaces, is_attribute=False):
namespace = namespaces.get(first_ident.value)
if namespace is None:
raise SelectorError(
first_ident,
f'undefined namespace prefix: {first_ident.value}')
first_ident, f'undefined namespace prefix: {first_ident.value}')
elif peek == '*':
next = tokens.next()
peek = tokens.peek()
if peek != '|':
if is_attribute:
raise SelectorError(
next, f'expected local name, got {next.type}')
raise SelectorError(next, f'expected local name, got {next.type}')
return namespaces.get(None, None), None
tokens.next()
namespace = None
Expand Down Expand Up @@ -405,10 +397,7 @@ def __init__(self, namespace):
self.namespace = namespace

def __repr__(self):
if self.namespace == '':
return '|'
else:
return f'{{{self.namespace}}}|'
return '|' if self.namespace == '' else f'{{{self.namespace}}}|'


class IDSelector:
Expand Down
12 changes: 4 additions & 8 deletions cssselect2/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ def _from_root(cls, root, content_language, in_html_document=True):
root = root.getroot()
return cls(
root, parent=None, index=0, previous=None,
in_html_document=in_html_document,
content_language=content_language)
in_html_document=in_html_document, content_language=content_language)

def __init__(self, etree_element, parent, index, previous,
in_html_document, content_language=None):
Expand Down Expand Up @@ -330,8 +329,7 @@ def classes(self):
def lang(self):
"""The language of this element, as a string."""
# http://whatwg.org/C#language
xml_lang = self.etree_element.get(
'{http://www.w3.org/XML/1998/namespace}lang')
xml_lang = self.etree_element.get('{http://www.w3.org/XML/1998/namespace}lang')
if xml_lang is not None:
return ascii_lower(xml_lang)
is_html = (
Expand All @@ -346,13 +344,11 @@ def lang(self):
# Root elememnt
if is_html:
content_language = None
iterator = self.etree_element.iter(
'{http://www.w3.org/1999/xhtml}meta')
iterator = self.etree_element.iter('{http://www.w3.org/1999/xhtml}meta')
for meta in iterator:
http_equiv = meta.get('http-equiv', '')
if ascii_lower(http_equiv) == 'content-language':
content_language = _parse_content_language(
meta.get('content'))
content_language = _parse_content_language(meta.get('content'))
if content_language is not None:
return ascii_lower(content_language)
# Empty string means unknown
Expand Down
3 changes: 1 addition & 2 deletions tests/test_cssselect2.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ def test_valid_selectors(test):
result = [element.id for element in root.query_all(test['selector'])]
if result != test['expect']: # pragma: no cover
raise AssertionError(
f'{test["selector"]!r}: {result} != {test["expect"]} '
f'({test["name"]})')
f'{test["selector"]!r}: {result} != {test["expect"]} ({test["name"]})')


def test_lang():
Expand Down

0 comments on commit cb92103

Please sign in to comment.