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