Build the body for a multipart/form-data request. Will successfully encode files when passed as a dict or a list of tuples. Order is retained if data is a list of tuples but arbitrary if parameters are supplied as a dict. The tuples may be 2-tuples (filename, fileobj
(
files: _t.FilesType, data: _t.RawDataType | None
)
| 182 | |
| 183 | @staticmethod |
| 184 | def _encode_files( |
| 185 | files: _t.FilesType, data: _t.RawDataType | None |
| 186 | ) -> tuple[bytes, str]: |
| 187 | """Build the body for a multipart/form-data request. |
| 188 | |
| 189 | Will successfully encode files when passed as a dict or a list of |
| 190 | tuples. Order is retained if data is a list of tuples but arbitrary |
| 191 | if parameters are supplied as a dict. |
| 192 | The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) |
| 193 | or 4-tuples (filename, fileobj, contentype, custom_headers). |
| 194 | """ |
| 195 | if not files: |
| 196 | raise ValueError("Files must be provided.") |
| 197 | elif isinstance(data, basestring): |
| 198 | raise ValueError("Data must not be a string.") |
| 199 | |
| 200 | new_fields: list[RequestField | tuple[str, bytes]] = [] |
| 201 | fields = to_key_val_list(data or {}) |
| 202 | files = to_key_val_list(files or {}) |
| 203 | |
| 204 | for field, val in fields: |
| 205 | if isinstance(val, basestring) or not hasattr(val, "__iter__"): |
| 206 | val = [val] |
| 207 | for v in val: |
| 208 | if v is not None: |
| 209 | # Don't call str() on bytestrings: in Py3 it all goes wrong. |
| 210 | if not isinstance(v, bytes): |
| 211 | v = str(v) |
| 212 | |
| 213 | new_fields.append( |
| 214 | ( |
| 215 | field.decode("utf-8") |
| 216 | if isinstance(field, bytes) |
| 217 | else field, |
| 218 | v.encode("utf-8") if isinstance(v, str) else v, |
| 219 | ) |
| 220 | ) |
| 221 | |
| 222 | for k, v in files: |
| 223 | # support for explicit filename |
| 224 | ft = None |
| 225 | fh = None |
| 226 | if isinstance(v, (tuple, list)): |
| 227 | if len(v) == 2: |
| 228 | fn, fp = v |
| 229 | elif len(v) == 3: |
| 230 | fn, fp, ft = v |
| 231 | else: |
| 232 | fn, fp, ft, fh = v |
| 233 | else: |
| 234 | fn = guess_filename(v) or k |
| 235 | fp = v |
| 236 | |
| 237 | if isinstance(fp, (str, bytes, bytearray)): |
| 238 | fdata = fp |
| 239 | elif isinstance(fp, _SupportsRead): # type: ignore[reportUnnecessaryIsInstance] # defensive check for untyped callers |
| 240 | fdata = fp.read() |
| 241 | elif fp is None: # type: ignore[reportUnnecessaryComparison] # defensive check for untyped callers |
no test coverage detected