Skip to content

Commit b08c34e

Browse files
committed
Merge branch 'python-import' into HEAD
2 parents fcccf49 + 813b4ea commit b08c34e

File tree

964 files changed

+62724
-29518
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

964 files changed

+62724
-29518
lines changed

graalpython/lib-python/3/_collections_abc.py

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

12-
__all__ = ["Awaitable", "Coroutine", "AsyncIterable", "AsyncIterator",
13-
"Hashable", "Iterable", "Iterator", "Generator",
14-
"Sized", "Container", "Callable",
12+
__all__ = ["Awaitable", "Coroutine",
13+
"AsyncIterable", "AsyncIterator", "AsyncGenerator",
14+
"Hashable", "Iterable", "Iterator", "Generator", "Reversible",
15+
"Sized", "Container", "Callable", "Collection",
1516
"Set", "MutableSet",
1617
"Mapping", "MutableMapping",
1718
"MappingView", "KeysView", "ItemsView", "ValuesView",
@@ -61,7 +62,7 @@ async def _coro(): pass
6162
# _coro.close() # Prevent ResourceWarning
6263
del _coro
6364
## asynchronous generator ##
64-
## This should be reverted, once async generators are supported.
65+
## Truffle todo: This should be reverted, once async generators are supported.
6566
## Temporary fix.
6667
#async def _ag(): yield
6768
#_ag = _ag()
@@ -71,6 +72,18 @@ async def _coro(): pass
7172

7273
### ONE-TRICK PONIES ###
7374

75+
def _check_methods(C, *methods):
76+
mro = C.__mro__
77+
for method in methods:
78+
for B in mro:
79+
if method in B.__dict__:
80+
if B.__dict__[method] is None:
81+
return NotImplemented
82+
break
83+
else:
84+
return NotImplemented
85+
return True
86+
7487
class Hashable(metaclass=ABCMeta):
7588

7689
__slots__ = ()
@@ -82,11 +95,7 @@ def __hash__(self):
8295
@classmethod
8396
def __subclasshook__(cls, C):
8497
if cls is Hashable:
85-
for B in C.__mro__:
86-
if "__hash__" in B.__dict__:
87-
if B.__dict__["__hash__"]:
88-
return True
89-
break
98+
return _check_methods(C, "__hash__")
9099
return NotImplemented
91100

92101

@@ -101,11 +110,7 @@ def __await__(self):
101110
@classmethod
102111
def __subclasshook__(cls, C):
103112
if cls is Awaitable:
104-
for B in C.__mro__:
105-
if "__await__" in B.__dict__:
106-
if B.__dict__["__await__"]:
107-
return True
108-
break
113+
return _check_methods(C, "__await__")
109114
return NotImplemented
110115

111116

@@ -146,14 +151,7 @@ def close(self):
146151
@classmethod
147152
def __subclasshook__(cls, C):
148153
if cls is Coroutine:
149-
mro = C.__mro__
150-
for method in ('__await__', 'send', 'throw', 'close'):
151-
for base in mro:
152-
if method in base.__dict__:
153-
break
154-
else:
155-
return NotImplemented
156-
return True
154+
return _check_methods(C, '__await__', 'send', 'throw', 'close')
157155
return NotImplemented
158156

159157

@@ -171,8 +169,7 @@ def __aiter__(self):
171169
@classmethod
172170
def __subclasshook__(cls, C):
173171
if cls is AsyncIterable:
174-
if any("__aiter__" in B.__dict__ for B in C.__mro__):
175-
return True
172+
return _check_methods(C, "__aiter__")
176173
return NotImplemented
177174

178175

@@ -191,12 +188,61 @@ def __aiter__(self):
191188
@classmethod
192189
def __subclasshook__(cls, C):
193190
if cls is AsyncIterator:
194-
if (any("__anext__" in B.__dict__ for B in C.__mro__) and
195-
any("__aiter__" in B.__dict__ for B in C.__mro__)):
196-
return True
191+
return _check_methods(C, "__anext__", "__aiter__")
197192
return NotImplemented
198193

199194

195+
class AsyncGenerator(AsyncIterator):
196+
197+
__slots__ = ()
198+
199+
async def __anext__(self):
200+
"""Return the next item from the asynchronous generator.
201+
When exhausted, raise StopAsyncIteration.
202+
"""
203+
return await self.asend(None)
204+
205+
@abstractmethod
206+
async def asend(self, value):
207+
"""Send a value into the asynchronous generator.
208+
Return next yielded value or raise StopAsyncIteration.
209+
"""
210+
raise StopAsyncIteration
211+
212+
@abstractmethod
213+
async def athrow(self, typ, val=None, tb=None):
214+
"""Raise an exception in the asynchronous generator.
215+
Return next yielded value or raise StopAsyncIteration.
216+
"""
217+
if val is None:
218+
if tb is None:
219+
raise typ
220+
val = typ()
221+
if tb is not None:
222+
val = val.with_traceback(tb)
223+
raise val
224+
225+
async def aclose(self):
226+
"""Raise GeneratorExit inside coroutine.
227+
"""
228+
try:
229+
await self.athrow(GeneratorExit)
230+
except (GeneratorExit, StopAsyncIteration):
231+
pass
232+
else:
233+
raise RuntimeError("asynchronous generator ignored GeneratorExit")
234+
235+
@classmethod
236+
def __subclasshook__(cls, C):
237+
if cls is AsyncGenerator:
238+
return _check_methods(C, '__aiter__', '__anext__',
239+
'asend', 'athrow', 'aclose')
240+
return NotImplemented
241+
242+
243+
AsyncGenerator.register(async_generator)
244+
245+
200246
class Iterable(metaclass=ABCMeta):
201247

202248
__slots__ = ()
@@ -209,8 +255,7 @@ def __iter__(self):
209255
@classmethod
210256
def __subclasshook__(cls, C):
211257
if cls is Iterable:
212-
if any("__iter__" in B.__dict__ for B in C.__mro__):
213-
return True
258+
return _check_methods(C, "__iter__")
214259
return NotImplemented
215260

216261

@@ -229,9 +274,7 @@ def __iter__(self):
229274
@classmethod
230275
def __subclasshook__(cls, C):
231276
if cls is Iterator:
232-
if (any("__next__" in B.__dict__ for B in C.__mro__) and
233-
any("__iter__" in B.__dict__ for B in C.__mro__)):
234-
return True
277+
return _check_methods(C, '__iter__', '__next__')
235278
return NotImplemented
236279

237280
Iterator.register(bytes_iterator)
@@ -250,6 +293,22 @@ def __subclasshook__(cls, C):
250293
Iterator.register(zip_iterator)
251294

252295

296+
class Reversible(Iterable):
297+
298+
__slots__ = ()
299+
300+
@abstractmethod
301+
def __reversed__(self):
302+
while False:
303+
yield None
304+
305+
@classmethod
306+
def __subclasshook__(cls, C):
307+
if cls is Reversible:
308+
return _check_methods(C, "__reversed__", "__iter__")
309+
return NotImplemented
310+
311+
253312
class Generator(Iterator):
254313

255314
__slots__ = ()
@@ -293,17 +352,10 @@ def close(self):
293352
@classmethod
294353
def __subclasshook__(cls, C):
295354
if cls is Generator:
296-
mro = C.__mro__
297-
for method in ('__iter__', '__next__', 'send', 'throw', 'close'):
298-
for base in mro:
299-
if method in base.__dict__:
300-
break
301-
else:
302-
return NotImplemented
303-
return True
355+
return _check_methods(C, '__iter__', '__next__',
356+
'send', 'throw', 'close')
304357
return NotImplemented
305358

306-
307359
Generator.register(generator)
308360

309361

@@ -318,8 +370,7 @@ def __len__(self):
318370
@classmethod
319371
def __subclasshook__(cls, C):
320372
if cls is Sized:
321-
if any("__len__" in B.__dict__ for B in C.__mro__):
322-
return True
373+
return _check_methods(C, "__len__")
323374
return NotImplemented
324375

325376

@@ -334,10 +385,18 @@ def __contains__(self, x):
334385
@classmethod
335386
def __subclasshook__(cls, C):
336387
if cls is Container:
337-
if any("__contains__" in B.__dict__ for B in C.__mro__):
338-
return True
388+
return _check_methods(C, "__contains__")
339389
return NotImplemented
340390

391+
class Collection(Sized, Iterable, Container):
392+
393+
__slots__ = ()
394+
395+
@classmethod
396+
def __subclasshook__(cls, C):
397+
if cls is Collection:
398+
return _check_methods(C, "__len__", "__iter__", "__contains__")
399+
return NotImplemented
341400

342401
class Callable(metaclass=ABCMeta):
343402

@@ -350,15 +409,14 @@ def __call__(self, *args, **kwds):
350409
@classmethod
351410
def __subclasshook__(cls, C):
352411
if cls is Callable:
353-
if any("__call__" in B.__dict__ for B in C.__mro__):
354-
return True
412+
return _check_methods(C, "__call__")
355413
return NotImplemented
356414

357415

358416
### SETS ###
359417

360418

361-
class Set(Sized, Iterable, Container):
419+
class Set(Collection):
362420

363421
"""A set is a finite, iterable container.
364422
@@ -583,7 +641,7 @@ def __isub__(self, it):
583641
### MAPPINGS ###
584642

585643

586-
class Mapping(Sized, Iterable, Container):
644+
class Mapping(Collection):
587645

588646
__slots__ = ()
589647

@@ -631,6 +689,8 @@ def __eq__(self, other):
631689
return NotImplemented
632690
return dict(self.items()) == dict(other.items())
633691

692+
__reversed__ = None
693+
634694
Mapping.register(mappingproxy)
635695

636696

@@ -680,7 +740,7 @@ def __contains__(self, item):
680740
except KeyError:
681741
return False
682742
else:
683-
return v == value
743+
return v is value or v == value
684744

685745
def __iter__(self):
686746
for key in self._mapping:
@@ -695,7 +755,8 @@ class ValuesView(MappingView):
695755

696756
def __contains__(self, value):
697757
for key in self._mapping:
698-
if value == self._mapping[key]:
758+
v = self._mapping[key]
759+
if v is value or v == value:
699760
return True
700761
return False
701762

@@ -804,7 +865,7 @@ def setdefault(self, key, default=None):
804865
### SEQUENCES ###
805866

806867

807-
class Sequence(Sized, Iterable, Container):
868+
class Sequence(Reversible, Collection):
808869

809870
"""All the operations on a read-only sequence.
810871
@@ -830,7 +891,7 @@ def __iter__(self):
830891

831892
def __contains__(self, value):
832893
for v in self:
833-
if v == value:
894+
if v is value or v == value:
834895
return True
835896
return False
836897

@@ -841,6 +902,9 @@ def __reversed__(self):
841902
def index(self, value, start=0, stop=None):
842903
'''S.index(value, [start, [stop]]) -> integer -- return first index of value.
843904
Raises ValueError if the value is not present.
905+
906+
Supporting start and stop arguments is optional, but
907+
recommended.
844908
'''
845909
if start is not None and start < 0:
846910
start = max(len(self) + start, 0)
@@ -850,7 +914,8 @@ def index(self, value, start=0, stop=None):
850914
i = start
851915
while stop is None or i < stop:
852916
try:
853-
if self[i] == value:
917+
v = self[i]
918+
if v is value or v == value:
854919
return i
855920
except IndexError:
856921
break
@@ -859,7 +924,7 @@ def index(self, value, start=0, stop=None):
859924

860925
def count(self, value):
861926
'S.count(value) -> integer -- return number of occurrences of value'
862-
return sum(1 for v in self if v == value)
927+
return sum(1 for v in self if v is value or v == value)
863928

864929
Sequence.register(tuple)
865930
Sequence.register(str)

graalpython/lib-python/3/_compat_pickle.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,10 @@
242242

243243
for excname in PYTHON3_OSERROR_EXCEPTIONS:
244244
REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'OSError')
245+
246+
PYTHON3_IMPORTERROR_EXCEPTIONS = (
247+
'ModuleNotFoundError',
248+
)
249+
250+
for excname in PYTHON3_IMPORTERROR_EXCEPTIONS:
251+
REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'ImportError')

0 commit comments

Comments
 (0)