Skip to content

Commit f2ec7df

Browse files
authored
Uncomment async code from 3.6 (#2017)
* Uncomment async code from 3.6 * Fix failing tests * Disable failing grammar * Change FunctionAttributes.Coroutine to 0x80 * Fix failing test * Uncomment code in typing * Disable failing test
1 parent 963fb95 commit f2ec7df

File tree

12 files changed

+495
-505
lines changed

12 files changed

+495
-505
lines changed

src/core/IronPython.StdLib/lib/_collections_abc.py

Lines changed: 140 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from abc import ABCMeta, abstractmethod
1010
import sys
1111

12-
__all__ = ["Awaitable",
13-
# "Coroutine", "AsyncIterable", "AsyncIterator", "AsyncGenerator", # https://github.com/IronLanguages/ironpython3/issues/1428
12+
__all__ = ["Awaitable", "Coroutine",
13+
"AsyncIterable", "AsyncIterator", "AsyncGenerator",
1414
"Hashable", "Iterable", "Iterator", "Generator", "Reversible",
1515
"Sized", "Container", "Callable", "Collection",
1616
"Set", "MutableSet",
@@ -54,18 +54,17 @@
5454
## misc ##
5555
mappingproxy = type(type.__dict__)
5656
generator = type((lambda: (yield))())
57-
# https://github.com/IronLanguages/ironpython3/issues/1428
58-
# ## coroutine ##
59-
# async def _coro(): pass
60-
# _coro = _coro()
61-
# coroutine = type(_coro)
62-
# _coro.close() # Prevent ResourceWarning
63-
# del _coro
64-
# ## asynchronous generator ##
65-
# async def _ag(): yield
66-
# _ag = _ag()
67-
# async_generator = type(_ag)
68-
# del _ag
57+
## coroutine ##
58+
async def _coro(): pass
59+
_coro = _coro()
60+
coroutine = type(_coro)
61+
_coro.close() # Prevent ResourceWarning
62+
del _coro
63+
## asynchronous generator ##
64+
async def _ag(): yield
65+
_ag = _ag()
66+
async_generator = type(_ag)
67+
del _ag
6968

7069

7170
### ONE-TRICK PONIES ###
@@ -112,134 +111,133 @@ def __subclasshook__(cls, C):
112111
return NotImplemented
113112

114113

115-
# https://github.com/IronLanguages/ironpython3/issues/1428
116-
# class Coroutine(Awaitable):
117-
#
118-
# __slots__ = ()
119-
#
120-
# @abstractmethod
121-
# def send(self, value):
122-
# """Send a value into the coroutine.
123-
# Return next yielded value or raise StopIteration.
124-
# """
125-
# raise StopIteration
126-
#
127-
# @abstractmethod
128-
# def throw(self, typ, val=None, tb=None):
129-
# """Raise an exception in the coroutine.
130-
# Return next yielded value or raise StopIteration.
131-
# """
132-
# if val is None:
133-
# if tb is None:
134-
# raise typ
135-
# val = typ()
136-
# if tb is not None:
137-
# val = val.with_traceback(tb)
138-
# raise val
139-
#
140-
# def close(self):
141-
# """Raise GeneratorExit inside coroutine.
142-
# """
143-
# try:
144-
# self.throw(GeneratorExit)
145-
# except (GeneratorExit, StopIteration):
146-
# pass
147-
# else:
148-
# raise RuntimeError("coroutine ignored GeneratorExit")
149-
#
150-
# @classmethod
151-
# def __subclasshook__(cls, C):
152-
# if cls is Coroutine:
153-
# return _check_methods(C, '__await__', 'send', 'throw', 'close')
154-
# return NotImplemented
155-
#
156-
#
157-
# Coroutine.register(coroutine)
158-
#
159-
#
160-
# class AsyncIterable(metaclass=ABCMeta):
161-
#
162-
# __slots__ = ()
163-
#
164-
# @abstractmethod
165-
# def __aiter__(self):
166-
# return AsyncIterator()
167-
#
168-
# @classmethod
169-
# def __subclasshook__(cls, C):
170-
# if cls is AsyncIterable:
171-
# return _check_methods(C, "__aiter__")
172-
# return NotImplemented
173-
#
174-
#
175-
# class AsyncIterator(AsyncIterable):
176-
#
177-
# __slots__ = ()
178-
#
179-
# @abstractmethod
180-
# async def __anext__(self):
181-
# """Return the next item or raise StopAsyncIteration when exhausted."""
182-
# raise StopAsyncIteration
183-
#
184-
# def __aiter__(self):
185-
# return self
186-
#
187-
# @classmethod
188-
# def __subclasshook__(cls, C):
189-
# if cls is AsyncIterator:
190-
# return _check_methods(C, "__anext__", "__aiter__")
191-
# return NotImplemented
192-
#
193-
#
194-
# class AsyncGenerator(AsyncIterator):
195-
#
196-
# __slots__ = ()
197-
#
198-
# async def __anext__(self):
199-
# """Return the next item from the asynchronous generator.
200-
# When exhausted, raise StopAsyncIteration.
201-
# """
202-
# return await self.asend(None)
203-
#
204-
# @abstractmethod
205-
# async def asend(self, value):
206-
# """Send a value into the asynchronous generator.
207-
# Return next yielded value or raise StopAsyncIteration.
208-
# """
209-
# raise StopAsyncIteration
210-
#
211-
# @abstractmethod
212-
# async def athrow(self, typ, val=None, tb=None):
213-
# """Raise an exception in the asynchronous generator.
214-
# Return next yielded value or raise StopAsyncIteration.
215-
# """
216-
# if val is None:
217-
# if tb is None:
218-
# raise typ
219-
# val = typ()
220-
# if tb is not None:
221-
# val = val.with_traceback(tb)
222-
# raise val
223-
#
224-
# async def aclose(self):
225-
# """Raise GeneratorExit inside coroutine.
226-
# """
227-
# try:
228-
# await self.athrow(GeneratorExit)
229-
# except (GeneratorExit, StopAsyncIteration):
230-
# pass
231-
# else:
232-
# raise RuntimeError("asynchronous generator ignored GeneratorExit")
233-
#
234-
# @classmethod
235-
# def __subclasshook__(cls, C):
236-
# if cls is AsyncGenerator:
237-
# return _check_methods(C, '__aiter__', '__anext__',
238-
# 'asend', 'athrow', 'aclose')
239-
# return NotImplemented
240-
#
241-
#
242-
# AsyncGenerator.register(async_generator)
114+
class Coroutine(Awaitable):
115+
116+
__slots__ = ()
117+
118+
@abstractmethod
119+
def send(self, value):
120+
"""Send a value into the coroutine.
121+
Return next yielded value or raise StopIteration.
122+
"""
123+
raise StopIteration
124+
125+
@abstractmethod
126+
def throw(self, typ, val=None, tb=None):
127+
"""Raise an exception in the coroutine.
128+
Return next yielded value or raise StopIteration.
129+
"""
130+
if val is None:
131+
if tb is None:
132+
raise typ
133+
val = typ()
134+
if tb is not None:
135+
val = val.with_traceback(tb)
136+
raise val
137+
138+
def close(self):
139+
"""Raise GeneratorExit inside coroutine.
140+
"""
141+
try:
142+
self.throw(GeneratorExit)
143+
except (GeneratorExit, StopIteration):
144+
pass
145+
else:
146+
raise RuntimeError("coroutine ignored GeneratorExit")
147+
148+
@classmethod
149+
def __subclasshook__(cls, C):
150+
if cls is Coroutine:
151+
return _check_methods(C, '__await__', 'send', 'throw', 'close')
152+
return NotImplemented
153+
154+
155+
Coroutine.register(coroutine)
156+
157+
158+
class AsyncIterable(metaclass=ABCMeta):
159+
160+
__slots__ = ()
161+
162+
@abstractmethod
163+
def __aiter__(self):
164+
return AsyncIterator()
165+
166+
@classmethod
167+
def __subclasshook__(cls, C):
168+
if cls is AsyncIterable:
169+
return _check_methods(C, "__aiter__")
170+
return NotImplemented
171+
172+
173+
class AsyncIterator(AsyncIterable):
174+
175+
__slots__ = ()
176+
177+
@abstractmethod
178+
async def __anext__(self):
179+
"""Return the next item or raise StopAsyncIteration when exhausted."""
180+
raise StopAsyncIteration
181+
182+
def __aiter__(self):
183+
return self
184+
185+
@classmethod
186+
def __subclasshook__(cls, C):
187+
if cls is AsyncIterator:
188+
return _check_methods(C, "__anext__", "__aiter__")
189+
return NotImplemented
190+
191+
192+
class AsyncGenerator(AsyncIterator):
193+
194+
__slots__ = ()
195+
196+
async def __anext__(self):
197+
"""Return the next item from the asynchronous generator.
198+
When exhausted, raise StopAsyncIteration.
199+
"""
200+
return await self.asend(None)
201+
202+
@abstractmethod
203+
async def asend(self, value):
204+
"""Send a value into the asynchronous generator.
205+
Return next yielded value or raise StopAsyncIteration.
206+
"""
207+
raise StopAsyncIteration
208+
209+
@abstractmethod
210+
async def athrow(self, typ, val=None, tb=None):
211+
"""Raise an exception in the asynchronous generator.
212+
Return next yielded value or raise StopAsyncIteration.
213+
"""
214+
if val is None:
215+
if tb is None:
216+
raise typ
217+
val = typ()
218+
if tb is not None:
219+
val = val.with_traceback(tb)
220+
raise val
221+
222+
async def aclose(self):
223+
"""Raise GeneratorExit inside coroutine.
224+
"""
225+
try:
226+
await self.athrow(GeneratorExit)
227+
except (GeneratorExit, StopAsyncIteration):
228+
pass
229+
else:
230+
raise RuntimeError("asynchronous generator ignored GeneratorExit")
231+
232+
@classmethod
233+
def __subclasshook__(cls, C):
234+
if cls is AsyncGenerator:
235+
return _check_methods(C, '__aiter__', '__anext__',
236+
'asend', 'athrow', 'aclose')
237+
return NotImplemented
238+
239+
240+
AsyncGenerator.register(async_generator)
243241

244242

245243
class Iterable(metaclass=ABCMeta):

0 commit comments

Comments
 (0)