python-socks 2.8.2__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. python_socks/__init__.py +11 -13
  2. python_socks/_abc.py +35 -22
  3. python_socks/_connectors/abc.py +5 -3
  4. python_socks/_connectors/factory_async.py +8 -8
  5. python_socks/_connectors/factory_sync.py +8 -8
  6. python_socks/_connectors/http_async.py +7 -7
  7. python_socks/_connectors/http_sync.py +7 -7
  8. python_socks/_connectors/socks4_async.py +10 -10
  9. python_socks/_connectors/socks4_sync.py +10 -10
  10. python_socks/_connectors/socks5_async.py +29 -26
  11. python_socks/_connectors/socks5_sync.py +36 -28
  12. python_socks/_errors.py +15 -2
  13. python_socks/_helpers.py +35 -32
  14. python_socks/_protocols/errors.py +10 -1
  15. python_socks/_protocols/http.py +55 -60
  16. python_socks/_protocols/socks4.py +22 -26
  17. python_socks/_protocols/socks5.py +77 -70
  18. python_socks/_types.py +4 -0
  19. python_socks/_version.py +2 -2
  20. python_socks/async_/__init__.py +0 -3
  21. python_socks/async_/anyio/__init__.py +1 -2
  22. python_socks/async_/anyio/_connect.py +6 -4
  23. python_socks/async_/anyio/_proxy.py +85 -92
  24. python_socks/async_/anyio/_resolver.py +10 -3
  25. python_socks/async_/anyio/_stream.py +11 -26
  26. python_socks/async_/anyio/v2/__init__.py +1 -5
  27. python_socks/async_/anyio/v2/_connect.py +7 -4
  28. python_socks/async_/anyio/v2/_proxy.py +36 -26
  29. python_socks/async_/anyio/v2/_stream.py +11 -11
  30. python_socks/async_/asyncio/__init__.py +1 -2
  31. python_socks/async_/asyncio/_connect.py +12 -7
  32. python_socks/async_/asyncio/_proxy.py +48 -49
  33. python_socks/async_/asyncio/_resolver.py +11 -4
  34. python_socks/async_/asyncio/_stream.py +9 -13
  35. python_socks/async_/asyncio/v2/__init__.py +1 -2
  36. python_socks/async_/asyncio/v2/_connect.py +8 -5
  37. python_socks/async_/asyncio/v2/_proxy.py +38 -28
  38. python_socks/async_/asyncio/v2/_stream.py +16 -18
  39. python_socks/async_/trio/__init__.py +1 -1
  40. python_socks/async_/trio/_connect.py +5 -4
  41. python_socks/async_/trio/_proxy.py +46 -48
  42. python_socks/async_/trio/_resolver.py +11 -3
  43. python_socks/async_/trio/_stream.py +9 -9
  44. python_socks/async_/trio/v2/__init__.py +1 -5
  45. python_socks/async_/trio/v2/_connect.py +3 -2
  46. python_socks/async_/trio/v2/_proxy.py +34 -24
  47. python_socks/async_/trio/v2/_stream.py +13 -13
  48. python_socks/sync/__init__.py +1 -3
  49. python_socks/sync/_connect.py +4 -3
  50. python_socks/sync/_proxy.py +42 -43
  51. python_socks/sync/_resolver.py +17 -5
  52. python_socks/sync/_stream.py +9 -9
  53. python_socks/sync/v2/__init__.py +1 -5
  54. python_socks/sync/v2/_connect.py +5 -3
  55. python_socks/sync/v2/_proxy.py +35 -26
  56. python_socks/sync/v2/_ssl_transport.py +3 -0
  57. python_socks/sync/v2/_stream.py +19 -14
  58. python_socks-3.0.0.dist-info/METADATA +346 -0
  59. python_socks-3.0.0.dist-info/RECORD +65 -0
  60. {python_socks-2.8.2.dist-info → python_socks-3.0.0.dist-info}/WHEEL +1 -1
  61. python_socks/async_/_proxy_chain.py +0 -34
  62. python_socks/async_/anyio/_chain.py +0 -42
  63. python_socks/async_/anyio/v2/_chain.py +0 -32
  64. python_socks/async_/asyncio/v2/_chain.py +0 -32
  65. python_socks/async_/curio/__init__.py +0 -4
  66. python_socks/async_/curio/_connect.py +0 -17
  67. python_socks/async_/curio/_proxy.py +0 -132
  68. python_socks/async_/curio/_resolver.py +0 -25
  69. python_socks/async_/curio/_stream.py +0 -32
  70. python_socks/async_/trio/v2/_chain.py +0 -32
  71. python_socks/sync/_chain.py +0 -32
  72. python_socks/sync/v2/_chain.py +0 -26
  73. python_socks-2.8.2.dist-info/METADATA +0 -295
  74. python_socks-2.8.2.dist-info/RECORD +0 -77
  75. {python_socks-2.8.2.dist-info → python_socks-3.0.0.dist-info}/licenses/LICENSE.txt +0 -0
  76. {python_socks-2.8.2.dist-info → python_socks-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,12 @@
1
+ from __future__ import annotations
2
+
1
3
  import ssl
2
4
  from typing import Union
3
5
 
4
6
  import trio
5
7
 
6
- from ...._errors import ProxyError
7
8
  from .... import _abc as abc
9
+ from ...._errors import IncompleteReadError
8
10
 
9
11
  DEFAULT_RECEIVE_SIZE = 65536
10
12
 
@@ -12,31 +14,29 @@ TrioStreamType = Union[trio.SocketStream, trio.SSLStream]
12
14
 
13
15
 
14
16
  class TrioSocketStream(abc.AsyncSocketStream):
15
- _stream: TrioStreamType
16
-
17
- def __init__(self, stream: TrioStreamType):
17
+ def __init__(self, stream: TrioStreamType) -> None:
18
18
  self._stream = stream
19
19
 
20
- async def write_all(self, data):
20
+ async def write(self, data: bytes) -> None:
21
21
  await self._stream.send_all(data)
22
22
 
23
- async def read(self, max_bytes=DEFAULT_RECEIVE_SIZE):
24
- return await self._stream.receive_some(max_bytes)
23
+ async def read(self, max_bytes: int = DEFAULT_RECEIVE_SIZE) -> bytes:
24
+ return await self._stream.receive_some(max_bytes) # type:ignore[return-value]
25
25
 
26
- async def read_exact(self, n):
26
+ async def read_exactly(self, n: int) -> bytes:
27
27
  data = bytearray()
28
28
  while len(data) < n:
29
29
  packet = await self._stream.receive_some(n - len(data))
30
30
  if not packet: # pragma: no cover
31
- raise ProxyError('Connection closed unexpectedly')
32
- data += packet
33
- return data
31
+ raise IncompleteReadError("Connection closed unexpectedly")
32
+ data.extend(packet)
33
+ return data # type:ignore[return-value]
34
34
 
35
35
  async def start_tls(
36
36
  self,
37
37
  hostname: str,
38
38
  ssl_context: ssl.SSLContext,
39
- ) -> 'TrioSocketStream':
39
+ ) -> TrioSocketStream:
40
40
  ssl_stream = trio.SSLStream(
41
41
  self._stream,
42
42
  ssl_context=ssl_context,
@@ -47,7 +47,7 @@ class TrioSocketStream(abc.AsyncSocketStream):
47
47
  await ssl_stream.do_handshake()
48
48
  return TrioSocketStream(ssl_stream)
49
49
 
50
- async def close(self):
50
+ async def close(self) -> None:
51
51
  await self._stream.aclose()
52
52
 
53
53
  @property
@@ -1,5 +1,3 @@
1
1
  from ._proxy import SyncProxy as Proxy
2
- from ._chain import ProxyChain
3
2
 
4
-
5
- __all__ = ('Proxy', 'ProxyChain')
3
+ __all__ = ("Proxy",)
@@ -1,12 +1,13 @@
1
+ from __future__ import annotations
2
+
1
3
  import socket
2
- from typing import Optional, Tuple
3
4
 
4
5
 
5
6
  def connect_tcp(
6
7
  host: str,
7
8
  port: int,
8
- timeout: Optional[float] = None,
9
- local_addr: Optional[Tuple[str, int]] = None,
9
+ timeout: float | None = None,
10
+ local_addr: tuple[str, int] | None = None,
10
11
  ) -> socket.socket:
11
12
  address = (host, port)
12
13
  return socket.create_connection(
@@ -1,18 +1,21 @@
1
- import socket
2
- from typing import Optional, Any
3
- import warnings
1
+ from __future__ import annotations
4
2
 
5
- from .._errors import ProxyConnectionError, ProxyTimeoutError, ProxyError
3
+ import socket
4
+ from typing import Any
6
5
 
7
- from .._types import ProxyType
6
+ from .._connectors.factory_sync import create_connector
7
+ from .._errors import (
8
+ IncompleteReadError,
9
+ ProxyConnectionError,
10
+ ProxyError,
11
+ ProxyTimeoutError,
12
+ )
8
13
  from .._helpers import parse_proxy_url
9
14
  from .._protocols.errors import ReplyError
10
- from .._connectors.factory_sync import create_connector
11
-
12
- from ._stream import SyncSocketStream
13
- from ._resolver import SyncResolver
15
+ from .._types import ProxyType
14
16
  from ._connect import connect_tcp
15
-
17
+ from ._resolver import SyncResolver
18
+ from ._stream import SyncSocketStream
16
19
 
17
20
  DEFAULT_TIMEOUT = 60
18
21
 
@@ -23,16 +26,18 @@ class SyncProxy:
23
26
  proxy_type: ProxyType,
24
27
  host: str,
25
28
  port: int,
26
- username: Optional[str] = None,
27
- password: Optional[str] = None,
28
- rdns: Optional[bool] = None,
29
- ):
29
+ username: str | None = None,
30
+ password: str | None = None,
31
+ rdns: bool | None = None, # noqa: FBT001
32
+ forward: SyncProxy | None = None,
33
+ ) -> None:
30
34
  self._proxy_type = proxy_type
31
35
  self._proxy_host = host
32
36
  self._proxy_port = port
33
37
  self._password = password
34
38
  self._username = username
35
39
  self._rdns = rdns
40
+ self._forward = forward
36
41
 
37
42
  self._resolver = SyncResolver()
38
43
 
@@ -40,38 +45,35 @@ class SyncProxy:
40
45
  self,
41
46
  dest_host: str,
42
47
  dest_port: int,
43
- timeout: Optional[float] = None,
48
+ timeout: float | None = None,
44
49
  **kwargs: Any,
45
50
  ) -> socket.socket:
46
51
  if timeout is None:
47
52
  timeout = DEFAULT_TIMEOUT
48
53
 
49
- _socket = kwargs.get('_socket')
50
- if _socket is not None:
51
- warnings.warn(
52
- "The '_socket' argument is deprecated and will be removed in the future",
53
- DeprecationWarning,
54
- stacklevel=2,
54
+ if self._forward is not None:
55
+ sock = self._forward.connect(
56
+ dest_host=self._proxy_host,
57
+ dest_port=self._proxy_port,
58
+ timeout=timeout,
55
59
  )
56
-
57
- if _socket is None:
58
- local_addr = kwargs.get('local_addr')
60
+ else:
61
+ local_addr = kwargs.get("local_addr")
59
62
  try:
60
- _socket = connect_tcp(
63
+ sock = connect_tcp(
61
64
  host=self._proxy_host,
62
65
  port=self._proxy_port,
63
66
  timeout=timeout,
64
67
  local_addr=local_addr,
65
68
  )
66
69
  except OSError as e:
67
- msg = 'Could not connect to proxy {}:{} [{}]'.format(
68
- self._proxy_host,
69
- self._proxy_port,
70
- e.strerror,
70
+ msg = (
71
+ f"Could not connect to proxy "
72
+ f"{self._proxy_host}:{self._proxy_port} [{e.strerror}]"
71
73
  )
72
74
  raise ProxyConnectionError(e.errno, msg) from e
73
75
 
74
- stream = SyncSocketStream(_socket)
76
+ stream = SyncSocketStream(sock)
75
77
 
76
78
  try:
77
79
  connector = create_connector(
@@ -87,30 +89,27 @@ class SyncProxy:
87
89
  port=dest_port,
88
90
  )
89
91
 
90
- return _socket
92
+ return sock
91
93
  except socket.timeout as e:
92
94
  stream.close()
93
- raise ProxyTimeoutError('Proxy connection timed out: {}'.format(timeout)) from e
95
+ raise ProxyTimeoutError(f"Proxy connection timed out: {timeout}") from e
94
96
  except ReplyError as e:
95
97
  stream.close()
96
- raise ProxyError(e, error_code=e.error_code)
98
+ raise ProxyError(e, error_code=e.error_code) from e
99
+ except IncompleteReadError as e:
100
+ stream.close()
101
+ raise ProxyError(e) from e
97
102
  except Exception:
98
103
  stream.close()
99
104
  raise
100
105
 
101
- @property
102
- def proxy_host(self):
103
- return self._proxy_host
104
-
105
- @property
106
- def proxy_port(self):
107
- return self._proxy_port
108
-
109
106
  @classmethod
110
- def create(cls, *args, **kwargs): # for backward compatibility
107
+ def create(
108
+ cls, *args: Any, **kwargs: Any
109
+ ) -> SyncProxy: # for backward compatibility
111
110
  return cls(*args, **kwargs)
112
111
 
113
112
  @classmethod
114
- def from_url(cls, url: str, **kwargs) -> 'SyncProxy':
113
+ def from_url(cls, url: str, **kwargs: Any) -> SyncProxy:
115
114
  url_args = parse_proxy_url(url)
116
115
  return cls(*url_args, **kwargs)
@@ -1,16 +1,28 @@
1
1
  import socket
2
+
2
3
  from .. import _abc as abc
4
+ from .._types import ResolvedAddress
3
5
 
4
6
 
5
7
  class SyncResolver(abc.SyncResolver):
6
- # noinspection PyMethodMayBeStatic
7
- def resolve(self, host, port=0, family=socket.AF_UNSPEC):
8
- infos = socket.getaddrinfo(host=host, port=port, family=family, type=socket.SOCK_STREAM)
8
+ def resolve(
9
+ self,
10
+ host: str,
11
+ port: int = 0,
12
+ family: socket.AddressFamily = socket.AF_UNSPEC,
13
+ ) -> ResolvedAddress:
14
+ infos = socket.getaddrinfo(
15
+ host=host,
16
+ port=port,
17
+ family=family,
18
+ type=socket.SOCK_STREAM,
19
+ )
9
20
 
10
21
  if not infos: # pragma: no cover
11
- raise OSError('Can`t resolve address {}:{} [{}]'.format(host, port, family))
22
+ raise OSError(f"Can`t resolve address {host}:{port} [{family}]")
12
23
 
24
+ # use IPv4 address first
13
25
  infos = sorted(infos, key=lambda info: info[0])
14
26
 
15
27
  family, _, _, _, address = infos[0]
16
- return family, address[0]
28
+ return family, address[0] # type: ignore[return-value]
@@ -1,7 +1,7 @@
1
1
  import socket
2
2
 
3
- from .._errors import ProxyError
4
3
  from .. import _abc as abc
4
+ from .._errors import IncompleteReadError
5
5
 
6
6
  DEFAULT_RECEIVE_SIZE = 65536
7
7
 
@@ -9,24 +9,24 @@ DEFAULT_RECEIVE_SIZE = 65536
9
9
  class SyncSocketStream(abc.SyncSocketStream):
10
10
  _socket: socket.socket
11
11
 
12
- def __init__(self, sock: socket.socket):
12
+ def __init__(self, sock: socket.socket) -> None:
13
13
  self._socket = sock
14
14
 
15
- def write_all(self, data):
15
+ def write(self, data: bytes) -> None:
16
16
  self._socket.sendall(data)
17
17
 
18
- def read(self, max_bytes=DEFAULT_RECEIVE_SIZE):
18
+ def read(self, max_bytes: int = DEFAULT_RECEIVE_SIZE) -> bytes:
19
19
  return self._socket.recv(max_bytes)
20
20
 
21
- def read_exact(self, n):
21
+ def read_exactly(self, n: int) -> bytes:
22
22
  data = bytearray()
23
23
  while len(data) < n:
24
24
  packet = self._socket.recv(n - len(data))
25
25
  if not packet: # pragma: no cover
26
- raise ProxyError('Connection closed unexpectedly')
27
- data += packet
28
- return data
26
+ raise IncompleteReadError("Connection closed unexpectedly")
27
+ data.extend(packet)
28
+ return data # type:ignore[return-value]
29
29
 
30
- def close(self):
30
+ def close(self) -> None:
31
31
  if self._socket is not None:
32
32
  self._socket.close()
@@ -1,7 +1,3 @@
1
1
  from ._proxy import SyncProxy as Proxy
2
- from ._chain import ProxyChain
3
2
 
4
- __all__ = (
5
- 'Proxy',
6
- 'ProxyChain',
7
- )
3
+ __all__ = ("Proxy",)
@@ -1,13 +1,15 @@
1
+ from __future__ import annotations
2
+
1
3
  import socket
2
- from typing import Optional, Tuple
4
+
3
5
  from ._stream import SyncSocketStream
4
6
 
5
7
 
6
8
  def connect_tcp(
7
9
  host: str,
8
10
  port: int,
9
- timeout: Optional[float] = None,
10
- local_addr: Optional[Tuple[str, int]] = None,
11
+ timeout: float | None = None,
12
+ local_addr: tuple[str, int] | None = None,
11
13
  ) -> SyncSocketStream:
12
14
  address = (host, port)
13
15
  sock = socket.create_connection(
@@ -1,17 +1,22 @@
1
+ from __future__ import annotations
2
+
1
3
  import socket
2
4
  import ssl
3
- from typing import Any, Optional
5
+ from typing import Any
4
6
 
5
- from ._connect import connect_tcp
6
- from ._stream import SyncSocketStream
7
- from .._resolver import SyncResolver
8
- from ..._types import ProxyType
9
- from ..._errors import ProxyConnectionError, ProxyTimeoutError, ProxyError
7
+ from ..._connectors.factory_sync import create_connector
8
+ from ..._errors import (
9
+ IncompleteReadError,
10
+ ProxyConnectionError,
11
+ ProxyError,
12
+ ProxyTimeoutError,
13
+ )
10
14
  from ..._helpers import parse_proxy_url
11
-
12
15
  from ..._protocols.errors import ReplyError
13
- from ..._connectors.factory_sync import create_connector
14
-
16
+ from ..._types import ProxyType
17
+ from .._resolver import SyncResolver
18
+ from ._connect import connect_tcp
19
+ from ._stream import SyncSocketStream
15
20
 
16
21
  DEFAULT_TIMEOUT = 60
17
22
 
@@ -22,12 +27,12 @@ class SyncProxy:
22
27
  proxy_type: ProxyType,
23
28
  host: str,
24
29
  port: int,
25
- username: Optional[str] = None,
26
- password: Optional[str] = None,
27
- rdns: Optional[bool] = None,
28
- proxy_ssl: Optional[ssl.SSLContext] = None,
29
- forward: Optional['SyncProxy'] = None,
30
- ):
30
+ username: str | None = None,
31
+ password: str | None = None,
32
+ rdns: bool | None = None, # noqa: FBT001
33
+ proxy_ssl: ssl.SSLContext | None = None,
34
+ forward: SyncProxy | None = None,
35
+ ) -> None:
31
36
  self._proxy_type = proxy_type
32
37
  self._proxy_host = host
33
38
  self._proxy_port = port
@@ -43,15 +48,15 @@ class SyncProxy:
43
48
  self,
44
49
  dest_host: str,
45
50
  dest_port: int,
46
- dest_ssl: Optional[ssl.SSLContext] = None,
47
- timeout: Optional[float] = None,
51
+ dest_ssl: ssl.SSLContext | None = None,
52
+ timeout: float | None = None,
48
53
  **kwargs: Any,
49
54
  ) -> SyncSocketStream:
50
55
  if timeout is None:
51
56
  timeout = DEFAULT_TIMEOUT
52
57
 
53
58
  if self._forward is None:
54
- local_addr = kwargs.get('local_addr')
59
+ local_addr = kwargs.get("local_addr")
55
60
  try:
56
61
  stream = connect_tcp(
57
62
  host=self._proxy_host,
@@ -60,10 +65,9 @@ class SyncProxy:
60
65
  local_addr=local_addr,
61
66
  )
62
67
  except OSError as e:
63
- msg = 'Could not connect to proxy {}:{} [{}]'.format(
64
- self._proxy_host,
65
- self._proxy_port,
66
- e.strerror,
68
+ msg = (
69
+ f"Could not connect to proxy "
70
+ f"{self._proxy_host}:{self._proxy_port} [{e.strerror}]"
67
71
  )
68
72
  raise ProxyConnectionError(e.errno, msg) from e
69
73
  else:
@@ -103,19 +107,24 @@ class SyncProxy:
103
107
 
104
108
  except socket.timeout as e:
105
109
  stream.close()
106
- raise ProxyTimeoutError(f'Proxy connection timed out: {timeout}') from e
110
+ raise ProxyTimeoutError(f"Proxy connection timed out: {timeout}") from e
107
111
  except ReplyError as e:
108
112
  stream.close()
109
- raise ProxyError(e, error_code=e.error_code)
113
+ raise ProxyError(e, error_code=e.error_code) from e
114
+ except IncompleteReadError as e:
115
+ stream.close()
116
+ raise ProxyError(e) from e
110
117
  except Exception:
111
118
  stream.close()
112
119
  raise
113
120
 
114
121
  @classmethod
115
- def create(cls, *args, **kwargs): # for backward compatibility
122
+ def create(
123
+ cls, *args: Any, **kwargs: Any
124
+ ) -> SyncProxy: # for backward compatibility
116
125
  return cls(*args, **kwargs)
117
126
 
118
127
  @classmethod
119
- def from_url(cls, url: str, **kwargs) -> 'SyncProxy':
128
+ def from_url(cls, url: str, **kwargs: Any) -> SyncProxy:
120
129
  url_args = parse_proxy_url(url)
121
130
  return cls(*url_args, **kwargs)
@@ -1,6 +1,9 @@
1
+ # ruff: noqa: PGH004
2
+ # ruff: noqa
1
3
  """
2
4
  Copied from urllib3.util.ssltransport
3
5
  """
6
+
4
7
  import io
5
8
  import socket
6
9
  import ssl
@@ -1,11 +1,12 @@
1
+ from __future__ import annotations
2
+
1
3
  import socket
2
4
  import ssl
3
5
  from typing import Union
4
6
 
5
- from ._ssl_transport import SSLTransport
6
-
7
- from ..._errors import ProxyError
8
7
  from ... import _abc as abc
8
+ from ..._errors import IncompleteReadError
9
+ from ._ssl_transport import SSLTransport
9
10
 
10
11
  DEFAULT_RECEIVE_SIZE = 65536
11
12
 
@@ -13,27 +14,31 @@ SocketType = Union[socket.socket, ssl.SSLSocket, SSLTransport]
13
14
 
14
15
 
15
16
  class SyncSocketStream(abc.SyncSocketStream):
16
- _socket: SocketType
17
-
18
- def __init__(self, sock: SocketType):
17
+ def __init__(self, sock: SocketType) -> None:
19
18
  self._socket = sock
20
19
 
21
- def write_all(self, data):
20
+ def write(self, data: bytes) -> None:
22
21
  self._socket.sendall(data)
23
22
 
24
- def read(self, max_bytes=DEFAULT_RECEIVE_SIZE):
23
+ def read(self, max_bytes: int = DEFAULT_RECEIVE_SIZE) -> bytes:
25
24
  return self._socket.recv(max_bytes)
26
25
 
27
- def read_exact(self, n):
26
+ def read_exactly(self, n: int) -> bytes:
28
27
  data = bytearray()
29
28
  while len(data) < n:
30
29
  packet = self._socket.recv(n - len(data))
31
30
  if not packet: # pragma: no cover
32
- raise ProxyError('Connection closed unexpectedly')
33
- data += packet
34
- return data
31
+ raise IncompleteReadError("Connection closed unexpectedly")
32
+ data.extend(packet)
33
+ return data # type:ignore[return-value]
34
+
35
+ def start_tls(
36
+ self,
37
+ hostname: str,
38
+ ssl_context: ssl.SSLContext,
39
+ ) -> SyncSocketStream:
40
+ ssl_socket: ssl.SSLSocket | SSLTransport
35
41
 
36
- def start_tls(self, hostname: str, ssl_context: ssl.SSLContext) -> 'SyncSocketStream':
37
42
  if isinstance(self._socket, (ssl.SSLSocket, SSLTransport)):
38
43
  ssl_socket = SSLTransport(
39
44
  self._socket,
@@ -48,7 +53,7 @@ class SyncSocketStream(abc.SyncSocketStream):
48
53
 
49
54
  return SyncSocketStream(ssl_socket)
50
55
 
51
- def close(self):
56
+ def close(self) -> None:
52
57
  self._socket.close()
53
58
 
54
59
  @property