Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ruff instead of flake8 and isort #57

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,4 @@ jobs:
- name: Launch tests
run: python -m pytest
- name: Check coding style
run: python -m flake8 --exclude tests/css-parsing-tests
- name: Check imports order
run: python -m isort . --check --diff
run: python -m ruff check
9 changes: 3 additions & 6 deletions docs/contribute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,12 @@ You can launch tests using the following command::

venv/bin/python -m pytest

tinycss2 also uses isort_ to check imports and flake8_ to check the coding
style::
tinycss2 also uses ruff_ to check the coding style::

venv/bin/python -m isort . --check --diff
venv/bin/python -m flake8 --exclude tests/css-parsing-tests
venv/bin/python -m ruff check

.. _pytest: https://docs.pytest.org/
.. _isort: https://pycqa.github.io/isort/
.. _flake8: https://flake8.pycqa.org/
.. _ruff: https://docs.astral.sh/ruff/


Documentation
Expand Down
12 changes: 7 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Donation = 'https://opencollective.com/courtbouillon'

[project.optional-dependencies]
doc = ['sphinx', 'sphinx_rtd_theme']
test = ['pytest', 'isort', 'flake8']
test = ['pytest', 'ruff']

[tool.flit.sdist]
exclude = ['.*']
Expand All @@ -56,7 +56,9 @@ include = ['tests/*', 'tinycss2/*']
exclude_lines = ['pragma: no cover', 'def __repr__', 'raise NotImplementedError']
omit = ['.*']

[tool.isort]
default_section = 'FIRSTPARTY'
multi_line_output = 4
extend_skip = ['tests/css-parsing-tests']
[tool.ruff]
extend-exclude = ['tests/css-parsing-tests']

[tool.ruff.lint]
select = ['E', 'W', 'F', 'I', 'N', 'RUF']
ignore = ['RUF001', 'RUF002', 'RUF003']
51 changes: 25 additions & 26 deletions tests/test_tinycss2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
from pathlib import Path

import pytest
from tinycss2 import (
from webencodings import Encoding, lookup

from tinycss2 import ( # isort:skip
parse_blocks_contents, parse_component_value_list, parse_declaration_list,
parse_one_component_value, parse_one_declaration, parse_one_rule,
parse_rule_list, parse_stylesheet, parse_stylesheet_bytes, serialize)
from tinycss2.ast import (
AtKeywordToken, AtRule, Comment, CurlyBracketsBlock, Declaration,
DimensionToken, FunctionBlock, HashToken, IdentToken, LiteralToken,
NumberToken, ParenthesesBlock, ParseError, PercentageToken, QualifiedRule,
SquareBracketsBlock, StringToken, UnicodeRangeToken, URLToken,
WhitespaceToken)
parse_one_component_value, parse_one_declaration, parse_one_rule, parse_rule_list,
parse_stylesheet, parse_stylesheet_bytes, serialize)
from tinycss2.ast import ( # isort:skip
AtKeywordToken, AtRule, Comment, CurlyBracketsBlock, Declaration, DimensionToken,
FunctionBlock, HashToken, IdentToken, LiteralToken, NumberToken, ParenthesesBlock,
ParseError, PercentageToken, QualifiedRule, SquareBracketsBlock, StringToken,
UnicodeRangeToken, URLToken, WhitespaceToken)
from tinycss2.color3 import RGBA, parse_color
from tinycss2.nth import parse_nth
from webencodings import Encoding, lookup


def generic(func):
Expand Down Expand Up @@ -49,26 +49,25 @@ def numeric(t):
LiteralToken: lambda t: t.value,
IdentToken: lambda t: ['ident', t.value],
AtKeywordToken: lambda t: ['at-keyword', t.value],
HashToken: lambda t: ['hash', t.value,
'id' if t.is_identifier else 'unrestricted'],
HashToken: lambda t: [
'hash', t.value, 'id' if t.is_identifier else 'unrestricted'],
StringToken: lambda t: ['string', t.value],
URLToken: lambda t: ['url', t.value],
NumberToken: lambda t: ['number'] + numeric(t),
PercentageToken: lambda t: ['percentage'] + numeric(t),
DimensionToken: lambda t: ['dimension'] + numeric(t) + [t.unit],
NumberToken: lambda t: ['number', *numeric(t)],
PercentageToken: lambda t: ['percentage', *numeric(t)],
DimensionToken: lambda t: ['dimension', *numeric(t), t.unit],
UnicodeRangeToken: lambda t: ['unicode-range', t.start, t.end],

CurlyBracketsBlock: lambda t: ['{}'] + to_json(t.content),
SquareBracketsBlock: lambda t: ['[]'] + to_json(t.content),
ParenthesesBlock: lambda t: ['()'] + to_json(t.content),
FunctionBlock: lambda t: ['function', t.name] + to_json(t.arguments),

Declaration: lambda d: ['declaration', d.name,
to_json(d.value), d.important],
AtRule: lambda r: ['at-rule', r.at_keyword, to_json(r.prelude),
to_json(r.content)],
QualifiedRule: lambda r: ['qualified rule', to_json(r.prelude),
to_json(r.content)],
CurlyBracketsBlock: lambda t: ['{}', *to_json(t.content)],
SquareBracketsBlock: lambda t: ['[]', *to_json(t.content)],
ParenthesesBlock: lambda t: ['()', *to_json(t.content)],
FunctionBlock: lambda t: ['function', t.name, *to_json(t.arguments)],

Declaration: lambda d: ['declaration', d.name, to_json(d.value), d.important],
AtRule: lambda r: [
'at-rule', r.at_keyword, to_json(r.prelude), to_json(r.content)],
QualifiedRule: lambda r: [
'qualified rule', to_json(r.prelude), to_json(r.content)],

RGBA: lambda v: [round(c, 10) for c in v],
}
Expand Down
2 changes: 1 addition & 1 deletion tinycss2/nth.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def parse_b(tokens, a):
def parse_signless_b(tokens, a, b_sign):
token = _next_significant(tokens)
if (token.type == 'number' and token.is_integer and
not token.representation[0] in '-+'):
token.representation[0] not in '-+'):
return parse_end(tokens, a, b_sign * token.int_value)


Expand Down
21 changes: 11 additions & 10 deletions tinycss2/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ def _parse_declaration(first_token, tokens, nested=True):
if state == 'value' and token == '!':
state = 'bang'
bang_position = i
elif state == 'bang' and token.type == 'ident' \
and token.lower_value == 'important':
elif (state == 'bang' and token.type == 'ident'
and token.lower_value == 'important'):
state = 'important'
elif token.type not in ('whitespace', 'comment'):
state = 'value'
Expand All @@ -161,8 +161,9 @@ def _parse_declaration(first_token, tokens, nested=True):

# TODO: Handle unicode-range

return Declaration(name.source_line, name.source_column, name.value,
name.lower_value, value, state == 'important')
return Declaration(
name.source_line, name.source_column, name.value, name.lower_value,
value, state == 'important')


def _consume_blocks_content(first_token, tokens):
Expand All @@ -183,8 +184,7 @@ def _consume_blocks_content(first_token, tokens):
return declaration
else:
tokens = chain(declaration_tokens, semicolon_token, tokens)
return _consume_qualified_rule(
first_token, tokens, stop_token=';', nested=True)
return _consume_qualified_rule(first_token, tokens, stop_token=';', nested=True)


def _consume_declaration_in_list(first_token, tokens):
Expand Down Expand Up @@ -478,8 +478,9 @@ def _consume_at_rule(at_keyword, tokens):
elif token == ';':
break
prelude.append(token)
return AtRule(at_keyword.source_line, at_keyword.source_column,
at_keyword.value, at_keyword.lower_value, prelude, content)
return AtRule(
at_keyword.source_line, at_keyword.source_column, at_keyword.value,
at_keyword.lower_value, prelude, content)


def _rule_error(token, name):
Expand Down Expand Up @@ -523,5 +524,5 @@ def _consume_qualified_rule(first_token, tokens, nested=False,
prelude.append(token)
else:
return _rule_error(prelude[-1], 'EOF')
return QualifiedRule(first_token.source_line, first_token.source_column,
prelude, block.content)
return QualifiedRule(
first_token.source_line, first_token.source_column, prelude, block.content)
3 changes: 1 addition & 2 deletions tinycss2/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ def _serialize_to(nodes, write):

BAD_PAIRS = set(
[(a, b)
for a in ('ident', 'at-keyword', 'hash', 'dimension', '#', '-',
'number')
for a in ('ident', 'at-keyword', 'hash', 'dimension', '#', '-', 'number')
for b in ('ident', 'function', 'url', 'number', 'percentage',
'dimension', 'unicode-range')] +
[(a, b)
Expand Down
23 changes: 9 additions & 14 deletions tinycss2/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

from webencodings import ascii_lower

from .ast import (
from .ast import ( # isort: skip
AtKeywordToken, Comment, CurlyBracketsBlock, DimensionToken, FunctionBlock,
HashToken, IdentToken, LiteralToken, NumberToken, ParenthesesBlock,
ParseError, PercentageToken, SquareBracketsBlock, StringToken,
UnicodeRangeToken, URLToken, WhitespaceToken)
HashToken, IdentToken, LiteralToken, NumberToken, ParenthesesBlock, ParseError,
PercentageToken, SquareBracketsBlock, StringToken, UnicodeRangeToken, URLToken,
WhitespaceToken)
from .serializer import serialize_string_value, serialize_url

_NUMBER_RE = re.compile(r'[-+]?([0-9]*\.)?[0-9]+([eE][+-]?[0-9]+)?')
Expand Down Expand Up @@ -108,11 +108,9 @@ def parse_component_value_list(css, skip_comments=False):
line, column, value, int_value, repr_, unit))
elif css.startswith('%', pos):
pos += 1
tokens.append(PercentageToken(
line, column, value, int_value, repr_))
tokens.append(PercentageToken(line, column, value, int_value, repr_))
else:
tokens.append(NumberToken(
line, column, value, int_value, repr_))
tokens.append(NumberToken(line, column, value, int_value, repr_))
elif c == '@':
pos += 1
if pos < length and _is_ident_start(css, pos):
Expand Down Expand Up @@ -175,12 +173,10 @@ def parse_component_value_list(css, skip_comments=False):
pos = css.find('*/', pos + 2)
if pos == -1:
if not skip_comments:
tokens.append(
Comment(line, column, css[token_start_pos + 2:]))
tokens.append(Comment(line, column, css[token_start_pos + 2:]))
break
if not skip_comments:
tokens.append(
Comment(line, column, css[token_start_pos + 2:pos]))
tokens.append(Comment(line, column, css[token_start_pos + 2:pos]))
pos += 2
elif css.startswith('<!--', pos):
tokens.append(LiteralToken(line, column, '<!--'))
Expand Down Expand Up @@ -219,8 +215,7 @@ def _is_ident_start(css, pos):
pos += 1
return (
# Name-start code point or hyphen:
(pos < len(css) and (
_is_name_start(css, pos) or css[pos] == '-')) or
(pos < len(css) and (_is_name_start(css, pos) or css[pos] == '-')) or
# Valid escape:
(css.startswith('\\', pos) and not css.startswith('\\\n', pos)))
elif css[pos] == '\\':
Expand Down