| 2602 | return line |
| 2603 | |
| 2604 | def readline(self, size=None): |
| 2605 | if self.closed: |
| 2606 | raise ValueError("read from closed file") |
| 2607 | if size is None: |
| 2608 | size = -1 |
| 2609 | else: |
| 2610 | try: |
| 2611 | size_index = size.__index__ |
| 2612 | except AttributeError: |
| 2613 | raise TypeError(f"{size!r} is not an integer") |
| 2614 | else: |
| 2615 | size = size_index() |
| 2616 | |
| 2617 | # Grab all the decoded text (we will rewind any extra bits later). |
| 2618 | line = self._get_decoded_chars() |
| 2619 | |
| 2620 | start = 0 |
| 2621 | # Make the decoder if it doesn't already exist. |
| 2622 | if not self._decoder: |
| 2623 | self._get_decoder() |
| 2624 | |
| 2625 | pos = endpos = None |
| 2626 | while True: |
| 2627 | if self._readtranslate: |
| 2628 | # Newlines are already translated, only search for \n |
| 2629 | pos = line.find('\n', start) |
| 2630 | if pos >= 0: |
| 2631 | endpos = pos + 1 |
| 2632 | break |
| 2633 | else: |
| 2634 | start = len(line) |
| 2635 | |
| 2636 | elif self._readuniversal: |
| 2637 | # Universal newline search. Find any of \r, \r\n, \n |
| 2638 | # The decoder ensures that \r\n are not split in two pieces |
| 2639 | |
| 2640 | # In C we'd look for these in parallel of course. |
| 2641 | nlpos = line.find("\n", start) |
| 2642 | crpos = line.find("\r", start) |
| 2643 | if crpos == -1: |
| 2644 | if nlpos == -1: |
| 2645 | # Nothing found |
| 2646 | start = len(line) |
| 2647 | else: |
| 2648 | # Found \n |
| 2649 | endpos = nlpos + 1 |
| 2650 | break |
| 2651 | elif nlpos == -1: |
| 2652 | # Found lone \r |
| 2653 | endpos = crpos + 1 |
| 2654 | break |
| 2655 | elif nlpos < crpos: |
| 2656 | # Found \n |
| 2657 | endpos = nlpos + 1 |
| 2658 | break |
| 2659 | elif nlpos == crpos + 1: |
| 2660 | # Found \r\n |
| 2661 | endpos = crpos + 2 |