1"""Handle files using a thread pool executor."""
2import asyncio
3from types import coroutine
4
5from io import (
6    FileIO,
7    TextIOBase,
8    BufferedReader,
9    BufferedWriter,
10    BufferedRandom,
11)
12from functools import partial, singledispatch
13
14from .binary import AsyncBufferedIOBase, AsyncBufferedReader, AsyncFileIO
15from .text import AsyncTextIOWrapper
16from ..base import AiofilesContextManager
17
18sync_open = open
19
20__all__ = ("open",)
21
22
23def open(
24    file,
25    mode="r",
26    buffering=-1,
27    encoding=None,
28    errors=None,
29    newline=None,
30    closefd=True,
31    opener=None,
32    *,
33    loop=None,
34    executor=None
35):
36    return AiofilesContextManager(
37        _open(
38            file,
39            mode=mode,
40            buffering=buffering,
41            encoding=encoding,
42            errors=errors,
43            newline=newline,
44            closefd=closefd,
45            opener=opener,
46            loop=loop,
47            executor=executor,
48        )
49    )
50
51
52@coroutine
53def _open(
54    file,
55    mode="r",
56    buffering=-1,
57    encoding=None,
58    errors=None,
59    newline=None,
60    closefd=True,
61    opener=None,
62    *,
63    loop=None,
64    executor=None
65):
66    """Open an asyncio file."""
67    if loop is None:
68        loop = asyncio.get_event_loop()
69    cb = partial(
70        sync_open,
71        file,
72        mode=mode,
73        buffering=buffering,
74        encoding=encoding,
75        errors=errors,
76        newline=newline,
77        closefd=closefd,
78        opener=opener,
79    )
80    f = yield from loop.run_in_executor(executor, cb)
81
82    return wrap(f, loop=loop, executor=executor)
83
84
85@singledispatch
86def wrap(file, *, loop=None, executor=None):
87    raise TypeError("Unsupported io type: {}.".format(file))
88
89
90@wrap.register(TextIOBase)
91def _(file, *, loop=None, executor=None):
92    return AsyncTextIOWrapper(file, loop=loop, executor=executor)
93
94
95@wrap.register(BufferedWriter)
96def _(file, *, loop=None, executor=None):
97    return AsyncBufferedIOBase(file, loop=loop, executor=executor)
98
99
100@wrap.register(BufferedReader)
101@wrap.register(BufferedRandom)
102def _(file, *, loop=None, executor=None):
103    return AsyncBufferedReader(file, loop=loop, executor=executor)
104
105
106@wrap.register(FileIO)
107def _(file, *, loop=None, executor=None):
108    return AsyncFileIO(file, loop, executor)
109