|
2 | 2 | Python implementation of the io module.
|
3 | 3 | """
|
4 | 4 |
|
5 |
| -import os |
6 |
| -import abc |
| 5 | +class _UnsupportedModuleWrapper: |
| 6 | + def __init__(self, module): |
| 7 | + self.__module = module |
| 8 | + def __getattr__(self, attr): |
| 9 | + raise RuntimeError(f"the {self.__module!r} module isn't available") |
| 10 | + |
| 11 | +import sys |
| 12 | +try: |
| 13 | + if 'posix' in sys.builtin_module_names: |
| 14 | + import posix as os |
| 15 | + linesep = '\n' |
| 16 | + else: |
| 17 | + import nt as os |
| 18 | + linesep = '\r\n' |
| 19 | +except ImportError: |
| 20 | + os = _UnsupportedModuleWrapper("_os") |
7 | 21 | import codecs
|
8 | 22 | import errno
|
9 | 23 | import stat
|
10 |
| -import sys |
11 | 24 | # Import _thread instead of threading to reduce startup cost
|
12 | 25 | try:
|
13 | 26 | from _thread import allocate_lock as Lock
|
|
18 | 31 | else:
|
19 | 32 | _setmode = None
|
20 | 33 |
|
21 |
| -import io |
22 |
| -from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END) |
| 34 | +del _UnsupportedModuleWrapper |
| 35 | + |
| 36 | + |
| 37 | +SEEK_SET = 0 |
| 38 | +SEEK_CUR = 1 |
| 39 | +SEEK_END = 2 |
23 | 40 |
|
24 | 41 | valid_seek_flags = {0, 1, 2} # Hardwired values
|
25 | 42 | if hasattr(os, 'SEEK_HOLE') :
|
|
29 | 46 | # open() uses st_blksize whenever we can
|
30 | 47 | DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes
|
31 | 48 |
|
32 |
| -# NOTE: Base classes defined here are registered with the "official" ABCs |
33 |
| -# defined in io.py. We don't use real inheritance though, because we don't want |
34 |
| -# to inherit the C implementations. |
35 |
| - |
36 | 49 | # Rebind for compatibility
|
37 | 50 | BlockingIOError = BlockingIOError
|
38 | 51 |
|
@@ -272,16 +285,11 @@ def __new__(cls, *args, **kwargs):
|
272 | 285 | return open(*args, **kwargs)
|
273 | 286 |
|
274 | 287 |
|
275 |
| -# In normal operation, both `UnsupportedOperation`s should be bound to the |
276 |
| -# same object. |
277 |
| -try: |
278 |
| - UnsupportedOperation = io.UnsupportedOperation |
279 |
| -except AttributeError: |
280 |
| - class UnsupportedOperation(OSError, ValueError): |
281 |
| - pass |
| 288 | +class UnsupportedOperation(OSError, ValueError): |
| 289 | + pass |
282 | 290 |
|
283 | 291 |
|
284 |
| -class IOBase(metaclass=abc.ABCMeta): |
| 292 | +class _IOBase: |
285 | 293 |
|
286 | 294 | """The abstract base class for all I/O classes, acting on streams of
|
287 | 295 | bytes. There is no public constructor.
|
@@ -549,10 +557,8 @@ def writelines(self, lines):
|
549 | 557 | for line in lines:
|
550 | 558 | self.write(line)
|
551 | 559 |
|
552 |
| -io.IOBase.register(IOBase) |
553 |
| - |
554 | 560 |
|
555 |
| -class RawIOBase(IOBase): |
| 561 | +class _RawIOBase(_IOBase): |
556 | 562 |
|
557 | 563 | """Base class for raw binary I/O."""
|
558 | 564 |
|
@@ -613,12 +619,8 @@ def write(self, b):
|
613 | 619 | """
|
614 | 620 | self._unsupported("write")
|
615 | 621 |
|
616 |
| -io.RawIOBase.register(RawIOBase) |
617 |
| -from _io import FileIO |
618 |
| -RawIOBase.register(FileIO) |
619 | 622 |
|
620 |
| - |
621 |
| -class BufferedIOBase(IOBase): |
| 623 | +class _BufferedIOBase(_IOBase): |
622 | 624 |
|
623 | 625 | """Base class for buffered IO objects.
|
624 | 626 |
|
@@ -721,10 +723,8 @@ def detach(self):
|
721 | 723 | """
|
722 | 724 | self._unsupported("detach")
|
723 | 725 |
|
724 |
| -io.BufferedIOBase.register(BufferedIOBase) |
725 |
| - |
726 | 726 |
|
727 |
| -class _BufferedIOMixin(BufferedIOBase): |
| 727 | +class _BufferedIOMixin(_BufferedIOBase): |
728 | 728 |
|
729 | 729 | """A mixin implementation of BufferedIOBase with an underlying raw stream.
|
730 | 730 |
|
@@ -829,7 +829,7 @@ def isatty(self):
|
829 | 829 | return self.raw.isatty()
|
830 | 830 |
|
831 | 831 |
|
832 |
| -class BytesIO(BufferedIOBase): |
| 832 | +class BytesIO(_BufferedIOBase): |
833 | 833 |
|
834 | 834 | """Buffered I/O implementation using an in-memory bytes buffer."""
|
835 | 835 |
|
@@ -1240,7 +1240,7 @@ def seek(self, pos, whence=0):
|
1240 | 1240 | return _BufferedIOMixin.seek(self, pos, whence)
|
1241 | 1241 |
|
1242 | 1242 |
|
1243 |
| -class BufferedRWPair(BufferedIOBase): |
| 1243 | +class BufferedRWPair(_BufferedIOBase): |
1244 | 1244 |
|
1245 | 1245 | """A buffered reader and writer object together.
|
1246 | 1246 |
|
@@ -1387,7 +1387,7 @@ def write(self, b):
|
1387 | 1387 | return BufferedWriter.write(self, b)
|
1388 | 1388 |
|
1389 | 1389 |
|
1390 |
| -class FileIO(RawIOBase): |
| 1390 | +class FileIO(_RawIOBase): |
1391 | 1391 | _fd = -1
|
1392 | 1392 | _created = False
|
1393 | 1393 | _readable = False
|
@@ -1726,7 +1726,7 @@ def mode(self):
|
1726 | 1726 | return 'wb'
|
1727 | 1727 |
|
1728 | 1728 |
|
1729 |
| -class TextIOBase(IOBase): |
| 1729 | +class _TextIOBase(_IOBase): |
1730 | 1730 |
|
1731 | 1731 | """Base class for text I/O.
|
1732 | 1732 |
|
@@ -1791,8 +1791,6 @@ def errors(self):
|
1791 | 1791 | Subclasses should override."""
|
1792 | 1792 | return None
|
1793 | 1793 |
|
1794 |
| -io.TextIOBase.register(TextIOBase) |
1795 |
| - |
1796 | 1794 |
|
1797 | 1795 | class IncrementalNewlineDecoder(codecs.IncrementalDecoder):
|
1798 | 1796 | r"""Codec used when reading a file in universal newlines mode. It wraps
|
@@ -1879,7 +1877,7 @@ def newlines(self):
|
1879 | 1877 | )[self.seennl]
|
1880 | 1878 |
|
1881 | 1879 |
|
1882 |
| -class TextIOWrapper(TextIOBase): |
| 1880 | +class TextIOWrapper(_TextIOBase): |
1883 | 1881 |
|
1884 | 1882 | r"""Character and line based layer over a BufferedIOBase object, buffer.
|
1885 | 1883 |
|
@@ -1950,7 +1948,7 @@ def __init__(self, buffer, encoding=None, errors=None, newline=None,
|
1950 | 1948 | self._readtranslate = newline is None
|
1951 | 1949 | self._readnl = newline
|
1952 | 1950 | self._writetranslate = newline != ''
|
1953 |
| - self._writenl = newline or os.linesep |
| 1951 | + self._writenl = newline or linesep |
1954 | 1952 | self._encoder = None
|
1955 | 1953 | self._decoder = None
|
1956 | 1954 | self._decoded_chars = '' # buffer for text returned from decoder
|
|
0 commit comments