33import functools
44import ipaddress
55import socket
6+ from collections .abc import Sequence
67from typing import TYPE_CHECKING
78from urllib .parse import urlparse
89
910from django .conf import settings
1011from django .utils .encoding import force_str
1112from urllib3 .exceptions import LocationParseError
1213from urllib3 .util .connection import _set_socket_options , allowed_gai_family
14+ from urllib3 .util .timeout import _DEFAULT_TIMEOUT , _TYPE_DEFAULT
1315
1416from sentry .exceptions import RestrictedIPAddress
1517
@@ -104,12 +106,12 @@ def is_safe_hostname(hostname: str | None) -> bool:
104106
105107# Modifed version of urllib3.util.connection.create_connection.
106108def safe_create_connection (
107- address ,
108- timeout = socket . _GLOBAL_DEFAULT_TIMEOUT ,
109- source_address = None ,
110- socket_options = None ,
109+ address : tuple [ str , int ] ,
110+ timeout : _TYPE_DEFAULT | float | None = _DEFAULT_TIMEOUT ,
111+ source_address : str | None = None ,
112+ socket_options : Sequence [ tuple [ int , int , int | bytes ]] | None = None ,
111113 is_ipaddress_permitted : IsIpAddressPermitted = None ,
112- ):
114+ ) -> socket . socket :
113115 if is_ipaddress_permitted is None :
114116 is_ipaddress_permitted = is_ipaddress_allowed
115117
@@ -137,6 +139,7 @@ def safe_create_connection(
137139
138140 # Begin custom code.
139141 ip = sa [0 ]
142+ assert isinstance (ip , str ), ip # we aren't running ipv6-disabled python
140143 if not is_ipaddress_permitted (ip ):
141144 # I am explicitly choosing to be overly aggressive here. This means
142145 # the first IP that matches that hits our restricted set of IP networks,
@@ -155,7 +158,7 @@ def safe_create_connection(
155158 # If provided, set socket level options before connecting.
156159 _set_socket_options (sock , socket_options )
157160
158- if timeout is not socket . _GLOBAL_DEFAULT_TIMEOUT :
161+ if timeout is not _DEFAULT_TIMEOUT :
159162 sock .settimeout (timeout )
160163 if source_address :
161164 sock .bind (source_address )
0 commit comments