Source code for nodeps.modules.errors

"""Errors Module."""
__all__ = (
    "CalledProcessError",
    "CmdError",
    "CommandNotFoundError",
    "InvalidArgumentError",
)

import signal
import subprocess
from collections.abc import Sequence
from typing import AnyStr

from .typings import StrOrBytesPath


class _NoDepsBaseError(Exception):
    """Base Exception from which all other custom Exceptions defined in semantic_release inherit."""


[docs] class CalledProcessError(subprocess.SubprocessError): """Patched :class:`subprocess.CalledProcessError`. Raised when run() and the process returns a non-zero exit status. Attributes: cmd: The command that was run. returncode: The exit code of the process. output: The output of the process. stderr: The error output of the process. completed: :class:`subprocess.CompletedProcess` object. """ returncode: int cmd: StrOrBytesPath | Sequence[StrOrBytesPath] output: AnyStr | None stderr: AnyStr | None completed: subprocess.CompletedProcess | None # noinspection PyShadowingNames def __init__( self, returncode: int | None = None, cmd: StrOrBytesPath | Sequence[StrOrBytesPath] | None = None, output: AnyStr | None = None, stderr: AnyStr | None = None, completed: subprocess.CompletedProcess | None = None, ) -> None: r"""Patched :class:`subprocess.CalledProcessError`. Args: cmd: The command that was run. returncode: The exit code of the process. output: The output of the process. stderr: The error output of the process. completed: :class:`subprocess.CompletedProcess` object. Examples: >>> import subprocess >>> 3/0 # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ZeroDivisionError: division by zero >>> subprocess.run(["ls", "foo"], capture_output=True, check=True) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): errors.CalledProcessError: Return Code: 1 <BLANKLINE> Command: ['ls', 'foo'] <BLANKLINE> Stderr: b'ls: foo: No such file or directory\n' <BLANKLINE> Stdout: b'' <BLANKLINE> """ self.returncode = returncode self.cmd = cmd self.output = output self.stderr = stderr self.completed = completed if self.returncode is None: self.returncode = self.completed.returncode self.cmd = self.completed.args self.output = self.completed.stdout self.stderr = self.completed.stderr def _message(self): if self.returncode and self.returncode < 0: try: return f"Died with {signal.Signals(-self.returncode)!r}." except ValueError: return f"Died with with unknown signal {-self.returncode}." else: return f"{self.returncode:d}" def __str__(self): """Returns str.""" return f""" Return Code: {self._message()} Command: {self.cmd} Stderr: {self.stderr} Stdout: {self.output} """ @property def stdout(self) -> str: """Alias for output attribute, to match stderr.""" return self.output @stdout.setter def stdout(self, value): # There's no obvious reason to set this, but allow it anyway so # .stdout is a transparent alias for .output self.output = value
[docs] class CmdError(subprocess.CalledProcessError): """Raised when run() and the process returns a non-zero exit status. Attribute: process: The CompletedProcess object returned by run(). """ def __init__(self, process: subprocess.CompletedProcess | None = None) -> None: """Init.""" super().__init__(process.returncode, process.args, output=process.stdout, stderr=process.stderr) def __str__(self) -> str: """Str.""" value = super().__str__() if self.stderr is not None: value += "\n" + self.stderr if self.stdout is not None: value += "\n" + self.stdout return value
[docs] class CommandNotFoundError(_NoDepsBaseError): """Raised when command is not found."""
[docs] class InvalidArgumentError(_NoDepsBaseError): """Raised when function is called with invalid argument."""
subprocess.CalledProcessError = CalledProcessError