@@ -429,17 +429,46 @@ def aiter(obj, sentinel=_NOT_PROVIDED):
429429 if not callable (obj ):
430430 raise TypeError (f'aiter expected an async callable, got { type (obj )} ' )
431431
432- async def ait ():
433- while True :
434- value = await obj ()
435- if value == sentinel :
436- break
437- yield value
432+ return _aiter_callable (obj , sentinel )
438433
439- return ait ()
440434
435+ class _aiter_callable :
436+ __slots__ = ('acallable' , 'sentinel' )
441437
442- async def anext (async_iterator , default = _NOT_PROVIDED ):
438+ def __init__ (self , acallable , sentinel ):
439+ self .acallable = acallable
440+ self .sentinel = sentinel
441+
442+ def __aiter__ (self ):
443+ return self
444+
445+ def __anext__ (self ):
446+ return _aiter_anext (self .acallable ().__await__ (), self .sentinel )
447+
448+
449+ class _aiter_anext :
450+ __slots__ = ('iterator' , 'sentinel' )
451+
452+ def __init__ (self , iterator , sentinel ):
453+ self .iterator = iterator
454+ self .sentinel = sentinel
455+
456+ def __await__ (self ):
457+ return self
458+
459+ def __iter__ (self ):
460+ return self
461+
462+ def __next__ (self ):
463+ try :
464+ return next (self .iterator )
465+ except StopIteration as end :
466+ if end .value == self .sentinel :
467+ raise StopAsyncIteration (end .value ) from None
468+ raise
469+
470+
471+ def anext (async_iterator , default = _NOT_PROVIDED ):
443472 """anext(async_iterator[, default])
444473
445474 Return the next item from the async iterator.
@@ -449,13 +478,32 @@ async def anext(async_iterator, default=_NOT_PROVIDED):
449478 from collections .abc import AsyncIterator
450479 if not isinstance (async_iterator , AsyncIterator ):
451480 raise TypeError (f'anext expected an AsyncIterator, got { type (async_iterator )} ' )
452- anxt = type (async_iterator ).__anext__
453- try :
454- return await anxt (async_iterator )
455- except StopAsyncIteration :
456- if default is _NOT_PROVIDED :
457- raise
458- return default
481+ anxt = type (async_iterator ).__anext__ (async_iterator )
482+
483+ if default is _NOT_PROVIDED :
484+ return anxt
485+
486+ return _anext_default (anxt , default )
487+
488+
489+ class _anext_default :
490+ __slots__ = ('iterator' , 'default' )
491+
492+ def __init__ (self , iterator , default ):
493+ self .iterator = iterator
494+ self .default = default
495+
496+ def __await__ (self ):
497+ return self
498+
499+ def __iter__ (self ):
500+ return self
501+
502+ def __next__ (self ):
503+ try :
504+ return next (self .iterator )
505+ except StopAsyncIteration :
506+ raise StopIteration (self .default ) from None
459507
460508
461509try :
0 commit comments