2828from functools import reduce
2929from operator import xor as xor_operator
3030
31+ from ._codec .hydration import BrokenHydrationObject
3132from ._conf import iter_items
33+ from ._meta import deprecated
34+ from .exceptions import BrokenRecordError
3235from .graph import (
3336 Node ,
3437 Path ,
@@ -55,9 +58,26 @@ def __new__(cls, iterable=()):
5558 inst .__keys = tuple (keys )
5659 return inst
5760
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+
5872 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__ ()
6181
6282 def __eq__ (self , other ):
6383 """ In order to be flexible regarding comparison, the equality rules
@@ -83,18 +103,26 @@ def __ne__(self, other):
83103 def __hash__ (self ):
84104 return reduce (xor_operator , map (hash , self .items ()))
85105
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+
86112 def __getitem__ (self , key ):
87113 if isinstance (key , slice ):
88114 keys = self .__keys [key ]
89- values = super (Record , self ).__getitem__ (key )
115+ values = super ().__getitem__ (key )
90116 return self .__class__ (zip (keys , values ))
91117 try :
92118 index = self .index (key )
93119 except IndexError :
94120 return None
95121 else :
96- return super ( Record , self ). __getitem__ (index )
122+ return self . _super_getitem_single (index )
97123
124+ # TODO: 6.0 - remove
125+ @deprecated ("This method is deprecated and will be removed in the future." )
98126 def __getslice__ (self , start , stop ):
99127 key = slice (start , stop )
100128 keys = self .__keys [key ]
@@ -114,7 +142,7 @@ def get(self, key, default=None):
114142 except ValueError :
115143 return default
116144 if 0 <= index < len (self ):
117- return super ( Record , self ). __getitem__ (index )
145+ return self . _super_getitem_single (index )
118146 else :
119147 return default
120148
@@ -197,7 +225,8 @@ def items(self, *keys):
197225 else :
198226 d .append ((self .__keys [i ], self [i ]))
199227 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 )))
201230
202231 def data (self , * keys ):
203232 """ Return the keys and values of this record as a dictionary,
0 commit comments