28
28
from functools import reduce
29
29
from operator import xor as xor_operator
30
30
31
+ from ._codec .hydration import BrokenHydrationObject
31
32
from ._conf import iter_items
33
+ from ._meta import deprecated
34
+ from .exceptions import BrokenRecordError
32
35
from .graph import (
33
36
Node ,
34
37
Path ,
@@ -55,9 +58,26 @@ def __new__(cls, iterable=()):
55
58
inst .__keys = tuple (keys )
56
59
return inst
57
60
61
+ def _broken_record_error (self , index ):
62
+ return BrokenRecordError (
63
+ f"Record contains broken data at { index } ('{ self .__keys [index ]} ')"
64
+ )
65
+
66
+ def _super_getitem_single (self , index ):
67
+ value = super ().__getitem__ (index )
68
+ if isinstance (value , BrokenHydrationObject ):
69
+ raise self ._broken_record_error (index ) from value .error
70
+ return value
71
+
58
72
def __repr__ (self ):
59
- return "<%s %s>" % (self .__class__ .__name__ ,
60
- " " .join ("%s=%r" % (field , self [i ]) for i , field in enumerate (self .__keys )))
73
+ return "<%s %s>" % (
74
+ self .__class__ .__name__ ,
75
+ " " .join ("%s=%r" % (field , value )
76
+ for field , value in zip (self .__keys , super ().__iter__ ()))
77
+ )
78
+
79
+ def __str__ (self ):
80
+ return self .__repr__ ()
61
81
62
82
def __eq__ (self , other ):
63
83
""" In order to be flexible regarding comparison, the equality rules
@@ -83,18 +103,26 @@ def __ne__(self, other):
83
103
def __hash__ (self ):
84
104
return reduce (xor_operator , map (hash , self .items ()))
85
105
106
+ def __iter__ (self ):
107
+ for i , v in enumerate (super ().__iter__ ()):
108
+ if isinstance (v , BrokenHydrationObject ):
109
+ raise self ._broken_record_error (i ) from v .error
110
+ yield v
111
+
86
112
def __getitem__ (self , key ):
87
113
if isinstance (key , slice ):
88
114
keys = self .__keys [key ]
89
- values = super (Record , self ).__getitem__ (key )
115
+ values = super ().__getitem__ (key )
90
116
return self .__class__ (zip (keys , values ))
91
117
try :
92
118
index = self .index (key )
93
119
except IndexError :
94
120
return None
95
121
else :
96
- return super ( Record , self ). __getitem__ (index )
122
+ return self . _super_getitem_single (index )
97
123
124
+ # TODO: 6.0 - remove
125
+ @deprecated ("This method is deprecated and will be removed in the future." )
98
126
def __getslice__ (self , start , stop ):
99
127
key = slice (start , stop )
100
128
keys = self .__keys [key ]
@@ -114,7 +142,7 @@ def get(self, key, default=None):
114
142
except ValueError :
115
143
return default
116
144
if 0 <= index < len (self ):
117
- return super ( Record , self ). __getitem__ (index )
145
+ return self . _super_getitem_single (index )
118
146
else :
119
147
return default
120
148
@@ -197,7 +225,8 @@ def items(self, *keys):
197
225
else :
198
226
d .append ((self .__keys [i ], self [i ]))
199
227
return d
200
- return list ((self .__keys [i ], super (Record , self ).__getitem__ (i )) for i in range (len (self )))
228
+ return list ((self .__keys [i ], self ._super_getitem_single (i ))
229
+ for i in range (len (self )))
201
230
202
231
def data (self , * keys ):
203
232
""" Return the keys and values of this record as a dictionary,
0 commit comments