Prepares the given HTTP body data.
(
self, data: _t.DataType, files: _t.FilesType, json: _t.JsonType = None
)
| 572 | self.headers[to_native_string(name)] = value |
| 573 | |
| 574 | def prepare_body( |
| 575 | self, data: _t.DataType, files: _t.FilesType, json: _t.JsonType = None |
| 576 | ) -> None: |
| 577 | """Prepares the given HTTP body data.""" |
| 578 | |
| 579 | # Check if file, fo, generator, iterator. |
| 580 | # If not, run through normal process. |
| 581 | |
| 582 | # Nottin' on you. |
| 583 | body = None |
| 584 | content_type = None |
| 585 | |
| 586 | if not data and json is not None: |
| 587 | # urllib3 requires a bytes-like body. Python 2's json.dumps |
| 588 | # provides this natively, but Python 3 gives a Unicode string. |
| 589 | content_type = "application/json" |
| 590 | |
| 591 | try: |
| 592 | body = complexjson.dumps(json, allow_nan=False) |
| 593 | except ValueError as ve: |
| 594 | raise InvalidJSONError(ve, request=self) |
| 595 | |
| 596 | if not isinstance(body, bytes): |
| 597 | body = body.encode("utf-8") |
| 598 | |
| 599 | # data that proxies attributes to underlying objects needs hasattr |
| 600 | is_iterable = isinstance(data, Iterable) or hasattr(data, "__iter__") |
| 601 | if is_iterable and not isinstance(data, (str, bytes, list, tuple, Mapping)): |
| 602 | try: |
| 603 | length = super_len(data) |
| 604 | except (TypeError, AttributeError, UnsupportedOperation): |
| 605 | length = None |
| 606 | |
| 607 | body = data |
| 608 | |
| 609 | if getattr(body, "tell", None) is not None: |
| 610 | # Record the current file position before reading. |
| 611 | # This will allow us to rewind a file in the event |
| 612 | # of a redirect. |
| 613 | try: |
| 614 | self._body_position = body.tell() # type: ignore[union-attr] # guarded by getattr check |
| 615 | except OSError: |
| 616 | # This differentiates from None, allowing us to catch |
| 617 | # a failed `tell()` later when trying to rewind the body |
| 618 | self._body_position = object() |
| 619 | |
| 620 | if files: |
| 621 | raise NotImplementedError( |
| 622 | "Streamed bodies and files are mutually exclusive." |
| 623 | ) |
| 624 | |
| 625 | if length: |
| 626 | self.headers["Content-Length"] = builtin_str(length) |
| 627 | else: |
| 628 | self.headers["Transfer-Encoding"] = "chunked" |
| 629 | else: |
| 630 | # After is_stream filtering, remaining data is raw (not streamed) |
| 631 | raw_data = cast("_t.RawDataType | None", data) |
no test coverage detected