Fix EM10{1,2} (exception must not use a string)

This commit is contained in:
Adam Turner 2023-08-13 20:07:28 +01:00 committed by Adam Turner
parent ae0d97bb26
commit d80eab689d
48 changed files with 179 additions and 112 deletions

View File

@ -170,9 +170,6 @@ ignore = [
"D", "D",
# flake8-django # flake8-django
"DJ", # Django is not used in Sphinx "DJ", # Django is not used in Sphinx
# flake8-errmsg
"EM101", # exception must not use a string literal, assign to variable first
"EM102", # exception must not use an f-string literal, assign to variable first
# eradicate # eradicate
"ERA001", # found commented-out code "ERA001", # found commented-out code
# flake8-executable # flake8-executable

View File

@ -21,7 +21,8 @@ _DEPRECATED_OBJECTS = {
def __getattr__(name): def __getattr__(name):
if name not in _DEPRECATED_OBJECTS: if name not in _DEPRECATED_OBJECTS:
raise AttributeError(f'module {__name__!r} has no attribute {name!r}') msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning

View File

@ -423,7 +423,8 @@ class Sphinx:
else: else:
major, minor = map(int, version.split('.')[:2]) major, minor = map(int, version.split('.')[:2])
if (major, minor) > sphinx.version_info[:2]: if (major, minor) > sphinx.version_info[:2]:
raise VersionRequirementError(f'{major}.{minor}') req = f'{major}.{minor}'
raise VersionRequirementError(req)
# event interface # event interface
def connect(self, event: str, callback: Callable, priority: int = 500) -> int: def connect(self, event: str, callback: Callable, priority: int = 500) -> int:
@ -1336,7 +1337,8 @@ class TemplateBridge:
*theme* is a :class:`sphinx.theming.Theme` object or None; in the latter *theme* is a :class:`sphinx.theming.Theme` object or None; in the latter
case, *dirs* can be list of fixed directories to look for templates. case, *dirs* can be list of fixed directories to look for templates.
""" """
raise NotImplementedError('must be implemented in subclasses') msg = 'must be implemented in subclasses'
raise NotImplementedError(msg)
def newest_template_mtime(self) -> float: def newest_template_mtime(self) -> float:
"""Called by the builder to determine if output files are outdated """Called by the builder to determine if output files are outdated
@ -1349,10 +1351,12 @@ class TemplateBridge:
"""Called by the builder to render a template given as a filename with """Called by the builder to render a template given as a filename with
a specified context (a Python dictionary). a specified context (a Python dictionary).
""" """
raise NotImplementedError('must be implemented in subclasses') msg = 'must be implemented in subclasses'
raise NotImplementedError(msg)
def render_string(self, template: str, context: dict) -> str: def render_string(self, template: str, context: dict) -> str:
"""Called by the builder to render a template given as a string with a """Called by the builder to render a template given as a string with a
specified context (a Python dictionary). specified context (a Python dictionary).
""" """
raise NotImplementedError('must be implemented in subclasses') msg = 'must be implemented in subclasses'
raise NotImplementedError(msg)

View File

@ -162,7 +162,8 @@ class Epub3Builder(_epub_base.EpubBuilder):
navstack[-1].children.append(navpoint) navstack[-1].children.append(navpoint)
navstack.append(navpoint) navstack.append(navpoint)
else: else:
raise RuntimeError('Should never reach here. It might be a bug.') unreachable = 'Should never reach here. It might be a bug.'
raise RuntimeError(unreachable)
return navstack[0].children return navstack[0].children

View File

@ -245,7 +245,8 @@ class MessageCatalogBuilder(I18nBuilder):
origin = MsgOrigin(template, line) origin = MsgOrigin(template, line)
self.catalogs['sphinx'].add(msg, origin) self.catalogs['sphinx'].add(msg, origin)
except Exception as exc: except Exception as exc:
raise ThemeError(f'{template}: {exc!r}') from exc msg = f'{template}: {exc!r}'
raise ThemeError(msg) from exc
def build( def build(
self, self,

View File

@ -1381,7 +1381,8 @@ _DEPRECATED_OBJECTS = {
def __getattr__(name): def __getattr__(name):
if name not in _DEPRECATED_OBJECTS: if name not in _DEPRECATED_OBJECTS:
raise AttributeError(f'module {__name__!r} has no attribute {name!r}') msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning

View File

@ -44,10 +44,12 @@ class _CascadingStyleSheet:
return hash((self.filename, self.priority, *sorted(self.attributes.items()))) return hash((self.filename, self.priority, *sorted(self.attributes.items())))
def __setattr__(self, key, value): def __setattr__(self, key, value):
raise AttributeError(f'{self.__class__.__name__} is immutable') msg = f'{self.__class__.__name__} is immutable'
raise AttributeError(msg)
def __delattr__(self, key): def __delattr__(self, key):
raise AttributeError(f'{self.__class__.__name__} is immutable') msg = f'{self.__class__.__name__} is immutable'
raise AttributeError(msg)
class _JavaScript: class _JavaScript:
@ -84,10 +86,12 @@ class _JavaScript:
return hash((self.filename, self.priority, *sorted(self.attributes.items()))) return hash((self.filename, self.priority, *sorted(self.attributes.items())))
def __setattr__(self, key, value): def __setattr__(self, key, value):
raise AttributeError(f'{self.__class__.__name__} is immutable') msg = f'{self.__class__.__name__} is immutable'
raise AttributeError(msg)
def __delattr__(self, key): def __delattr__(self, key):
raise AttributeError(f'{self.__class__.__name__} is immutable') msg = f'{self.__class__.__name__} is immutable'
raise AttributeError(msg)
def _file_checksum(outdir: Path, filename: str | os.PathLike[str]) -> str: def _file_checksum(outdir: Path, filename: str | os.PathLike[str]) -> str:

View File

@ -37,7 +37,8 @@ def _deprecation_warning(
def __getattr__(name): def __getattr__(name):
if name not in _DEPRECATED_OBJECTS: if name not in _DEPRECATED_OBJECTS:
raise AttributeError(f'module {__name__!r} has no attribute {name!r}') msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning
@ -51,7 +52,8 @@ def _deprecation_warning(
elif remove == (9, 0): elif remove == (9, 0):
warning_class = RemovedInSphinx90Warning warning_class = RemovedInSphinx90Warning
else: else:
raise RuntimeError(f'removal version {remove!r} is invalid!') msg = f'removal version {remove!r} is invalid!'
raise RuntimeError(msg)
qualified_name = f'{module}.{attribute}' qualified_name = f'{module}.{attribute}'
if canonical_name: if canonical_name:

View File

@ -35,7 +35,8 @@ def optional_int(argument: str) -> int | None:
else: else:
value = int(argument) value = int(argument)
if value < 0: if value < 0:
raise ValueError('negative value; must be positive or zero') msg = 'negative value; must be positive or zero'
raise ValueError(msg)
return value return value

View File

@ -214,11 +214,13 @@ class ASTNestedName(ASTBase):
# just print the name part, with template args, not template params # just print the name part, with template args, not template params
if mode == 'noneIsName': if mode == 'noneIsName':
if self.rooted: if self.rooted:
raise AssertionError("Can this happen?") # TODO unreachable = "Can this happen?"
raise AssertionError(unreachable) # TODO
signode += nodes.Text('.') signode += nodes.Text('.')
for i in range(len(self.names)): for i in range(len(self.names)):
if i != 0: if i != 0:
raise AssertionError("Can this happen?") # TODO unreachable = "Can this happen?"
raise AssertionError(unreachable) # TODO
signode += nodes.Text('.') signode += nodes.Text('.')
n = self.names[i] n = self.names[i]
n.describe_signature(signode, mode, env, '', symbol) n.describe_signature(signode, mode, env, '', symbol)

View File

@ -775,15 +775,18 @@ class ASTNestedName(ASTBase):
# just print the name part, with template args, not template params # just print the name part, with template args, not template params
if mode == 'noneIsName': if mode == 'noneIsName':
if self.rooted: if self.rooted:
raise AssertionError("Can this happen?") # TODO unreachable = "Can this happen?"
raise AssertionError(unreachable) # TODO
signode += nodes.Text('::') signode += nodes.Text('::')
for i in range(len(self.names)): for i in range(len(self.names)):
if i != 0: if i != 0:
raise AssertionError("Can this happen?") # TODO unreachable = "Can this happen?"
raise AssertionError(unreachable) # TODO
signode += nodes.Text('::blah') signode += nodes.Text('::blah')
n = self.names[i] n = self.names[i]
if self.templates[i]: if self.templates[i]:
raise AssertionError("Can this happen?") # TODO unreachable = "Can this happen?"
raise AssertionError(unreachable) # TODO
signode += nodes.Text("template") signode += nodes.Text("template")
signode += nodes.Text(" ") signode += nodes.Text(" ")
n.describe_signature(signode, mode, env, '', symbol) n.describe_signature(signode, mode, env, '', symbol)
@ -6120,7 +6123,8 @@ class DefinitionParser(BaseParser):
if modifier is not None: if modifier is not None:
self.fail(f"Can not have {modifier} without a floating point type.") self.fail(f"Can not have {modifier} without a floating point type.")
else: else:
raise AssertionError(f"Unhandled type {typ}") msg = f'Unhandled type {typ}'
raise AssertionError(msg)
canonNames: list[str] = [] canonNames: list[str] = []
if modifier is not None: if modifier is not None:

View File

@ -310,8 +310,9 @@ class _TypeParameterListParser(TokenProcessor):
tp_default = self._build_identifier(tokens) tp_default = self._build_identifier(tokens)
if tp_kind != Parameter.POSITIONAL_OR_KEYWORD and tp_ann != Parameter.empty: if tp_kind != Parameter.POSITIONAL_OR_KEYWORD and tp_ann != Parameter.empty:
raise SyntaxError('type parameter bound or constraint is not allowed ' msg = ('type parameter bound or constraint is not allowed '
f'for {tp_kind.description} parameters') f'for {tp_kind.description} parameters')
raise SyntaxError(msg)
type_param = (tp_name, tp_kind, tp_default, tp_ann) type_param = (tp_name, tp_kind, tp_default, tp_ann)
self.type_params.append(type_param) self.type_params.append(type_param)
@ -408,8 +409,9 @@ def _parse_type_list(
for (tp_name, tp_kind, tp_default, tp_ann) in parser.type_params: for (tp_name, tp_kind, tp_default, tp_ann) in parser.type_params:
# no positional-only or keyword-only allowed in a type parameters list # no positional-only or keyword-only allowed in a type parameters list
if tp_kind in {Parameter.POSITIONAL_ONLY, Parameter.KEYWORD_ONLY}: if tp_kind in {Parameter.POSITIONAL_ONLY, Parameter.KEYWORD_ONLY}:
raise SyntaxError('positional-only or keyword-only parameters' msg = ('positional-only or keyword-only parameters '
' are prohibited in type parameter lists') 'are prohibited in type parameter lists')
raise SyntaxError(msg)
node = addnodes.desc_type_parameter() node = addnodes.desc_type_parameter()
if tp_kind == Parameter.VAR_POSITIONAL: if tp_kind == Parameter.VAR_POSITIONAL:
@ -774,10 +776,10 @@ class PyObject(ObjectDescription[tuple[str, str]]):
sig_prefix = self.get_signature_prefix(sig) sig_prefix = self.get_signature_prefix(sig)
if sig_prefix: if sig_prefix:
if type(sig_prefix) is str: if type(sig_prefix) is str:
raise TypeError( msg = ("Python directive method get_signature_prefix()"
"Python directive method get_signature_prefix()" " must return a list of nodes."
" must return a list of nodes." f" Return value was '{sig_prefix}'.")
f" Return value was '{sig_prefix}'.") raise TypeError(msg)
signode += addnodes.desc_annotation(str(sig_prefix), '', *sig_prefix) signode += addnodes.desc_annotation(str(sig_prefix), '', *sig_prefix)
if prefix: if prefix:
@ -839,7 +841,8 @@ class PyObject(ObjectDescription[tuple[str, str]]):
def get_index_text(self, modname: str, name: tuple[str, str]) -> str: def get_index_text(self, modname: str, name: tuple[str, str]) -> str:
"""Return the text for the index entry of the object.""" """Return the text for the index entry of the object."""
raise NotImplementedError('must be implemented in subclasses') msg = 'must be implemented in subclasses'
raise NotImplementedError(msg)
def add_target_and_index(self, name_cls: tuple[str, str], sig: str, def add_target_and_index(self, name_cls: tuple[str, str], sig: str,
signode: desc_signature) -> None: signode: desc_signature) -> None:

View File

@ -297,7 +297,8 @@ def _toctree_entry(
'detected, ignoring: %s <- %s'), 'detected, ignoring: %s <- %s'),
ref, ' <- '.join(parents), ref, ' <- '.join(parents),
location=ref, type='toc', subtype='circular') location=ref, type='toc', subtype='circular')
raise LookupError('circular reference') msg = 'circular reference'
raise LookupError(msg)
toc, refdoc = _toctree_standard_entry( toc, refdoc = _toctree_standard_entry(
title, title,
@ -468,7 +469,8 @@ def _toctree_copy(node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tag
child.parent = sub_node_copy child.parent = sub_node_copy
copy.append(sub_node_copy) copy.append(sub_node_copy)
else: else:
raise ValueError(f"Unexpected node type {subnode.__class__.__name__!r}!") msg = f'Unexpected node type {subnode.__class__.__name__!r}!'
raise ValueError(msg)
return copy return copy

View File

@ -320,7 +320,8 @@ class Documenter:
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any, def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
) -> bool: ) -> bool:
"""Called to see if a member can be documented by this Documenter.""" """Called to see if a member can be documented by this Documenter."""
raise NotImplementedError('must be implemented in subclasses') msg = 'must be implemented in subclasses'
raise NotImplementedError(msg)
def __init__(self, directive: DocumenterBridge, name: str, indent: str = '') -> None: def __init__(self, directive: DocumenterBridge, name: str, indent: str = '') -> None:
self.directive = directive self.directive = directive
@ -368,7 +369,8 @@ class Documenter:
example, it would return ``('zipfile', ['ZipFile', 'open'])`` for the example, it would return ``('zipfile', ['ZipFile', 'open'])`` for the
``zipfile.ZipFile.open`` method. ``zipfile.ZipFile.open`` method.
""" """
raise NotImplementedError('must be implemented in subclasses') msg = 'must be implemented in subclasses'
raise NotImplementedError(msg)
def parse_name(self) -> bool: def parse_name(self) -> bool:
"""Determine what module to import and what attribute to document. """Determine what module to import and what attribute to document.
@ -626,7 +628,8 @@ class Documenter:
If *want_all* is True, return all members. Else, only return those If *want_all* is True, return all members. Else, only return those
members given by *self.options.members* (which may also be None). members given by *self.options.members* (which may also be None).
""" """
raise NotImplementedError('must be implemented in subclasses') msg = 'must be implemented in subclasses'
raise NotImplementedError(msg)
def filter_members(self, members: ObjectMembers, want_all: bool, def filter_members(self, members: ObjectMembers, want_all: bool,
) -> list[tuple[str, Any, bool]]: ) -> list[tuple[str, Any, bool]]:

View File

@ -695,7 +695,7 @@ def _import_by_name(name: str, grouped_exception: bool = True) -> tuple[Any, Any
except (ValueError, ImportError, AttributeError, KeyError) as exc: except (ValueError, ImportError, AttributeError, KeyError) as exc:
errors.append(exc) errors.append(exc)
if grouped_exception: if grouped_exception:
raise ImportExceptionGroup('', errors) from None raise ImportExceptionGroup('', errors) from None # NoQA: EM101
else: else:
raise ImportError(*exc.args) from exc raise ImportError(*exc.args) from exc

View File

@ -109,7 +109,8 @@ def setup_documenters(app: Any) -> None:
def _underline(title: str, line: str = '=') -> str: def _underline(title: str, line: str = '=') -> str:
if '\n' in title: if '\n' in title:
raise ValueError('Can only underline single lines') msg = 'Can only underline single lines'
raise ValueError(msg)
return title + '\n' + line * len(title) return title + '\n' + line * len(title)
@ -118,7 +119,8 @@ class AutosummaryRenderer:
def __init__(self, app: Sphinx) -> None: def __init__(self, app: Sphinx) -> None:
if isinstance(app, Builder): if isinstance(app, Builder):
raise ValueError('Expected a Sphinx application object!') msg = 'Expected a Sphinx application object!'
raise ValueError(msg)
system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
loader = SphinxTemplateLoader(app.srcdir, app.config.templates_path, loader = SphinxTemplateLoader(app.srcdir, app.config.templates_path,

View File

@ -156,7 +156,8 @@ def compile_math(latex: str, builder: Builder) -> str:
builder.config.imgmath_latex) builder.config.imgmath_latex)
raise InvokeError from exc raise InvokeError from exc
except CalledProcessError as exc: except CalledProcessError as exc:
raise MathExtError('latex exited with error', exc.stderr, exc.stdout) from exc msg = 'latex exited with error'
raise MathExtError(msg, exc.stderr, exc.stdout) from exc
def convert_dvi_to_image(command: list[str], name: str) -> tuple[str, str]: def convert_dvi_to_image(command: list[str], name: str) -> tuple[str, str]:
@ -236,7 +237,8 @@ def render_math(
""" """
image_format = self.builder.config.imgmath_image_format.lower() image_format = self.builder.config.imgmath_image_format.lower()
if image_format not in SUPPORT_FORMAT: if image_format not in SUPPORT_FORMAT:
raise MathExtError('imgmath_image_format must be either "png" or "svg"') unsupported_format_msg = 'imgmath_image_format must be either "png" or "svg"'
raise MathExtError(unsupported_format_msg)
latex = generate_latex_macro(image_format, latex = generate_latex_macro(image_format,
math, math,
@ -285,7 +287,8 @@ def render_maths_to_base64(image_format: str, generated_path: str) -> str:
return f'data:image/png;base64,{encoded}' return f'data:image/png;base64,{encoded}'
if image_format == 'svg': if image_format == 'svg':
return f'data:image/svg+xml;base64,{encoded}' return f'data:image/svg+xml;base64,{encoded}'
raise MathExtError('imgmath_image_format must be either "png" or "svg"') unsupported_format_msg = 'imgmath_image_format must be either "png" or "svg"'
raise MathExtError(unsupported_format_msg)
def clean_up_files(app: Sphinx, exc: Exception) -> None: def clean_up_files(app: Sphinx, exc: Exception) -> None:

View File

@ -152,8 +152,8 @@ class InheritanceGraph:
self.class_info = self._class_info(classes, show_builtins, self.class_info = self._class_info(classes, show_builtins,
private_bases, parts, aliases, top_classes) private_bases, parts, aliases, top_classes)
if not self.class_info: if not self.class_info:
raise InheritanceException('No classes found for ' msg = 'No classes found for inheritance diagram'
'inheritance diagram') raise InheritanceException(msg)
def _import_classes(self, class_names: list[str], currmodule: str) -> list[Any]: def _import_classes(self, class_names: list[str], currmodule: str) -> list[Any]:
"""Import a list of classes.""" """Import a list of classes."""

View File

@ -566,7 +566,8 @@ class IntersphinxRole(SphinxRole):
elif name[8] == ':': elif name[8] == ':':
return None, suffix return None, suffix
else: else:
raise ValueError(f'Malformed :external: role name: {name}') msg = f'Malformed :external: role name: {name}'
raise ValueError(msg)
def get_role_name(self, name: str) -> tuple[str, str] | None: def get_role_name(self, name: str) -> tuple[str, str] | None:
names = name.split(':') names = name.split(':')

View File

@ -23,8 +23,8 @@ def doctree_read(app: Sphinx, doctree: Node) -> None:
resolve_target = getattr(env.config, 'linkcode_resolve', None) resolve_target = getattr(env.config, 'linkcode_resolve', None)
if not callable(env.config.linkcode_resolve): if not callable(env.config.linkcode_resolve):
raise LinkcodeError( msg = 'Function `linkcode_resolve` is not given in conf.py'
"Function `linkcode_resolve` is not given in conf.py") raise LinkcodeError(msg)
assert resolve_target is not None # for mypy assert resolve_target is not None # for mypy
domain_keys = { domain_keys = {

View File

@ -76,8 +76,8 @@ def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: dict
): ):
return return
if not app.config.mathjax_path: if not app.config.mathjax_path:
raise ExtensionError('mathjax_path config value must be set for the ' msg = 'mathjax_path config value must be set for the mathjax extension to work'
'mathjax extension to work') raise ExtensionError(msg)
domain = cast(MathDomain, app.env.get_domain('math')) domain = cast(MathDomain, app.env.get_domain('math'))
builder = cast(StandaloneHTMLBuilder, app.builder) builder = cast(StandaloneHTMLBuilder, app.builder)

View File

@ -138,7 +138,8 @@ class ModuleAnalyzer:
self.tagorder = parser.deforders self.tagorder = parser.deforders
self._analyzed = True self._analyzed = True
except Exception as exc: except Exception as exc:
raise PycodeError(f'parsing {self.srcname!r} failed: {exc!r}') from exc msg = f'parsing {self.srcname!r} failed: {exc!r}'
raise PycodeError(msg) from exc
def find_attr_docs(self) -> dict[tuple[str, str], list[str]]: def find_attr_docs(self) -> dict[tuple[str, str], list[str]]:
"""Find class and module-level attributes and their documentation.""" """Find class and module-level attributes and their documentation."""

View File

@ -336,7 +336,8 @@ class SphinxComponentRegistry:
try: try:
return builder.default_translator_class return builder.default_translator_class
except AttributeError as err: except AttributeError as err:
raise AttributeError(f'translator not found for {builder.name}') from err msg = f'translator not found for {builder.name}'
raise AttributeError(msg) from err
def create_translator(self, builder: Builder, *args: Any) -> nodes.NodeVisitor: def create_translator(self, builder: Builder, *args: Any) -> nodes.NodeVisitor:
translator_class = self.get_translator_class(builder) translator_class = self.get_translator_class(builder)

View File

@ -83,8 +83,8 @@ def app_params(request: Any, test_params: dict, shared_result: SharedResult,
# ##### process pytest.mark.test_params # ##### process pytest.mark.test_params
if test_params['shared_result']: if test_params['shared_result']:
if 'srcdir' in kwargs: if 'srcdir' in kwargs:
raise pytest.Exception('You can not specify shared_result and ' msg = 'You can not specify shared_result and srcdir in same time.'
'srcdir in same time.') raise pytest.Exception(msg)
kwargs['srcdir'] = test_params['shared_result'] kwargs['srcdir'] = test_params['shared_result']
restore = shared_result.restore(test_params['shared_result']) restore = shared_result.restore(test_params['shared_result'])
kwargs.update(restore) kwargs.update(restore)
@ -123,9 +123,9 @@ def test_params(request: Any) -> dict:
} }
result.update(kwargs) result.update(kwargs)
if (result['shared_result'] and not isinstance(result['shared_result'], str)): if result['shared_result'] and not isinstance(result['shared_result'], str):
raise pytest.Exception('You can only provide a string type of value ' msg = 'You can only provide a string type of value for "shared_result"'
'for "shared_result" ') raise pytest.Exception(msg)
return result return result

View File

@ -56,8 +56,8 @@ def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) ->
for key, value in kwargs.items(): for key, value in kwargs.items():
if key not in node: if key not in node:
if (key := key.replace('_', '-')) not in node: if (key := key.replace('_', '-')) not in node:
raise AssertionError(f'The node{xpath} does not have {key!r}' msg = f'The node{xpath} does not have {key!r} attribute: {node!r}'
f' attribute: {node!r}') raise AssertionError(msg)
assert node[key] == value, \ assert node[key] == value, \
f'The node{xpath}[{key}] is not {value!r}: {node[key]!r}' f'The node{xpath}[{key}] is not {value!r}: {node[key]!r}'

View File

@ -482,7 +482,8 @@ def _sort_key(node: nodes.Node) -> int:
return 0 return 0
if isinstance(node, nodes.target): if isinstance(node, nodes.target):
return 1 return 1
raise ValueError(f'_sort_key called with unexpected node type {type(node)!r}') msg = f'_sort_key called with unexpected node type {type(node)!r}'
raise ValueError(msg)
def setup(app: Sphinx) -> dict[str, Any]: def setup(app: Sphinx) -> dict[str, Any]:

View File

@ -580,8 +580,9 @@ class AddTranslationClasses(SphinxTransform):
add_translated = False add_translated = False
add_untranslated = True add_untranslated = True
else: else:
raise ConfigError('translation_progress_classes must be' msg = ('translation_progress_classes must be '
' True, False, "translated" or "untranslated"') 'True, False, "translated" or "untranslated"')
raise ConfigError(msg)
for node in self.document.findall(NodeMatcher(translated=Any)): # type: nodes.Element for node in self.document.findall(NodeMatcher(translated=Any)): # type: nodes.Element
if node['translated']: if node['translated']:

View File

@ -218,7 +218,8 @@ class ImageConverter(BaseImageConverter):
if rule in self.conversion_rules: if rule in self.conversion_rules:
return rule return rule
raise ValueError('No conversion rule found') msg = 'No conversion rule found'
raise ValueError(msg)
def is_available(self) -> bool: def is_available(self) -> bool:
"""Return the image converter is available or not.""" """Return the image converter is available or not."""

View File

@ -215,7 +215,8 @@ def parselinenos(spec: str, total: int) -> list[int]:
else: else:
raise ValueError raise ValueError
except ValueError as exc: except ValueError as exc:
raise ValueError(f'invalid line number spec: {spec!r}') from exc msg = f'invalid line number spec: {spec!r}'
raise ValueError(msg) from exc
return items return items
@ -286,7 +287,8 @@ _DEPRECATED_OBJECTS = {
def __getattr__(name): def __getattr__(name):
if name not in _DEPRECATED_OBJECTS: if name not in _DEPRECATED_OBJECTS:
raise AttributeError(f'module {__name__!r} has no attribute {name!r}') msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning

View File

@ -46,7 +46,8 @@ _DEPRECATED_OBJECTS = {
def __getattr__(name): def __getattr__(name):
if name not in _DEPRECATED_OBJECTS: if name not in _DEPRECATED_OBJECTS:
raise AttributeError(f'module {__name__!r} has no attribute {name!r}') msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning
@ -478,7 +479,8 @@ class SphinxRole:
if not self.name: if not self.name:
self.name = self.env.config.default_role self.name = self.env.config.default_role
if not self.name: if not self.name:
raise SphinxError('cannot determine default role!') msg = 'cannot determine default role!'
raise SphinxError(msg)
return self.run() return self.run()

View File

@ -240,7 +240,8 @@ def get_image_filename_for_language(
language=env.config.language, language=env.config.language,
) )
except KeyError as exc: except KeyError as exc:
raise SphinxError(f'Invalid figure_language_filename: {exc!r}') from exc msg = f'Invalid figure_language_filename: {exc!r}'
raise SphinxError(msg) from exc
def search_image_for_language(filename: str, env: BuildEnvironment) -> str: def search_image_for_language(filename: str, env: BuildEnvironment) -> str:

View File

@ -142,4 +142,5 @@ def _image_type_from_file(filename: PathLike[str] | str) -> str:
if header.startswith(b'RIFF') and header[8:12] == b'WEBP': if header.startswith(b'RIFF') and header[8:12] == b'WEBP':
return 'webp' return 'webp'
raise ValueError('Could not detect image type!') msg = 'Could not detect image type!'
raise ValueError(msg)

View File

@ -14,12 +14,14 @@ def split_index_msg(entry_type: str, value: str) -> list[str]:
return _split_into(3, 'triple', value) return _split_into(3, 'triple', value)
if entry_type in {'see', 'seealso'}: if entry_type in {'see', 'seealso'}:
return _split_into(2, 'see', value) return _split_into(2, 'see', value)
raise ValueError(f'invalid {entry_type} index entry {value!r}') msg = f'invalid {entry_type} index entry {value!r}'
raise ValueError(msg)
def _split_into(n: int, type: str, value: str) -> list[str]: def _split_into(n: int, type: str, value: str) -> list[str]:
"""Split an index entry into a given number of parts at semicolons.""" """Split an index entry into a given number of parts at semicolons."""
parts = [x.strip() for x in value.split(';', n - 1)] parts = [x.strip() for x in value.split(';', n - 1)]
if len(list(filter(None, parts))) < n: if len(list(filter(None, parts))) < n:
raise ValueError(f'invalid {type} index entry {value!r}') msg = f'invalid {type} index entry {value!r}'
raise ValueError(msg)
return parts return parts

View File

@ -275,14 +275,16 @@ def get_node_source(node: Element) -> str:
for pnode in traverse_parent(node): for pnode in traverse_parent(node):
if pnode.source: if pnode.source:
return pnode.source return pnode.source
raise ValueError("node source not found") msg = 'node source not found'
raise ValueError(msg)
def get_node_line(node: Element) -> int: def get_node_line(node: Element) -> int:
for pnode in traverse_parent(node): for pnode in traverse_parent(node):
if pnode.line: if pnode.line:
return pnode.line return pnode.line
raise ValueError("node line not found") msg = 'node line not found'
raise ValueError(msg)
def traverse_parent(node: Element, cls: Any = None) -> Iterable[Element]: def traverse_parent(node: Element, cls: Any = None) -> Iterable[Element]:

View File

@ -179,7 +179,8 @@ class FileAvoidWrite:
def close(self) -> None: def close(self) -> None:
"""Stop accepting writes and write file, if needed.""" """Stop accepting writes and write file, if needed."""
if not self._io: if not self._io:
raise Exception('FileAvoidWrite does not support empty files.') msg = 'FileAvoidWrite does not support empty files.'
raise Exception(msg)
buf = self.getvalue() buf = self.getvalue()
self._io.close() self._io.close()
@ -207,8 +208,8 @@ class FileAvoidWrite:
def __getattr__(self, name: str) -> Any: def __getattr__(self, name: str) -> Any:
# Proxy to _io instance. # Proxy to _io instance.
if not self._io: if not self._io:
raise Exception('Must write to FileAvoidWrite before other ' msg = 'Must write to FileAvoidWrite before other methods can be used'
'methods can be used') raise Exception(msg)
return getattr(self._io, name) return getattr(self._io, name)

View File

@ -63,7 +63,8 @@ class Tags:
parser = BooleanParser(env, condition, state='variable') parser = BooleanParser(env, condition, state='variable')
expr = parser.parse_expression() expr = parser.parse_expression()
if not parser.stream.eos: if not parser.stream.eos:
raise ValueError('chunk after expression') msg = 'chunk after expression'
raise ValueError(msg)
def eval_node(node: Node) -> bool: def eval_node(node: Node) -> bool:
if isinstance(node, nodes.CondExpr): if isinstance(node, nodes.CondExpr):
@ -80,6 +81,7 @@ class Tags:
elif isinstance(node, nodes.Name): elif isinstance(node, nodes.Name):
return self.tags.get(node.name, False) return self.tags.get(node.name, False)
else: else:
raise ValueError('invalid node, check parsing') msg = 'invalid node, check parsing'
raise ValueError(msg)
return eval_node(expr) return eval_node(expr)

View File

@ -232,8 +232,9 @@ def stringify_annotation(
from sphinx.util.inspect import isNewType # lazy loading from sphinx.util.inspect import isNewType # lazy loading
if mode not in {'fully-qualified-except-typing', 'fully-qualified', 'smart'}: if mode not in {'fully-qualified-except-typing', 'fully-qualified', 'smart'}:
raise ValueError("'mode' must be one of 'fully-qualified-except-typing', " msg = ("'mode' must be one of 'fully-qualified-except-typing', "
f"'fully-qualified', or 'smart'; got {mode!r}.") f"'fully-qualified', or 'smart'; got {mode!r}.")
raise ValueError(msg)
if mode == 'smart': if mode == 'smart':
module_prefix = '~' module_prefix = '~'
@ -352,7 +353,8 @@ _DEPRECATED_OBJECTS = {
def __getattr__(name): def __getattr__(name):
if name not in _DEPRECATED_OBJECTS: if name not in _DEPRECATED_OBJECTS:
raise AttributeError(f'module {__name__!r} has no attribute {name!r}') msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning

View File

@ -155,7 +155,8 @@ class Table:
This takes into account cells spanning multiple columns. This takes into account cells spanning multiple columns.
""" """
if cell.row is None or cell.col is None: if cell.row is None or cell.col is None:
raise ValueError('Cell co-ordinates have not been set') msg = 'Cell co-ordinates have not been set'
raise ValueError(msg)
width = 0 width = 0
for i in range(self[cell.row, cell.col].colspan): for i in range(self[cell.row, cell.col].colspan):
width += source[cell.col + i] width += source[cell.col + i]
@ -180,7 +181,8 @@ class Table:
if not cell.wrapped: if not cell.wrapped:
continue continue
if cell.row is None or cell.col is None: if cell.row is None or cell.col is None:
raise ValueError('Cell co-ordinates have not been set') msg = 'Cell co-ordinates have not been set'
raise ValueError(msg)
width = math.ceil(max(column_width(x) for x in cell.wrapped) / cell.colspan) width = math.ceil(max(column_width(x) for x in cell.wrapped) / cell.colspan)
for col in range(cell.col, cell.col + cell.colspan): for col in range(cell.col, cell.col + cell.colspan):
self.measured_widths[col] = max(self.measured_widths[col], width) self.measured_widths[col] = max(self.measured_widths[col], width)
@ -891,7 +893,8 @@ class TextTranslator(SphinxTranslator):
def visit_table(self, node: Element) -> None: def visit_table(self, node: Element) -> None:
if hasattr(self, 'table'): if hasattr(self, 'table'):
raise NotImplementedError('Nested tables are not supported.') msg = 'Nested tables are not supported.'
raise NotImplementedError(msg)
self.new_state(0) self.new_state(0)
self.table = Table() self.table = Table()

View File

@ -385,7 +385,8 @@ def test_run_epubcheck(app):
except CalledProcessError as exc: except CalledProcessError as exc:
print(exc.stdout.decode('utf-8')) print(exc.stdout.decode('utf-8'))
print(exc.stderr.decode('utf-8')) print(exc.stderr.decode('utf-8'))
raise AssertionError(f'epubcheck exited with return code {exc.returncode}') from exc msg = f'epubcheck exited with return code {exc.returncode}'
raise AssertionError(msg) from exc
def test_xml_name_pattern_check(): def test_xml_name_pattern_check():

View File

@ -74,7 +74,8 @@ def test_msgfmt(app):
except CalledProcessError as exc: except CalledProcessError as exc:
print(exc.stdout) print(exc.stdout)
print(exc.stderr) print(exc.stderr)
raise AssertionError(f'msginit exited with return code {exc.returncode}') from exc msg = f'msginit exited with return code {exc.returncode}'
raise AssertionError(msg) from exc
assert (app.outdir / 'en_US.po').is_file(), 'msginit failed' assert (app.outdir / 'en_US.po').is_file(), 'msginit failed'
try: try:
@ -86,7 +87,8 @@ def test_msgfmt(app):
except CalledProcessError as exc: except CalledProcessError as exc:
print(exc.stdout) print(exc.stdout)
print(exc.stderr) print(exc.stderr)
raise AssertionError(f'msgfmt exited with return code {exc.returncode}') from exc msg = f'msgfmt exited with return code {exc.returncode}'
raise AssertionError(msg) from exc
mo = app.outdir / 'en' / 'LC_MESSAGES' / 'test_root.mo' mo = app.outdir / 'en' / 'LC_MESSAGES' / 'test_root.mo'
assert mo.is_file(), 'msgfmt failed' assert mo.is_file(), 'msgfmt failed'

View File

@ -74,7 +74,8 @@ def tail_check(check):
for node in nodes: for node in nodes:
if node.tail and rex.search(node.tail): if node.tail and rex.search(node.tail):
return True return True
raise AssertionError(f'{check!r} not found in tail of any nodes {nodes}') msg = f'{check!r} not found in tail of any nodes {nodes}'
raise AssertionError(msg)
return checker return checker

View File

@ -72,8 +72,8 @@ def compile_latex_document(app, filename='python.tex', docclass='manual'):
except CalledProcessError as exc: except CalledProcessError as exc:
print(exc.stdout.decode('utf8')) print(exc.stdout.decode('utf8'))
print(exc.stderr.decode('utf8')) print(exc.stderr.decode('utf8'))
raise AssertionError(f'{app.config.latex_engine} exited with ' msg = f'{app.config.latex_engine} exited with return code {exc.returncode}'
f'return code {exc.returncode}') from exc raise AssertionError(msg) from exc
def skip_if_requested(testfunc): def skip_if_requested(testfunc):

View File

@ -56,7 +56,8 @@ def test_texinfo(app, status, warning):
except CalledProcessError as exc: except CalledProcessError as exc:
print(exc.stdout) print(exc.stdout)
print(exc.stderr) print(exc.stderr)
raise AssertionError(f'makeinfo exited with return code {exc.retcode}') from exc msg = f'makeinfo exited with return code {exc.retcode}'
raise AssertionError(msg) from exc
@pytest.mark.sphinx('texinfo', testroot='markup-rubric') @pytest.mark.sphinx('texinfo', testroot='markup-rubric')

View File

@ -70,7 +70,7 @@ def _check(name, input, idDict, output, key, asTextOutput):
print("Input: ", input) print("Input: ", input)
print("Result: ", res) print("Result: ", res)
print("Expected: ", outputAst) print("Expected: ", outputAst)
raise DefinitionError("") raise DefinitionError
rootSymbol = Symbol(None, None, None, None, None) rootSymbol = Symbol(None, None, None, None, None)
symbol = rootSymbol.add_declaration(ast, docname="TestDoc", line=42) symbol = rootSymbol.add_declaration(ast, docname="TestDoc", line=42)
parentNode = addnodes.desc() parentNode = addnodes.desc()
@ -83,7 +83,7 @@ def _check(name, input, idDict, output, key, asTextOutput):
print("Input: ", input) print("Input: ", input)
print("astext(): ", resAsText) print("astext(): ", resAsText)
print("Expected: ", outputAsText) print("Expected: ", outputAsText)
raise DefinitionError("") raise DefinitionError
idExpected = [None] idExpected = [None]
for i in range(1, _max_id + 1): for i in range(1, _max_id + 1):
@ -113,7 +113,7 @@ def _check(name, input, idDict, output, key, asTextOutput):
print("result: %s" % idActual[i]) print("result: %s" % idActual[i])
print("expected: %s" % idExpected[i]) print("expected: %s" % idExpected[i])
# print(rootSymbol.dump(0)) # print(rootSymbol.dump(0))
raise DefinitionError("") raise DefinitionError
def check(name, input, idDict, output=None, key=None, asTextOutput=None): def check(name, input, idDict, output=None, key=None, asTextOutput=None):
@ -142,7 +142,7 @@ def test_domain_c_ast_expressions():
print("Input: ", input) print("Input: ", input)
print("Result: ", res) print("Result: ", res)
print("Expected: ", output) print("Expected: ", output)
raise DefinitionError("") raise DefinitionError
displayString = ast.get_display_string() displayString = ast.get_display_string()
if res != displayString: if res != displayString:
# note: if the expression contains an anon name then this will trigger a falsely # note: if the expression contains an anon name then this will trigger a falsely
@ -150,7 +150,7 @@ def test_domain_c_ast_expressions():
print("Input: ", expr) print("Input: ", expr)
print("Result: ", res) print("Result: ", res)
print("Display: ", displayString) print("Display: ", displayString)
raise DefinitionError("") raise DefinitionError
# type expressions # type expressions
exprCheck('int*') exprCheck('int*')
@ -617,7 +617,7 @@ def test_extra_keywords():
# # used for getting all the ids out for checking # # used for getting all the ids out for checking
# for a in ids: # for a in ids:
# print(a) # print(a)
# raise DefinitionError("") # raise DefinitionError
def split_warnigns(warning): def split_warnigns(warning):

View File

@ -71,7 +71,7 @@ def _check(name, input, idDict, output, key, asTextOutput):
print("Input: ", input) print("Input: ", input)
print("Result: ", res) print("Result: ", res)
print("Expected: ", outputAst) print("Expected: ", outputAst)
raise DefinitionError("") raise DefinitionError
rootSymbol = Symbol(None, None, None, None, None, None, None) rootSymbol = Symbol(None, None, None, None, None, None, None)
symbol = rootSymbol.add_declaration(ast, docname="TestDoc", line=42) symbol = rootSymbol.add_declaration(ast, docname="TestDoc", line=42)
parentNode = addnodes.desc() parentNode = addnodes.desc()
@ -85,7 +85,7 @@ def _check(name, input, idDict, output, key, asTextOutput):
print("astext(): ", resAsText) print("astext(): ", resAsText)
print("Expected: ", outputAsText) print("Expected: ", outputAsText)
print("Node:", parentNode) print("Node:", parentNode)
raise DefinitionError("") raise DefinitionError
idExpected = [None] idExpected = [None]
for i in range(1, _max_id + 1): for i in range(1, _max_id + 1):
@ -115,7 +115,7 @@ def _check(name, input, idDict, output, key, asTextOutput):
print("result: %s" % idActual[i]) print("result: %s" % idActual[i])
print("expected: %s" % idExpected[i]) print("expected: %s" % idExpected[i])
print(rootSymbol.dump(0)) print(rootSymbol.dump(0))
raise DefinitionError("") raise DefinitionError
def check(name, input, idDict, output=None, key=None, asTextOutput=None): def check(name, input, idDict, output=None, key=None, asTextOutput=None):
@ -187,7 +187,7 @@ def test_domain_cpp_ast_expressions():
print("") print("")
print("Input: ", expr) print("Input: ", expr)
print("Result: ", res) print("Result: ", res)
raise DefinitionError("") raise DefinitionError
displayString = ast.get_display_string() displayString = ast.get_display_string()
if res != displayString: if res != displayString:
# note: if the expression contains an anon name then this will trigger a falsely # note: if the expression contains an anon name then this will trigger a falsely
@ -195,7 +195,7 @@ def test_domain_cpp_ast_expressions():
print("Input: ", expr) print("Input: ", expr)
print("Result: ", res) print("Result: ", res)
print("Display: ", displayString) print("Display: ", displayString)
raise DefinitionError("") raise DefinitionError
# primary # primary
exprCheck('nullptr', 'LDnE') exprCheck('nullptr', 'LDnE')
@ -1101,7 +1101,7 @@ def test_domain_cpp_template_parameters_is_pack(param: str, is_pack: bool):
# # used for getting all the ids out for checking # # used for getting all the ids out for checking
# for a in ids: # for a in ids:
# print(a) # print(a)
# raise DefinitionError("") # raise DefinitionError
def filter_warnings(warning, file): def filter_warnings(warning, file):

View File

@ -29,9 +29,11 @@ def has_binary(binary):
def test_imgmath_png(app, status, warning): def test_imgmath_png(app, status, warning):
app.builder.build_all() app.builder.build_all()
if "LaTeX command 'latex' cannot be run" in warning.getvalue(): if "LaTeX command 'latex' cannot be run" in warning.getvalue():
raise pytest.skip.Exception('LaTeX command "latex" is not available') msg = 'LaTeX command "latex" is not available'
raise pytest.skip.Exception(msg)
if "dvipng command 'dvipng' cannot be run" in warning.getvalue(): if "dvipng command 'dvipng' cannot be run" in warning.getvalue():
raise pytest.skip.Exception('dvipng command "dvipng" is not available') msg = 'dvipng command "dvipng" is not available'
raise pytest.skip.Exception(msg)
content = (app.outdir / 'index.html').read_text(encoding='utf8') content = (app.outdir / 'index.html').read_text(encoding='utf8')
shutil.rmtree(app.outdir) shutil.rmtree(app.outdir)
@ -48,9 +50,11 @@ def test_imgmath_png(app, status, warning):
def test_imgmath_svg(app, status, warning): def test_imgmath_svg(app, status, warning):
app.builder.build_all() app.builder.build_all()
if "LaTeX command 'latex' cannot be run" in warning.getvalue(): if "LaTeX command 'latex' cannot be run" in warning.getvalue():
raise pytest.skip.Exception('LaTeX command "latex" is not available') msg = 'LaTeX command "latex" is not available'
raise pytest.skip.Exception(msg)
if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue(): if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue():
raise pytest.skip.Exception('dvisvgm command "dvisvgm" is not available') msg = 'dvisvgm command "dvisvgm" is not available'
raise pytest.skip.Exception(msg)
content = (app.outdir / 'index.html').read_text(encoding='utf8') content = (app.outdir / 'index.html').read_text(encoding='utf8')
shutil.rmtree(app.outdir) shutil.rmtree(app.outdir)
@ -68,9 +72,11 @@ def test_imgmath_svg(app, status, warning):
def test_imgmath_svg_embed(app, status, warning): def test_imgmath_svg_embed(app, status, warning):
app.builder.build_all() app.builder.build_all()
if "LaTeX command 'latex' cannot be run" in warning.getvalue(): if "LaTeX command 'latex' cannot be run" in warning.getvalue():
pytest.skip('LaTeX command "latex" is not available') msg = 'LaTeX command "latex" is not available'
raise pytest.skip.Exception(msg)
if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue(): if "dvisvgm command 'dvisvgm' cannot be run" in warning.getvalue():
pytest.skip('dvisvgm command "dvisvgm" is not available') msg = 'dvisvgm command "dvisvgm" is not available'
raise pytest.skip.Exception(msg)
content = (app.outdir / 'index.html').read_text(encoding='utf8') content = (app.outdir / 'index.html').read_text(encoding='utf8')
shutil.rmtree(app.outdir) shutil.rmtree(app.outdir)

View File

@ -78,7 +78,7 @@ def test_progress_message(app, status, warning):
# skipping case # skipping case
with progress_message('testing'): with progress_message('testing'):
raise SkipProgressMessage('Reason: %s', 'error') raise SkipProgressMessage('Reason: %s', 'error') # NoQA: EM101
output = strip_escseq(status.getvalue()) output = strip_escseq(status.getvalue())
assert 'testing... skipped\nReason: error\n' in output assert 'testing... skipped\nReason: error\n' in output

View File

@ -171,7 +171,8 @@ def main():
if changes.in_development: if changes.in_development:
changes.finalize_release_date() changes.finalize_release_date()
else: else:
raise Skip('version not changed') reason = 'version not changed'
raise Skip(reason)
else: else:
if changes.in_development: if changes.in_development:
print('WARNING: last version is not released yet: %s' % changes.version) print('WARNING: last version is not released yet: %s' % changes.version)