mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
Loader: work around Python 3.7 await headache caused by PEP 479
Generators can no longer raise StopIteration, and we are supposed to use "return" instead. But, return with value inside generator is a syntax error in Python 2. Fixes #513
This commit is contained in:
parent
d1845530aa
commit
649372d333
@ -27,6 +27,42 @@ class Loader(DirectObject):
|
||||
# This indicates that this class behaves like a Future.
|
||||
_asyncio_future_blocking = False
|
||||
|
||||
class ResultAwaiter(object):
|
||||
"""Reinvents generators because of PEP 479, sigh. See #513."""
|
||||
|
||||
__slots__ = 'requestList', 'index'
|
||||
|
||||
def __init__(self, requestList):
|
||||
self.requestList = requestList
|
||||
self.index = 0
|
||||
|
||||
def __await__(self):
|
||||
return self
|
||||
|
||||
def __anext__(self):
|
||||
if self.index >= len(self.requestList):
|
||||
raise StopAsyncIteration
|
||||
return self
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
i = self.index
|
||||
request = self.requestList[i]
|
||||
if not request.done():
|
||||
return request
|
||||
|
||||
self.index = i + 1
|
||||
|
||||
result = request.result()
|
||||
if isinstance(result, PandaNode):
|
||||
result = NodePath(result)
|
||||
|
||||
exc = StopIteration(result)
|
||||
exc.value = result
|
||||
raise exc
|
||||
|
||||
def __init__(self, loader, numObjects, gotList, callback, extraArgs):
|
||||
self._loader = loader
|
||||
self.objects = [None] * numObjects
|
||||
@ -81,16 +117,14 @@ class Loader(DirectObject):
|
||||
def __await__(self):
|
||||
""" Returns a generator that raises StopIteration when the loading
|
||||
is complete. This allows this class to be used with 'await'."""
|
||||
|
||||
if self.requests:
|
||||
self._asyncio_future_blocking = True
|
||||
yield self
|
||||
|
||||
# This should be a simple return, but older versions of Python
|
||||
# don't allow return statements with arguments.
|
||||
result = self.result()
|
||||
exc = StopIteration(result)
|
||||
exc.value = result
|
||||
raise exc
|
||||
if self.gotList:
|
||||
return self.ResultAwaiter([self])
|
||||
else:
|
||||
return self.ResultAwaiter(self.requestList)
|
||||
|
||||
def __aiter__(self):
|
||||
""" This allows using `async for` to iterate asynchronously over
|
||||
@ -100,19 +134,7 @@ class Loader(DirectObject):
|
||||
requestList = self.requestList
|
||||
assert requestList is not None, "Request was cancelled."
|
||||
|
||||
class AsyncIter:
|
||||
index = 0
|
||||
def __anext__(self):
|
||||
if self.index < len(requestList):
|
||||
i = self.index
|
||||
self.index = i + 1
|
||||
return requestList[i]
|
||||
else:
|
||||
raise StopAsyncIteration
|
||||
|
||||
iter = AsyncIter()
|
||||
iter.objects = self.objects
|
||||
return iter
|
||||
return self.ResultAwaiter(requestList)
|
||||
|
||||
# special methods
|
||||
def __init__(self, base):
|
||||
|
Loading…
x
Reference in New Issue
Block a user