4343 Date ,
4444 DateTime ,
4545)
46+ from .._debug import AsyncNonConcurrentMethodChecker
4647from ..io import ConnectionErrorHandler
4748
4849
7172)
7273
7374
74- class AsyncResult :
75+ class AsyncResult ( AsyncNonConcurrentMethodChecker ) :
7576 """Handler for the result of Cypher query execution.
7677
7778 Instances of this class are typically constructed and returned by
@@ -109,6 +110,7 @@ def __init__(self, connection, fetch_size, on_closed, on_error):
109110 self ._out_of_scope = False
110111 # exception shared across all results of a transaction
111112 self ._exception = None
113+ super ().__init__ ()
112114
113115 async def _connection_error_handler (self , exc ):
114116 self ._exception = exc
@@ -251,11 +253,15 @@ def on_success(summary_metadata):
251253 )
252254 self ._streaming = True
253255
256+ @AsyncNonConcurrentMethodChecker .non_concurrent_iter
254257 async def __aiter__ (self ) -> t .AsyncIterator [Record ]:
255258 """Iterator returning Records.
256259
257- :returns: Record, it is an immutable ordered collection of key-value pairs.
258- :rtype: :class:`neo4j.Record`
260+ Advancing the iterator advances the underlying result stream.
261+ So even when creating multiple iterators from the same result, each
262+ Record will only be returned once.
263+
264+ :returns: Iterator over the result stream's records.
259265 """
260266 while self ._record_buffer or self ._attached :
261267 if self ._record_buffer :
@@ -278,7 +284,9 @@ async def __aiter__(self) -> t.AsyncIterator[Record]:
278284 if self ._consumed :
279285 raise ResultConsumedError (self , _RESULT_CONSUMED_ERROR )
280286
287+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
281288 async def __anext__ (self ) -> Record :
289+ """Advance the result stream and return the record."""
282290 return await self .__aiter__ ().__anext__ ()
283291
284292 async def _attach (self ):
@@ -367,6 +375,7 @@ def _tx_failure(self, exc):
367375 self ._attached = False
368376 self ._exception = exc
369377
378+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
370379 async def consume (self ) -> ResultSummary :
371380 """Consume the remainder of this result and return a :class:`neo4j.ResultSummary`.
372381
@@ -434,6 +443,7 @@ async def single(
434443 async def single (self , strict : te .Literal [True ]) -> Record :
435444 ...
436445
446+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
437447 async def single (self , strict : bool = False ) -> t .Optional [Record ]:
438448 """Obtain the next and only remaining record or None.
439449
@@ -495,6 +505,7 @@ async def single(self, strict: bool = False) -> t.Optional[Record]:
495505 )
496506 return buffer .popleft ()
497507
508+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
498509 async def fetch (self , n : int ) -> t .List [Record ]:
499510 """Obtain up to n records from this result.
500511
@@ -517,6 +528,7 @@ async def fetch(self, n: int) -> t.List[Record]:
517528 for _ in range (min (n , len (self ._record_buffer )))
518529 ]
519530
531+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
520532 async def peek (self ) -> t .Optional [Record ]:
521533 """Obtain the next record from this result without consuming it.
522534
@@ -537,6 +549,7 @@ async def peek(self) -> t.Optional[Record]:
537549 return self ._record_buffer [0 ]
538550 return None
539551
552+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
540553 async def graph (self ) -> Graph :
541554 """Turn the result into a :class:`neo4j.Graph`.
542555
@@ -559,6 +572,7 @@ async def graph(self) -> Graph:
559572 await self ._buffer_all ()
560573 return self ._hydration_scope .get_graph ()
561574
575+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
562576 async def value (
563577 self , key : _TResultKey = 0 , default : t .Optional [object ] = None
564578 ) -> t .List [t .Any ]:
@@ -580,6 +594,7 @@ async def value(
580594 """
581595 return [record .value (key , default ) async for record in self ]
582596
597+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
583598 async def values (
584599 self , * keys : _TResultKey
585600 ) -> t .List [t .List [t .Any ]]:
@@ -600,6 +615,7 @@ async def values(
600615 """
601616 return [record .values (* keys ) async for record in self ]
602617
618+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
603619 async def data (self , * keys : _TResultKey ) -> t .List [t .Dict [str , t .Any ]]:
604620 """Return the remainder of the result as a list of dictionaries.
605621
@@ -626,6 +642,7 @@ async def data(self, *keys: _TResultKey) -> t.List[t.Dict[str, t.Any]]:
626642 """
627643 return [record .data (* keys ) async for record in self ]
628644
645+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
629646 async def to_eager_result (self ) -> EagerResult :
630647 """Convert this result to an :class:`.EagerResult`.
631648
@@ -650,6 +667,7 @@ async def to_eager_result(self) -> EagerResult:
650667 summary = await self .consume ()
651668 )
652669
670+ @AsyncNonConcurrentMethodChecker .non_concurrent_method
653671 async def to_df (
654672 self ,
655673 expand : bool = False ,
0 commit comments