← baseline_full_v2

requests_7433

failed NO_PATCH NO_PATCH UNSUBMITTED empty_patch(None) · None tool calls · 0 s · psf/requests

Task input

Fix `prepare_body` stream detection for `__getattr__`-based file wrappers

Resolves #7432 .

Add `hasattr(data, "__iter__")` as a fallback stream detector:
```python
if (
    isinstance(data, Iterable) or hasattr(data, "__iter__")
) and not isinstance(data, (str, bytes, list, tuple, Mapping)):
```
This catches file-like objects that proxy their interface through `__getattr__`, restoring the 2.33.1 behavior without reverting the isinstance(Iterable) modernization for standard iterables.

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Test output

show
equests.TestRequests object at 0x1031fac60>
httpbin = <function prepare_url.<locals>.inner at 0x10436a340>

    def test_getattr_proxy_stream_follows_redirect(self, httpbin):
        """Ensure stream wrappers that don't implement __iter__ directly are still detected."""
    
        class AttrProxy:
            def __init__(self):
                self._file = io.BytesIO(b"data")
    
            def __getattr__(self, name):
                return getattr(self._file, name)
    
>       r = requests.post(
            httpbin("redirect-to?url=/post&status_code=307"), data=AttrProxy()
        )

tests/test_requests.py:2086: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/api.py:134: in post
    return request("post", url, data=data, json=json, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/api.py:71: in request
    return session.request(method=method, url=url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/sessions.py:635: in request
    prep = self.prepare_request(req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/sessions.py:541: in prepare_request
    p.prepare(
/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/models.py:442: in prepare
    self.prepare_body(data, files, json)
/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/models.py:638: in prepare_body
    body = self._encode_params(raw_data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/models.py:168: in _encode_params
    for k, vs in to_key_val_list(data):
                 ^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

value = <tests.test_requests.TestRequests.test_getattr_proxy_stream_follows_redirect.<locals>.AttrProxy object at 0x10328b0e0>

    def to_key_val_list(
        value: _t.SupportsItems[_KT, _VT] | Iterable[tuple[_KT, _VT]] | None,
    ) -> list[tuple[_KT, _VT]] | None:
        """Take an object and test to see if it can be represented as a
        dictionary. If it can be, return a list of tuples, e.g.,
    
        ::
    
            >>> to_key_val_list([('key', 'val')])
            [('key', 'val')]
            >>> to_key_val_list({'key': 'val'})
            [('key', 'val')]
            >>> to_key_val_list('string')
            Traceback (most recent call last):
            ...
            ValueError: cannot encode objects that are not 2-tuples
    
        :rtype: list
        """
        if value is None:
            return None
    
        if isinstance(value, (str, bytes, bool, int)):
            raise ValueError("cannot encode objects that are not 2-tuples")
    
        if isinstance(value, _SupportsItems):
            return list(value.items())
    
>       return list(value)
               ^^^^^^^^^^^
E       TypeError: 'AttrProxy' object is not iterable

/tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/utils.py:404: TypeError
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/requests/lib/python3.13/site-packages/_pytest/config/__init__.py:1464
  /Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/requests/lib/python3.13/site-packages/_pytest/config/__init__.py:1464: PytestConfigWarning: Unknown config option: timeout
  
    self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
  /tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/auth.py:45: DeprecationWarning: Non-string usernames will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (42) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
tests/test_requests.py::TestRequests::test_set_basicauth[42-42]
  /tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/auth.py:55: DeprecationWarning: Non-string passwords will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (<class 'int'>) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
  /tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/auth.py:45: DeprecationWarning: Non-string usernames will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (None) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
tests/test_requests.py::TestRequests::test_set_basicauth[None-None]
  /tmp/swe_work/baseline_full_v2/requests_7433/b/workspace/src/requests/auth.py:55: DeprecationWarning: Non-string passwords will no longer be supported in Requests 3.0.0. Please convert the object you've passed in (<class 'NoneType'>) to a string or bytes object in the near future to avoid problems.
    warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
1 failed, 229 passed, 1 skipped, 9 warnings in 1.10s
[2026-09-23 20:58:08,832] WARNING in core: flasgger is not installed; serving the static landing page at / and skipping the Swagger UI and /spec.json.
127.0.0.1 - - [23/Sep/2026 20:58:09] "GET /status/404 HTTP/1.1" 404 0