11import dataclasses as std_dc
22
3- from collections import deque
4- from typing import Any , Dict , Generic , Optional , Protocol , Type , TypeVar , Union
5-
6- T = TypeVar ("T" )
7-
8-
9- class Result (Generic [T ]):
10- """Represents a result."""
11-
12- ok_data : Optional [T ]
13- errors : Optional ["deque[str]" ] # O(1)
14-
15- def __init__ (self , okd : Optional [T ], errors : Optional ["deque[str]" ]):
16- self .ok_data = okd
17- self .errors = errors
18-
19- @classmethod
20- def Ok (cls , data : T ) -> "Result[T]" :
21- return cls (data , None )
22-
23- @classmethod
24- def Err (cls , * errors : str ) -> "Result[T]" :
25- return cls (None , deque (errors ))
26-
27- def unwrap (self ) -> T :
28- """Unwrap the OK data."""
29- # cheap operation lmfao
30- return self .ok_data # type: ignore
31-
32- def unwrap_err (self ) -> "deque[str]" :
33- """Unwrap the Err data."""
34- # AGAIN. lmfao! you gotta be responsible.
35- return self .errors # type: ignore
36-
37- def is_ok (self ) -> bool :
38- """CALL."""
39- return not self .errors
40-
41- def trace (self , upper : str ) -> "Result[T]" :
42- if self .errors is not None :
43- self .errors .appendleft ("indent" )
44- self .errors .appendleft (upper )
45- self .errors .append ("unindent" )
46-
47- return self
48-
49- @classmethod
50- def trace_below (cls , upper : str , * items : str ) -> "Result[T]" :
51- errors = deque (items )
52- errors .appendleft ("indent" )
53- errors .appendleft (upper )
54- errors .append ("unindent" )
55-
56- return cls (okd = None , errors = errors )
57-
58- def __repr__ (self ) -> str :
59- if self .is_ok ():
60- return f"Result.Ok({ self .unwrap ()!r} )"
61- else :
62- return f"Result.Err({ self .unwrap_err ()!r} )"
3+ from typing import Any , Dict , Protocol , Type , Union
634
645
656class Dataclass (Protocol ):
@@ -72,6 +13,7 @@ class Dataclass(Protocol):
7213class _Indexable :
7314 def __getitem__ (self , k : str ): ...
7415 def __setitem__ (self , k : str , data : Any ): ...
16+ def get (self , k : str ): ...
7517 def as_dict (self ) -> dict : ...
7618 def as_dc (self ) -> Dataclass : ...
7719
@@ -80,8 +22,11 @@ class _DefinitelyDict(_Indexable):
8022 def __init__ (self , d : Dict ):
8123 self .data = d
8224
25+ def get (self , k : str ):
26+ return self .data .get (k , std_dc .MISSING )
27+
8328 def __getitem__ (self , k : str ):
84- self .data [k ]
29+ return self .data [k ]
8530
8631 def __setitem__ (self , k : str , data : Any ):
8732 self .data [k ] = data
@@ -97,6 +42,9 @@ class _DefinitelyDataclass(_Indexable):
9742 def __init__ (self , dc : Dataclass ):
9843 self .dc = dc
9944
45+ def get (self , k : str ):
46+ return getattr (self .dc , k , std_dc .MISSING )
47+
10048 def __getitem__ (self , k : str ):
10149 return getattr (self .dc , k )
10250
@@ -115,3 +63,7 @@ def indexable(item: Any) -> "_Indexable":
11563 return _DefinitelyDict (item )
11664 else :
11765 return _DefinitelyDataclass (item )
66+
67+
68+ class ValidationError (RuntimeError ):
69+ """Validation error for `exacting`."""
0 commit comments