first commit
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""Handle files using a thread pool executor."""
|
||||
import asyncio
|
||||
|
||||
from io import (FileIO, TextIOBase, BufferedReader, BufferedWriter,
|
||||
BufferedRandom)
|
||||
from functools import partial, singledispatch
|
||||
|
||||
from .binary import AsyncBufferedIOBase, AsyncBufferedReader, AsyncFileIO
|
||||
from .text import AsyncTextIOWrapper
|
||||
from ..base import AiofilesContextManager
|
||||
|
||||
sync_open = open
|
||||
|
||||
__all__ = ('open', )
|
||||
|
||||
|
||||
def open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None,
|
||||
closefd=True, opener=None, *, loop=None, executor=None):
|
||||
return AiofilesContextManager(_open(file, mode=mode, buffering=buffering,
|
||||
encoding=encoding, errors=errors,
|
||||
newline=newline, closefd=closefd,
|
||||
opener=opener, loop=loop,
|
||||
executor=executor))
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def _open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None,
|
||||
closefd=True, opener=None, *, loop=None, executor=None):
|
||||
"""Open an asyncio file."""
|
||||
if loop is None:
|
||||
loop = asyncio.get_event_loop()
|
||||
cb = partial(sync_open, file, mode=mode, buffering=buffering,
|
||||
encoding=encoding, errors=errors, newline=newline,
|
||||
closefd=closefd, opener=opener)
|
||||
f = yield from loop.run_in_executor(executor, cb)
|
||||
|
||||
return wrap(f, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@singledispatch
|
||||
def wrap(file, *, loop=None, executor=None):
|
||||
raise TypeError('Unsupported io type: {}.'.format(file))
|
||||
|
||||
|
||||
@wrap.register(TextIOBase)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncTextIOWrapper(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(BufferedWriter)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncBufferedIOBase(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(BufferedReader)
|
||||
@wrap.register(BufferedRandom)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncBufferedReader(file, loop=loop, executor=executor)
|
||||
|
||||
|
||||
@wrap.register(FileIO)
|
||||
def _(file, *, loop=None, executor=None):
|
||||
return AsyncFileIO(file, loop, executor)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
from ..base import AsyncBase
|
||||
from .utils import (delegate_to_executor, proxy_property_directly,
|
||||
proxy_method_directly)
|
||||
|
||||
|
||||
@delegate_to_executor('close', 'flush', 'isatty', 'read', 'read1', 'readinto',
|
||||
'readline', 'readlines', 'seek', 'seekable', 'tell',
|
||||
'truncate', 'writable', 'write', 'writelines')
|
||||
@proxy_method_directly('detach', 'fileno', 'readable')
|
||||
@proxy_property_directly('closed', 'raw')
|
||||
class AsyncBufferedIOBase(AsyncBase):
|
||||
"""The asyncio executor version of io.BufferedWriter."""
|
||||
|
||||
|
||||
@delegate_to_executor('peek')
|
||||
class AsyncBufferedReader(AsyncBufferedIOBase):
|
||||
"""The asyncio executor version of io.BufferedReader and Random."""
|
||||
|
||||
|
||||
@delegate_to_executor('close', 'flush', 'isatty', 'read', 'readall', 'readinto',
|
||||
'readline', 'readlines', 'seek', 'seekable', 'tell',
|
||||
'truncate', 'writable', 'write', 'writelines')
|
||||
@proxy_method_directly('fileno', 'readable')
|
||||
@proxy_property_directly('closed')
|
||||
class AsyncFileIO(AsyncBase):
|
||||
"""The asyncio executor version of io.FileIO."""
|
||||
@@ -0,0 +1,13 @@
|
||||
from .utils import (delegate_to_executor, proxy_property_directly,
|
||||
proxy_method_directly)
|
||||
from ..base import AsyncBase
|
||||
|
||||
|
||||
@delegate_to_executor('close', 'flush', 'isatty', 'read', 'readable',
|
||||
'readline', 'readlines', 'seek', 'seekable', 'tell',
|
||||
'truncate', 'write', 'writable', 'writelines')
|
||||
@proxy_method_directly('detach', 'fileno', 'readable')
|
||||
@proxy_property_directly('buffer', 'closed', 'encoding', 'errors',
|
||||
'line_buffering', 'newlines')
|
||||
class AsyncTextIOWrapper(AsyncBase):
|
||||
"""The asyncio executor version of io.TextIOWrapper."""
|
||||
@@ -0,0 +1,49 @@
|
||||
import asyncio
|
||||
import functools
|
||||
|
||||
|
||||
def delegate_to_executor(*attrs):
|
||||
def cls_builder(cls):
|
||||
for attr_name in attrs:
|
||||
setattr(cls, attr_name, _make_delegate_method(attr_name))
|
||||
return cls
|
||||
return cls_builder
|
||||
|
||||
|
||||
def proxy_method_directly(*attrs):
|
||||
def cls_builder(cls):
|
||||
for attr_name in attrs:
|
||||
setattr(cls, attr_name, _make_proxy_method(attr_name))
|
||||
return cls
|
||||
|
||||
return cls_builder
|
||||
|
||||
|
||||
def proxy_property_directly(*attrs):
|
||||
def cls_builder(cls):
|
||||
for attr_name in attrs:
|
||||
setattr(cls, attr_name, _make_proxy_property(attr_name))
|
||||
return cls
|
||||
|
||||
return cls_builder
|
||||
|
||||
|
||||
def _make_delegate_method(attr_name):
|
||||
@asyncio.coroutine
|
||||
def method(self, *args, **kwargs):
|
||||
cb = functools.partial(getattr(self._file, attr_name),
|
||||
*args, **kwargs)
|
||||
return (yield from self._loop.run_in_executor(self._executor, cb))
|
||||
return method
|
||||
|
||||
|
||||
def _make_proxy_method(attr_name):
|
||||
def method(self, *args, **kwargs):
|
||||
return getattr(self._file, attr_name)(*args, **kwargs)
|
||||
return method
|
||||
|
||||
|
||||
def _make_proxy_property(attr_name):
|
||||
def proxy_property(self):
|
||||
return getattr(self._file, attr_name)
|
||||
return property(proxy_property)
|
||||
Reference in New Issue
Block a user