41
41
Node ,
42
42
Relationship ,
43
43
)
44
- from neo4j .exceptions import ResultNotSingleError
44
+ from neo4j .exceptions import (
45
+ BrokenRecordError ,
46
+ ResultNotSingleError ,
47
+ )
45
48
from neo4j .graph import (
46
49
EntitySetView ,
47
50
Graph ,
@@ -55,18 +58,18 @@ def __init__(self, fields, records):
55
58
self .fields = tuple (fields )
56
59
self .hydration_scope = HydrationHandler ().new_hydration_scope ()
57
60
self .records = tuple (records )
58
- self ._hydrate_records ()
59
-
60
61
assert all (len (self .fields ) == len (r ) for r in self .records )
61
62
63
+ self ._hydrate_records ()
64
+
62
65
def _hydrate_records (self ):
63
66
def _hydrate (value ):
67
+ if isinstance (value , (list , tuple )):
68
+ value = type (value )(_hydrate (v ) for v in value )
69
+ elif isinstance (value , dict ):
70
+ value = {k : _hydrate (v ) for k , v in value .items ()}
64
71
if type (value ) in self .hydration_scope .hydration_hooks :
65
72
return self .hydration_scope .hydration_hooks [type (value )](value )
66
- if isinstance (value , (list , tuple )):
67
- return type (value )(_hydrate (v ) for v in value )
68
- if isinstance (value , dict ):
69
- return {k : _hydrate (v ) for k , v in value .items ()}
70
73
return value
71
74
72
75
self .records = tuple (_hydrate (r ) for r in self .records )
@@ -605,7 +608,6 @@ async def test_data(num_records):
605
608
assert record .data .called_once_with ("hello" , "world" )
606
609
607
610
608
- # TODO: dehydration now happens on a much lower level
609
611
@pytest .mark .parametrize ("records" , (
610
612
Records (["n" ], []),
611
613
Records (["n" ], [[42 ], [69 ], [420 ], [1337 ]]),
@@ -621,19 +623,9 @@ async def test_data(num_records):
621
623
]),
622
624
))
623
625
@mark_async_test
624
- async def test_result_graph (records , async_scripted_connection ):
625
- async_scripted_connection .set_script ((
626
- ("run" , {"on_success" : ({"fields" : records .fields },),
627
- "on_summary" : None }),
628
- ("pull" , {
629
- "on_records" : (records .records ,),
630
- "on_success" : None ,
631
- "on_summary" : None
632
- }),
633
- ))
634
- async_scripted_connection .new_hydration_scope .return_value = \
635
- records .hydration_scope
636
- result = AsyncResult (async_scripted_connection , 1 , noop , noop )
626
+ async def test_result_graph (records ):
627
+ connection = AsyncConnectionStub (records = records )
628
+ result = AsyncResult (connection , 1 , noop , noop )
637
629
await result ._run ("CYPHER" , {}, None , None , "r" , None )
638
630
graph = await result .graph ()
639
631
assert isinstance (graph , Graph )
@@ -1095,3 +1087,25 @@ async def test_to_df_parse_dates(keys, values, expected_df, expand):
1095
1087
df = await result .to_df (expand = expand , parse_dates = True )
1096
1088
1097
1089
pd .testing .assert_frame_equal (df , expected_df )
1090
+
1091
+
1092
+ @pytest .mark .parametrize ("nested" , [True , False ])
1093
+ @mark_async_test
1094
+ async def test_broken_hydration (nested ):
1095
+ value_in = Structure (b"a" , "broken" )
1096
+ if nested :
1097
+ value_in = [value_in ]
1098
+ records_in = Records (["foo" , "bar" ], [["foobar" , value_in ]])
1099
+ connection = AsyncConnectionStub (records = records_in )
1100
+ result = AsyncResult (connection , 1 , noop , noop )
1101
+ await result ._run ("CYPHER" , {}, None , None , "r" , None )
1102
+ records_out = await AsyncUtil .list (result )
1103
+ assert len (records_out ) == 1
1104
+ record_out = records_out [0 ]
1105
+ assert len (record_out ) == 2
1106
+ assert record_out [0 ] == "foobar"
1107
+ with pytest .raises (BrokenRecordError ) as exc :
1108
+ record_out [1 ]
1109
+ cause = exc .value .__cause__
1110
+ assert isinstance (cause , ValueError )
1111
+ assert repr (b"a" ) in str (cause )
0 commit comments