← pod_r5_v1h

requests_6644

resolved RESOLVED PASS · 22 tool calls · 106 s · psf/requests

Task input

Trim excess leading path separators

A URL with excess leading / (path-separator)s would cause urllib3 to attempt to reparse the request-uri as a full URI with a host and port. This bypasses that logic in ConnectionPool.urlopen by replacing these leading /s with just a single /.

Closes #6643

Tool calls (23)

#ToolArgumentsResult
1run_command
{
 "command": "grep -rn \"ConnectionPool.urlopen\" src/requests"
}
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
full
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
2run_command
{
 "command": "grep -rn \"leading /\" src/requests"
}
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
full
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
3run_command
{
 "command": "grep -rn \"PreparedRequest\" src/requests | head -20"
}
{"status": "ok", "stdout": "src/requests/sessions.py:36: PreparedRequest,\nsrc/requests/sessions.py:458: \"\"\"Constructs a :class:`PreparedRequest <PreparedReq
full
{"status": "ok", "stdout": "src/requests/sessions.py:36:    PreparedRequest,\nsrc/requests/sessions.py:458:        \"\"\"Constructs a :class:`PreparedRequest <PreparedRequest>` for\nsrc/requests/sessions.py:459:        transmission and returns it. The :class:`PreparedRequest` has settings\nsrc/requests/sessions.py:465:        :rtype: requests.PreparedRequest\nsrc/requests/sessions.py:483:        p = PreparedRequest()\nsrc/requests/sessions.py:674:        \"\"\"Send a given PreparedRequest.\nsrc/requests/sessions.py:689:            raise ValueError(\"You can only send PreparedRequests.\")\nsrc/requests/models.py:233:    Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server.\nsrc/requests/models.py:255:      <PreparedRequest [GET]>\nsrc/requests/models.py:296:        \"\"\"Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.\"\"\"\nsrc/requests/models.py:297:        p = PreparedRequest()\nsrc/requests/models.py:313:class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):\nsrc/requests/models.py:314:    \"\"\"The fully mutable :class:`PreparedRequest <PreparedRequest>` object,\nsrc/requests/models.py:327:      <PreparedRequest [GET]>\nsrc/requests/models.py:380:        return f\"<PreparedRequest [{self.method}]>\"\nsrc/requests/models.py:383:        p = PreparedRequest()\nsrc/requests/models.py:617:        :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls\nsrc/requests/models.py:701:        #: The :class:`PreparedRequest <PreparedRequest>` object to which this\nsrc/requests/models.py:786:        \"\"\"Returns a PreparedRequest for the next request in a redirect chain, if there is one.\"\"\"\nsrc/requests/__init__.py:173:from .models import PreparedRequest, Request, Response\n", "stderr": "", "exit_code": 0}
4run_command
{
 "command": "grep -rn \"PreparedRequest\" src/requests/models.py | grep \"def\""
}
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
full
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
5run_command
{
 "command": "grep -rn \"prepare_url\" src/requests"
}
{"status": "ok", "stdout": "src/requests/models.py:367: self.prepare_url(url, params)\nsrc/requests/models.py:409: def prepare_url(self, url, params):\n", "stde
full
{"status": "ok", "stdout": "src/requests/models.py:367:        self.prepare_url(url, params)\nsrc/requests/models.py:409:    def prepare_url(self, url, params):\n", "stderr": "", "exit_code": 0}
6run_command
{
 "command": "sed -n '409,450p' src/requests/models.py"
}
{"status": "ok", "stdout": " def prepare_url(self, url, params):\n \"\"\"Prepares the given HTTP URL.\"\"\"\n #: Accept objects that have string representations
full
{"status": "ok", "stdout": "    def prepare_url(self, url, params):\n        \"\"\"Prepares the given HTTP URL.\"\"\"\n        #: Accept objects that have string representations.\n        #: We're unable to blindly call unicode/str functions\n        #: as this will include the bytestring indicator (b'')\n        #: on python 3.x.\n        #: https://github.com/psf/requests/pull/2238\n        if isinstance(url, bytes):\n            url = url.decode(\"utf8\")\n        else:\n            url = str(url)\n\n        # Remove leading whitespaces from url\n        url = url.lstrip()\n\n        # Don't do any URL preparation for non-HTTP schemes like `mailto`,\n        # `data` etc to work around exceptions from `url_parse`, which\n        # handles RFC 3986 only.\n        if \":\" in url and not url.lower().startswith(\"http\"):\n            self.url = url\n            return\n\n        # Support for unicode domain names and paths.\n        try:\n            scheme, auth, host, port, path, query, fragment = parse_url(url)\n        except LocationParseError as e:\n            raise InvalidURL(*e.args)\n\n        if not scheme:\n            raise MissingSchema(\n                f\"Invalid URL {url!r}: No scheme supplied. \"\n                f\"Perhaps you meant https://{url}?\"\n            )\n\n        if not host:\n            raise InvalidURL(f\"Invalid URL {url!r}: No host supplied\")\n\n        # In general, we want to try IDNA encoding the hostname if the string contains\n        # non-ASCII characters. This allows users to automatically get the correct IDNA\n        # behaviour. For strings containing only ASCII characters, we need to also verify\n        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.\n        if not unicode_is_ascii(host):\n", "stderr": "", "exit_code": 0}
7run_command
{
 "command": "sed -n '409,550p' src/requests/models.py"
}
{"status": "ok", "stdout": " def prepare_url(self, url, params):\n \"\"\"Prepares the given HTTP URL.\"\"\"\n #: Accept objects that have string representations
full
{"status": "ok", "stdout": "    def prepare_url(self, url, params):\n        \"\"\"Prepares the given HTTP URL.\"\"\"\n        #: Accept objects that have string representations.\n        #: We're unable to blindly call unicode/str functions\n        #: as this will include the bytestring indicator (b'')\n        #: on python 3.x.\n        #: https://github.com/psf/requests/pull/2238\n        if isinstance(url, bytes):\n            url = url.decode(\"utf8\")\n        else:\n            url = str(url)\n\n        # Remove leading whitespaces from url\n        url = url.lstrip()\n\n        # Don't do any URL preparation for non-HTTP schemes like `mailto`,\n        # `data` etc to work around exceptions from `url_parse`, which\n        # handles RFC 3986 only.\n        if \":\" in url and not url.lower().startswith(\"http\"):\n            self.url = url\n            return\n\n        # Support for unicode domain names and paths.\n        try:\n            scheme, auth, host, port, path, query, fragment = parse_url(url)\n        except LocationParseError as e:\n            raise InvalidURL(*e.args)\n\n        if not scheme:\n            raise MissingSchema(\n                f\"Invalid URL {url!r}: No scheme supplied. \"\n                f\"Perhaps you meant https://{url}?\"\n            )\n\n        if not host:\n            raise InvalidURL(f\"Invalid URL {url!r}: No host supplied\")\n\n        # In general, we want to try IDNA encoding the hostname if the string contains\n        # non-ASCII characters. This allows users to automatically get the correct IDNA\n        # behaviour. For strings containing only ASCII characters, we need to also verify\n        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.\n        if not unicode_is_ascii(host):\n            try:\n                host = self._get_idna_encoded_host(host)\n            except UnicodeError:\n                raise InvalidURL(\"URL has an invalid label.\")\n        elif host.star
8run_command
{
 "command": "grep -rn \"requote_uri\" src/requests"
}
{"status": "ok", "stdout": "src/requests/sessions.py:47: requote_uri,\nsrc/requests/sessions.py:215: url = urljoin(resp.url, requote_uri(url))\nsrc/requests/ses
full
{"status": "ok", "stdout": "src/requests/sessions.py:47:    requote_uri,\nsrc/requests/sessions.py:215:                url = urljoin(resp.url, requote_uri(url))\nsrc/requests/sessions.py:217:                url = requote_uri(url)\nsrc/requests/models.py:63:    requote_uri,\nsrc/requests/models.py:480:        url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))\nsrc/requests/utils.py:655:def requote_uri(uri):\n", "stderr": "", "exit_code": 0}
9run_command
{
 "command": "sed -n '655,700p' src/requests/utils.py"
}
{"status": "ok", "stdout": "def requote_uri(uri):\n \"\"\"Re-quote the given URI.\n\n This function passes the given URI through an unquote/quote cycle to\n ens
full
{"status": "ok", "stdout": "def requote_uri(uri):\n    \"\"\"Re-quote the given URI.\n\n    This function passes the given URI through an unquote/quote cycle to\n    ensure that it is fully and consistently quoted.\n\n    :rtype: str\n    \"\"\"\n    safe_with_percent = \"!#$%&'()*+,/:;=?@[]~\"\n    safe_without_percent = \"!#$&'()*+,/:;=?@[]~\"\n    try:\n        # Unquote only the unreserved characters\n        # Then quote only illegal characters (do not quote reserved,\n        # unreserved, or '%')\n        return quote(unquote_unreserved(uri), safe=safe_with_percent)\n    except InvalidURL:\n        # We couldn't unquote the given URI, so let's try quoting it, but\n        # there may be unquoted '%'s in the URI. We need to make sure they're\n        # properly quoted so they do not cause issues elsewhere.\n        return quote(uri, safe=safe_without_percent)\n\n\ndef address_in_network(ip, net):\n    \"\"\"This function allows you to check if an IP belongs to a network subnet\n\n    Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24\n             returns False if ip = 192.168.1.1 and net = 192.168.100.0/24\n\n    :rtype: bool\n    \"\"\"\n    ipaddr = struct.unpack(\"=L\", socket.inet_aton(ip))[0]\n    netaddr, bits = net.split(\"/\")\n    netmask = struct.unpack(\"=L\", socket.inet_aton(dotted_netmask(int(bits))))[0]\n    network = struct.unpack(\"=L\", socket.inet_aton(netaddr))[0] & netmask\n    return (ipaddr & netmask) == (network & netmask)\n\n\ndef dotted_netmask(mask):\n    \"\"\"Converts mask from /xx format to xxx.xxx.xxx.xxx\n\n    Example: if mask is 24 function returns 255.255.255.0\n\n    :rtype: str\n    \"\"\"\n    bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1\n    return socket.inet_ntoa(struct.pack(\">I\", bits))\n", "stderr": "", "exit_code": 0}
10run_command
{
 "command": "sed -n '450,480p' src/requests/models.py"
}
{"status": "ok", "stdout": " if not unicode_is_ascii(host):\n try:\n host = self._get_idna_encoded_host(host)\n except UnicodeError:\n raise InvalidURL(\"URL ha
full
{"status": "ok", "stdout": "        if not unicode_is_ascii(host):\n            try:\n                host = self._get_idna_encoded_host(host)\n            except UnicodeError:\n                raise InvalidURL(\"URL has an invalid label.\")\n        elif host.startswith((\"*\", \".\")):\n            raise InvalidURL(\"URL has an invalid label.\")\n\n        # Carefully reconstruct the network location\n        netloc = auth or \"\"\n        if netloc:\n            netloc += \"@\"\n        netloc += host\n        if port:\n            netloc += f\":{port}\"\n\n        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n\n        if isinstance(params, (str, bytes)):\n            params = to_native_string(params)\n\n        enc_params = self._encode_params(params)\n        if enc_params:\n            if query:\n                query = f\"{query}&{enc_params}\"\n            else:\n                query = enc_params\n\n        url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))\n", "stderr": "", "exit_code": 0}
11run_command
{
 "command": "grep -rn \"parse_url\" src/requests"
}
{"status": "ok", "stdout": "src/requests/models.py:25:from urllib3.util import parse_url\nsrc/requests/models.py:433: scheme, auth, host, port, path, query, fra
full
{"status": "ok", "stdout": "src/requests/models.py:25:from urllib3.util import parse_url\nsrc/requests/models.py:433:            scheme, auth, host, port, path, query, fragment = parse_url(url)\nsrc/requests/utils.py:22:from urllib3.util import make_headers, parse_url\nsrc/requests/utils.py:990:    parsed = parse_url(url)\nsrc/requests/utils.py:996:    # maintained with parse_url for backwards compatibility.\nsrc/requests/utils.py:1002:        # parse_url doesn't provide the netloc with auth\nsrc/requests/adapters.py:26:from urllib3.util import parse_url\nsrc/requests/adapters.py:343:            proxy_url = parse_url(proxy)\n", "stderr": "", "exit_code": 0}
12run_command
{
 "command": "cat > /tmp/check_leading_slashes.py <<'PY'\nimport requests\nfrom requests.models import PreparedRequest\n\ndef test_leading_slashes():\n    p = PreparedRequest()\n    url = \"http://example.com//path\"\n    p.prepare_url(url, params=None)\n    print(f\"URL: {url} -> Prepared: {p.url}\")\n    \n    url2 = \"http://example.com///path\"\n    p.prepare_url(url2, params=None)\n    print(f\"URL: {url2} -> Prepared: {p.url}\")\n\nif __name__ == \"__main__\":\n    test_leading_slashes()\nPY\npython3 /tmp/check_leading_slashes.py\n"
}
{"status": "ok", "stdout": "URL: http://example.com//path -> Prepared: http://example.com//path\nURL: http://example.com///path -> Prepared: http://example.com/
full
{"status": "ok", "stdout": "URL: http://example.com//path -> Prepared: http://example.com//path\nURL: http://example.com///path -> Prepared: http://example.com///path\n", "stderr": "", "exit_code": 0}
13run_command
{
 "command": "sed -n '460,480p' src/requests/models.py"
}
{"status": "ok", "stdout": " if netloc:\n netloc += \"@\"\n netloc += host\n if port:\n netloc += f\":{port}\"\n\n # Bare domains aren't valid URLs.\n if not pa
full
{"status": "ok", "stdout": "        if netloc:\n            netloc += \"@\"\n        netloc += host\n        if port:\n            netloc += f\":{port}\"\n\n        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n\n        if isinstance(params, (str, bytes)):\n            params = to_native_string(params)\n\n        enc_params = self._encode_params(params)\n        if enc_params:\n            if query:\n                query = f\"{query}&{enc_params}\"\n            else:\n                query = enc_params\n\n        url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))\n", "stderr": "", "exit_code": 0}
14run_command
{
 "command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"src/requests/models.py\"); s = p.read_text()\nold = \"\"\"        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n\"\"\"\nnew = \"\"\"        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n        elif path.startswith(\"//\"):\n            path = \"/\" + path.lstrip(\"/\")\n\"\"\"\nassert s.count(old) == 1, (\"old text found this many times:\", s.count(old))\nt = s.replace(old, new); compile(t, str(p), \"exec\"); p.write_text(t)\nPY\n\"\"\""
}
{"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: -c: line 16: unexpected EOF while looking for matching `\"'\n/bin/bash: -c: line
full
{"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: -c: line 16: unexpected EOF while looking for matching `\"'\n/bin/bash: -c: line 17: syntax error: unexpected end of file\n", "details": {"stdout": "", "stderr": "/bin/bash: -c: line 16: unexpected EOF while looking for matching `\"'\n/bin/bash: -c: line 17: syntax error: unexpected end of file\n", "exit_code": 2}}
15run_command
{
 "command": "python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"src/requests/models.py\"); s = p.read_text()\nold = \"\"\"        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n\"\"\"\nnew = \"\"\"        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n        elif path.startswith(\"//\"):\n            path = \"/\" + path.lstrip(\"/\")\n\"\"\"\nt = s.replace(old, new)\np.write_text(t)\nPY\n"
}
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
16run_command
{
 "command": "python3 /tmp/check_leading_slashes.py"
}
{"status": "ok", "stdout": "URL: http://example.com//path -> Prepared: http://example.com/path\nURL: http://example.com///path -> Prepared: http://example.com/p
full
{"status": "ok", "stdout": "URL: http://example.com//path -> Prepared: http://example.com/path\nURL: http://example.com///path -> Prepared: http://example.com/path\n", "stderr": "", "exit_code": 0}
17run_command
{
 "command": "python3 - <<'PY'\nimport requests\nfrom requests.models import PreparedRequest\n\ndef test_leading_slashes():\n    p = PreparedRequest()\n    \n    # Test multiple leading slashes\n    url = \"http://example.com//path\"\n    p.prepare_url(url, params=None)\n    assert p.url == \"http://example.com/path\", f\"Expected http://example.com/path, got {p.url}\"\n    \n    url2 = \"http://example.com///path\"\n    p.prepare_url(url2, params=None)\n    assert p.url == \"http://example.com/path\", f\"Expected http://example.com/path, got {p.url}\"\n    \n    # Test single leading slash (should remain)\n    url3 = \"http://example.com/path\"\n    p.prepare_url(url3, params=None)\n    assert p.url == \"http://example.com/path\", f\"Expected http://example.com/path, got {p.url}\"\n    \n    # Test no path (should become /)\n    url4 = \"http://example.com\"\n    p.prepare_url(url4, params=None)\n    assert p.url == \"http://example.com/\", f\"Expected http://example.com/, got {p.url}\"\n\n    # Test path with query and fragment\n    url5 = \"http://example.com//path?query=1#frag\"\n    p.prepare_url(url5, params=None)\n    assert p.url == \"http://example.com/path?query=1#frag\", f\"Expected http://example.com/path?query=1#frag, got {p.url}\"\n\n    print(\"All tests passed!\")\n\nif __name__ == \"__main__\":\n    test_leading_slashes()\nPY\n"
}
{"status": "ok", "stdout": "All tests passed!\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "All tests passed!\n", "stderr": "", "exit_code": 0}
18run_command
{
 "command": "git diff"
}
{"status": "ok", "stdout": "diff --git a/src/requests/models.py b/src/requests/models.py\nindex 44556394..6718375f 100644\n--- a/src/requests/models.py\n+++ b/s
full
{"status": "ok", "stdout": "diff --git a/src/requests/models.py b/src/requests/models.py\nindex 44556394..6718375f 100644\n--- a/src/requests/models.py\n+++ b/src/requests/models.py\n@@ -466,6 +466,10 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):\n         # Bare domains aren't valid URLs.\n         if not path:\n             path = \"/\"\n+        elif path.startswith(\"//\"):\n+            path = \"/\" + path.lstrip(\"/\")\n+        elif path.startswith(\"//\"):\n+            path = \"/\" + path.lstrip(\"/\")\n \n         if isinstance(params, (str, bytes)):\n             params = to_native_string(params)\n", "stderr": "", "exit_code": 0}
19run_command
{
 "command": "python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"src/requests/models.py\"); s = p.read_text()\n# Find the line that we mistakenly duplicated\n# Looking for the duplicate block\nimport re\n# We want to find the section:\n#         # Bare domains aren't valid URLs.\n#         if not path:\n#             path = \"/\"\n#         elif path.startswith(\"//\"):\n#             path = \"/\" + path.lstrip(\"/\")\n#         elif path.startswith(\"//\"):\n#             path = \"/\" + path.lstrip(\"/\")\n\npattern = r'        # Bare domains aren\\'t valid URLs\\.\\n        if not path:\\n            path = \"/\"\\n        elif path\\.startswith(\"//\"):\\n            path = \"/\" + path\\.lstrip(\"/\")\\n        elif path\\.startswith(\"//\"):\\n            path = \"/\" + path\\.lstrip(\"/\")'\n# Since the duplicate is exactly the same, let's just replace the whole block with the correct one.\n# But let's be more precise.\n\nold_block = \"\"\"        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n        elif path.startswith(\"//\"):\n            path = \"/\" + path.lstrip(\"/\")\n        elif path.startswith(\"//\"):\n            path = \"/\" + path.lstrip(\"/\")\"\"\"\n\nnew_block = \"\"\"        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n        elif path.startswith(\"//\"):\n            path = \"/\" + path.lstrip(\"/\")\"\"\"\n\nif old_block in s:\n    t = s.replace(old_block, new_block)\n    p.write_text(t)\n    print(\"Fixed duplication\")\nelse:\n    print(\"Old block not found as expected\")\nPY\n"
}
{"status": "ok", "stdout": "Fixed duplication\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "Fixed duplication\n", "stderr": "", "exit_code": 0}
20run_command
{
 "command": "git diff"
}
{"status": "ok", "stdout": "diff --git a/src/requests/models.py b/src/requests/models.py\nindex 44556394..efed0d91 100644\n--- a/src/requests/models.py\n+++ b/s
full
{"status": "ok", "stdout": "diff --git a/src/requests/models.py b/src/requests/models.py\nindex 44556394..efed0d91 100644\n--- a/src/requests/models.py\n+++ b/src/requests/models.py\n@@ -466,6 +466,8 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):\n         # Bare domains aren't valid URLs.\n         if not path:\n             path = \"/\"\n+        elif path.startswith(\"//\"):\n+            path = \"/\" + path.lstrip(\"/\")\n \n         if isinstance(params, (str, bytes)):\n             params = to_native_string(params)\n", "stderr": "", "exit_code": 0}
21run_command
{
 "command": "python3 - <<'PY'\nimport requests\nfrom requests.models import PreparedRequest\n\ndef test_leading_slashes():\n    p = PreparedRequest()\n    \n    # Test multiple leading slashes\n    url = \"http://example.com//path\"\n    p.prepare_url(url, params=None)\n    assert p.url == \"http://example.com/path\", f\"Expected http://example.com/path, got {p.url}\"\n    \n    url2 = \"http://example.com///path\"\n    p.prepare_url(url2, params=None)\n    assert p.url == \"http://example.com/path\", f\"Expected http://example.com/path, got {p.url}\"\n    \n    # Test single leading slash (should remain)\n    url3 = \"http://example.com/path\"\n    p.prepare_url(url3, params=None)\n    assert p.url == \"http://example.com/path\", f\"Expected http://example.com/path, got {p.url}\"\n    \n    # Test no path (should become /)\n    url4 = \"http://example.com\"\n    p.prepare_url(url4, params=None)\n    assert p.url == \"http://example.com/\", f\"Expected http://example.com/, got {p.url}\"\n\n    # Test path with query and fragment\n    url5 = \"http://example.com//path?query=1#frag\"\n    p.prepare_url(url5, params=None)\n    assert p.url == \"http://example.com/path?query=1#frag\", f\"Expected http://example.com/path?query=1#frag, got {p.url}\"\n\n    print(\"All tests passed!\")\n\nif __name__ == \"__main__\":\n    test_leading_slashes()\nPY\n"
}
{"status": "ok", "stdout": "All tests passed!\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "All tests passed!\n", "stderr": "", "exit_code": 0}
22run_command
{
 "command": "submit_patch"
}
{"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: submit_patch: command not found\n", "details": {"stdout": "", "stderr": "/bin/bas
full
{"status": "error", "error_type": "CommandError", "error_message": "/bin/bash: submit_patch: command not found\n", "details": {"stdout": "", "stderr": "/bin/bash: submit_patch: command not found\n", "exit_code": 127}}
23submit_patch
{}
{"status": "ok", "patch_size": 499, "files_changed": 1}
full
{"status": "ok", "patch_size": 499, "files_changed": 1}

Patch

diff --git a/src/requests/models.py b/src/requests/models.py
index 44556394..efed0d91 100644
--- a/src/requests/models.py
+++ b/src/requests/models.py
@@ -466,6 +466,8 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
         # Bare domains aren't valid URLs.
         if not path:
             path = "/"
+        elif path.startswith("//"):
+            path = "/" + path.lstrip("/")
 
         if isinstance(params, (str, bytes)):
             params = to_native_string(params)

Test output

show
.                                                                        [100%]
=============================== 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")

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
1 passed, 1 warning in 0.01s
[2026-09-25 19:17:19,605] WARNING in core: flasgger is not installed; serving the static landing page at / and skipping the Swagger UI and /spec.json.