diff --git a/structio/io/files.py b/structio/io/files.py index 616b8fc..c11870c 100644 --- a/structio/io/files.py +++ b/structio/io/files.py @@ -16,7 +16,6 @@ _FILE_SYNC_ATTRS = { "readable", "seekable", "writable", - # not defined in *IOBase: "buffer", "raw", "line_buffering", @@ -27,7 +26,6 @@ _FILE_SYNC_ATTRS = { "getbuffer", } -# This list is also in the docs, make sure to keep them in sync _FILE_ASYNC_METHODS = { "flush", "read", @@ -41,7 +39,6 @@ _FILE_ASYNC_METHODS = { "truncate", "write", "writelines", - # not defined in *IOBase: "readinto1", "peek", } @@ -49,8 +46,10 @@ _FILE_ASYNC_METHODS = { class AsyncResourceWrapper(AsyncResource): """ - Asynchronous wrapper around file-like objects. Blocking - operations are turned into async ones using threads + Asynchronous wrapper around regular file-like objects. + Blocking operations are turned into async ones using threads. + Note that this class can wrap pretty much anything with a fileno() + and read/write methods """ def __init__(self, f): @@ -91,13 +90,12 @@ class AsyncResourceWrapper(AsyncResource): # cache the generated method setattr(self, name, wrapper) return wrapper - raise AttributeError(name) def __dir__(self): attrs = set(super().__dir__()) - attrs.update(a for a in _FILE_SYNC_ATTRS if hasattr(self.wrapped, a)) - attrs.update(a for a in _FILE_ASYNC_METHODS if hasattr(self.wrapped, a)) + attrs.update(a for a in _FILE_SYNC_ATTRS if hasattr(self.handle, a)) + attrs.update(a for a in _FILE_ASYNC_METHODS if hasattr(self.handle, a)) return attrs async def close(self): diff --git a/structio/io/socket.py b/structio/io/socket.py new file mode 100644 index 0000000..9684eee --- /dev/null +++ b/structio/io/socket.py @@ -0,0 +1,4 @@ +import structio +from structio.abc import AsyncResource +from structio.core.syscalls import check_cancelled + diff --git a/tests/files.py b/tests/files.py index 221fdfc..ae4c930 100644 --- a/tests/files.py +++ b/tests/files.py @@ -1,4 +1,6 @@ import structio +import tempfile +import os async def main(): @@ -9,4 +11,17 @@ async def main(): print(f"[main] Exited in {structio.clock() - t:.2f} seconds") +async def main_2(data: bytes): + t = structio.clock() + async with await structio.open_file(os.path.join(tempfile.gettempdir(), "structio_test.txt"), "wb+") as f: + print(f"[main] Opened async file {f.name!r}, writing payload of {len(data)} bytes") + await f.write(data) + await f.seek(0) + assert await f.read(len(data)) == data + print(f"[main] Deleting {f.name!r}") + await structio.thread.run_in_worker(os.unlink, f.name) + print(f"[main] Done in {structio.clock() - t:.2f} seconds") + + structio.run(main) +structio.run(main_2, b"a" * 10000)