makefile.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. # -*- coding: utf-8 -*-
  2. # SPDX-License-Identifier: MIT
  3. """
  4. backports.makefile
  5. ~~~~~~~~~~~~~~~~~~
  6. Backports the Python 3 ``socket.makefile`` method for use with anything that
  7. wants to create a "fake" socket object.
  8. """
  9. import io
  10. from socket import SocketIO
  11. def backport_makefile(self, mode="r", buffering=None, encoding=None,
  12. errors=None, newline=None):
  13. """
  14. Backport of ``socket.makefile`` from Python 3.5.
  15. """
  16. if not set(mode) <= set(["r", "w", "b"]):
  17. raise ValueError(
  18. "invalid mode %r (only r, w, b allowed)" % (mode,)
  19. )
  20. writing = "w" in mode
  21. reading = "r" in mode or not writing
  22. assert reading or writing
  23. binary = "b" in mode
  24. rawmode = ""
  25. if reading:
  26. rawmode += "r"
  27. if writing:
  28. rawmode += "w"
  29. raw = SocketIO(self, rawmode)
  30. self._makefile_refs += 1
  31. if buffering is None:
  32. buffering = -1
  33. if buffering < 0:
  34. buffering = io.DEFAULT_BUFFER_SIZE
  35. if buffering == 0:
  36. if not binary:
  37. raise ValueError("unbuffered streams must be binary")
  38. return raw
  39. if reading and writing:
  40. buffer = io.BufferedRWPair(raw, raw, buffering)
  41. elif reading:
  42. buffer = io.BufferedReader(raw, buffering)
  43. else:
  44. assert writing
  45. buffer = io.BufferedWriter(raw, buffering)
  46. if binary:
  47. return buffer
  48. text = io.TextIOWrapper(buffer, encoding, errors, newline)
  49. text.mode = mode
  50. return text