Skip to content

Commit f64807a

Browse files
socketserver: improve bytes handling (#9096)
Co-authored-by: Alex Waygood <[email protected]>
1 parent 63c7fb0 commit f64807a

File tree

2 files changed

+34
-28
lines changed

2 files changed

+34
-28
lines changed

stdlib/http/server.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import _socket
12
import email.message
23
import io
34
import socketserver
@@ -56,7 +57,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
5657
def __init__(
5758
self,
5859
request: socketserver._RequestType,
59-
client_address: socketserver._AddressType,
60+
client_address: _socket._RetAddress,
6061
server: socketserver.BaseServer,
6162
*,
6263
directory: str | None = ...,

stdlib/socketserver.pyi

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sys
22
import types
3-
from _typeshed import Self
3+
from _socket import _Address, _RetAddress
4+
from _typeshed import ReadableBuffer, Self
45
from collections.abc import Callable
56
from socket import socket as _socket
67
from typing import Any, BinaryIO, ClassVar, Union
@@ -29,38 +30,39 @@ if sys.platform != "win32":
2930
]
3031

3132
_RequestType: TypeAlias = Union[_socket, tuple[bytes, _socket]]
32-
_AddressType: TypeAlias = Union[tuple[str, int], str]
33+
_AfUnixAddress: TypeAlias = str | ReadableBuffer # adddress acceptable for an AF_UNIX socket
34+
_AfInetAddress: TypeAlias = tuple[str | bytes | bytearray, int] # address acceptable for an AF_INET socket
3335

3436
# This can possibly be generic at some point:
3537
class BaseServer:
3638
address_family: int
37-
server_address: tuple[str, int]
39+
server_address: _Address
3840
socket: _socket
3941
allow_reuse_address: bool
4042
request_queue_size: int
4143
socket_type: int
4244
timeout: float | None
4345
def __init__(
44-
self: Self, server_address: Any, RequestHandlerClass: Callable[[Any, Any, Self], BaseRequestHandler]
46+
self: Self, server_address: _Address, RequestHandlerClass: Callable[[Any, _RetAddress, Self], BaseRequestHandler]
4547
) -> None: ...
4648
# It is not actually a `@property`, but we need a `Self` type:
4749
@property
48-
def RequestHandlerClass(self: Self) -> Callable[[Any, Any, Self], BaseRequestHandler]: ...
50+
def RequestHandlerClass(self: Self) -> Callable[[Any, _RetAddress, Self], BaseRequestHandler]: ...
4951
@RequestHandlerClass.setter
50-
def RequestHandlerClass(self: Self, val: Callable[[Any, Any, Self], BaseRequestHandler]) -> None: ...
52+
def RequestHandlerClass(self: Self, val: Callable[[Any, _RetAddress, Self], BaseRequestHandler]) -> None: ...
5153
def fileno(self) -> int: ...
5254
def handle_request(self) -> None: ...
5355
def serve_forever(self, poll_interval: float = ...) -> None: ...
5456
def shutdown(self) -> None: ...
5557
def server_close(self) -> None: ...
56-
def finish_request(self, request: _RequestType, client_address: _AddressType) -> None: ...
58+
def finish_request(self, request: _RequestType, client_address: _RetAddress) -> None: ...
5759
def get_request(self) -> tuple[Any, Any]: ...
58-
def handle_error(self, request: _RequestType, client_address: _AddressType) -> None: ...
60+
def handle_error(self, request: _RequestType, client_address: _RetAddress) -> None: ...
5961
def handle_timeout(self) -> None: ...
60-
def process_request(self, request: _RequestType, client_address: _AddressType) -> None: ...
62+
def process_request(self, request: _RequestType, client_address: _RetAddress) -> None: ...
6163
def server_activate(self) -> None: ...
6264
def server_bind(self) -> None: ...
63-
def verify_request(self, request: _RequestType, client_address: _AddressType) -> bool: ...
65+
def verify_request(self, request: _RequestType, client_address: _RetAddress) -> bool: ...
6466
def __enter__(self: Self) -> Self: ...
6567
def __exit__(
6668
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None
@@ -72,32 +74,35 @@ class BaseServer:
7274
class TCPServer(BaseServer):
7375
if sys.version_info >= (3, 11):
7476
allow_reuse_port: bool
77+
server_address: _AfInetAddress # type: ignore[assignment]
7578
def __init__(
7679
self: Self,
77-
server_address: tuple[str, int],
78-
RequestHandlerClass: Callable[[Any, Any, Self], BaseRequestHandler],
80+
server_address: _AfInetAddress,
81+
RequestHandlerClass: Callable[[Any, _RetAddress, Self], BaseRequestHandler],
7982
bind_and_activate: bool = ...,
8083
) -> None: ...
81-
def get_request(self) -> tuple[_socket, Any]: ...
84+
def get_request(self) -> tuple[_socket, _RetAddress]: ...
8285

8386
class UDPServer(TCPServer):
8487
max_packet_size: ClassVar[int]
85-
def get_request(self) -> tuple[tuple[bytes, _socket], Any]: ... # type: ignore[override]
88+
def get_request(self) -> tuple[tuple[bytes, _socket], _RetAddress]: ... # type: ignore[override]
8689

8790
if sys.platform != "win32":
8891
class UnixStreamServer(BaseServer):
92+
server_address: _AfUnixAddress # type: ignore[assignment]
8993
def __init__(
9094
self: Self,
91-
server_address: str | bytes,
92-
RequestHandlerClass: Callable[[Any, Any, Self], BaseRequestHandler],
95+
server_address: _AfUnixAddress,
96+
RequestHandlerClass: Callable[[Any, _RetAddress, Self], BaseRequestHandler],
9397
bind_and_activate: bool = ...,
9498
) -> None: ...
9599

96100
class UnixDatagramServer(BaseServer):
101+
server_address: _AfUnixAddress # type: ignore[assignment]
97102
def __init__(
98103
self: Self,
99-
server_address: str | bytes,
100-
RequestHandlerClass: Callable[[Any, Any, Self], BaseRequestHandler],
104+
server_address: _AfUnixAddress,
105+
RequestHandlerClass: Callable[[Any, _RetAddress, Self], BaseRequestHandler],
101106
bind_and_activate: bool = ...,
102107
) -> None: ...
103108

@@ -110,14 +115,14 @@ if sys.platform != "win32":
110115
def collect_children(self, *, blocking: bool = ...) -> None: ... # undocumented
111116
def handle_timeout(self) -> None: ... # undocumented
112117
def service_actions(self) -> None: ... # undocumented
113-
def process_request(self, request: _RequestType, client_address: _AddressType) -> None: ...
118+
def process_request(self, request: _RequestType, client_address: _RetAddress) -> None: ...
114119
def server_close(self) -> None: ...
115120

116121
class ThreadingMixIn:
117122
daemon_threads: bool
118123
block_on_close: bool
119-
def process_request_thread(self, request: _RequestType, client_address: _AddressType) -> None: ... # undocumented
120-
def process_request(self, request: _RequestType, client_address: _AddressType) -> None: ...
124+
def process_request_thread(self, request: _RequestType, client_address: _RetAddress) -> None: ... # undocumented
125+
def process_request(self, request: _RequestType, client_address: _RetAddress) -> None: ...
121126
def server_close(self) -> None: ...
122127

123128
if sys.platform != "win32":
@@ -132,16 +137,16 @@ if sys.platform != "win32":
132137
class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): ...
133138

134139
class BaseRequestHandler:
135-
# Those are technically of types, respectively:
136-
# * _RequestType
137-
# * _AddressType
138-
# But there are some concerns that having unions here would cause
140+
# `request` is technically of type _RequestType,
141+
# but there are some concerns that having a union here would cause
139142
# too much inconvenience to people using it (see
140143
# https://github.com/python/typeshed/pull/384#issuecomment-234649696)
144+
#
145+
# Note also that _RetAddress is also just an alias for `Any`
141146
request: Any
142-
client_address: Any
147+
client_address: _RetAddress
143148
server: BaseServer
144-
def __init__(self, request: _RequestType, client_address: _AddressType, server: BaseServer) -> None: ...
149+
def __init__(self, request: _RequestType, client_address: _RetAddress, server: BaseServer) -> None: ...
145150
def setup(self) -> None: ...
146151
def handle(self) -> None: ...
147152
def finish(self) -> None: ...

0 commit comments

Comments
 (0)