From d03c6f28693567d201a5d103c3e79a2f2393ec23 Mon Sep 17 00:00:00 2001 From: George Sladkovsky Date: Tue, 7 Apr 2026 11:20:48 +0200 Subject: [PATCH 1/4] [tinycss2] Add stubs for tinycss2 --- stubs/tinycss2/METADATA.toml | 3 + stubs/tinycss2/tinycss2/__init__.pyi | 14 +++ stubs/tinycss2/tinycss2/ast.pyi | 162 +++++++++++++++++++++++++ stubs/tinycss2/tinycss2/bytes.pyi | 14 +++ stubs/tinycss2/tinycss2/color3.pyi | 12 ++ stubs/tinycss2/tinycss2/color4.pyi | 15 +++ stubs/tinycss2/tinycss2/color5.pyi | 12 ++ stubs/tinycss2/tinycss2/nth.pyi | 8 ++ stubs/tinycss2/tinycss2/parser.pyi | 18 +++ stubs/tinycss2/tinycss2/serializer.pyi | 9 ++ stubs/tinycss2/tinycss2/tokenizer.pyi | 3 + 11 files changed, 270 insertions(+) create mode 100644 stubs/tinycss2/METADATA.toml create mode 100644 stubs/tinycss2/tinycss2/__init__.pyi create mode 100644 stubs/tinycss2/tinycss2/ast.pyi create mode 100644 stubs/tinycss2/tinycss2/bytes.pyi create mode 100644 stubs/tinycss2/tinycss2/color3.pyi create mode 100644 stubs/tinycss2/tinycss2/color4.pyi create mode 100644 stubs/tinycss2/tinycss2/color5.pyi create mode 100644 stubs/tinycss2/tinycss2/nth.pyi create mode 100644 stubs/tinycss2/tinycss2/parser.pyi create mode 100644 stubs/tinycss2/tinycss2/serializer.pyi create mode 100644 stubs/tinycss2/tinycss2/tokenizer.pyi diff --git a/stubs/tinycss2/METADATA.toml b/stubs/tinycss2/METADATA.toml new file mode 100644 index 000000000000..3446733867fe --- /dev/null +++ b/stubs/tinycss2/METADATA.toml @@ -0,0 +1,3 @@ +version = "1.5.1" +upstream_repository = "https://github.com/Kozea/tinycss2" +dependencies = ["types-webencodings"] diff --git a/stubs/tinycss2/tinycss2/__init__.pyi b/stubs/tinycss2/tinycss2/__init__.pyi new file mode 100644 index 000000000000..50b27f02771f --- /dev/null +++ b/stubs/tinycss2/tinycss2/__init__.pyi @@ -0,0 +1,14 @@ +from .bytes import parse_stylesheet_bytes as parse_stylesheet_bytes +from .parser import ( + parse_blocks_contents as parse_blocks_contents, + parse_declaration_list as parse_declaration_list, + parse_one_component_value as parse_one_component_value, + parse_one_declaration as parse_one_declaration, + parse_one_rule as parse_one_rule, + parse_rule_list as parse_rule_list, + parse_stylesheet as parse_stylesheet, +) +from .serializer import serialize as serialize, serialize_identifier as serialize_identifier +from .tokenizer import parse_component_value_list as parse_component_value_list + +__version__: str = ... diff --git a/stubs/tinycss2/tinycss2/ast.pyi b/stubs/tinycss2/tinycss2/ast.pyi new file mode 100644 index 000000000000..efbb137ec582 --- /dev/null +++ b/stubs/tinycss2/tinycss2/ast.pyi @@ -0,0 +1,162 @@ +from collections.abc import Iterable +from typing import Literal + +class Node: + __slots__ = str | Iterable[str] + source_line: int + source_column: int + type: str + + def __init__(self, source_line: int, source_column: int) -> None: ... + def serialize(self) -> str: ... + +class ParseError(Node): + __slots__ = str | Iterable[str] + type: Literal["error"] + kind: str + message: str + def __init__(self, line: int, column: int, kind: str, message: str) -> None: ... + +class Comment(Node): + __slots__ = str | Iterable[str] + type: Literal["comment"] + value: str + def __init__(self, line: int, column: int, value: str) -> None: ... + +class WhitespaceToken(Node): + __slots__ = str | Iterable[str] + type: Literal["whitespace"] + value: str + def __init__(self, line: int, column: int, value: str) -> None: ... + +class LiteralToken(Node): + __slots__ = str | Iterable[str] + type: Literal["literal"] + value: str + def __init__(self, line: int, column: int, value: str) -> None: ... + def __eq__(self, other: object) -> bool: ... + def __ne__(self, other: object) -> bool: ... + +class IdentToken(Node): + __slots__ = str | Iterable[str] + type: Literal["ident"] + value: str + lower_value: str + def __init__(self, line: int, column: int, value: str) -> None: ... + +class AtKeywordToken(Node): + __slots__ = str | Iterable[str] + type: Literal["at-keyword"] + value: str + lower_value: str + def __init__(self, line: int, column: int, value: str) -> None: ... + +class HashToken(Node): + __slots__ = str | Iterable[str] + type: Literal["hash"] + value: str + is_identifier: bool + def __init__(self, line: int, column: int, value: str, is_identifier: bool) -> None: ... + +class StringToken(Node): + __slots__ = str | Iterable[str] + type: Literal["string"] + value: str + representation: str + def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... + +class URLToken(Node): + __slots__ = str | Iterable[str] + type: Literal["url"] + value: str + representation: str + def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... + +class UnicodeRangeToken(Node): + __slots__ = str | Iterable[str] + type: Literal["unicode-range"] + start: int + end: int + def __init__(self, line: int, column: int, start: int, end: int) -> None: ... + +class NumberToken(Node): + __slots__ = str | Iterable[str] + type: Literal["number"] + value: float + int_value: int | None + is_integer: bool + representation: str + def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... + +class PercentageToken(Node): + __slots__ = str | Iterable[str] + type: Literal["percentage"] + value: float + int_value: int | None + is_integer: bool + representation: str + def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... + +class DimensionToken(Node): + __slots__ = str | Iterable[str] + type: Literal["dimension"] + value: float + int_value: int | None + is_integer: bool + representation: str + unit: str + lower_unit: str + def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str, unit: str) -> None: ... + +class ParenthesesBlock(Node): + __slots__ = str | Iterable[str] + type: Literal["()"] + content: list[Node] + def __init__(self, line: int, column: int, content: list[Node]) -> None: ... + +class SquareBracketsBlock(Node): + __slots__ = str | Iterable[str] + type: Literal["[]"] + content: list[Node] + def __init__(self, line: int, column: int, content: list[Node]) -> None: ... + +class CurlyBracketsBlock(Node): + __slots__ = str | Iterable[str] + type: Literal["{}"] + content: list[Node] + def __init__(self, line: int, column: int, content: list[Node]) -> None: ... + +class FunctionBlock(Node): + __slots__ = str | Iterable[str] + type: Literal["function"] + name: str + lower_name: str + arguments: list[Node] + def __init__(self, line: int, column: int, name: str, arguments: list[Node]) -> None: ... + +class Declaration(Node): + __slots__ = str | Iterable[str] + type: Literal["declaration"] + name: str + lower_name: str + value: list[Node] + important: bool + def __init__(self, line: int, column: int, name: str, lower_name: str, value: list[Node], important: bool) -> None: ... + +class QualifiedRule(Node): + __slots__ = str | Iterable[str] + type: Literal["qualified-rule"] + prelude: list[Node] + content: list[Node] + def __init__(self, line: int, column: int, prelude: list[Node], content: list[Node]) -> None: ... + +class AtRule(Node): + __slots__ = str | Iterable[str] + type: Literal["at-rule"] + at_keyword: str + lower_at_keyword: str + prelude: list[Node] + content: list[Node] | None + def __init__( + self, line: int, column: int, at_keyword: str, lower_at_keyword: str, prelude: list[Node], content: list[Node] | None + ) -> None: ... diff --git a/stubs/tinycss2/tinycss2/bytes.pyi b/stubs/tinycss2/tinycss2/bytes.pyi new file mode 100644 index 000000000000..a305f672f221 --- /dev/null +++ b/stubs/tinycss2/tinycss2/bytes.pyi @@ -0,0 +1,14 @@ +from webencodings import Encoding + +from .ast import Node + +def decode_stylesheet_bytes( + css_bytes: bytes, protocol_encoding: str | None = ..., environment_encoding: Encoding | None = ... +) -> tuple[str, Encoding]: ... +def parse_stylesheet_bytes( + css_bytes: bytes, + protocol_encoding: str | None = ..., + environment_encoding: Encoding | None = ..., + skip_comments: bool = ..., + skip_whitespace: bool = ..., +) -> tuple[list[Node], Encoding]: ... diff --git a/stubs/tinycss2/tinycss2/color3.pyi b/stubs/tinycss2/tinycss2/color3.pyi new file mode 100644 index 000000000000..664acf304a11 --- /dev/null +++ b/stubs/tinycss2/tinycss2/color3.pyi @@ -0,0 +1,12 @@ +from collections.abc import Iterable +from typing import NamedTuple + +from .ast import Node + +class RGBA(NamedTuple): + red: float + green: float + blue: float + alpha: float + +def parse_color(input: str | Iterable[Node]) -> str | RGBA | None: ... diff --git a/stubs/tinycss2/tinycss2/color4.pyi b/stubs/tinycss2/tinycss2/color4.pyi new file mode 100644 index 000000000000..da28bfddbf3a --- /dev/null +++ b/stubs/tinycss2/tinycss2/color4.pyi @@ -0,0 +1,15 @@ +from collections.abc import Iterable, Iterator +from typing import Literal + +from .ast import Node + +class Color: + COLOR_SPACES: set[str] + def __init__(self, space: str, coordinates: tuple[float | None, ...], alpha: float) -> None: ... + def __iter__(self) -> Iterator[float | None]: ... + def __getitem__(self, key: int) -> float: ... + def __hash__(self) -> int: ... + def __eq__(self, other: object) -> bool: ... + def to(self, space: str) -> Color: ... + +def parse_color(input: str | Iterable[Node]) -> Color | Literal["currentcolor"] | None: ... diff --git a/stubs/tinycss2/tinycss2/color5.pyi b/stubs/tinycss2/tinycss2/color5.pyi new file mode 100644 index 000000000000..d57047533dee --- /dev/null +++ b/stubs/tinycss2/tinycss2/color5.pyi @@ -0,0 +1,12 @@ +from collections.abc import Iterable +from typing import Literal + +from . import color4 +from .ast import Node + +class Color(color4.Color): + COLOR_SPACES: set[str] + +def parse_color( + input: str | Iterable[Node], color_schemes: Literal["normal"] | Iterable[str] = ... +) -> color4.Color | Color | Literal["currentcolor"] | None: ... diff --git a/stubs/tinycss2/tinycss2/nth.pyi b/stubs/tinycss2/tinycss2/nth.pyi new file mode 100644 index 000000000000..65315013e680 --- /dev/null +++ b/stubs/tinycss2/tinycss2/nth.pyi @@ -0,0 +1,8 @@ +from collections.abc import Iterable + +from .ast import Node + +def parse_nth(input: str | Iterable[Node]) -> tuple[int, int] | None: ... +def parse_b(tokens: Iterable[Node], a: int) -> tuple[int, int] | None: ... +def parse_signless_b(tokens: Iterable[Node], a: int, b_sign: int) -> tuple[int, int] | None: ... +def parse_end(tokens: Iterable[Node], a: int, b: int) -> tuple[int, int] | None: ... diff --git a/stubs/tinycss2/tinycss2/parser.pyi b/stubs/tinycss2/tinycss2/parser.pyi new file mode 100644 index 000000000000..d85d66c2f513 --- /dev/null +++ b/stubs/tinycss2/tinycss2/parser.pyi @@ -0,0 +1,18 @@ +from collections.abc import Iterable +from typing import TypeAlias + +from .ast import AtRule, Comment, Declaration, Node, ParseError, QualifiedRule, WhitespaceToken + +Rule: TypeAlias = QualifiedRule | AtRule | Comment | WhitespaceToken | ParseError + +def parse_one_component_value(input: str | Iterable[Node], skip_comments: bool = ...) -> Node: ... +def parse_one_declaration(input: str | Iterable[Node], skip_comments: bool = ...) -> Declaration | ParseError: ... +def parse_blocks_contents( + input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ... +) -> list[Declaration | AtRule | QualifiedRule | Comment | WhitespaceToken | ParseError]: ... +def parse_declaration_list( + input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ... +) -> list[Declaration | AtRule | Comment | WhitespaceToken | ParseError]: ... +def parse_one_rule(input: str | Iterable[Node], skip_comments: bool = ...) -> QualifiedRule | AtRule | ParseError: ... +def parse_rule_list(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[Rule]: ... +def parse_stylesheet(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[Rule]: ... diff --git a/stubs/tinycss2/tinycss2/serializer.pyi b/stubs/tinycss2/tinycss2/serializer.pyi new file mode 100644 index 000000000000..a1a7fe38a0f7 --- /dev/null +++ b/stubs/tinycss2/tinycss2/serializer.pyi @@ -0,0 +1,9 @@ +from collections.abc import Iterable + +from .ast import Node + +def serialize(nodes: Iterable[Node]) -> str: ... +def serialize_identifier(value: str) -> str: ... +def serialize_name(value: str) -> str: ... +def serialize_string_value(value: str) -> str: ... +def serialize_url(value: str) -> str: ... diff --git a/stubs/tinycss2/tinycss2/tokenizer.pyi b/stubs/tinycss2/tinycss2/tokenizer.pyi new file mode 100644 index 000000000000..ee1cf7255ed3 --- /dev/null +++ b/stubs/tinycss2/tinycss2/tokenizer.pyi @@ -0,0 +1,3 @@ +from .ast import Node + +def parse_component_value_list(css: str, skip_comments: bool = ...) -> list[Node]: ... From d5bf66c0eb016da19ed5524bb990e42edf4d73c5 Mon Sep 17 00:00:00 2001 From: George Sladkovsky Date: Tue, 7 Apr 2026 12:08:17 +0200 Subject: [PATCH 2/4] Fixing third-party stubtest errors --- stubs/tinycss2/tinycss2/__init__.pyi | 1 + stubs/tinycss2/tinycss2/ast.pyi | 48 ++++++++++++-------------- stubs/tinycss2/tinycss2/color4.pyi | 6 +++- stubs/tinycss2/tinycss2/color5.pyi | 9 +++-- stubs/tinycss2/tinycss2/nth.pyi | 3 ++ stubs/tinycss2/tinycss2/parser.pyi | 6 ++-- stubs/tinycss2/tinycss2/serializer.pyi | 2 ++ 7 files changed, 44 insertions(+), 31 deletions(-) diff --git a/stubs/tinycss2/tinycss2/__init__.pyi b/stubs/tinycss2/tinycss2/__init__.pyi index 50b27f02771f..1bf5d63370cb 100644 --- a/stubs/tinycss2/tinycss2/__init__.pyi +++ b/stubs/tinycss2/tinycss2/__init__.pyi @@ -12,3 +12,4 @@ from .serializer import serialize as serialize, serialize_identifier as serializ from .tokenizer import parse_component_value_list as parse_component_value_list __version__: str = ... +VERSION: str = ... diff --git a/stubs/tinycss2/tinycss2/ast.pyi b/stubs/tinycss2/tinycss2/ast.pyi index efbb137ec582..3390a86fcb78 100644 --- a/stubs/tinycss2/tinycss2/ast.pyi +++ b/stubs/tinycss2/tinycss2/ast.pyi @@ -1,8 +1,6 @@ -from collections.abc import Iterable from typing import Literal class Node: - __slots__ = str | Iterable[str] source_line: int source_column: int type: str @@ -11,94 +9,93 @@ class Node: def serialize(self) -> str: ... class ParseError(Node): - __slots__ = str | Iterable[str] type: Literal["error"] kind: str message: str + repr_format: str def __init__(self, line: int, column: int, kind: str, message: str) -> None: ... class Comment(Node): - __slots__ = str | Iterable[str] type: Literal["comment"] value: str + repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class WhitespaceToken(Node): - __slots__ = str | Iterable[str] type: Literal["whitespace"] value: str + repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class LiteralToken(Node): - __slots__ = str | Iterable[str] type: Literal["literal"] value: str + repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... def __eq__(self, other: object) -> bool: ... def __ne__(self, other: object) -> bool: ... class IdentToken(Node): - __slots__ = str | Iterable[str] type: Literal["ident"] value: str lower_value: str + repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class AtKeywordToken(Node): - __slots__ = str | Iterable[str] type: Literal["at-keyword"] value: str lower_value: str + repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class HashToken(Node): - __slots__ = str | Iterable[str] type: Literal["hash"] value: str is_identifier: bool + repr_format: str def __init__(self, line: int, column: int, value: str, is_identifier: bool) -> None: ... class StringToken(Node): - __slots__ = str | Iterable[str] type: Literal["string"] value: str representation: str + repr_format: str def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... class URLToken(Node): - __slots__ = str | Iterable[str] type: Literal["url"] value: str representation: str + repr_format: str def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... class UnicodeRangeToken(Node): - __slots__ = str | Iterable[str] type: Literal["unicode-range"] start: int end: int + repr_format: str def __init__(self, line: int, column: int, start: int, end: int) -> None: ... class NumberToken(Node): - __slots__ = str | Iterable[str] type: Literal["number"] value: float int_value: int | None is_integer: bool representation: str + repr_format: str def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... class PercentageToken(Node): - __slots__ = str | Iterable[str] type: Literal["percentage"] value: float int_value: int | None is_integer: bool representation: str + repr_format: str def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... class DimensionToken(Node): - __slots__ = str | Iterable[str] type: Literal["dimension"] value: float int_value: int | None @@ -106,57 +103,58 @@ class DimensionToken(Node): representation: str unit: str lower_unit: str + repr_format: str def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str, unit: str) -> None: ... class ParenthesesBlock(Node): - __slots__ = str | Iterable[str] - type: Literal["()"] + type: Literal["() block"] content: list[Node] + repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class SquareBracketsBlock(Node): - __slots__ = str | Iterable[str] - type: Literal["[]"] + type: Literal["[] block"] content: list[Node] + repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class CurlyBracketsBlock(Node): - __slots__ = str | Iterable[str] - type: Literal["{}"] + type: Literal["{} block"] content: list[Node] + repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class FunctionBlock(Node): - __slots__ = str | Iterable[str] type: Literal["function"] name: str lower_name: str arguments: list[Node] + repr_format: str def __init__(self, line: int, column: int, name: str, arguments: list[Node]) -> None: ... class Declaration(Node): - __slots__ = str | Iterable[str] type: Literal["declaration"] name: str lower_name: str value: list[Node] important: bool + repr_format: str def __init__(self, line: int, column: int, name: str, lower_name: str, value: list[Node], important: bool) -> None: ... class QualifiedRule(Node): - __slots__ = str | Iterable[str] type: Literal["qualified-rule"] prelude: list[Node] content: list[Node] + repr_format: str def __init__(self, line: int, column: int, prelude: list[Node], content: list[Node]) -> None: ... class AtRule(Node): - __slots__ = str | Iterable[str] type: Literal["at-rule"] at_keyword: str lower_at_keyword: str prelude: list[Node] content: list[Node] | None + repr_format: str def __init__( self, line: int, column: int, at_keyword: str, lower_at_keyword: str, prelude: list[Node], content: list[Node] | None ) -> None: ... diff --git a/stubs/tinycss2/tinycss2/color4.pyi b/stubs/tinycss2/tinycss2/color4.pyi index da28bfddbf3a..d393e156e295 100644 --- a/stubs/tinycss2/tinycss2/color4.pyi +++ b/stubs/tinycss2/tinycss2/color4.pyi @@ -4,7 +4,7 @@ from typing import Literal from .ast import Node class Color: - COLOR_SPACES: set[str] + COLOR_SPACES: set[str] | None def __init__(self, space: str, coordinates: tuple[float | None, ...], alpha: float) -> None: ... def __iter__(self) -> Iterator[float | None]: ... def __getitem__(self, key: int) -> float: ... @@ -13,3 +13,7 @@ class Color: def to(self, space: str) -> Color: ... def parse_color(input: str | Iterable[Node]) -> Color | Literal["currentcolor"] | None: ... + +COLOR_SPACES: set[str] +D50: tuple[float, float, float] +D65: tuple[float, float, float] diff --git a/stubs/tinycss2/tinycss2/color5.pyi b/stubs/tinycss2/tinycss2/color5.pyi index d57047533dee..a72ffb68422e 100644 --- a/stubs/tinycss2/tinycss2/color5.pyi +++ b/stubs/tinycss2/tinycss2/color5.pyi @@ -4,9 +4,14 @@ from typing import Literal from . import color4 from .ast import Node +COLOR_SCHEMES: set[str] +COLOR_SPACES: set[str] +D50: tuple[float, float, float] +D65: tuple[float, float, float] + class Color(color4.Color): - COLOR_SPACES: set[str] + COLOR_SPACES: set[str] | None def parse_color( - input: str | Iterable[Node], color_schemes: Literal["normal"] | Iterable[str] = ... + input: str | Iterable[Node], color_schemes: Literal["normal"] | Iterable[str] | None = ... ) -> color4.Color | Color | Literal["currentcolor"] | None: ... diff --git a/stubs/tinycss2/tinycss2/nth.pyi b/stubs/tinycss2/tinycss2/nth.pyi index 65315013e680..6a0aa906cb70 100644 --- a/stubs/tinycss2/tinycss2/nth.pyi +++ b/stubs/tinycss2/tinycss2/nth.pyi @@ -1,4 +1,5 @@ from collections.abc import Iterable +from re import Pattern from .ast import Node @@ -6,3 +7,5 @@ def parse_nth(input: str | Iterable[Node]) -> tuple[int, int] | None: ... def parse_b(tokens: Iterable[Node], a: int) -> tuple[int, int] | None: ... def parse_signless_b(tokens: Iterable[Node], a: int, b_sign: int) -> tuple[int, int] | None: ... def parse_end(tokens: Iterable[Node], a: int, b: int) -> tuple[int, int] | None: ... + +N_DASH_DIGITS_RE: Pattern[str] diff --git a/stubs/tinycss2/tinycss2/parser.pyi b/stubs/tinycss2/tinycss2/parser.pyi index d85d66c2f513..f3646958163d 100644 --- a/stubs/tinycss2/tinycss2/parser.pyi +++ b/stubs/tinycss2/tinycss2/parser.pyi @@ -3,7 +3,7 @@ from typing import TypeAlias from .ast import AtRule, Comment, Declaration, Node, ParseError, QualifiedRule, WhitespaceToken -Rule: TypeAlias = QualifiedRule | AtRule | Comment | WhitespaceToken | ParseError +_Rule: TypeAlias = QualifiedRule | AtRule | Comment | WhitespaceToken | ParseError def parse_one_component_value(input: str | Iterable[Node], skip_comments: bool = ...) -> Node: ... def parse_one_declaration(input: str | Iterable[Node], skip_comments: bool = ...) -> Declaration | ParseError: ... @@ -14,5 +14,5 @@ def parse_declaration_list( input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ... ) -> list[Declaration | AtRule | Comment | WhitespaceToken | ParseError]: ... def parse_one_rule(input: str | Iterable[Node], skip_comments: bool = ...) -> QualifiedRule | AtRule | ParseError: ... -def parse_rule_list(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[Rule]: ... -def parse_stylesheet(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[Rule]: ... +def parse_rule_list(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[_Rule]: ... +def parse_stylesheet(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[_Rule]: ... diff --git a/stubs/tinycss2/tinycss2/serializer.pyi b/stubs/tinycss2/tinycss2/serializer.pyi index a1a7fe38a0f7..9ea5c7458855 100644 --- a/stubs/tinycss2/tinycss2/serializer.pyi +++ b/stubs/tinycss2/tinycss2/serializer.pyi @@ -7,3 +7,5 @@ def serialize_identifier(value: str) -> str: ... def serialize_name(value: str) -> str: ... def serialize_string_value(value: str) -> str: ... def serialize_url(value: str) -> str: ... + +BAD_PAIRS: set[tuple[str, str]] From dec38e3394cad7ba2859d6d07a4d679f1380ff77 Mon Sep 17 00:00:00 2001 From: George Sladkovsky Date: Tue, 7 Apr 2026 15:30:36 +0200 Subject: [PATCH 3/4] Added change requests --- stubs/tinycss2/METADATA.toml | 2 +- stubs/tinycss2/tinycss2/__init__.pyi | 6 ++-- stubs/tinycss2/tinycss2/ast.pyi | 43 +++++++++++++-------------- stubs/tinycss2/tinycss2/bytes.pyi | 10 +++---- stubs/tinycss2/tinycss2/color5.pyi | 2 +- stubs/tinycss2/tinycss2/parser.pyi | 14 ++++----- stubs/tinycss2/tinycss2/tokenizer.pyi | 2 +- 7 files changed, 40 insertions(+), 39 deletions(-) diff --git a/stubs/tinycss2/METADATA.toml b/stubs/tinycss2/METADATA.toml index 3446733867fe..fe09240a6401 100644 --- a/stubs/tinycss2/METADATA.toml +++ b/stubs/tinycss2/METADATA.toml @@ -1,3 +1,3 @@ version = "1.5.1" -upstream_repository = "https://github.com/Kozea/tinycss2" +upstream-repository = "https://github.com/Kozea/tinycss2" dependencies = ["types-webencodings"] diff --git a/stubs/tinycss2/tinycss2/__init__.pyi b/stubs/tinycss2/tinycss2/__init__.pyi index 1bf5d63370cb..ea57523496f3 100644 --- a/stubs/tinycss2/tinycss2/__init__.pyi +++ b/stubs/tinycss2/tinycss2/__init__.pyi @@ -1,3 +1,5 @@ +from typing import Final + from .bytes import parse_stylesheet_bytes as parse_stylesheet_bytes from .parser import ( parse_blocks_contents as parse_blocks_contents, @@ -11,5 +13,5 @@ from .parser import ( from .serializer import serialize as serialize, serialize_identifier as serialize_identifier from .tokenizer import parse_component_value_list as parse_component_value_list -__version__: str = ... -VERSION: str = ... +__version__: Final[str] +VERSION: Final[str] diff --git a/stubs/tinycss2/tinycss2/ast.pyi b/stubs/tinycss2/tinycss2/ast.pyi index 3390a86fcb78..f87b02e59ca4 100644 --- a/stubs/tinycss2/tinycss2/ast.pyi +++ b/stubs/tinycss2/tinycss2/ast.pyi @@ -1,34 +1,33 @@ -from typing import Literal +from typing import Final class Node: source_line: int source_column: int - type: str def __init__(self, source_line: int, source_column: int) -> None: ... def serialize(self) -> str: ... class ParseError(Node): - type: Literal["error"] + type: Final = "error" kind: str message: str repr_format: str def __init__(self, line: int, column: int, kind: str, message: str) -> None: ... class Comment(Node): - type: Literal["comment"] + type: Final = "comment" value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class WhitespaceToken(Node): - type: Literal["whitespace"] + type: Final = "whitespace" value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class LiteralToken(Node): - type: Literal["literal"] + type: Final = "literal" value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... @@ -36,49 +35,49 @@ class LiteralToken(Node): def __ne__(self, other: object) -> bool: ... class IdentToken(Node): - type: Literal["ident"] + type: Final = "ident" value: str lower_value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class AtKeywordToken(Node): - type: Literal["at-keyword"] + type: Final = "at-keyword" value: str lower_value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class HashToken(Node): - type: Literal["hash"] + type: Final = "hash" value: str is_identifier: bool repr_format: str def __init__(self, line: int, column: int, value: str, is_identifier: bool) -> None: ... class StringToken(Node): - type: Literal["string"] + type: Final = "string" value: str representation: str repr_format: str def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... class URLToken(Node): - type: Literal["url"] + type: Final = "url" value: str representation: str repr_format: str def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... class UnicodeRangeToken(Node): - type: Literal["unicode-range"] + type: Final = "unicode-range" start: int end: int repr_format: str def __init__(self, line: int, column: int, start: int, end: int) -> None: ... class NumberToken(Node): - type: Literal["number"] + type: Final = "number" value: float int_value: int | None is_integer: bool @@ -87,7 +86,7 @@ class NumberToken(Node): def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... class PercentageToken(Node): - type: Literal["percentage"] + type: Final = "percentage" value: float int_value: int | None is_integer: bool @@ -96,7 +95,7 @@ class PercentageToken(Node): def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... class DimensionToken(Node): - type: Literal["dimension"] + type: Final = "dimension" value: float int_value: int | None is_integer: bool @@ -107,25 +106,25 @@ class DimensionToken(Node): def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str, unit: str) -> None: ... class ParenthesesBlock(Node): - type: Literal["() block"] + type: Final = "() block" content: list[Node] repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class SquareBracketsBlock(Node): - type: Literal["[] block"] + type: Final = "[] block" content: list[Node] repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class CurlyBracketsBlock(Node): - type: Literal["{} block"] + type: Final = "{} block" content: list[Node] repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class FunctionBlock(Node): - type: Literal["function"] + type: Final = "function" name: str lower_name: str arguments: list[Node] @@ -133,7 +132,7 @@ class FunctionBlock(Node): def __init__(self, line: int, column: int, name: str, arguments: list[Node]) -> None: ... class Declaration(Node): - type: Literal["declaration"] + type: Final = "declaration" name: str lower_name: str value: list[Node] @@ -142,14 +141,14 @@ class Declaration(Node): def __init__(self, line: int, column: int, name: str, lower_name: str, value: list[Node], important: bool) -> None: ... class QualifiedRule(Node): - type: Literal["qualified-rule"] + type: Final = "qualified-rule" prelude: list[Node] content: list[Node] repr_format: str def __init__(self, line: int, column: int, prelude: list[Node], content: list[Node]) -> None: ... class AtRule(Node): - type: Literal["at-rule"] + type: Final = "at-rule" at_keyword: str lower_at_keyword: str prelude: list[Node] diff --git a/stubs/tinycss2/tinycss2/bytes.pyi b/stubs/tinycss2/tinycss2/bytes.pyi index a305f672f221..24687b7f2711 100644 --- a/stubs/tinycss2/tinycss2/bytes.pyi +++ b/stubs/tinycss2/tinycss2/bytes.pyi @@ -3,12 +3,12 @@ from webencodings import Encoding from .ast import Node def decode_stylesheet_bytes( - css_bytes: bytes, protocol_encoding: str | None = ..., environment_encoding: Encoding | None = ... + css_bytes: bytes, protocol_encoding: str | None = None, environment_encoding: Encoding | None = None ) -> tuple[str, Encoding]: ... def parse_stylesheet_bytes( css_bytes: bytes, - protocol_encoding: str | None = ..., - environment_encoding: Encoding | None = ..., - skip_comments: bool = ..., - skip_whitespace: bool = ..., + protocol_encoding: str | None = None, + environment_encoding: Encoding | None = None, + skip_comments: bool = False, + skip_whitespace: bool = False, ) -> tuple[list[Node], Encoding]: ... diff --git a/stubs/tinycss2/tinycss2/color5.pyi b/stubs/tinycss2/tinycss2/color5.pyi index a72ffb68422e..03246e07e6e9 100644 --- a/stubs/tinycss2/tinycss2/color5.pyi +++ b/stubs/tinycss2/tinycss2/color5.pyi @@ -13,5 +13,5 @@ class Color(color4.Color): COLOR_SPACES: set[str] | None def parse_color( - input: str | Iterable[Node], color_schemes: Literal["normal"] | Iterable[str] | None = ... + input: str | Iterable[Node], color_schemes: Literal["normal"] | Iterable[str] | None = None ) -> color4.Color | Color | Literal["currentcolor"] | None: ... diff --git a/stubs/tinycss2/tinycss2/parser.pyi b/stubs/tinycss2/tinycss2/parser.pyi index f3646958163d..6b8ebae7dd64 100644 --- a/stubs/tinycss2/tinycss2/parser.pyi +++ b/stubs/tinycss2/tinycss2/parser.pyi @@ -5,14 +5,14 @@ from .ast import AtRule, Comment, Declaration, Node, ParseError, QualifiedRule, _Rule: TypeAlias = QualifiedRule | AtRule | Comment | WhitespaceToken | ParseError -def parse_one_component_value(input: str | Iterable[Node], skip_comments: bool = ...) -> Node: ... -def parse_one_declaration(input: str | Iterable[Node], skip_comments: bool = ...) -> Declaration | ParseError: ... +def parse_one_component_value(input: str | Iterable[Node], skip_comments: bool = False) -> Node: ... +def parse_one_declaration(input: str | Iterable[Node], skip_comments: bool = False) -> Declaration | ParseError: ... def parse_blocks_contents( - input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ... + input: str | Iterable[Node], skip_comments: bool = False, skip_whitespace: bool = False ) -> list[Declaration | AtRule | QualifiedRule | Comment | WhitespaceToken | ParseError]: ... def parse_declaration_list( - input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ... + input: str | Iterable[Node], skip_comments: bool = False, skip_whitespace: bool = False ) -> list[Declaration | AtRule | Comment | WhitespaceToken | ParseError]: ... -def parse_one_rule(input: str | Iterable[Node], skip_comments: bool = ...) -> QualifiedRule | AtRule | ParseError: ... -def parse_rule_list(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[_Rule]: ... -def parse_stylesheet(input: str | Iterable[Node], skip_comments: bool = ..., skip_whitespace: bool = ...) -> list[_Rule]: ... +def parse_one_rule(input: str | Iterable[Node], skip_comments: bool = False) -> QualifiedRule | AtRule | ParseError: ... +def parse_rule_list(input: str | Iterable[Node], skip_comments: bool = False, skip_whitespace: bool = False) -> list[_Rule]: ... +def parse_stylesheet(input: str | Iterable[Node], skip_comments: bool = False, skip_whitespace: bool = False) -> list[_Rule]: ... diff --git a/stubs/tinycss2/tinycss2/tokenizer.pyi b/stubs/tinycss2/tinycss2/tokenizer.pyi index ee1cf7255ed3..52e27c7480c6 100644 --- a/stubs/tinycss2/tinycss2/tokenizer.pyi +++ b/stubs/tinycss2/tinycss2/tokenizer.pyi @@ -1,3 +1,3 @@ from .ast import Node -def parse_component_value_list(css: str, skip_comments: bool = ...) -> list[Node]: ... +def parse_component_value_list(css: str, skip_comments: bool = False) -> list[Node]: ... From e360840b83be39646bdbf405513dd70f6e2ae95d Mon Sep 17 00:00:00 2001 From: George Sladkovsky Date: Tue, 7 Apr 2026 16:17:42 +0200 Subject: [PATCH 4/4] Fix ast type narrowing (back to Literal) --- stubs/tinycss2/tinycss2/ast.pyi | 43 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/stubs/tinycss2/tinycss2/ast.pyi b/stubs/tinycss2/tinycss2/ast.pyi index f87b02e59ca4..3390a86fcb78 100644 --- a/stubs/tinycss2/tinycss2/ast.pyi +++ b/stubs/tinycss2/tinycss2/ast.pyi @@ -1,33 +1,34 @@ -from typing import Final +from typing import Literal class Node: source_line: int source_column: int + type: str def __init__(self, source_line: int, source_column: int) -> None: ... def serialize(self) -> str: ... class ParseError(Node): - type: Final = "error" + type: Literal["error"] kind: str message: str repr_format: str def __init__(self, line: int, column: int, kind: str, message: str) -> None: ... class Comment(Node): - type: Final = "comment" + type: Literal["comment"] value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class WhitespaceToken(Node): - type: Final = "whitespace" + type: Literal["whitespace"] value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class LiteralToken(Node): - type: Final = "literal" + type: Literal["literal"] value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... @@ -35,49 +36,49 @@ class LiteralToken(Node): def __ne__(self, other: object) -> bool: ... class IdentToken(Node): - type: Final = "ident" + type: Literal["ident"] value: str lower_value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class AtKeywordToken(Node): - type: Final = "at-keyword" + type: Literal["at-keyword"] value: str lower_value: str repr_format: str def __init__(self, line: int, column: int, value: str) -> None: ... class HashToken(Node): - type: Final = "hash" + type: Literal["hash"] value: str is_identifier: bool repr_format: str def __init__(self, line: int, column: int, value: str, is_identifier: bool) -> None: ... class StringToken(Node): - type: Final = "string" + type: Literal["string"] value: str representation: str repr_format: str def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... class URLToken(Node): - type: Final = "url" + type: Literal["url"] value: str representation: str repr_format: str def __init__(self, line: int, column: int, value: str, representation: str) -> None: ... class UnicodeRangeToken(Node): - type: Final = "unicode-range" + type: Literal["unicode-range"] start: int end: int repr_format: str def __init__(self, line: int, column: int, start: int, end: int) -> None: ... class NumberToken(Node): - type: Final = "number" + type: Literal["number"] value: float int_value: int | None is_integer: bool @@ -86,7 +87,7 @@ class NumberToken(Node): def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... class PercentageToken(Node): - type: Final = "percentage" + type: Literal["percentage"] value: float int_value: int | None is_integer: bool @@ -95,7 +96,7 @@ class PercentageToken(Node): def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str) -> None: ... class DimensionToken(Node): - type: Final = "dimension" + type: Literal["dimension"] value: float int_value: int | None is_integer: bool @@ -106,25 +107,25 @@ class DimensionToken(Node): def __init__(self, line: int, column: int, value: float, int_value: int | None, representation: str, unit: str) -> None: ... class ParenthesesBlock(Node): - type: Final = "() block" + type: Literal["() block"] content: list[Node] repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class SquareBracketsBlock(Node): - type: Final = "[] block" + type: Literal["[] block"] content: list[Node] repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class CurlyBracketsBlock(Node): - type: Final = "{} block" + type: Literal["{} block"] content: list[Node] repr_format: str def __init__(self, line: int, column: int, content: list[Node]) -> None: ... class FunctionBlock(Node): - type: Final = "function" + type: Literal["function"] name: str lower_name: str arguments: list[Node] @@ -132,7 +133,7 @@ class FunctionBlock(Node): def __init__(self, line: int, column: int, name: str, arguments: list[Node]) -> None: ... class Declaration(Node): - type: Final = "declaration" + type: Literal["declaration"] name: str lower_name: str value: list[Node] @@ -141,14 +142,14 @@ class Declaration(Node): def __init__(self, line: int, column: int, name: str, lower_name: str, value: list[Node], important: bool) -> None: ... class QualifiedRule(Node): - type: Final = "qualified-rule" + type: Literal["qualified-rule"] prelude: list[Node] content: list[Node] repr_format: str def __init__(self, line: int, column: int, prelude: list[Node], content: list[Node]) -> None: ... class AtRule(Node): - type: Final = "at-rule" + type: Literal["at-rule"] at_keyword: str lower_at_keyword: str prelude: list[Node]