codekingpro/portable-devtools
115k
1"""2Errors, oh no!3"""4 5from __future__ import annotations6 7from typing import TYPE_CHECKING, Any8 9import attrs10 11from referencing._attrs import frozen12 13if TYPE_CHECKING:14 from referencing import Resource15 from referencing.typing import URI16 17 18@frozen19class NoSuchResource(KeyError):20 """21 The given URI is not present in a registry.22 23 Unlike most exceptions, this class *is* intended to be publicly24 instantiable and *is* part of the public API of the package.25 """26 27 ref: URI28 29 def __eq__(self, other: object) -> bool:30 if self.__class__ is not other.__class__:31 return NotImplemented32 return attrs.astuple(self) == attrs.astuple(other)33 34 def __hash__(self) -> int:35 return hash(attrs.astuple(self))36 37 38@frozen39class NoInternalID(Exception):40 """41 A resource has no internal ID, but one is needed.42 43 E.g. in modern JSON Schema drafts, this is the :kw:`$id` keyword.44 45 One might be needed if a resource was to-be added to a registry but no46 other URI is available, and the resource doesn't declare its canonical URI.47 """48 49 resource: Resource[Any]50 51 def __eq__(self, other: object) -> bool:52 if self.__class__ is not other.__class__:53 return NotImplemented54 return attrs.astuple(self) == attrs.astuple(other)55 56 def __hash__(self) -> int:57 return hash(attrs.astuple(self))58 59 60@frozen61class Unretrievable(KeyError):62 """63 The given URI is not present in a registry, and retrieving it failed.64 """65 66 ref: URI67 68 def __eq__(self, other: object) -> bool:69 if self.__class__ is not other.__class__:70 return NotImplemented71 return attrs.astuple(self) == attrs.astuple(other)72 73 def __hash__(self) -> int:74 return hash(attrs.astuple(self))75 76 77@frozen78class CannotDetermineSpecification(Exception):79 """80 Attempting to detect the appropriate `Specification` failed.81 82 This happens if no discernible information is found in the contents of the83 new resource which would help identify it.84 """85 86 contents: Any87 88 def __eq__(self, other: object) -> bool:89 if self.__class__ is not other.__class__:90 return NotImplemented91 return attrs.astuple(self) == attrs.astuple(other)92 93 def __hash__(self) -> int:94 return hash(attrs.astuple(self))95 96 97@attrs.frozen # Because here we allow subclassing below.98class Unresolvable(Exception):99 """100 A reference was unresolvable.101 """102 103 ref: URI104 105 def __eq__(self, other: object) -> bool:106 if self.__class__ is not other.__class__:107 return NotImplemented108 return attrs.astuple(self) == attrs.astuple(other)109 110 def __hash__(self) -> int:111 return hash(attrs.astuple(self))112 113 114@frozen115class PointerToNowhere(Unresolvable):116 """117 A JSON Pointer leads to a part of a document that does not exist.118 """119 120 resource: Resource[Any]121 122 def __str__(self) -> str:123 msg = f"{self.ref!r} does not exist within {self.resource.contents!r}"124 if self.ref == "/":125 msg += (126 ". The pointer '/' is a valid JSON Pointer but it points to "127 "an empty string property ''. If you intended to point "128 "to the entire resource, you should use '#'."129 )130 return msg131 132 133@frozen134class NoSuchAnchor(Unresolvable):135 """136 An anchor does not exist within a particular resource.137 """138 139 resource: Resource[Any]140 anchor: str141 142 def __str__(self) -> str:143 return (144 f"{self.anchor!r} does not exist within {self.resource.contents!r}"145 )146 147 148@frozen149class InvalidAnchor(Unresolvable):150 """151 An anchor which could never exist in a resource was dereferenced.152 153 It is somehow syntactically invalid.154 """155 156 resource: Resource[Any]157 anchor: str158 159 def __str__(self) -> str:160 return (161 f"'#{self.anchor}' is not a valid anchor, neither as a "162 "plain name anchor nor as a JSON Pointer. You may have intended "163 f"to use '#/{self.anchor}', as the slash is required *before each "164 "segment* of a JSON pointer."165 )166 