Skip to content

Commit

Permalink
Add dedicated exception type to mark invalid HMMs
Browse files Browse the repository at this point in the history
  • Loading branch information
althonos committed Oct 21, 2023
1 parent cbf4181 commit 81daebd
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
32 changes: 30 additions & 2 deletions pyhmmer/errors.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import typing

from pyhmmer.easel import Alphabet
from pyhmmer.plan7 import HMM

statuscode: typing.Dict[int, str]

Expand All @@ -20,7 +21,7 @@ class AllocationError(MemoryError):
def __repr__(self) -> str: ...
def __str__(self) -> str: ...

class EaselException(RuntimeError):
class EaselError(RuntimeError):
code: int
message: str
def __init__(self, code: int, message: str) -> None: ...
Expand All @@ -46,4 +47,31 @@ class ServerError(RuntimeError):
class MissingCutoffs(ValueError):
def __init__(self) -> None: ...
def __repr__(self) -> str: ...
def __str__(self) -> str: ...
def __str__(self) -> str: ...


class InvalidParameter(ValueError):
name: str
value: object
choices: typing.Optional[typing.List[str]]
hint: typing.Optional[str]
def __init__(
self,
name: str,
value: object,
*,
choices: typing.Optional[typing.List[str]],
hint: typing.Optional[str]
) -> None:
def __repr__(self) -> str: ...
def __str__(self) -> str: ...


class InvalidHMM(ValueError):
hmm: HMM
message: str
def __init__(self, hmm: HMM, message: str) -> None: ...
def __repr__(self) -> str: ...
def __str__(self) -> str: ...


26 changes: 25 additions & 1 deletion pyhmmer/errors.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,28 @@ class InvalidParameter(ValueError):
if hint is not None:
options = f" (expected {hint})"

return f"Invalid {self.name!r} parameter value: {self.value!r}{options}"
return f"Invalid {self.name!r} parameter value: {self.value!r}{options}"


class InvalidHMM(ValueError):
"""A value error caused by a HMM that fails validation.
.. versionadded:: 0.10.3
"""

def __init__(self, object hmm, str message):
super().__init__(hmm, message)
self.message = message
self.hmm = hmm

def __repr__(self):
cdef str ty = type(self).__name__
return f"{ty}({self.code!r}, {self.message!r})"

def __str__(self):
return "HMM {!r} is invalid: {}".format(
self.hmm.name.decode('utf-8', 'replace'),
self.message
)

3 changes: 2 additions & 1 deletion pyhmmer/plan7.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ from .errors import (
AlphabetMismatch,
MissingCutoffs,
InvalidParameter,
InvalidHMM,
)


Expand Down Expand Up @@ -3301,7 +3302,7 @@ cdef class HMM:

if libhmmer.p7_hmm.p7_hmm_Validate(self._hmm, errbuf, tolerance) != libeasel.eslOK:
err_msg = errbuf.decode("utf-8", "replace")
raise ValueError(f"Invalid HMM: {err_msg}")
raise InvalidHMM(self, err_msg)

cpdef void write(self, object fh, bint binary=False) except *:
"""write(self, fh, binary=False)\n--
Expand Down

0 comments on commit 81daebd

Please sign in to comment.