base.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. """Various base classes."""
  2. from types import coroutine
  3. from collections.abc import Coroutine
  4. class AsyncBase:
  5. def __init__(self, file, loop, executor):
  6. self._file = file
  7. self._loop = loop
  8. self._executor = executor
  9. def __aiter__(self):
  10. """We are our own iterator."""
  11. return self
  12. def __repr__(self):
  13. return super().__repr__() + " wrapping " + repr(self._file)
  14. async def __anext__(self):
  15. """Simulate normal file iteration."""
  16. line = await self.readline()
  17. if line:
  18. return line
  19. else:
  20. raise StopAsyncIteration
  21. class _ContextManager(Coroutine):
  22. __slots__ = ("_coro", "_obj")
  23. def __init__(self, coro):
  24. self._coro = coro
  25. self._obj = None
  26. def send(self, value):
  27. return self._coro.send(value)
  28. def throw(self, typ, val=None, tb=None):
  29. if val is None:
  30. return self._coro.throw(typ)
  31. elif tb is None:
  32. return self._coro.throw(typ, val)
  33. else:
  34. return self._coro.throw(typ, val, tb)
  35. def close(self):
  36. return self._coro.close()
  37. @property
  38. def gi_frame(self):
  39. return self._coro.gi_frame
  40. @property
  41. def gi_running(self):
  42. return self._coro.gi_running
  43. @property
  44. def gi_code(self):
  45. return self._coro.gi_code
  46. def __next__(self):
  47. return self.send(None)
  48. @coroutine
  49. def __iter__(self):
  50. resp = yield from self._coro
  51. return resp
  52. def __await__(self):
  53. resp = yield from self._coro
  54. return resp
  55. async def __anext__(self):
  56. resp = await self._coro
  57. return resp
  58. async def __aenter__(self):
  59. self._obj = await self._coro
  60. return self._obj
  61. async def __aexit__(self, exc_type, exc, tb):
  62. self._obj.close()
  63. self._obj = None
  64. class AiofilesContextManager(_ContextManager):
  65. """An adjusted async context manager for aiofiles."""
  66. async def __aexit__(self, exc_type, exc_val, exc_tb):
  67. await self._obj.close()
  68. self._obj = None