From 6bb0ace7a5a18fa20adaba867be4c3649a4052a1 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Sun, 1 Mar 2026 06:43:01 +0000 Subject: [PATCH 1/2] Bump types-docutils and fix ty type checker errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update types-docutils from 0.22.3.20251115 to 0.22.3.20260223 - Fix 115 ty errors by updating renamed rule names and adding inline suppressions - Update ty.toml: rename non-subscriptable → not-subscriptable - Add ty ignore comments for false positives in Napoleon config, autosummary, C/C++ domain code, and other modules where ty can't narrow union types - Add None checks for reference node access in intersphinx ty check now passes with 0 errors while keeping mypy passing. Co-Authored-By: Claude Sonnet 4.6 --- pyproject.toml | 2 +- sphinx/builders/gettext.py | 2 +- sphinx/builders/html/__init__.py | 4 +- sphinx/domains/c/__init__.py | 6 +- sphinx/domains/c/_ast.py | 8 +- sphinx/domains/c/_parser.py | 4 +- sphinx/domains/c/_symbol.py | 10 +- sphinx/domains/cpp/__init__.py | 12 +- sphinx/domains/cpp/_ast.py | 38 +++---- sphinx/domains/cpp/_symbol.py | 6 +- sphinx/ext/apidoc/_generate.py | 2 +- sphinx/ext/autodoc/_dynamic/_member_finder.py | 4 +- sphinx/ext/autosummary/generate.py | 14 +-- sphinx/ext/napoleon/docstring.py | 40 +++---- sphinx/util/matching.py | 2 +- tests/test_builders/xpath_util.py | 4 +- .../test_ext_intersphinx.py | 11 +- tests/test_pycode/test_pycode.py | 1 + tests/test_util/test_util_inspect.py | 2 +- tests/test_util/test_util_typing.py | 5 +- ty.toml | 2 +- uv.lock | 104 +++++++++--------- 22 files changed, 147 insertions(+), 136 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1195b0442dd..c25fe590c5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -137,7 +137,7 @@ type-stubs = [ # align with versions used elsewhere "types-colorama==0.4.15.20250801", "types-defusedxml==0.7.0.20250822", - "types-docutils==0.22.3.20251115", + "types-docutils==0.22.3.20260223", "types-Pillow==10.2.0.20240822", "types-Pygments==2.19.0.20251121", "types-requests==2.32.4.20250913", diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index fc659d744d5..89e720a23be 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -264,7 +264,7 @@ def _extract_from_template(self) -> None: logger.info(bold(__('building [%s]: ')), self.name, nonl=True) logger.info(__('targets for %d template files'), len(files)) - extract_translations = self.templates.environment.extract_translations + extract_translations = self.templates.environment.extract_translations # ty: ignore[unresolved-attribute] for template in status_iterator( files, diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index 153cfa141ce..86c17ba0c59 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -575,7 +575,7 @@ def get_doc_context(self, docname: str, body: str, metatags: str) -> dict[str, A 'link': self.get_relative_uri(docname, related[2]), 'title': self.render_partial(titles[related[2]])['title'], } - rellinks.append((related[2], next['title'], 'N', _('next'))) + rellinks.append((related[2], next['title'], 'N', _('next'))) # ty: ignore[unresolved-attribute] except KeyError: next = None if related and related[1]: @@ -584,7 +584,7 @@ def get_doc_context(self, docname: str, body: str, metatags: str) -> dict[str, A 'link': self.get_relative_uri(docname, related[1]), 'title': self.render_partial(titles[related[1]])['title'], } - rellinks.append((related[1], prev['title'], 'P', _('previous'))) + rellinks.append((related[1], prev['title'], 'P', _('previous'))) # ty: ignore[unresolved-attribute] except KeyError: # the relation is (somehow) not in the TOC tree, handle # that gracefully diff --git a/sphinx/domains/c/__init__.py b/sphinx/domains/c/__init__.py index 194916122cd..af24ca8bdc9 100644 --- a/sphinx/domains/c/__init__.py +++ b/sphinx/domains/c/__init__.py @@ -150,7 +150,7 @@ def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None: if s is not None: # something is already declared with that name return - decl_clone = symbol.declaration.clone() + decl_clone = symbol.declaration.clone() # ty: ignore[unresolved-attribute] decl_clone.enumeratorScopedSymbol = symbol Symbol( parent=target_symbol, @@ -175,7 +175,7 @@ def add_target_and_index( newest_id = ids[0] assert newest_id # shouldn't be None - name = ast.symbol.get_full_nested_name().get_display_string().lstrip('.') + name = ast.symbol.get_full_nested_name().get_display_string().lstrip('.') # ty: ignore[unresolved-attribute] if newest_id not in self.state.document.ids: # always add the newest id assert newest_id @@ -554,7 +554,7 @@ def _render_symbol( if not skip_this: signode = addnodes.desc_signature('', '') nodes.append(signode) - s.declaration.describe_signature( + s.declaration.describe_signature( # ty: ignore[unresolved-attribute] signode, 'markName', self.env, render_options ) diff --git a/sphinx/domains/c/_ast.py b/sphinx/domains/c/_ast.py index 89e76627b66..a8e9308c3c6 100644 --- a/sphinx/domains/c/_ast.py +++ b/sphinx/domains/c/_ast.py @@ -834,7 +834,7 @@ def __hash__(self) -> int: def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=False) + return symbol.parent.declaration.get_id(version, prefixed=False) # ty: ignore[unresolved-attribute] def _stringify(self, transform: StringifyTransform) -> str: if self.ellipsis: @@ -849,7 +849,7 @@ def describe_signature( if self.ellipsis: signode += addnodes.desc_sig_punctuation('...', '...') else: - self.arg.describe_signature(signode, mode, env, symbol=symbol) + self.arg.describe_signature(signode, mode, env, symbol=symbol) # ty: ignore[unresolved-attribute] class ASTParameters(ASTBase): @@ -1670,7 +1670,7 @@ def describe_signature( name = str(self) signode += addnodes.desc_sig_name(name, name) else: - self.arg.describe_signature(signode, mode, env, symbol=symbol) + self.arg.describe_signature(signode, mode, env, symbol=symbol) # ty: ignore[unresolved-attribute] class ASTMacro(ASTBase): @@ -1906,7 +1906,7 @@ def function_params(self) -> list[ASTFunctionParameter] | None: def get_id(self, version: int, prefixed: bool = True) -> str: if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: - return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed) + return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed) # ty: ignore[unresolved-attribute] id_ = self.declaration.get_id(version, self.objectType, self.symbol) if prefixed: return _id_prefix[version] + id_ diff --git a/sphinx/domains/c/_parser.py b/sphinx/domains/c/_parser.py index c59352b6ee2..9d9c13e4a11 100644 --- a/sphinx/domains/c/_parser.py +++ b/sphinx/domains/c/_parser.py @@ -150,8 +150,8 @@ def _parse_literal(self) -> ASTLiteral | None: # character-literal if self.match(char_literal_re): - prefix = self.last_match.group(1) # may be None when no prefix - data = self.last_match.group(2) + prefix = self.last_match.group(1) # may be None when no prefix # ty: ignore[unresolved-attribute] + data = self.last_match.group(2) # ty: ignore[unresolved-attribute] try: return ASTCharLiteral(prefix, data) except UnicodeDecodeError as e: diff --git a/sphinx/domains/c/_symbol.py b/sphinx/domains/c/_symbol.py index 0494305dd3d..ddfcb15d796 100644 --- a/sphinx/domains/c/_symbol.py +++ b/sphinx/domains/c/_symbol.py @@ -143,22 +143,22 @@ def _children(self) -> Iterable[Symbol]: return self._children_by_name.values() def _add_child(self, child: Symbol) -> None: - name = child.ident.name + name = child.ident.name # ty: ignore[unresolved-attribute] if name in self._children_by_name: # Duplicate so don't add - will be reported in _add_symbols() return self._children_by_name[name] = child child_docname: str = child.docname self._children_by_docname.setdefault(child_docname, {})[name] = child - if child.ident.is_anonymous: + if child.ident.is_anonymous: # ty: ignore[unresolved-attribute] self._anon_children.add(child) def _remove_child(self, child: Symbol) -> None: - name = child.ident.name + name = child.ident.name # ty: ignore[unresolved-attribute] self._children_by_name.pop(name, None) if children := self._children_by_docname.get(child.docname): children.pop(name, None) - if child.ident.is_anonymous: + if child.ident.is_anonymous: # ty: ignore[unresolved-attribute] self._anon_children.discard(child) def _fill_empty(self, declaration: ASTDeclaration, docname: str, line: int) -> None: @@ -551,7 +551,7 @@ def merge_with( assert other is not None for other_child in other._children: - other_name = other_child.ident.name + other_name = other_child.ident.name # ty: ignore[unresolved-attribute] if other_name not in self._children_by_name: # TODO: hmm, should we prune by docnames? other_child.parent = self diff --git a/sphinx/domains/cpp/__init__.py b/sphinx/domains/cpp/__init__.py index 0ccdc106c44..91c7229eb06 100644 --- a/sphinx/domains/cpp/__init__.py +++ b/sphinx/domains/cpp/__init__.py @@ -211,7 +211,7 @@ def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None: if s is not None: # something is already declared with that name return - decl_clone = symbol.declaration.clone() + decl_clone = symbol.declaration.clone() # ty: ignore[unresolved-attribute] decl_clone.enumeratorScopedSymbol = symbol Symbol( parent=target_symbol, @@ -247,10 +247,10 @@ def add_target_and_index( location=self.get_location(), ) - name = ast.symbol.get_full_nested_name().get_display_string().lstrip(':') + name = ast.symbol.get_full_nested_name().get_display_string().lstrip(':') # ty: ignore[unresolved-attribute] # Add index entry, but not if it's a declaration inside a concept is_in_concept = False - s = ast.symbol.parent + s = ast.symbol.parent # ty: ignore[unresolved-attribute] while s is not None: decl = s.declaration s = s.parent @@ -278,7 +278,7 @@ def add_target_and_index( # if the name is not unique, the first one will win names = self.env.domaindata['cpp']['names'] if name not in names: - names[name] = ast.symbol.docname + names[name] = ast.symbol.docname # ty: ignore[unresolved-attribute] # always add the newest id assert newest_id signode['ids'].append(newest_id) @@ -424,7 +424,7 @@ def before_content(self) -> None: self.env.ref_context['cpp:parent_key'] = last_symbol.get_lookup_key() self.env.current_document.cpp_domain_name = ( *self.env.current_document.cpp_domain_name, - last_symbol.identOrOp._stringify(str), + last_symbol.identOrOp._stringify(str), # ty: ignore[unresolved-attribute] ) def after_content(self) -> None: @@ -672,7 +672,7 @@ def _render_symbol( if not skip_this: signode = addnodes.desc_signature('', '') nodes.append(signode) - s.declaration.describe_signature( + s.declaration.describe_signature( # ty: ignore[unresolved-attribute] signode, 'markName', self.env, render_options ) diff --git a/sphinx/domains/cpp/_ast.py b/sphinx/domains/cpp/_ast.py index 90730196a2a..9424c26c032 100644 --- a/sphinx/domains/cpp/_ast.py +++ b/sphinx/domains/cpp/_ast.py @@ -313,8 +313,8 @@ def describe_signature( template_params: list[Any] = [] if mode == 'lastIsName': assert symbol is not None - if symbol.declaration.templatePrefix is not None: - template_params = symbol.declaration.templatePrefix.templates + if symbol.declaration.templatePrefix is not None: # ty: ignore[unresolved-attribute] + template_params = symbol.declaration.templatePrefix.templates # ty: ignore[unresolved-attribute] i_template_params = 0 template_params_prefix = '' prefix = '' @@ -2038,7 +2038,7 @@ def get_id( # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=False) + return symbol.parent.declaration.get_id(version, prefixed=False) # ty: ignore[unresolved-attribute] # else, do the usual if self.ellipsis: return 'z' @@ -3394,7 +3394,7 @@ def get_id( if objectType: # needs the name if objectType == 'function': # also modifiers res.extend(( - symbol.get_full_nested_name().get_id(version), + symbol.get_full_nested_name().get_id(version), # ty: ignore[unresolved-attribute] self.decl.get_param_id(version), self.decl.get_modifiers_id(version), )) @@ -3404,7 +3404,7 @@ def get_id( ): res.append('CE') elif objectType == 'type': # just the name - res.append(symbol.get_full_nested_name().get_id(version)) + res.append(symbol.get_full_nested_name().get_id(version)) # ty: ignore[unresolved-attribute] else: raise AssertionError(objectType) else: # only type encoding @@ -3421,10 +3421,10 @@ def get_id( if objectType: # needs the name if objectType == 'function': # also modifiers modifiers = self.decl.get_modifiers_id(version) - res.append(symbol.get_full_nested_name().get_id(version, modifiers)) + res.append(symbol.get_full_nested_name().get_id(version, modifiers)) # ty: ignore[unresolved-attribute] if version >= 4: # with templates we need to mangle the return type in as well - templ = symbol.declaration.templatePrefix + templ = symbol.declaration.templatePrefix # ty: ignore[unresolved-attribute] if templ is not None: type_id = self.decl.get_ptr_suffix_id(version) if self.trailingReturn: @@ -3435,7 +3435,7 @@ def get_id( res.append(return_type_id) res.append(self.decl.get_param_id(version)) elif objectType == 'type': # just the name - res.append(symbol.get_full_nested_name().get_id(version)) + res.append(symbol.get_full_nested_name().get_id(version)) # ty: ignore[unresolved-attribute] else: raise AssertionError(objectType) else: # only type encoding @@ -3504,7 +3504,7 @@ def get_id( assert version >= 2 if symbol: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=False) + return symbol.parent.declaration.get_id(version, prefixed=False) # ty: ignore[unresolved-attribute] else: return self.type.get_id(version) @@ -3554,11 +3554,11 @@ def get_id( return self.type.get_id(version, objectType) if version == 1: return ( - symbol.get_full_nested_name().get_id(version) + symbol.get_full_nested_name().get_id(version) # ty: ignore[unresolved-attribute] + '__' + self.type.get_id(version) ) - return symbol.get_full_nested_name().get_id(version) + return symbol.get_full_nested_name().get_id(version) # ty: ignore[unresolved-attribute] def _stringify(self, transform: StringifyTransform) -> str: res = [transform(self.type)] @@ -3593,7 +3593,7 @@ def get_id( ) -> str: if version == 1: raise NoOldIdError - return symbol.get_full_nested_name().get_id(version) + return symbol.get_full_nested_name().get_id(version) # ty: ignore[unresolved-attribute] def _stringify(self, transform: StringifyTransform) -> str: res = [transform(self.name)] @@ -3645,7 +3645,7 @@ def get_id( ) -> str: if version == 1: raise NoOldIdError - return symbol.get_full_nested_name().get_id(version) + return symbol.get_full_nested_name().get_id(version) # ty: ignore[unresolved-attribute] def _stringify(self, transform: StringifyTransform) -> str: res = transform(self.nestedName) @@ -4051,7 +4051,7 @@ def get_id( assert version >= 2 if symbol: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=False) + return symbol.parent.declaration.get_id(version, prefixed=False) # ty: ignore[unresolved-attribute] else: return self.data.get_id(version) @@ -4100,7 +4100,7 @@ def get_id( # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=None) + return symbol.parent.declaration.get_id(version, prefixed=None) # ty: ignore[unresolved-attribute] else: return self.nestedParams.get_id(version) + self.data.get_id(version) @@ -4161,7 +4161,7 @@ def get_id( # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=None) + return symbol.parent.declaration.get_id(version, prefixed=None) # ty: ignore[unresolved-attribute] else: res = '_' if self.parameterPack: @@ -4312,7 +4312,7 @@ def get_id( # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent - return symbol.parent.declaration.get_id(version, prefixed=None) + return symbol.parent.declaration.get_id(version, prefixed=None) # ty: ignore[unresolved-attribute] else: if self.parameterPack: return 'Dp' @@ -4584,11 +4584,11 @@ def get_id(self, version: int, prefixed: bool = True) -> str: if self.templatePrefix or self.trailingRequiresClause: raise NoOldIdError if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: - return self.enumeratorScopedSymbol.declaration.get_id(version) + return self.enumeratorScopedSymbol.declaration.get_id(version) # ty: ignore[unresolved-attribute] return self.declaration.get_id(version, self.objectType, self.symbol) # version >= 2 if self.objectType == 'enumerator' and self.enumeratorScopedSymbol: - return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed) + return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed) # ty: ignore[unresolved-attribute] if prefixed: res = [_id_prefix[version]] else: diff --git a/sphinx/domains/cpp/_symbol.py b/sphinx/domains/cpp/_symbol.py index edc7ab6885b..23d353c45c2 100644 --- a/sphinx/domains/cpp/_symbol.py +++ b/sphinx/domains/cpp/_symbol.py @@ -321,7 +321,7 @@ def get_all_symbols(self) -> Iterator[Any]: def children_recurse_anon(self) -> Iterator[Symbol]: for c in self._children: yield c - if not c.identOrOp.is_anon(): + if not c.identOrOp.is_anon(): # ty: ignore[unresolved-attribute] continue yield from c.children_recurse_anon @@ -959,8 +959,8 @@ def merge_with( else: our_object_type = our_child.declaration.objectType other_object_type = other_child.declaration.objectType - our_child_parent_decl = our_child.parent.declaration - other_child_parent_decl = other_child.parent.declaration + our_child_parent_decl = our_child.parent.declaration # ty: ignore[unresolved-attribute] + other_child_parent_decl = other_child.parent.declaration # ty: ignore[unresolved-attribute] if ( other_object_type == our_object_type and other_object_type in {'templateParam', 'functionParam'} diff --git a/sphinx/ext/apidoc/_generate.py b/sphinx/ext/apidoc/_generate.py index 3a0a99e8da0..40d773dec6f 100644 --- a/sphinx/ext/apidoc/_generate.py +++ b/sphinx/ext/apidoc/_generate.py @@ -40,7 +40,7 @@ def is_initpy(filename: str | Path) -> bool: """Check *filename* is __init__ file or not.""" basename = Path(filename).name return any( - basename == '__init__' + suffix + basename == '__init__' + suffix # ty: ignore[unsupported-operator] for suffix in sorted(PY_SUFFIXES, key=len, reverse=True) ) diff --git a/sphinx/ext/autodoc/_dynamic/_member_finder.py b/sphinx/ext/autodoc/_dynamic/_member_finder.py index e9afbf9e9cd..af563b6f6f3 100644 --- a/sphinx/ext/autodoc/_dynamic/_member_finder.py +++ b/sphinx/ext/autodoc/_dynamic/_member_finder.py @@ -241,9 +241,9 @@ def _get_members_to_document( if ( props.obj_type == 'module' and not ignore_module_all - and props.all is not None + and props.all is not None # ty: ignore[unresolved-attribute] ): - wanted_members = frozenset(props.all) + wanted_members = frozenset(props.all) # ty: ignore[unresolved-attribute] else: wanted_members = ALL else: diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index aec02012ddf..dc544c1964f 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -652,21 +652,21 @@ def generate_autosummary_docs( # write for entry in sorted(set(items), key=str): - if entry.path is None: + if entry.path is None: # ty: ignore[unresolved-attribute] # The corresponding autosummary:: directive did not have # a :toctree: option continue - path = output_dir or Path(entry.path).resolve() + path = output_dir or Path(entry.path).resolve() # ty: ignore[unresolved-attribute] ensuredir(path) try: - name, obj, parent, modname = import_by_name(entry.name) + name, obj, parent, modname = import_by_name(entry.name) # ty: ignore[unresolved-attribute] qualname = name.replace(modname + '.', '') except ImportExceptionGroup as exc: try: # try to import as an instance attribute - name, obj, parent, modname = import_ivar_by_name(entry.name) + name, obj, parent, modname = import_ivar_by_name(entry.name) # ty: ignore[unresolved-attribute] qualname = name.replace(modname + '.', '') except ImportError as exc2: if exc2.__cause__: @@ -677,7 +677,7 @@ def generate_autosummary_docs( errors = list({f'* {type(e).__name__}: {e}' for e in exceptions}) logger.warning( __('[autosummary] failed to import %s.\nPossible hints:\n%s'), - entry.name, + entry.name, # ty: ignore[unresolved-attribute] '\n'.join(errors), ) continue @@ -689,9 +689,9 @@ def generate_autosummary_docs( obj, parent, template, - entry.template, + entry.template, # ty: ignore[unresolved-attribute] imported_members, - entry.recursive, + entry.recursive, # ty: ignore[unresolved-attribute] context, modname, qualname, diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 6c866f3db42..c8bbe691873 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -498,10 +498,10 @@ def _consume_field( if prefer_type and not _type: _type, _name = _name, _type - if _type and self._config.napoleon_preprocess_types: + if _type and self._config.napoleon_preprocess_types: # ty: ignore[unresolved-attribute] _type = _convert_type_spec( _type, - translations=self._config.napoleon_type_aliases or {}, + translations=self._config.napoleon_type_aliases or {}, # ty: ignore[unresolved-attribute] debug_location=self._get_location(), ) @@ -549,10 +549,10 @@ def _consume_returns_section( _type = before - if _type and preprocess_types and self._config.napoleon_preprocess_types: + if _type and preprocess_types and self._config.napoleon_preprocess_types: # ty: ignore[unresolved-attribute] _type = _convert_type_spec( _type, - translations=self._config.napoleon_type_aliases or {}, + translations=self._config.napoleon_type_aliases or {}, # ty: ignore[unresolved-attribute] debug_location=self._get_location(), ) @@ -805,8 +805,8 @@ def _is_section_break(self) -> bool: ) def _load_custom_sections(self) -> None: - if self._config.napoleon_custom_sections is not None: - for entry in self._config.napoleon_custom_sections: + if self._config.napoleon_custom_sections is not None: # ty: ignore[unresolved-attribute] + for entry in self._config.napoleon_custom_sections: # ty: ignore[unresolved-attribute] if isinstance(entry, str): # if entry is just a label, add to sections list, # using generic section logic. @@ -876,7 +876,7 @@ def _parse_attributes_section(self, section: str) -> list[str]: for _name, _type, _desc in self._consume_fields(): if not _type: _type = self._lookup_annotation(_name) - if self._config.napoleon_use_ivar: + if self._config.napoleon_use_ivar: # ty: ignore[unresolved-attribute] field = f':ivar {_name}: ' lines.extend(self._format_block(field, _desc)) if _type: @@ -893,7 +893,7 @@ def _parse_attributes_section(self, section: str) -> list[str]: lines.append('') lines.extend(self._indent([f':type: {_type}'], 3)) lines.append('') - if self._config.napoleon_use_ivar: + if self._config.napoleon_use_ivar: # ty: ignore[unresolved-attribute] lines.append('') return lines @@ -902,7 +902,7 @@ def _parse_examples_section(self, section: str) -> list[str]: 'example': _('Example'), 'examples': _('Examples'), } - use_admonition = self._config.napoleon_use_admonition_for_examples + use_admonition = self._config.napoleon_use_admonition_for_examples # ty: ignore[unresolved-attribute] label = labels.get(section.lower(), section) return self._parse_generic_section(label, use_admonition) @@ -939,7 +939,7 @@ def _parse_generic_section(self, section: str, use_admonition: bool) -> list[str def _parse_keyword_arguments_section(self, section: str) -> list[str]: fields = self._consume_fields() - if self._config.napoleon_use_keyword: + if self._config.napoleon_use_keyword: # ty: ignore[unresolved-attribute] return self._format_docutils_params( fields, field_role='keyword', type_role='kwtype' ) @@ -958,11 +958,11 @@ def _parse_methods_section(self, section: str) -> list[str]: return lines def _parse_notes_section(self, section: str) -> list[str]: - use_admonition = self._config.napoleon_use_admonition_for_notes + use_admonition = self._config.napoleon_use_admonition_for_notes # ty: ignore[unresolved-attribute] return self._parse_generic_section(_('Notes'), use_admonition) def _parse_other_parameters_section(self, section: str) -> list[str]: - if self._config.napoleon_use_param: + if self._config.napoleon_use_param: # ty: ignore[unresolved-attribute] # Allow to declare multiple parameters at once (ex: x, y: int) fields = self._consume_fields(multiple=True) return self._format_docutils_params(fields) @@ -971,7 +971,7 @@ def _parse_other_parameters_section(self, section: str) -> list[str]: return self._format_fields(_('Other Parameters'), fields) def _parse_parameters_section(self, section: str) -> list[str]: - if self._config.napoleon_use_param: + if self._config.napoleon_use_param: # ty: ignore[unresolved-attribute] # Allow to declare multiple parameters at once (ex: x, y: int) fields = self._consume_fields(multiple=True) return self._format_docutils_params(fields) @@ -998,7 +998,7 @@ def _parse_raises_section(self, section: str) -> list[str]: return lines def _parse_receives_section(self, section: str) -> list[str]: - if self._config.napoleon_use_param: + if self._config.napoleon_use_param: # ty: ignore[unresolved-attribute] # Allow to declare multiple parameters at once (ex: x, y: int) fields = self._consume_fields(multiple=True) return self._format_docutils_params(fields) @@ -1007,13 +1007,13 @@ def _parse_receives_section(self, section: str) -> list[str]: return self._format_fields(_('Receives'), fields) def _parse_references_section(self, section: str) -> list[str]: - use_admonition = self._config.napoleon_use_admonition_for_references + use_admonition = self._config.napoleon_use_admonition_for_references # ty: ignore[unresolved-attribute] return self._parse_generic_section(_('References'), use_admonition) def _parse_returns_section(self, section: str) -> list[str]: fields = self._consume_returns_section() multi = len(fields) > 1 - use_rtype = False if multi else self._config.napoleon_use_rtype + use_rtype = False if multi else self._config.napoleon_use_rtype # ty: ignore[unresolved-attribute] lines: list[str] = [] for _name, _type, _desc in fields: @@ -1086,7 +1086,7 @@ def _strip_empty(self, lines: list[str]) -> list[str]: return lines def _lookup_annotation(self, _name: str) -> str: - if self._config.napoleon_attr_annotations: + if self._config.napoleon_attr_annotations: # ty: ignore[unresolved-attribute] if self._what in {'module', 'class', 'exception'} and self._obj: # cache the class annotations if not hasattr(self, '_annotations'): @@ -1245,10 +1245,10 @@ def _consume_field( if prefer_type and not _type: _type, _name = _name, _type - if self._config.napoleon_preprocess_types: + if self._config.napoleon_preprocess_types: # ty: ignore[unresolved-attribute] _type = _convert_type_spec( _type, - translations=self._config.napoleon_type_aliases or {}, + translations=self._config.napoleon_type_aliases or {}, # ty: ignore[unresolved-attribute] debug_location=self._get_location(), ) @@ -1367,7 +1367,7 @@ def translate( description: list[str], role: str | None, ) -> tuple[str, list[str], str | None]: - translations = self._config.napoleon_type_aliases + translations = self._config.napoleon_type_aliases # ty: ignore[unresolved-attribute] if role is not None or not translations: return func, description, role diff --git a/sphinx/util/matching.py b/sphinx/util/matching.py index 8b666ea26e1..65cdb3e8471 100644 --- a/sphinx/util/matching.py +++ b/sphinx/util/matching.py @@ -109,7 +109,7 @@ def patfilter(names: Iterable[str], pat: str) -> list[str]: if pat not in _pat_cache: _pat_cache[pat] = re.compile(_translate_pattern(pat)) match = _pat_cache[pat].match - return list(filter(match, names)) + return list(filter(match, names)) # ty: ignore[no-matching-overload] def get_matching_files( diff --git a/tests/test_builders/xpath_util.py b/tests/test_builders/xpath_util.py index 6ea0891478d..0875928cc76 100644 --- a/tests/test_builders/xpath_util.py +++ b/tests/test_builders/xpath_util.py @@ -65,12 +65,12 @@ def check_xpath( return if callable(check): - check(nodes) + check(nodes) # ty: ignore[call-top-callable] return # https://github.com/astral-sh/ty/issues/117 # callable(...) does not currently narrow in ty. - rex = re.compile(check) # ty: ignore[no-matching-overload] + rex = re.compile(check) if be_found: if any(rex.search(_get_text(node)) for node in nodes): return diff --git a/tests/test_ext_intersphinx/test_ext_intersphinx.py b/tests/test_ext_intersphinx/test_ext_intersphinx.py index 5fcfe4d9260..50bc0ae9b19 100644 --- a/tests/test_ext_intersphinx/test_ext_intersphinx.py +++ b/tests/test_ext_intersphinx/test_ext_intersphinx.py @@ -277,12 +277,14 @@ def test_missing_reference_pydomain(tmp_path, app): kwargs = {'py:module': 'module1'} node, contnode = fake_node('py', 'func', 'func', 'func()', **kwargs) rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'func()' # py:attr context helps to search objects kwargs = {'py:module': 'module1'} node, contnode = fake_node('py', 'attr', 'Foo.bar', 'Foo.bar', **kwargs) rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'Foo.bar' @@ -311,32 +313,38 @@ def test_missing_reference_stddomain(tmp_path, app): kwargs = {'std:program': 'ls'} node, contnode = fake_node('std', 'option', '-l', 'ls -l', **kwargs) rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'ls -l' # refers inventory by name kwargs = {} node, contnode = fake_node('std', 'option', 'cmd:ls -l', '-l', **kwargs) rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == '-l' # term reference (normal) node, contnode = fake_node('std', 'term', 'a term', 'a term') rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'a term' # term reference (case insensitive) node, contnode = fake_node('std', 'term', 'A TERM', 'A TERM') rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'A TERM' # label reference (normal) node, contnode = fake_node('std', 'ref', 'The-Julia-Domain', 'The-Julia-Domain') rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'The Julia Domain' # label reference (case insensitive) node, contnode = fake_node('std', 'ref', 'the-julia-domain', 'the-julia-domain') rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'The Julia Domain' @@ -431,6 +439,7 @@ def test_missing_reference_jsdomain(tmp_path, app): kwargs = {'js:module': 'foo', 'js:object': 'bar'} node, contnode = fake_node('js', 'meth', 'baz', 'baz()', **kwargs) rn = missing_reference(app, app.env, node, contnode) + assert rn is not None assert rn.astext() == 'baz()' @@ -801,7 +810,7 @@ def test_intersphinx_cache_limit(app, monkeypatch, cache_limit, expected_expired 'sphinx.ext.intersphinx._load._load_inventory', mock_fetch_inventory ) - for name, (uri, locations) in app.config.intersphinx_mapping.values(): + for name, (uri, locations) in app.config.intersphinx_mapping.values(): # ty: ignore[not-iterable] project = _IntersphinxProject(name=name, target_uri=uri, locations=locations) updated = _fetch_inventory_group( project=project, diff --git a/tests/test_pycode/test_pycode.py b/tests/test_pycode/test_pycode.py index 4caf5019b94..20b7c541a38 100644 --- a/tests/test_pycode/test_pycode.py +++ b/tests/test_pycode/test_pycode.py @@ -16,6 +16,7 @@ def test_ModuleAnalyzer_get_module_source() -> None: + assert sphinx.__spec__ is not None assert isinstance(sphinx.__spec__.loader, SourceFileLoader) # type checking assert ModuleAnalyzer.get_module_source('sphinx') == ( Path(sphinx.__file__), diff --git a/tests/test_util/test_util_inspect.py b/tests/test_util/test_util_inspect.py index 4018a9632a0..57df8247882 100644 --- a/tests/test_util/test_util_inspect.py +++ b/tests/test_util/test_util_inspect.py @@ -119,7 +119,7 @@ def test_TypeAliasForwardRef(): sig_str = stringify_annotation(alias, 'fully-qualified-except-typing') assert sig_str == "TypeAliasForwardRef('example')" - alias = Optional[alias] # NoQA: UP045 + alias = Optional[alias] # NoQA: UP045 # ty: ignore[invalid-type-form] sig_str = stringify_annotation(alias, 'fully-qualified-except-typing') assert sig_str == "TypeAliasForwardRef('example') | None" diff --git a/tests/test_util/test_util_typing.py b/tests/test_util/test_util_typing.py index d5fd2b1092d..ca24b587d45 100644 --- a/tests/test_util/test_util_typing.py +++ b/tests/test_util/test_util_typing.py @@ -706,10 +706,11 @@ def test_stringify_type_hints_pep_585(): # Mix typing and pep 585 ann_str = stringify_annotation( - tuple[List[dict[int, str]], str, ...], 'fully-qualified-except-typing' + tuple[List[dict[int, str]], str, ...], # ty: ignore[invalid-type-form] + 'fully-qualified-except-typing', ) assert ann_str == 'tuple[List[dict[int, str]], str, ...]' - ann_str = stringify_annotation(tuple[List[dict[int, str]], str, ...], 'smart') + ann_str = stringify_annotation(tuple[List[dict[int, str]], str, ...], 'smart') # ty: ignore[invalid-type-form] assert ann_str == 'tuple[~typing.List[dict[int, str]], str, ...]' diff --git a/ty.toml b/ty.toml index 6a5c8bf1fe7..af28eb822db 100644 --- a/ty.toml +++ b/ty.toml @@ -22,5 +22,5 @@ exclude = [ invalid-argument-type = "ignore" invalid-assignment = "ignore" invalid-method-override = "ignore" -non-subscriptable = "ignore" +not-subscriptable = "ignore" possibly-missing-attribute = "ignore" diff --git a/uv.lock b/uv.lock index e0d5c5cc922..de9abb4e0c4 100644 --- a/uv.lock +++ b/uv.lock @@ -567,35 +567,35 @@ wheels = [ [[package]] name = "mypy" -version = "1.19.0" +version = "1.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "librt" }, + { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, { name = "mypy-extensions" }, { name = "pathspec" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/b5/b58cdc25fadd424552804bf410855d52324183112aa004f0732c5f6324cf/mypy-1.19.0.tar.gz", hash = "sha256:f6b874ca77f733222641e5c46e4711648c4037ea13646fd0cdc814c2eaec2528", size = 3579025, upload-time = "2025-11-28T15:49:01.26Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/7e/1afa8fb188b876abeaa14460dc4983f909aaacaa4bf5718c00b2c7e0b3d5/mypy-1.19.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0fb3115cb8fa7c5f887c8a8d81ccdcb94cff334684980d847e5a62e926910e1d", size = 13207728, upload-time = "2025-11-28T15:46:26.463Z" }, - { url = "https://files.pythonhosted.org/packages/b2/13/f103d04962bcbefb1644f5ccb235998b32c337d6c13145ea390b9da47f3e/mypy-1.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3e19e3b897562276bb331074d64c076dbdd3e79213f36eed4e592272dabd760", size = 12202945, upload-time = "2025-11-28T15:48:49.143Z" }, - { url = "https://files.pythonhosted.org/packages/e4/93/a86a5608f74a22284a8ccea8592f6e270b61f95b8588951110ad797c2ddd/mypy-1.19.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9d491295825182fba01b6ffe2c6fe4e5a49dbf4e2bb4d1217b6ced3b4797bc6", size = 12718673, upload-time = "2025-11-28T15:47:37.193Z" }, - { url = "https://files.pythonhosted.org/packages/3d/58/cf08fff9ced0423b858f2a7495001fda28dc058136818ee9dffc31534ea9/mypy-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6016c52ab209919b46169651b362068f632efcd5eb8ef9d1735f6f86da7853b2", size = 13608336, upload-time = "2025-11-28T15:48:32.625Z" }, - { url = "https://files.pythonhosted.org/packages/64/ed/9c509105c5a6d4b73bb08733102a3ea62c25bc02c51bca85e3134bf912d3/mypy-1.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f188dcf16483b3e59f9278c4ed939ec0254aa8a60e8fc100648d9ab5ee95a431", size = 13833174, upload-time = "2025-11-28T15:45:48.091Z" }, - { url = "https://files.pythonhosted.org/packages/cd/71/01939b66e35c6f8cb3e6fdf0b657f0fd24de2f8ba5e523625c8e72328208/mypy-1.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:0e3c3d1e1d62e678c339e7ade72746a9e0325de42cd2cccc51616c7b2ed1a018", size = 10112208, upload-time = "2025-11-28T15:46:41.702Z" }, - { url = "https://files.pythonhosted.org/packages/cb/0d/a1357e6bb49e37ce26fcf7e3cc55679ce9f4ebee0cd8b6ee3a0e301a9210/mypy-1.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7686ed65dbabd24d20066f3115018d2dce030d8fa9db01aa9f0a59b6813e9f9e", size = 13191993, upload-time = "2025-11-28T15:47:22.336Z" }, - { url = "https://files.pythonhosted.org/packages/5d/75/8e5d492a879ec4490e6ba664b5154e48c46c85b5ac9785792a5ec6a4d58f/mypy-1.19.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fd4a985b2e32f23bead72e2fb4bbe5d6aceee176be471243bd831d5b2644672d", size = 12174411, upload-time = "2025-11-28T15:44:55.492Z" }, - { url = "https://files.pythonhosted.org/packages/71/31/ad5dcee9bfe226e8eaba777e9d9d251c292650130f0450a280aec3485370/mypy-1.19.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc51a5b864f73a3a182584b1ac75c404396a17eced54341629d8bdcb644a5bba", size = 12727751, upload-time = "2025-11-28T15:44:14.169Z" }, - { url = "https://files.pythonhosted.org/packages/77/06/b6b8994ce07405f6039701f4b66e9d23f499d0b41c6dd46ec28f96d57ec3/mypy-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37af5166f9475872034b56c5efdcf65ee25394e9e1d172907b84577120714364", size = 13593323, upload-time = "2025-11-28T15:46:34.699Z" }, - { url = "https://files.pythonhosted.org/packages/68/b1/126e274484cccdf099a8e328d4fda1c7bdb98a5e888fa6010b00e1bbf330/mypy-1.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:510c014b722308c9bd377993bcbf9a07d7e0692e5fa8fc70e639c1eb19fc6bee", size = 13818032, upload-time = "2025-11-28T15:46:18.286Z" }, - { url = "https://files.pythonhosted.org/packages/f8/56/53a8f70f562dfc466c766469133a8a4909f6c0012d83993143f2a9d48d2d/mypy-1.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:cabbee74f29aa9cd3b444ec2f1e4fa5a9d0d746ce7567a6a609e224429781f53", size = 10120644, upload-time = "2025-11-28T15:47:43.99Z" }, - { url = "https://files.pythonhosted.org/packages/b0/f4/7751f32f56916f7f8c229fe902cbdba3e4dd3f3ea9e8b872be97e7fc546d/mypy-1.19.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f2e36bed3c6d9b5f35d28b63ca4b727cb0228e480826ffc8953d1892ddc8999d", size = 13185236, upload-time = "2025-11-28T15:45:20.696Z" }, - { url = "https://files.pythonhosted.org/packages/35/31/871a9531f09e78e8d145032355890384f8a5b38c95a2c7732d226b93242e/mypy-1.19.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a18d8abdda14035c5718acb748faec09571432811af129bf0d9e7b2d6699bf18", size = 12213902, upload-time = "2025-11-28T15:46:10.117Z" }, - { url = "https://files.pythonhosted.org/packages/58/b8/af221910dd40eeefa2077a59107e611550167b9994693fc5926a0b0f87c0/mypy-1.19.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75e60aca3723a23511948539b0d7ed514dda194bc3755eae0bfc7a6b4887aa7", size = 12738600, upload-time = "2025-11-28T15:44:22.521Z" }, - { url = "https://files.pythonhosted.org/packages/11/9f/c39e89a3e319c1d9c734dedec1183b2cc3aefbab066ec611619002abb932/mypy-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f44f2ae3c58421ee05fe609160343c25f70e3967f6e32792b5a78006a9d850f", size = 13592639, upload-time = "2025-11-28T15:48:08.55Z" }, - { url = "https://files.pythonhosted.org/packages/97/6d/ffaf5f01f5e284d9033de1267e6c1b8f3783f2cf784465378a86122e884b/mypy-1.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:63ea6a00e4bd6822adbfc75b02ab3653a17c02c4347f5bb0cf1d5b9df3a05835", size = 13799132, upload-time = "2025-11-28T15:47:06.032Z" }, - { url = "https://files.pythonhosted.org/packages/fe/b0/c33921e73aaa0106224e5a34822411bea38046188eb781637f5a5b07e269/mypy-1.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:3ad925b14a0bb99821ff6f734553294aa6a3440a8cb082fe1f5b84dfb662afb1", size = 10269832, upload-time = "2025-11-28T15:47:29.392Z" }, - { url = "https://files.pythonhosted.org/packages/09/0e/fe228ed5aeab470c6f4eb82481837fadb642a5aa95cc8215fd2214822c10/mypy-1.19.0-py3-none-any.whl", hash = "sha256:0c01c99d626380752e527d5ce8e69ffbba2046eb8a060db0329690849cf9b6f9", size = 2469714, upload-time = "2025-11-28T15:45:33.22Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/8a/19bfae96f6615aa8a0604915512e0289b1fad33d5909bf7244f02935d33a/mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1", size = 13206053, upload-time = "2025-12-15T05:03:46.622Z" }, + { url = "https://files.pythonhosted.org/packages/a5/34/3e63879ab041602154ba2a9f99817bb0c85c4df19a23a1443c8986e4d565/mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e", size = 12219134, upload-time = "2025-12-15T05:03:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/89/cc/2db6f0e95366b630364e09845672dbee0cbf0bbe753a204b29a944967cd9/mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2", size = 12731616, upload-time = "2025-12-15T05:02:44.725Z" }, + { url = "https://files.pythonhosted.org/packages/00/be/dd56c1fd4807bc1eba1cf18b2a850d0de7bacb55e158755eb79f77c41f8e/mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8", size = 13620847, upload-time = "2025-12-15T05:03:39.633Z" }, + { url = "https://files.pythonhosted.org/packages/6d/42/332951aae42b79329f743bf1da088cd75d8d4d9acc18fbcbd84f26c1af4e/mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a", size = 13834976, upload-time = "2025-12-15T05:03:08.786Z" }, + { url = "https://files.pythonhosted.org/packages/6f/63/e7493e5f90e1e085c562bb06e2eb32cae27c5057b9653348d38b47daaecc/mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13", size = 10118104, upload-time = "2025-12-15T05:03:10.834Z" }, + { url = "https://files.pythonhosted.org/packages/de/9f/a6abae693f7a0c697dbb435aac52e958dc8da44e92e08ba88d2e42326176/mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250", size = 13201927, upload-time = "2025-12-15T05:02:29.138Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a4/45c35ccf6e1c65afc23a069f50e2c66f46bd3798cbe0d680c12d12935caa/mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b", size = 12206730, upload-time = "2025-12-15T05:03:01.325Z" }, + { url = "https://files.pythonhosted.org/packages/05/bb/cdcf89678e26b187650512620eec8368fded4cfd99cfcb431e4cdfd19dec/mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e", size = 12724581, upload-time = "2025-12-15T05:03:20.087Z" }, + { url = "https://files.pythonhosted.org/packages/d1/32/dd260d52babf67bad8e6770f8e1102021877ce0edea106e72df5626bb0ec/mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef", size = 13616252, upload-time = "2025-12-15T05:02:49.036Z" }, + { url = "https://files.pythonhosted.org/packages/71/d0/5e60a9d2e3bd48432ae2b454b7ef2b62a960ab51292b1eda2a95edd78198/mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75", size = 13840848, upload-time = "2025-12-15T05:02:55.95Z" }, + { url = "https://files.pythonhosted.org/packages/98/76/d32051fa65ecf6cc8c6610956473abdc9b4c43301107476ac03559507843/mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd", size = 10135510, upload-time = "2025-12-15T05:02:58.438Z" }, + { url = "https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1", size = 13199744, upload-time = "2025-12-15T05:03:30.823Z" }, + { url = "https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718", size = 12215815, upload-time = "2025-12-15T05:02:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/0a/c6/bdd60774a0dbfb05122e3e925f2e9e846c009e479dcec4821dad881f5b52/mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b", size = 12740047, upload-time = "2025-12-15T05:03:33.168Z" }, + { url = "https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045", size = 13601998, upload-time = "2025-12-15T05:03:13.056Z" }, + { url = "https://files.pythonhosted.org/packages/e3/da/5055c63e377c5c2418760411fd6a63ee2b96cf95397259038756c042574f/mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957", size = 13807476, upload-time = "2025-12-15T05:03:17.977Z" }, + { url = "https://files.pythonhosted.org/packages/cd/09/4ebd873390a063176f06b0dbf1f7783dd87bd120eae7727fa4ae4179b685/mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f", size = 10281872, upload-time = "2025-12-15T05:03:05.549Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f4/4ce9a05ce5ded1de3ec1c1d96cf9f9504a04e54ce0ed55cfa38619a32b8d/mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247", size = 2471239, upload-time = "2025-12-15T05:03:07.248Z" }, ] [[package]] @@ -1144,28 +1144,28 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b7/5b/dd7406afa6c95e3d8fa9d652b6d6dd17dd4a6bf63cb477014e8ccd3dcd46/ruff-0.14.7.tar.gz", hash = "sha256:3417deb75d23bd14a722b57b0a1435561db65f0ad97435b4cf9f85ffcef34ae5", size = 5727324, upload-time = "2025-11-28T20:55:10.525Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/b1/7ea5647aaf90106f6d102230e5df874613da43d1089864da1553b899ba5e/ruff-0.14.7-py3-none-linux_armv6l.whl", hash = "sha256:b9d5cb5a176c7236892ad7224bc1e63902e4842c460a0b5210701b13e3de4fca", size = 13414475, upload-time = "2025-11-28T20:54:54.569Z" }, - { url = "https://files.pythonhosted.org/packages/af/19/fddb4cd532299db9cdaf0efdc20f5c573ce9952a11cb532d3b859d6d9871/ruff-0.14.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3f64fe375aefaf36ca7d7250292141e39b4cea8250427482ae779a2aa5d90015", size = 13634613, upload-time = "2025-11-28T20:55:17.54Z" }, - { url = "https://files.pythonhosted.org/packages/40/2b/469a66e821d4f3de0440676ed3e04b8e2a1dc7575cf6fa3ba6d55e3c8557/ruff-0.14.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:93e83bd3a9e1a3bda64cb771c0d47cda0e0d148165013ae2d3554d718632d554", size = 12765458, upload-time = "2025-11-28T20:55:26.128Z" }, - { url = "https://files.pythonhosted.org/packages/f1/05/0b001f734fe550bcfde4ce845948ac620ff908ab7241a39a1b39bb3c5f49/ruff-0.14.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3838948e3facc59a6070795de2ae16e5786861850f78d5914a03f12659e88f94", size = 13236412, upload-time = "2025-11-28T20:55:28.602Z" }, - { url = "https://files.pythonhosted.org/packages/11/36/8ed15d243f011b4e5da75cd56d6131c6766f55334d14ba31cce5461f28aa/ruff-0.14.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24c8487194d38b6d71cd0fd17a5b6715cda29f59baca1defe1e3a03240f851d1", size = 13182949, upload-time = "2025-11-28T20:55:33.265Z" }, - { url = "https://files.pythonhosted.org/packages/3b/cf/fcb0b5a195455729834f2a6eadfe2e4519d8ca08c74f6d2b564a4f18f553/ruff-0.14.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79c73db6833f058a4be8ffe4a0913b6d4ad41f6324745179bd2aa09275b01d0b", size = 13816470, upload-time = "2025-11-28T20:55:08.203Z" }, - { url = "https://files.pythonhosted.org/packages/7f/5d/34a4748577ff7a5ed2f2471456740f02e86d1568a18c9faccfc73bd9ca3f/ruff-0.14.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:12eb7014fccff10fc62d15c79d8a6be4d0c2d60fe3f8e4d169a0d2def75f5dad", size = 15289621, upload-time = "2025-11-28T20:55:30.837Z" }, - { url = "https://files.pythonhosted.org/packages/53/53/0a9385f047a858ba133d96f3f8e3c9c66a31cc7c4b445368ef88ebeac209/ruff-0.14.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c623bbdc902de7ff715a93fa3bb377a4e42dd696937bf95669118773dbf0c50", size = 14975817, upload-time = "2025-11-28T20:55:24.107Z" }, - { url = "https://files.pythonhosted.org/packages/a8/d7/2f1c32af54c3b46e7fadbf8006d8b9bcfbea535c316b0bd8813d6fb25e5d/ruff-0.14.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f53accc02ed2d200fa621593cdb3c1ae06aa9b2c3cae70bc96f72f0000ae97a9", size = 14284549, upload-time = "2025-11-28T20:55:06.08Z" }, - { url = "https://files.pythonhosted.org/packages/92/05/434ddd86becd64629c25fb6b4ce7637dd52a45cc4a4415a3008fe61c27b9/ruff-0.14.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:281f0e61a23fcdcffca210591f0f53aafaa15f9025b5b3f9706879aaa8683bc4", size = 14071389, upload-time = "2025-11-28T20:55:35.617Z" }, - { url = "https://files.pythonhosted.org/packages/ff/50/fdf89d4d80f7f9d4f420d26089a79b3bb1538fe44586b148451bc2ba8d9c/ruff-0.14.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:dbbaa5e14148965b91cb090236931182ee522a5fac9bc5575bafc5c07b9f9682", size = 14202679, upload-time = "2025-11-28T20:55:01.472Z" }, - { url = "https://files.pythonhosted.org/packages/77/54/87b34988984555425ce967f08a36df0ebd339bb5d9d0e92a47e41151eafc/ruff-0.14.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1464b6e54880c0fe2f2d6eaefb6db15373331414eddf89d6b903767ae2458143", size = 13147677, upload-time = "2025-11-28T20:55:19.933Z" }, - { url = "https://files.pythonhosted.org/packages/67/29/f55e4d44edfe053918a16a3299e758e1c18eef216b7a7092550d7a9ec51c/ruff-0.14.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f217ed871e4621ea6128460df57b19ce0580606c23aeab50f5de425d05226784", size = 13151392, upload-time = "2025-11-28T20:55:21.967Z" }, - { url = "https://files.pythonhosted.org/packages/36/69/47aae6dbd4f1d9b4f7085f4d9dcc84e04561ee7ad067bf52e0f9b02e3209/ruff-0.14.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6be02e849440ed3602d2eb478ff7ff07d53e3758f7948a2a598829660988619e", size = 13412230, upload-time = "2025-11-28T20:55:12.749Z" }, - { url = "https://files.pythonhosted.org/packages/b7/4b/6e96cb6ba297f2ba502a231cd732ed7c3de98b1a896671b932a5eefa3804/ruff-0.14.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19a0f116ee5e2b468dfe80c41c84e2bbd6b74f7b719bee86c2ecde0a34563bcc", size = 14195397, upload-time = "2025-11-28T20:54:56.896Z" }, - { url = "https://files.pythonhosted.org/packages/69/82/251d5f1aa4dcad30aed491b4657cecd9fb4274214da6960ffec144c260f7/ruff-0.14.7-py3-none-win32.whl", hash = "sha256:e33052c9199b347c8937937163b9b149ef6ab2e4bb37b042e593da2e6f6cccfa", size = 13126751, upload-time = "2025-11-28T20:55:03.47Z" }, - { url = "https://files.pythonhosted.org/packages/a8/b5/d0b7d145963136b564806f6584647af45ab98946660d399ec4da79cae036/ruff-0.14.7-py3-none-win_amd64.whl", hash = "sha256:e17a20ad0d3fad47a326d773a042b924d3ac31c6ca6deb6c72e9e6b5f661a7c6", size = 14531726, upload-time = "2025-11-28T20:54:59.121Z" }, - { url = "https://files.pythonhosted.org/packages/1d/d2/1637f4360ada6a368d3265bf39f2cf737a0aaab15ab520fc005903e883f8/ruff-0.14.7-py3-none-win_arm64.whl", hash = "sha256:be4d653d3bea1b19742fcc6502354e32f65cd61ff2fbdb365803ef2c2aec6228", size = 13609215, upload-time = "2025-11-28T20:55:15.375Z" }, +version = "0.14.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/1b/ab712a9d5044435be8e9a2beb17cbfa4c241aa9b5e4413febac2a8b79ef2/ruff-0.14.9.tar.gz", hash = "sha256:35f85b25dd586381c0cc053f48826109384c81c00ad7ef1bd977bfcc28119d5b", size = 5809165, upload-time = "2025-12-11T21:39:47.381Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/1c/d1b1bba22cffec02351c78ab9ed4f7d7391876e12720298448b29b7229c1/ruff-0.14.9-py3-none-linux_armv6l.whl", hash = "sha256:f1ec5de1ce150ca6e43691f4a9ef5c04574ad9ca35c8b3b0e18877314aba7e75", size = 13576541, upload-time = "2025-12-11T21:39:14.806Z" }, + { url = "https://files.pythonhosted.org/packages/94/ab/ffe580e6ea1fca67f6337b0af59fc7e683344a43642d2d55d251ff83ceae/ruff-0.14.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ed9d7417a299fc6030b4f26333bf1117ed82a61ea91238558c0268c14e00d0c2", size = 13779363, upload-time = "2025-12-11T21:39:20.29Z" }, + { url = "https://files.pythonhosted.org/packages/7d/f8/2be49047f929d6965401855461e697ab185e1a6a683d914c5c19c7962d9e/ruff-0.14.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d5dc3473c3f0e4a1008d0ef1d75cee24a48e254c8bed3a7afdd2b4392657ed2c", size = 12925292, upload-time = "2025-12-11T21:39:38.757Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e9/08840ff5127916bb989c86f18924fd568938b06f58b60e206176f327c0fe/ruff-0.14.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84bf7c698fc8f3cb8278830fb6b5a47f9bcc1ed8cb4f689b9dd02698fa840697", size = 13362894, upload-time = "2025-12-11T21:39:02.524Z" }, + { url = "https://files.pythonhosted.org/packages/31/1c/5b4e8e7750613ef43390bb58658eaf1d862c0cc3352d139cd718a2cea164/ruff-0.14.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa733093d1f9d88a5d98988d8834ef5d6f9828d03743bf5e338bf980a19fce27", size = 13311482, upload-time = "2025-12-11T21:39:17.51Z" }, + { url = "https://files.pythonhosted.org/packages/5b/3a/459dce7a8cb35ba1ea3e9c88f19077667a7977234f3b5ab197fad240b404/ruff-0.14.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a1cfb04eda979b20c8c19550c8b5f498df64ff8da151283311ce3199e8b3648", size = 14016100, upload-time = "2025-12-11T21:39:41.948Z" }, + { url = "https://files.pythonhosted.org/packages/a6/31/f064f4ec32524f9956a0890fc6a944e5cf06c63c554e39957d208c0ffc45/ruff-0.14.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1e5cb521e5ccf0008bd74d5595a4580313844a42b9103b7388eca5a12c970743", size = 15477729, upload-time = "2025-12-11T21:39:23.279Z" }, + { url = "https://files.pythonhosted.org/packages/7a/6d/f364252aad36ccd443494bc5f02e41bf677f964b58902a17c0b16c53d890/ruff-0.14.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd429a8926be6bba4befa8cdcf3f4dd2591c413ea5066b1e99155ed245ae42bb", size = 15122386, upload-time = "2025-12-11T21:39:33.125Z" }, + { url = "https://files.pythonhosted.org/packages/20/02/e848787912d16209aba2799a4d5a1775660b6a3d0ab3944a4ccc13e64a02/ruff-0.14.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab208c1b7a492e37caeaf290b1378148f75e13c2225af5d44628b95fd7834273", size = 14497124, upload-time = "2025-12-11T21:38:59.33Z" }, + { url = "https://files.pythonhosted.org/packages/f3/51/0489a6a5595b7760b5dbac0dd82852b510326e7d88d51dbffcd2e07e3ff3/ruff-0.14.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72034534e5b11e8a593f517b2f2f2b273eb68a30978c6a2d40473ad0aaa4cb4a", size = 14195343, upload-time = "2025-12-11T21:39:44.866Z" }, + { url = "https://files.pythonhosted.org/packages/f6/53/3bb8d2fa73e4c2f80acc65213ee0830fa0c49c6479313f7a68a00f39e208/ruff-0.14.9-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:712ff04f44663f1b90a1195f51525836e3413c8a773574a7b7775554269c30ed", size = 14346425, upload-time = "2025-12-11T21:39:05.927Z" }, + { url = "https://files.pythonhosted.org/packages/ad/04/bdb1d0ab876372da3e983896481760867fc84f969c5c09d428e8f01b557f/ruff-0.14.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a111fee1db6f1d5d5810245295527cda1d367c5aa8f42e0fca9a78ede9b4498b", size = 13258768, upload-time = "2025-12-11T21:39:08.691Z" }, + { url = "https://files.pythonhosted.org/packages/40/d9/8bf8e1e41a311afd2abc8ad12be1b6c6c8b925506d9069b67bb5e9a04af3/ruff-0.14.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8769efc71558fecc25eb295ddec7d1030d41a51e9dcf127cbd63ec517f22d567", size = 13326939, upload-time = "2025-12-11T21:39:53.842Z" }, + { url = "https://files.pythonhosted.org/packages/f4/56/a213fa9edb6dd849f1cfbc236206ead10913693c72a67fb7ddc1833bf95d/ruff-0.14.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:347e3bf16197e8a2de17940cd75fd6491e25c0aa7edf7d61aa03f146a1aa885a", size = 13578888, upload-time = "2025-12-11T21:39:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/33/09/6a4a67ffa4abae6bf44c972a4521337ffce9cbc7808faadede754ef7a79c/ruff-0.14.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7715d14e5bccf5b660f54516558aa94781d3eb0838f8e706fb60e3ff6eff03a8", size = 14314473, upload-time = "2025-12-11T21:39:50.78Z" }, + { url = "https://files.pythonhosted.org/packages/12/0d/15cc82da5d83f27a3c6b04f3a232d61bc8c50d38a6cd8da79228e5f8b8d6/ruff-0.14.9-py3-none-win32.whl", hash = "sha256:df0937f30aaabe83da172adaf8937003ff28172f59ca9f17883b4213783df197", size = 13202651, upload-time = "2025-12-11T21:39:26.628Z" }, + { url = "https://files.pythonhosted.org/packages/32/f7/c78b060388eefe0304d9d42e68fab8cffd049128ec466456cef9b8d4f06f/ruff-0.14.9-py3-none-win_amd64.whl", hash = "sha256:c0b53a10e61df15a42ed711ec0bda0c582039cf6c754c49c020084c55b5b0bc2", size = 14702079, upload-time = "2025-12-11T21:39:11.954Z" }, + { url = "https://files.pythonhosted.org/packages/26/09/7a9520315decd2334afa65ed258fed438f070e31f05a2e43dd480a5e5911/ruff-0.14.9-py3-none-win_arm64.whl", hash = "sha256:8e821c366517a074046d92f0e9213ed1c13dbc5b37a7fc20b07f79b64d62cc84", size = 13744730, upload-time = "2025-12-11T21:39:29.659Z" }, ] [[package]] @@ -1353,7 +1353,7 @@ requires-dist = [ [package.metadata.requires-dev] docs = [{ name = "sphinxcontrib-websupport" }] lint = [ - { name = "ruff", specifier = "==0.14.7" }, + { name = "ruff", specifier = "==0.14.9" }, { name = "sphinx-lint", specifier = ">=0.9" }, ] package = [ @@ -1376,20 +1376,20 @@ translations = [ type-stubs = [ { name = "types-colorama", specifier = "==0.4.15.20250801" }, { name = "types-defusedxml", specifier = "==0.7.0.20250822" }, - { name = "types-docutils", specifier = "==0.22.3.20251115" }, + { name = "types-docutils", specifier = "==0.22.3.20260223" }, { name = "types-pillow", specifier = "==10.2.0.20240822" }, { name = "types-pygments", specifier = "==2.19.0.20251121" }, { name = "types-requests", specifier = "==2.32.4.20250913" }, { name = "types-urllib3", specifier = "==1.26.25.14" }, ] types = [ - { name = "mypy", specifier = "==1.19.0" }, + { name = "mypy", specifier = "==1.19.1" }, { name = "pyrefly" }, { name = "pyright", specifier = "==1.1.407" }, { name = "ty" }, { name = "types-colorama", specifier = "==0.4.15.20250801" }, { name = "types-defusedxml", specifier = "==0.7.0.20250822" }, - { name = "types-docutils", specifier = "==0.22.3.20251115" }, + { name = "types-docutils", specifier = "==0.22.3.20260223" }, { name = "types-pillow", specifier = "==10.2.0.20240822" }, { name = "types-pygments", specifier = "==2.19.0.20251121" }, { name = "types-requests", specifier = "==2.32.4.20250913" }, @@ -1555,11 +1555,11 @@ wheels = [ [[package]] name = "types-docutils" -version = "0.22.3.20251115" +version = "0.22.3.20260223" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/d7/576ec24bf61a280f571e1f22284793adc321610b9bcfba1bf468cf7b334f/types_docutils-0.22.3.20251115.tar.gz", hash = "sha256:0f79ea6a7bd4d12d56c9f824a0090ffae0ea4204203eb0006392906850913e16", size = 56828, upload-time = "2025-11-15T02:59:57.371Z" } +sdist = { url = "https://files.pythonhosted.org/packages/80/33/92c0129283363e3b3ba270bf6a2b7d077d949d2f90afc4abaf6e73578563/types_docutils-0.22.3.20260223.tar.gz", hash = "sha256:e90e868da82df615ea2217cf36dff31f09660daa15fc0f956af53f89c1364501", size = 57230, upload-time = "2026-02-23T04:11:21.806Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/01/61ac9eb38f1f978b47443dc6fd2e0a3b0f647c2da741ddad30771f1b2b6f/types_docutils-0.22.3.20251115-py3-none-any.whl", hash = "sha256:c6e53715b65395d00a75a3a8a74e352c669bc63959e65a207dffaa22f4a2ad6e", size = 91951, upload-time = "2025-11-15T02:59:56.413Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c7/a4ae6a75d5b07d63089d5c04d450a0de4a5d48ffcb84b95659b22d3885fe/types_docutils-0.22.3.20260223-py3-none-any.whl", hash = "sha256:cc2d6b7560a28e351903db0989091474aa619ad287843a018324baee9c4d9a8f", size = 91969, upload-time = "2026-02-23T04:11:20.966Z" }, ] [[package]] From ce41d520114bce755e876fc25c5efd9503a62b1d Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Sun, 1 Mar 2026 06:49:08 +0000 Subject: [PATCH 2/2] Fix ruff E501: shorten long line in c/_parser.py Remove redundant inline comment from line 153 to bring it within the 95-character line length limit. Co-Authored-By: Claude Sonnet 4.6 --- sphinx/domains/c/_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/domains/c/_parser.py b/sphinx/domains/c/_parser.py index 9d9c13e4a11..3e74b0d80d7 100644 --- a/sphinx/domains/c/_parser.py +++ b/sphinx/domains/c/_parser.py @@ -150,7 +150,7 @@ def _parse_literal(self) -> ASTLiteral | None: # character-literal if self.match(char_literal_re): - prefix = self.last_match.group(1) # may be None when no prefix # ty: ignore[unresolved-attribute] + prefix = self.last_match.group(1) # ty: ignore[unresolved-attribute] data = self.last_match.group(2) # ty: ignore[unresolved-attribute] try: return ASTCharLiteral(prefix, data)