Copy data from file-like object source_f to file-like object target_f.
(source_f, target_f)
| 111 | |
| 112 | |
| 113 | def copyfileobj(source_f, target_f): |
| 114 | """ |
| 115 | Copy data from file-like object source_f to file-like object target_f. |
| 116 | """ |
| 117 | try: |
| 118 | source_fd = source_f.fileno() |
| 119 | target_fd = target_f.fileno() |
| 120 | except Exception: |
| 121 | pass # Fall through to generic code. |
| 122 | else: |
| 123 | try: |
| 124 | # Use OS copy-on-write where available. |
| 125 | if _ficlone: |
| 126 | try: |
| 127 | _ficlone(source_fd, target_fd) |
| 128 | return |
| 129 | except OSError as err: |
| 130 | if err.errno not in (EBADF, EOPNOTSUPP, ETXTBSY, EXDEV): |
| 131 | raise err |
| 132 | |
| 133 | # Use OS copy where available. |
| 134 | if _fcopyfile: |
| 135 | try: |
| 136 | _fcopyfile(source_fd, target_fd) |
| 137 | return |
| 138 | except OSError as err: |
| 139 | if err.errno not in (EINVAL, ENOTSUP): |
| 140 | raise err |
| 141 | if _copy_file_range: |
| 142 | try: |
| 143 | _copy_file_range(source_fd, target_fd) |
| 144 | return |
| 145 | except OSError as err: |
| 146 | if err.errno not in (ETXTBSY, EXDEV): |
| 147 | raise err |
| 148 | if _sendfile: |
| 149 | try: |
| 150 | _sendfile(source_fd, target_fd) |
| 151 | return |
| 152 | except OSError as err: |
| 153 | if err.errno != ENOTSOCK: |
| 154 | raise err |
| 155 | except OSError as err: |
| 156 | # Produce more useful error messages. |
| 157 | err.filename = source_f.name |
| 158 | err.filename2 = target_f.name |
| 159 | raise err |
| 160 | |
| 161 | # Last resort: copy with fileobj read() and write(). |
| 162 | read_source = source_f.read |
| 163 | write_target = target_f.write |
| 164 | while buf := read_source(1024 * 1024): |
| 165 | write_target(buf) |
| 166 | |
| 167 | |
| 168 | def _open_reader(obj): |
no test coverage detected
searching dependent graphs…