| 1495 | |
| 1496 | |
| 1497 | class FileIO(RawIOBase): |
| 1498 | _fd = -1 |
| 1499 | _created = False |
| 1500 | _readable = False |
| 1501 | _writable = False |
| 1502 | _appending = False |
| 1503 | _seekable = None |
| 1504 | _truncate = False |
| 1505 | _closefd = True |
| 1506 | |
| 1507 | def __init__(self, file, mode='r', closefd=True, opener=None): |
| 1508 | """Open a file. The mode can be 'r' (default), 'w', 'x' or 'a' for reading, |
| 1509 | writing, exclusive creation or appending. The file will be created if it |
| 1510 | doesn't exist when opened for writing or appending; it will be truncated |
| 1511 | when opened for writing. A FileExistsError will be raised if it already |
| 1512 | exists when opened for creating. Opening a file for creating implies |
| 1513 | writing so this mode behaves in a similar way to 'w'. Add a '+' to the mode |
| 1514 | to allow simultaneous reading and writing. A custom opener can be used by |
| 1515 | passing a callable as *opener*. The underlying file descriptor for the file |
| 1516 | object is then obtained by calling opener with (*name*, *flags*). |
| 1517 | *opener* must return an open file descriptor (passing os.open as *opener* |
| 1518 | results in functionality similar to passing None). |
| 1519 | """ |
| 1520 | if self._fd >= 0: |
| 1521 | # Have to close the existing file first. |
| 1522 | self._stat_atopen = None |
| 1523 | try: |
| 1524 | if self._closefd: |
| 1525 | os.close(self._fd) |
| 1526 | finally: |
| 1527 | self._fd = -1 |
| 1528 | |
| 1529 | if isinstance(file, float): |
| 1530 | raise TypeError('integer argument expected, got float') |
| 1531 | if isinstance(file, int): |
| 1532 | if isinstance(file, bool): |
| 1533 | import warnings |
| 1534 | warnings.warn("bool is used as a file descriptor", |
| 1535 | RuntimeWarning, stacklevel=2) |
| 1536 | file = int(file) |
| 1537 | fd = file |
| 1538 | if fd < 0: |
| 1539 | raise ValueError('negative file descriptor') |
| 1540 | else: |
| 1541 | fd = -1 |
| 1542 | |
| 1543 | if not isinstance(mode, str): |
| 1544 | raise TypeError('invalid mode: %s' % (mode,)) |
| 1545 | if not set(mode) <= set('xrwab+'): |
| 1546 | raise ValueError('invalid mode: %s' % (mode,)) |
| 1547 | if sum(c in 'rwax' for c in mode) != 1 or mode.count('+') > 1: |
| 1548 | raise ValueError('Must have exactly one of create/read/write/append ' |
| 1549 | 'mode and at most one plus') |
| 1550 | |
| 1551 | if 'x' in mode: |
| 1552 | self._created = True |
| 1553 | self._writable = True |
| 1554 | flags = os.O_EXCL | os.O_CREAT |