Updates
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
"""
|
||||
Errors, oh no!
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import attrs
|
||||
|
||||
from referencing._attrs import frozen
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from referencing import Resource
|
||||
from referencing.typing import URI
|
||||
|
||||
|
||||
@frozen
|
||||
class NoSuchResource(KeyError):
|
||||
"""
|
||||
The given URI is not present in a registry.
|
||||
|
||||
Unlike most exceptions, this class *is* intended to be publicly
|
||||
instantiable and *is* part of the public API of the package.
|
||||
"""
|
||||
|
||||
ref: URI
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if self.__class__ is not other.__class__:
|
||||
return NotImplemented
|
||||
return attrs.astuple(self) == attrs.astuple(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(attrs.astuple(self))
|
||||
|
||||
|
||||
@frozen
|
||||
class NoInternalID(Exception):
|
||||
"""
|
||||
A resource has no internal ID, but one is needed.
|
||||
|
||||
E.g. in modern JSON Schema drafts, this is the :kw:`$id` keyword.
|
||||
|
||||
One might be needed if a resource was to-be added to a registry but no
|
||||
other URI is available, and the resource doesn't declare its canonical URI.
|
||||
"""
|
||||
|
||||
resource: Resource[Any]
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if self.__class__ is not other.__class__:
|
||||
return NotImplemented
|
||||
return attrs.astuple(self) == attrs.astuple(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(attrs.astuple(self))
|
||||
|
||||
|
||||
@frozen
|
||||
class Unretrievable(KeyError):
|
||||
"""
|
||||
The given URI is not present in a registry, and retrieving it failed.
|
||||
"""
|
||||
|
||||
ref: URI
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if self.__class__ is not other.__class__:
|
||||
return NotImplemented
|
||||
return attrs.astuple(self) == attrs.astuple(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(attrs.astuple(self))
|
||||
|
||||
|
||||
@frozen
|
||||
class CannotDetermineSpecification(Exception):
|
||||
"""
|
||||
Attempting to detect the appropriate `Specification` failed.
|
||||
|
||||
This happens if no discernible information is found in the contents of the
|
||||
new resource which would help identify it.
|
||||
"""
|
||||
|
||||
contents: Any
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if self.__class__ is not other.__class__:
|
||||
return NotImplemented
|
||||
return attrs.astuple(self) == attrs.astuple(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(attrs.astuple(self))
|
||||
|
||||
|
||||
@attrs.frozen # Because here we allow subclassing below.
|
||||
class Unresolvable(Exception):
|
||||
"""
|
||||
A reference was unresolvable.
|
||||
"""
|
||||
|
||||
ref: URI
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if self.__class__ is not other.__class__:
|
||||
return NotImplemented
|
||||
return attrs.astuple(self) == attrs.astuple(other)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(attrs.astuple(self))
|
||||
|
||||
|
||||
@frozen
|
||||
class PointerToNowhere(Unresolvable):
|
||||
"""
|
||||
A JSON Pointer leads to a part of a document that does not exist.
|
||||
"""
|
||||
|
||||
resource: Resource[Any]
|
||||
|
||||
def __str__(self) -> str:
|
||||
msg = f"{self.ref!r} does not exist within {self.resource.contents!r}"
|
||||
if self.ref == "/":
|
||||
msg += (
|
||||
". The pointer '/' is a valid JSON Pointer but it points to "
|
||||
"an empty string property ''. If you intended to point "
|
||||
"to the entire resource, you should use '#'."
|
||||
)
|
||||
return msg
|
||||
|
||||
|
||||
@frozen
|
||||
class NoSuchAnchor(Unresolvable):
|
||||
"""
|
||||
An anchor does not exist within a particular resource.
|
||||
"""
|
||||
|
||||
resource: Resource[Any]
|
||||
anchor: str
|
||||
|
||||
def __str__(self) -> str:
|
||||
return (
|
||||
f"{self.anchor!r} does not exist within {self.resource.contents!r}"
|
||||
)
|
||||
|
||||
|
||||
@frozen
|
||||
class InvalidAnchor(Unresolvable):
|
||||
"""
|
||||
An anchor which could never exist in a resource was dereferenced.
|
||||
|
||||
It is somehow syntactically invalid.
|
||||
"""
|
||||
|
||||
resource: Resource[Any]
|
||||
anchor: str
|
||||
|
||||
def __str__(self) -> str:
|
||||
return (
|
||||
f"'#{self.anchor}' is not a valid anchor, neither as a "
|
||||
"plain name anchor nor as a JSON Pointer. You may have intended "
|
||||
f"to use '#/{self.anchor}', as the slash is required *before each "
|
||||
"segment* of a JSON pointer."
|
||||
)
|
||||
Reference in New Issue
Block a user