Upgrading black 24 to 25
Breaking24.10.0 → 25.12.0Breaking1Platform1New5Changed33Fixed31Other5
BreakingUpgrade verdict
1 breaking change and a platform requirement change.
In plain terms
- Black no longer accepts code that uses `async` or `await` as ordinary names, which only worked on Python versions older than 3.7.
- Black can no longer be run on Python 3.9; use a newer Python version.
Must act 2 items need code or config changes
Python requirement changed in 25.12.0: >=3.9 → >=3.10.
Adds pytokens >=0.3.0.
Installs 6 packages in all (was 5).
What you must change
Breaking1
Removes support for pre-Python 3.7
await/async as soft keywords or variable names.awaitasyncPlatform1
Drops support for running Black with Python 3.9.
API changes
Generated by DepDelta from published Python source. Not mixed with prose notes.
- removed:
function nullcontext() -> Iterator[None] - removed:
function path_empty(src: Sized, msg: str, quiet: bool, verbose: bool, ctx: click.Context) -> None - changed:
function decode_bytes(src: bytes) -> tuple[FileContent, Encoding, NewLine] → function decode_bytes(src: bytes, mode: Mode) -> tuple[FileContent, Encoding, NewLine] - changed:
function detect_target_versions(node: Node, *, future_imports: Optional[set[str]]=…) -> set[TargetVersion] → function detect_target_versions(node: Node, *, future_imports: set[str] | None=…) -> set[TargetVersion] - changed:
function enable_unstable_feature_callback(c: click.Context, p: Union[click.Option, click.Parameter], v: tuple[str, ...]) -> list[Preview] → function enable_unstable_feature_callback(c: click.Context, p: click.Option | click.Parameter, v: tuple[str, ...]) -> list[Preview] - changed:
function format_stdin_to_stdout(fast: bool, *, content: Optional[str]=…, write_back: WriteBack=…, mode: Mode, lines: Collection[tuple[int, int]]=…) -> bool → function format_stdin_to_stdout(fast: bool, *, content: str | None=…, write_back: WriteBack=…, mode: Mode, lines: Collection[tuple[int, int]]=…) -> bool - changed:
function get_features_used(node: Node, *, future_imports: Optional[set[str]]=…) -> set[Feature] → function get_features_used(node: Node, *, future_imports: set[str] | None=…) -> set[Feature] - changed:
function get_sources(*, root: Path, src: tuple[str, ...], quiet: bool, verbose: bool, include: Pattern[str], exclude: Optional[Pattern[str]], extend_exclude: Optional[Pattern[str]], force_exclude: Optional[Pattern[str]], report: Report, stdin_filename: Optional[str]) -> set[Path] → function get_sources(*, root: Path, src: tuple[str, ...], quiet: bool, verbose: bool, include: Pattern[str], exclude: Pattern[str] | None, extend_exclude: Pattern[str] | None, force_exclude: Pattern[str] | None, report: Report, stdin_filename: str | None) -> set[Path] - changed:
function main(ctx: click.Context, code: Optional[str], line_length: int, target_version: list[TargetVersion], check: bool, diff: bool, line_ranges: Sequence[str], color: bool, fast: bool, pyi: bool, ipynb: bool, python_cell_magics: Sequence[str], skip_source_first_line: bool, skip_string_normalization: bool, skip_magic_trailing_comma: bool, preview: bool, unstable: bool, enable_unstable_feature:… → function main(ctx: click.Context, code: str | None, line_length: int, target_version: list[TargetVersion], check: bool, diff: bool, line_ranges: Sequence[str], color: bool, fast: bool, pyi: bool, ipynb: bool, python_cell_magics: Sequence[str], skip_source_first_line: bool, skip_string_normalization: bool, skip_magic_trailing_comma: bool, preview: bool, unstable: bool, enable_unstable_feature: lis… - changed:
function read_pyproject_toml(ctx: click.Context, param: click.Parameter, value: Optional[str]) -> Optional[str] → function read_pyproject_toml(ctx: click.Context, param: click.Parameter, value: str | None) -> str | None - changed:
function reformat_one(src: Path, fast: bool, write_back: WriteBack, mode: Mode, report: Report, *, lines: Collection[tuple[int, int]]=…) -> None → function reformat_one(src: Path, fast: bool, write_back: WriteBack, mode: Mode, report: Report, *, lines: Collection[tuple[int, int]]=…, no_cache: bool=…) -> None - changed:
function target_version_option_callback(c: click.Context, p: Union[click.Option, click.Parameter], v: tuple[str, ...]) -> list[TargetVersion] → function target_version_option_callback(c: click.Context, p: click.Option | click.Parameter, v: tuple[str, ...]) -> list[TargetVersion] - changed:
function validate_regex(ctx: click.Context, param: click.Parameter, value: Optional[str]) -> Optional[Pattern[str]] → function validate_regex(ctx: click.Context, param: click.Parameter, value: str | None) -> Pattern[str] | None
- changed:
field BracketTracker.previous: Optional[Leaf] → field BracketTracker.previous: Leaf | None - changed:
function is_split_before_delimiter(leaf: Leaf, previous: Optional[Leaf]=…) -> Priority → function is_split_before_delimiter(leaf: Leaf, previous: Leaf | None=…) -> Priority - changed:
method BracketTracker.get_open_lsqb() -> Optional[Leaf] → method BracketTracker.get_open_lsqb() -> Leaf | None
- changed:
function children_contains_fmt_on(container: LN) -> bool → function children_contains_fmt_on(container: LN, mode: Mode) -> bool - changed:
function generate_comments(leaf: LN) -> Iterator[Leaf] → function generate_comments(leaf: LN, mode: Mode) -> Iterator[Leaf] - changed:
function is_fmt_on(container: LN) -> bool → function is_fmt_on(container: LN, mode: Mode) -> bool - changed:
function list_comments(prefix: str, *, is_endmarker: bool) -> list[ProtoComment] → function list_comments(prefix: str, *, is_endmarker: bool, mode: Mode) -> list[ProtoComment] - changed:
function make_comment(content: str) -> str → function make_comment(content: str, mode: Mode) -> str - added:
function contains_fmt_directive(comment_line: str, directives: set[str]=…) -> bool
- changed:
async function schedule_formatting(sources: set[Path], fast: bool, write_back: WriteBack, mode: Mode, report: Report, loop: asyncio.AbstractEventLoop, executor: Executor) -> None → async function schedule_formatting(sources: set[Path], fast: bool, write_back: WriteBack, mode: Mode, report: Report, loop: asyncio.AbstractEventLoop, executor: Executor, no_cache: bool=…) -> None - changed:
function reformat_many(sources: set[Path], fast: bool, write_back: WriteBack, mode: Mode, report: Report, workers: Optional[int]) -> None → function reformat_many(sources: set[Path], fast: bool, write_back: WriteBack, mode: Mode, report: Report, workers: int | None, no_cache: bool=…) -> None
- changed:
static method DebugVisitor.show(code: Union[str, Leaf, Node]) -> None → static method DebugVisitor.show(code: str | Leaf | Node) -> None
- changed:
function find_project_root(srcs: Sequence[str], stdin_filename: Optional[str]=…) -> tuple[Path, str] → function find_project_root(srcs: Sequence[str], stdin_filename: str | None=…) -> tuple[Path, str] - changed:
function find_pyproject_toml(path_search_start: tuple[str, ...], stdin_filename: Optional[str]=…) -> Optional[str] → function find_pyproject_toml(path_search_start: tuple[str, ...], stdin_filename: str | None=…) -> str | None - changed:
function gen_python_files(paths: Iterable[Path], root: Path, include: Pattern[str], exclude: Pattern[str], extend_exclude: Optional[Pattern[str]], force_exclude: Optional[Pattern[str]], report: Report, gitignore_dict: Optional[dict[Path, PathSpec]], *, verbose: bool, quiet: bool) -> Iterator[Path] → function gen_python_files(paths: Iterable[Path], root: Path, include: Pattern[str], exclude: Pattern[str], extend_exclude: Pattern[str] | None, force_exclude: Pattern[str] | None, report: Report, gitignore_dict: dict[Path, PathSpec] | None, *, verbose: bool, quiet: bool) -> Iterator[Path] - changed:
function infer_target_version(pyproject_toml: dict[str, Any]) -> Optional[list[TargetVersion]] → function infer_target_version(pyproject_toml: dict[str, Any]) -> list[TargetVersion] | None - changed:
function parse_req_python_specifier(requires_python: str) -> Optional[list[TargetVersion]] → function parse_req_python_specifier(requires_python: str) -> list[TargetVersion] | None - changed:
function parse_req_python_version(requires_python: str) -> Optional[list[TargetVersion]] → function parse_req_python_version(requires_python: str) -> list[TargetVersion] | None - changed:
function path_is_excluded(normalized_path: str, pattern: Optional[Pattern[str]]) -> bool → function path_is_excluded(normalized_path: str, pattern: Pattern[str] | None) -> bool - changed:
function resolves_outside_root_or_cannot_stat(path: Path, root: Path, report: Optional[Report]=…) -> bool → function resolves_outside_root_or_cannot_stat(path: Path, root: Path, report: Report | None=…) -> bool
- removed:
variable TOKEN_HEX - changed:
constructor CellMagicFinder(cell_magic: Optional[CellMagic]=…) -> None → constructor CellMagicFinder(cell_magic: CellMagic | None=…) -> None - changed:
field CellMagic.params: Optional[str] → field CellMagic.params: str | None - added:
function create_token(n_chars: int) -> str
- changed:
function maybe_make_parens_invisible_in_atom(node: LN, parent: LN, remove_brackets_around_comma: bool=…) -> bool → function maybe_make_parens_invisible_in_atom(node: LN, parent: LN, mode: Mode, features: Collection[Feature], remove_brackets_around_comma: bool=…, allow_star_expr: bool=…) -> bool - changed:
function remove_await_parens(node: Node) -> None → function remove_await_parens(node: Node, mode: Mode, features: Collection[Feature]) -> None - changed:
function remove_with_parens(node: Node, parent: Node) -> None → function remove_with_parens(node: Node, parent: Node, mode: Mode, features: Collection[Feature]) -> None - added:
method LineGenerator.visit_atom(node: Node) -> Iterator[Line] - added:
method LineGenerator.visit_comp_for(node: Node) -> Iterator[Line] - added:
method LineGenerator.visit_old_comp_for(node: Node) -> Iterator[Line] - added:
method LineGenerator.visit_tstring(node: Node) -> Iterator[Line]
- changed:
field EmptyLineTracker.previous_block: Optional[LinesBlock] → field EmptyLineTracker.previous_block: LinesBlock | None - changed:
field EmptyLineTracker.previous_line: Optional[Line] → field EmptyLineTracker.previous_line: Line | None - changed:
field EmptyLineTracker.semantic_leading_comment: Optional[LinesBlock] → field EmptyLineTracker.semantic_leading_comment: LinesBlock | None - changed:
field Line.magic_trailing_comma: Optional[Leaf] → field Line.magic_trailing_comma: Leaf | None - changed:
method Line.is_fmt_pass_converted(*, first_leaf_matches: Optional[Callable[[Leaf], bool]]=…) -> bool → method Line.is_fmt_pass_converted(*, first_leaf_matches: Callable[[Leaf], bool] | None=…) -> bool
- removed:
field Feature.FSTRING_PARSING - removed:
field Preview.docstring_check_for_newline - removed:
field Preview.hex_codes_in_unicode_sequences - removed:
field Preview.is_simple_lookup_for_doublestar_expression - removed:
field Preview.no_normalize_fmt_skip_whitespace - removed:
field Preview.parens_for_long_if_clauses_in_case_block - removed:
field Preview.pep646_typed_star_arg_type_var_tuple - removed:
field Preview.remove_redundant_guard_parens - removed:
field Preview.typed_params_trailing_comma - removed:
field Preview.unify_docstring_detection - added:
field Feature.T_STRINGS - added:
field Feature.UNPARENTHESIZED_EXCEPT_TYPES - added:
field Preview.always_one_newline_after_import - added:
field Preview.fix_fmt_skip_in_one_liners - added:
field Preview.fix_module_docstring_detection - added:
field Preview.fix_type_expansion_split - added:
field Preview.normalize_cr_newlines - added:
field Preview.remove_parens_around_except_types - added:
field Preview.remove_parens_from_assignment_lhs - added:
field Preview.standardize_type_comments - added:
field Preview.wrap_comprehension_in - added:
field TargetVersion.PY314
- removed:
function fstring_to_string(node: Node) -> Leaf - changed:
function child_towards(ancestor: Node, descendant: LN) -> Optional[LN] → function child_towards(ancestor: Node, descendant: LN) -> LN | None - changed:
function first_leaf(node: LN) -> Optional[Leaf] → function first_leaf(node: LN) -> Leaf | None - changed:
function first_leaf_of(node: LN) -> Optional[Leaf] → function first_leaf_of(node: LN) -> Leaf | None - changed:
function is_docstring(node: NL, mode: Mode) -> bool → function is_docstring(node: NL) -> bool - changed:
function is_type_comment(leaf: Leaf) -> bool → function is_type_comment(leaf: Leaf, mode: Mode) -> bool - changed:
function is_type_ignore_comment(leaf: Leaf) -> bool → function is_type_ignore_comment(leaf: Leaf, mode: Mode) -> bool - changed:
function is_type_ignore_comment_string(value: str) -> bool → function is_type_ignore_comment_string(value: str, mode: Mode) -> bool - changed:
function last_leaf(node: LN) -> Optional[Leaf] → function last_leaf(node: LN) -> Leaf | None - changed:
function parent_type(node: Optional[LN]) -> Optional[NodeType] → function parent_type(node: LN | None) -> NodeType | None - changed:
function preceding_leaf(node: Optional[LN]) -> Optional[Leaf] → function preceding_leaf(node: LN | None) -> Leaf | None - changed:
function prev_siblings_are(node: Optional[LN], tokens: list[Optional[NodeType]]) -> bool → function prev_siblings_are(node: LN | None, tokens: list[NodeType | None]) -> bool - changed:
function unwrap_singleton_parenthesis(node: LN) -> Optional[LN] → function unwrap_singleton_parenthesis(node: LN) -> LN | None - added:
function fstring_tstring_to_string(node: Node) -> Leaf - added:
function has_sibling_with_type(node: LN, type: int) -> bool - added:
function is_generator(node: LN) -> bool - added:
function is_tuple(node: LN) -> bool - added:
function is_tuple_containing_star(node: LN) -> bool - added:
function is_type_comment_string(value: str, mode: Mode) -> bool
- changed:
function err(message: Optional[str]=…, nl: bool=…, **styles: Any) -> None → function err(message: str | None=…, nl: bool=…, **styles: Any) -> None - changed:
function out(message: Optional[str]=…, nl: bool=…, **styles: Any) -> None → function out(message: str | None=…, nl: bool=…, **styles: Any) -> None
- removed:
function fix_docstring(docstring: str, prefix: str) -> str - added:
function fix_multiline_docstring(docstring: str, prefix: str) -> str
- removed:
function original_is_simple_lookup_func(line: Line, index: int, step: Literal[1, -1]) -> bool - added:
variable CustomSplitMapKey
- added:
function executor() -> Executor
- added:
async method BlackDClient.format_code(unformatted_code: str) -> str - added:
class BlackDClient - added:
constructor BlackDClient(url: StrOrURL=…, line_length: int | None=…, skip_source_first_line: bool=…, skip_string_normalization: bool=…, skip_magic_trailing_comma: bool=…, preview: bool=…, fast: bool=…, python_variant: str | None=…, diff: bool=…, headers: dict[str, str] | None=…)
- removed:
method Driver.parse_stream(stream: IO[str], debug: bool=…) -> NL - removed:
method Driver.parse_stream_raw(stream: IO[str], debug: bool=…) -> NL - changed:
constructor Driver(grammar: Grammar, logger: Optional[Logger]=…) -> None → constructor Driver(grammar: Grammar, logger: Logger | None=…) -> None - changed:
function load_grammar(gt: str=…, gp: Optional[str]=…, save: bool=…, force: bool=…, logger: Optional[Logger]=…) -> Grammar → function load_grammar(gt: str=…, gp: str | None=…, save: bool=…, force: bool=…, logger: Logger | None=…) -> Grammar - changed:
method Driver.parse_file(filename: Path, encoding: Optional[str]=…, debug: bool=…) -> NL → method Driver.parse_file(filename: Path, encoding: str | None=…, debug: bool=…) -> NL - changed:
method Driver.parse_tokens(tokens: Iterable[GoodTokenInfo], debug: bool=…) -> NL → method Driver.parse_tokens(tokens: Iterable[TokenInfo], debug: bool=…) -> NL
- changed:
function escape(m: Match[str]) -> str → function escape(m: re.Match[str]) -> str
- changed:
constructor ParseError(msg: str, type: Optional[int], value: Optional[str], context: Context) -> None → constructor ParseError(msg: str, type: int | None, value: str | None, context: Context) -> None - changed:
constructor Parser(grammar: Grammar, convert: Optional[Convert]=…) -> None → constructor Parser(grammar: Grammar, convert: Convert | None=…) -> None - changed:
method Parser.setup(proxy: TokenProxy, start: Optional[int]=…) -> None → method Parser.setup(proxy: TokenProxy, start: int | None=…) -> None - changed:
method Recorder.determine_route(value: Optional[str]=…, force: bool=…) -> Optional[int] → method Recorder.determine_route(value: str | None=…, force: bool=…) -> int | None
- changed:
constructor ParserGenerator(filename: Path, stream: Optional[IO[str]]=…) -> None → constructor ParserGenerator(filename: Path, stream: IO[str] | None=…) -> None - changed:
field NFAState.arcs: list[tuple[Optional[str], NFAState]] → field NFAState.arcs: list[tuple[str | None, NFAState]] - changed:
field ParserGenerator.first: dict[str, Optional[dict[str, int]]] → field ParserGenerator.first: dict[str, dict[str, int] | None] - changed:
field ParserGenerator.generator: Iterator[GoodTokenInfo] → field ParserGenerator.generator: Iterator[TokenInfo] - changed:
method NFAState.addarc(next: NFAState, label: Optional[str]=…) -> None → method NFAState.addarc(next: NFAState, label: str | None=…) -> None - changed:
method ParserGenerator.expect(type: int, value: Optional[Any]=…) -> str → method ParserGenerator.expect(type: int, value: Any | None=…) -> str - changed:
method ParserGenerator.raise_error(msg: str, *args: Any) -> NoReturn → method ParserGenerator.raise_error(msg: str) -> NoReturn
- added:
variable TSTRING_END: Final - added:
variable TSTRING_MIDDLE: Final - added:
variable TSTRING_START: Final
- removed:
class FStringState - removed:
class StopTokenizing(Exception) - removed:
class Untokenizer - removed:
constructor FStringState() -> None - removed:
constructor Untokenizer() -> None - removed:
field Untokenizer.prev_col: int - removed:
field Untokenizer.prev_row: int - removed:
field Untokenizer.tokens: list[str] - removed:
function any(*choices: str) -> str - removed:
function detect_encoding(readline: Callable[[], bytes]) -> tuple[str, list[bytes]] - removed:
function generate_tokens(readline: Callable[[], str], grammar: Optional[Grammar]=…) -> Iterator[GoodTokenInfo] - removed:
function group(*choices: str) -> str - removed:
function is_fstring_start(token: str) -> bool - removed:
function maybe(*choices: str) -> str - removed:
function tokenize_loop(readline: Callable[[], str], tokeneater: TokenEater) -> None - removed:
function untokenize(iterable: Iterable[TokenInfo]) -> str - removed:
method FStringState.consume_colon() -> None - removed:
method FStringState.consume_lbrace() -> None - removed:
method FStringState.consume_rbrace() -> None - removed:
method FStringState.current() -> int - removed:
method FStringState.enter_fstring() -> None - removed:
method FStringState.is_in_fstring_expression() -> bool - removed:
method FStringState.leave_fstring() -> None - removed:
method Untokenizer.add_whitespace(start: Coord) -> None - removed:
method Untokenizer.compat(token: tuple[int, str], iterable: Iterable[TokenInfo]) -> None - removed:
method Untokenizer.untokenize(iterable: Iterable[TokenInfo]) -> str - removed:
variable Bang - removed:
variable Binnumber - removed:
variable Bracket - removed:
variable Colon - removed:
variable Comment - removed:
variable ContStr - removed:
variable Decnumber - removed:
variable Double - removed:
variable Double3 - removed:
variable Double3Lbrace - removed:
variable DoubleLbrace - removed:
variable Expfloat - removed:
variable Exponent - removed:
variable Floatnumber - removed:
variable FstringMiddleAfterColon - removed:
variable Funny - removed:
variable GoodTokenInfo - removed:
variable Hexnumber - removed:
variable Ignore - removed:
variable Imagnumber - removed:
variable Intnumber - removed:
variable Name - removed:
variable Number - removed:
variable Octnumber - removed:
variable Operator - removed:
variable Pointfloat - removed:
variable PseudoExtras - removed:
variable PseudoToken - removed:
variable STATE_IN_BRACES: Final - removed:
variable STATE_IN_COLON: Final - removed:
variable STATE_MIDDLE: Final - removed:
variable STATE_NOT_FSTRING: Final - removed:
variable Single - removed:
variable Single3 - removed:
variable Single3Lbrace - removed:
variable SingleLbrace - removed:
variable Special - removed:
variable TokenEater - removed:
variable Triple - removed:
variable Whitespace - removed:
variable bang - removed:
variable blank_re - removed:
variable colon - removed:
variable cookie_re - removed:
variable double3prog - removed:
variable double3prog_plus_lbrace - removed:
variable doubleprog - removed:
variable doubleprog_plus_lbrace - removed:
variable endprogs: Final - removed:
variable fstring_middle_after_colon - removed:
variable fstring_prefix: Final - removed:
variable pseudoprog: Final - removed:
variable single3prog - removed:
variable single3prog_plus_lbrace - removed:
variable single_quoted: Final - removed:
variable singleprog - removed:
variable singleprog_plus_lbrace - removed:
variable tabsize - removed:
variable triple_quoted: Final - changed:
function tokenize(readline: Callable[[], str], tokeneater: TokenEater=…) -> None → function tokenize(source: str, grammar: Grammar | None=…) -> Iterator[TokenInfo] - added:
function transform_whitespace(token: pytokens.Token, source: str, prev_token: pytokens.Token | None) -> pytokens.Token - added:
variable TOKEN_TYPE_MAP - added:
variable token_iterator
- removed:
property Base.next_sibling -> Optional[NL] - removed:
property Base.prev_sibling -> Optional[NL] - changed:
constructor Leaf(type: int, value: str, context: Optional[Context]=…, prefix: Optional[str]=…, fixers_applied: list[Any]=…, opening_bracket: Optional[Leaf]=…, fmt_pass_converted_first_leaf: Optional[Leaf]=…) -> None → constructor Leaf(type: int, value: str, context: Context | None=…, prefix: str | None=…, fixers_applied: list[Any]=…, opening_bracket: Optional[Leaf]=…, fmt_pass_converted_first_leaf: Optional[Leaf]=…) -> None - changed:
constructor LeafPattern(type: Optional[int]=…, content: Optional[str]=…, name: Optional[str]=…) -> None → constructor LeafPattern(type: int | None=…, content: str | None=…, name: str | None=…) -> None - changed:
constructor NegatedPattern(content: Optional[BasePattern]=…) -> None → constructor NegatedPattern(content: BasePattern | None=…) -> None - changed:
constructor Node(type: int, children: list[NL], context: Optional[Any]=…, prefix: Optional[str]=…, fixers_applied: Optional[list[Any]]=…) -> None → constructor Node(type: int, children: list[NL], context: Any | None=…, prefix: str | None=…, fixers_applied: list[Any] | None=…) -> None - changed:
constructor NodePattern(type: Optional[int]=…, content: Optional[Iterable[str]]=…, name: Optional[str]=…) -> None → constructor NodePattern(type: int | None=…, content: Iterable[str] | None=…, name: str | None=…) -> None - changed:
constructor WildcardPattern(content: Optional[str]=…, min: int=…, max: int=…, name: Optional[str]=…) -> None → constructor WildcardPattern(content: str | None=…, min: int=…, max: int=…, name: str | None=…) -> None - changed:
field BasePattern.name: Optional[str] → field BasePattern.name: str | None - changed:
field BasePattern.type: Optional[int] → field BasePattern.type: int | None - changed:
field Leaf.used_names: Optional[set[str]] → field Leaf.used_names: set[str] | None - changed:
field Node.fixers_applied: Optional[list[Any]] → field Node.fixers_applied: list[Any] | None - changed:
field Node.used_names: Optional[set[str]] → field Node.used_names: set[str] | None - changed:
function type_repr(type_num: int) -> Union[str, int] → function type_repr(type_num: int) -> str | int - changed:
method Base.get_lineno() -> Optional[int] → method Base.get_lineno() -> int | None - changed:
method Base.remove() -> Optional[int] → method Base.remove() -> int | None - changed:
method Base.replace(new: Union[NL, list[NL]]) -> None → method Base.replace(new: NL | list[NL]) -> None - changed:
method BasePattern.match(node: NL, results: Optional[_Results]=…) -> bool → method BasePattern.match(node: NL, results: _Results | None=…) -> bool - changed:
method BasePattern.match_seq(nodes: list[NL], results: Optional[_Results]=…) -> bool → method BasePattern.match_seq(nodes: list[NL], results: _Results | None=…) -> bool - added:
property Base.next_sibling -> NL | None - added:
property Base.prev_sibling -> NL | None