[gunicorn] Update to 24.1.0 (#15323)

This commit is contained in:
Semyon Moroz
2026-01-26 10:21:15 +00:00
committed by GitHub
parent f424458cbb
commit 10933499b2
29 changed files with 455 additions and 51 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
version = "23.0.*"
version = "24.1.0"
upstream_repository = "https://github.com/benoitc/gunicorn"
requires = ["types-gevent"]
+6 -4
View File
@@ -1,4 +1,6 @@
version_info: tuple[int, int, int]
__version__: str
SERVER: str
SERVER_SOFTWARE: str
from typing import Final
version_info: Final[tuple[int, int, int]]
__version__: Final[str]
SERVER: Final[str]
SERVER_SOFTWARE: Final[str]
+7 -4
View File
@@ -1,3 +1,4 @@
from queue import SimpleQueue
from types import FrameType
from typing import ClassVar
@@ -16,11 +17,11 @@ class Arbiter:
START_CTX: ClassVar[dict[int | str, str | list[str]]]
LISTENERS: ClassVar[list[BaseSocket]]
WORKERS: ClassVar[dict[int, Worker]]
PIPE: ClassVar[list[int]]
SIG_QUEUE: ClassVar[list[int]]
WAKEUP_REQUEST: ClassVar[int]
SIGNALS: ClassVar[list[int]]
SIG_NAMES: ClassVar[dict[int, str]]
log: GLogger | None
SIG_QUEUE: SimpleQueue[int]
pidfile: Pidfile | None
systemd: bool
worker_age: int
@@ -42,7 +43,9 @@ class Arbiter:
def init_signals(self) -> None: ...
def signal(self, sig: int, frame: FrameType | None) -> None: ...
def run(self) -> None: ...
def handle_chld(self, sig: int, frame: FrameType | None) -> None: ...
def signal_chld(self, sig: int, frame: FrameType | None) -> None: ...
def handle_chld(self) -> None: ...
handle_cld = handle_chld
def handle_hup(self) -> None: ...
def handle_term(self) -> None: ...
def handle_int(self) -> None: ...
@@ -55,7 +58,7 @@ class Arbiter:
def maybe_promote_master(self) -> None: ...
def wakeup(self) -> None: ...
def halt(self, reason: str | None = None, exit_status: int = 0) -> None: ...
def sleep(self) -> None: ...
def wait_for_signals(self, timeout: float | None = 1.0) -> list[int]: ...
def stop(self, graceful: bool = True) -> None: ...
def reexec(self) -> None: ...
def reload(self) -> None: ...
@@ -0,0 +1,5 @@
from gunicorn.asgi.lifespan import LifespanManager as LifespanManager
from gunicorn.asgi.message import AsyncRequest as AsyncRequest
from gunicorn.asgi.unreader import AsyncUnreader as AsyncUnreader
__all__ = ["AsyncUnreader", "AsyncRequest", "LifespanManager"]
+14
View File
@@ -0,0 +1,14 @@
from _typeshed import Incomplete
from gunicorn.glogging import Logger as GLogger
from .._types import _ASGIAppType
class LifespanManager:
app: _ASGIAppType
logger: GLogger
state: dict[Incomplete, Incomplete]
def __init__(self, app: _ASGIAppType, logger: GLogger, state: dict[Incomplete, Incomplete] | None = None) -> None: ...
async def startup(self) -> None: ...
async def shutdown(self) -> None: ...
+50
View File
@@ -0,0 +1,50 @@
import re
from typing import Final, Literal
from typing_extensions import Self
from gunicorn.asgi.unreader import AsyncUnreader
from gunicorn.config import Config
from .._types import _AddressType
MAX_REQUEST_LINE: Final = 8190
MAX_HEADERS: Final = 32768
DEFAULT_MAX_HEADERFIELD_SIZE: Final = 8190
RFC9110_5_6_2_TOKEN_SPECIALS: Final = r"!#$%&'*+-.^_`|~"
TOKEN_RE: Final[re.Pattern[str]]
METHOD_BADCHAR_RE: Final[re.Pattern[str]]
VERSION_RE: Final[re.Pattern[str]]
RFC9110_5_5_INVALID_AND_DANGEROUS: Final[re.Pattern[str]]
class AsyncRequest:
cfg: Config
unreader: AsyncUnreader
peer_addr: _AddressType
remote_addr: _AddressType
req_number: int
version: tuple[int, int] | None
method: str | None
uri: str | None
path: str | None
query: str | None
fragment: str | None
headers: list[tuple[str, str]]
trailers: list[tuple[str, str]]
scheme: Literal["https", "http"]
must_close: bool
proxy_protocol_info: dict[str, str | int | None] | None # TODO: Use TypedDict
limit_request_line: int
limit_request_fields: int
limit_request_field_size: int
max_buffer_headers: int
content_length: int | None
chunked: bool
def __init__(self, cfg: Config, unreader: AsyncUnreader, peer_addr: _AddressType, req_number: int = 1) -> None: ...
@classmethod
async def parse(cls, cfg: Config, unreader: AsyncUnreader, peer_addr: _AddressType, req_number: int = 1) -> Self: ...
def force_close(self) -> None: ...
def should_close(self) -> bool: ...
def get_header(self, name: str) -> str: ...
async def read_body(self, size: int = 8192) -> bytes: ...
async def drain_body(self) -> None: ...
+27
View File
@@ -0,0 +1,27 @@
import asyncio
from collections.abc import Iterable
from gunicorn.config import Config
from gunicorn.glogging import Logger as GLogger
from gunicorn.workers.gasgi import ASGIWorker
from .._types import _ASGIAppType
class ASGIResponseInfo:
status: str | int
sent: int
headers: list[tuple[str, str]]
def __init__(self, status: str | int, headers: Iterable[tuple[str | bytes, str | bytes]], sent: int) -> None: ...
class ASGIProtocol(asyncio.Protocol):
worker: ASGIWorker
cfg: Config
log: GLogger
app: _ASGIAppType
transport: asyncio.BaseTransport | None
reader: asyncio.StreamReader | None
writer: asyncio.BaseTransport | None
req_count: int
def __init__(self, worker: ASGIWorker) -> None: ...
+13
View File
@@ -0,0 +1,13 @@
import asyncio
import io
from _typeshed import ReadableBuffer
class AsyncUnreader:
reader: asyncio.StreamReader
buf: io.BytesIO
max_chunk: int
def __init__(self, reader: asyncio.StreamReader, max_chunk: int = 8192) -> None: ...
async def read(self, size: int | None = None) -> bytes: ...
def unread(self, data: ReadableBuffer) -> None: ...
def has_buffered_data(self) -> bool: ...
@@ -0,0 +1,41 @@
import asyncio
from typing import Final
from gunicorn.glogging import Logger as GLogger
from .._types import _ASGIAppType, _ScopeType
OPCODE_CONTINUATION: Final = 0x0
OPCODE_TEXT: Final = 0x1
OPCODE_BINARY: Final = 0x2
OPCODE_CLOSE: Final = 0x8
OPCODE_PING: Final = 0x9
OPCODE_PONG: Final = 0xA
CLOSE_NORMAL: Final = 1000
CLOSE_GOING_AWAY: Final = 1001
CLOSE_PROTOCOL_ERROR: Final = 1002
CLOSE_UNSUPPORTED: Final = 1003
CLOSE_NO_STATUS: Final = 1005
CLOSE_ABNORMAL: Final = 1006
CLOSE_INVALID_DATA: Final = 1007
CLOSE_POLICY_VIOLATION: Final = 1008
CLOSE_MESSAGE_TOO_BIG: Final = 1009
CLOSE_MANDATORY_EXT: Final = 1010
CLOSE_INTERNAL_ERROR: Final = 1011
WS_GUID: Final = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
class WebSocketProtocol:
transport: asyncio.Transport
reader: asyncio.StreamReader
scope: _ScopeType
app: _ASGIAppType
log: GLogger
accepted: bool
closed: bool
close_code: int | None
close_reason: str | None
def __init__(
self, transport: asyncio.Transport, reader: asyncio.StreamReader, scope: _ScopeType, app: _ASGIAppType, log: GLogger
) -> None: ...
async def run(self) -> None: ...
+71 -4
View File
@@ -63,6 +63,9 @@ _ClassValidatorType: TypeAlias = Callable[[object | str | None], type[Any] | Non
_UserGroupValidatorType: TypeAlias = Callable[[str | int | None], int]
_AddressValidatorType: TypeAlias = Callable[[str | None], _AddressType | None]
_CallableValidatorType: TypeAlias = Callable[[str | _HookType], _HookType]
_ProxyProtocolValidatorType: TypeAlias = Callable[[str | bool | None], str]
_ASGILoopValidatorType: TypeAlias = Callable[[str | None], str]
_ASGILifespanValidatorType: TypeAlias = Callable[[str | None], str]
_ValidatorType: TypeAlias = ( # noqa: Y047
_BoolValidatorType
@@ -74,6 +77,9 @@ _ValidatorType: TypeAlias = ( # noqa: Y047
| _UserGroupValidatorType
| _AddressValidatorType
| _CallableValidatorType
| _ProxyProtocolValidatorType
| _ASGILoopValidatorType
| _ASGILifespanValidatorType
)
KNOWN_SETTINGS: list[Setting]
@@ -138,7 +144,7 @@ class Setting(metaclass=SettingMeta):
short: ClassVar[str | None]
desc: ClassVar[str | None]
nargs: ClassVar[int | str | None]
const: ClassVar[bool | None]
const: ClassVar[bool | str | None]
order: ClassVar[int]
def __init__(self) -> None: ...
@@ -649,6 +655,7 @@ class SyslogTo(Setting):
validator: ClassVar[_StringValidatorType]
default: ClassVar[str]
desc: ClassVar[str]
default_doc: ClassVar[str]
class Syslog(Setting):
name: ClassVar[str]
@@ -713,6 +720,15 @@ class StatsdPrefix(Setting):
validator: ClassVar[_StringValidatorType]
desc: ClassVar[str]
class BacklogMetric(Setting):
name: ClassVar[str]
section: ClassVar[str]
cli: ClassVar[list[str]]
validator: ClassVar[_BoolValidatorType]
default: ClassVar[bool]
action: ClassVar[str]
desc: ClassVar[str]
class Procname(Setting):
name: ClassVar[str]
section: ClassVar[str]
@@ -906,13 +922,17 @@ class NewSSLContext(Setting):
def ssl_context(config: Config, default_ssl_context_factory: Callable[[], SSLContext]) -> SSLContext: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
def validate_proxy_protocol(val: str | bool | None) -> str: ...
class ProxyProtocol(Setting):
name: ClassVar[str]
section: ClassVar[str]
cli: ClassVar[list[str]]
validator: ClassVar[_BoolValidatorType]
default: ClassVar[bool]
action: ClassVar[str]
meta: ClassVar[str]
validator: ClassVar[_ProxyProtocolValidatorType]
default: ClassVar[str]
nargs: ClassVar[str]
const: ClassVar[str]
desc: ClassVar[str]
class ProxyAllowFrom(Setting):
@@ -923,6 +943,23 @@ class ProxyAllowFrom(Setting):
default: ClassVar[str]
desc: ClassVar[str]
class Protocol(Setting):
name: ClassVar[str]
section: ClassVar[str]
cli: ClassVar[list[str]]
meta: ClassVar[str]
validator: ClassVar[_StringValidatorType]
default: ClassVar[str]
desc: ClassVar[str]
class UWSGIAllowFrom(Setting):
name: ClassVar[str]
section: ClassVar[str]
cli: ClassVar[list[str]]
validator: ClassVar[_ListStringValidatorType]
default: ClassVar[str]
desc: ClassVar[str]
class KeyFile(Setting):
name: ClassVar[str]
section: ClassVar[str]
@@ -1062,3 +1099,33 @@ class HeaderMap(Setting):
validator: ClassVar[_StringValidatorType]
default: ClassVar[str]
desc: ClassVar[str]
def validate_asgi_loop(val: str | None) -> str: ...
def validate_asgi_lifespan(val: str | None) -> str: ...
class ASGILoop(Setting):
name: ClassVar[str]
section: ClassVar[str]
cli: ClassVar[list[str]]
meta: ClassVar[str]
validator: ClassVar[_ASGILoopValidatorType]
default: ClassVar[str]
desc: ClassVar[str]
class ASGILifespan(Setting):
name: ClassVar[str]
section: ClassVar[str]
cli: ClassVar[list[str]]
meta: ClassVar[str]
validator: ClassVar[_ASGILifespanValidatorType]
default: ClassVar[str]
desc: ClassVar[str]
class RootPath(Setting):
name: ClassVar[str]
section: ClassVar[str]
cli: ClassVar[list[str]]
meta: ClassVar[str]
validator: ClassVar[_StringValidatorType]
default: ClassVar[str]
desc: ClassVar[str]
+12 -1
View File
@@ -1,4 +1,15 @@
import socket
from collections.abc import Iterable
from gunicorn.config import Config
from gunicorn.http.message import Message as Message, Request as Request
from gunicorn.http.parser import RequestParser as RequestParser
from gunicorn.uwsgi.parser import UWSGIParser
__all__ = ["Message", "Request", "RequestParser"]
from .._types import _AddressType
def get_parser(
cfg: Config, source: socket.socket | Iterable[bytes], source_addr: _AddressType
) -> UWSGIParser | RequestParser: ...
__all__ = ["Message", "Request", "RequestParser", "get_parser"]
+6
View File
@@ -80,6 +80,12 @@ class InvalidProxyLine(ParseException):
def __init__(self, line: str) -> None: ...
class InvalidProxyHeader(ParseException):
msg: str
code: int
def __init__(self, msg: str) -> None: ...
class ForbiddenProxyRequest(ParseException):
host: str
code: int
+31 -12
View File
@@ -1,5 +1,7 @@
import io
import re
from enum import IntEnum
from typing import Final
from gunicorn.config import Config
from gunicorn.http.body import Body
@@ -7,14 +9,31 @@ from gunicorn.http.unreader import Unreader
from .._types import _AddressType
MAX_REQUEST_LINE: int
MAX_HEADERS: int
DEFAULT_MAX_HEADERFIELD_SIZE: int
RFC9110_5_6_2_TOKEN_SPECIALS: str
TOKEN_RE: re.Pattern[str]
METHOD_BADCHAR_RE: re.Pattern[str]
VERSION_RE: re.Pattern[str]
RFC9110_5_5_INVALID_AND_DANGEROUS: re.Pattern[str]
PP_V2_SIGNATURE: Final = b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a"
class PPCommand(IntEnum):
LOCAL = 0x0
PROXY = 0x1
class PPFamily(IntEnum):
UNSPEC = 0x0
INET = 0x1
INET6 = 0x2
UNIX = 0x3
class PPProtocol(IntEnum):
UNSPEC = 0x0
STREAM = 0x1
DGRAM = 0x2
MAX_REQUEST_LINE: Final = 8190
MAX_HEADERS: Final = 32768
DEFAULT_MAX_HEADERFIELD_SIZE: Final = 8190
RFC9110_5_6_2_TOKEN_SPECIALS: Final = r"!#$%&'*+-.^_`|~"
TOKEN_RE: Final[re.Pattern[str]]
METHOD_BADCHAR_RE: Final[re.Pattern[str]]
VERSION_RE: Final[re.Pattern[str]]
RFC9110_5_5_INVALID_AND_DANGEROUS: Final[re.Pattern[str]]
class Message:
cfg: Config
@@ -46,14 +65,14 @@ class Request(Message):
fragment: str | None
limit_request_line: int
req_number: int
proxy_protocol_info: dict[str, str | int] | None
proxy_protocol_info: dict[str, str | int | None] | None # TODO: Use TypedDict
def __init__(self, cfg: Config, unreader: Unreader, peer_addr: _AddressType, req_number: int = 1) -> None: ...
def get_data(self, unreader: Unreader, buf: io.BytesIO, stop: bool = False) -> None: ...
def parse(self, unreader: Unreader) -> bytes: ...
def read_line(self, unreader: Unreader, buf: io.BytesIO, limit: int = 0) -> tuple[bytes, bytes]: ...
def proxy_protocol(self, line: str) -> bool: ...
def read_into(self, unreader: Unreader, buf: bytearray, stop: bool | None = False) -> None: ...
def read_line(self, unreader: Unreader, buf: bytearray, limit: int = 0) -> tuple[bytes, bytearray]: ...
def read_bytes(self, unreader: Unreader, buf: bytearray, count: int) -> tuple[bytes, bytearray]: ...
def proxy_protocol_access_check(self) -> None: ...
def parse_proxy_protocol(self, line: str) -> None: ...
def parse_request_line(self, line_bytes: bytes) -> None: ...
def set_body_reader(self) -> None: ...
+2
View File
@@ -9,6 +9,7 @@ from gunicorn.http.unreader import Unreader
from .._types import _AddressType
class Parser:
# TODO: Use Protocol instead of Request class
mesg_class: ClassVar[type[Request] | None]
cfg: Config
unreader: Unreader
@@ -18,6 +19,7 @@ class Parser:
def __init__(self, cfg: Config, source: socket.socket | Iterable[bytes], source_addr: _AddressType) -> None: ...
def __iter__(self) -> Iterator[Request]: ...
def finish_body(self) -> None: ...
def __next__(self) -> Request: ...
next: Callable[[Parser], Request]
+3 -3
View File
@@ -4,15 +4,15 @@ import re
import socket
from _typeshed import ReadableBuffer
from collections.abc import Callable
from typing import Any
from typing import Any, Final
from gunicorn.config import Config
from gunicorn.http import Request
from .._types import _AddressType, _EnvironType, _HeadersType, _StatusType
BLKSIZE: int
HEADER_VALUE_RE: re.Pattern[str]
BLKSIZE: Final = 0x3FFFFFFF
HEADER_VALUE_RE: Final[re.Pattern[str]]
log: logging.Logger
class FileWrapper:
@@ -2,6 +2,7 @@ import logging
import socket
from collections.abc import Mapping
from datetime import timedelta
from typing import Final
from gunicorn.config import Config
from gunicorn.glogging import Logger
@@ -11,12 +12,13 @@ from gunicorn.http.wsgi import Response
from .._types import _EnvironType
from ..glogging import _LogLevelType
METRIC_VAR: str
VALUE_VAR: str
MTYPE_VAR: str
GAUGE_TYPE: str
COUNTER_TYPE: str
HISTOGRAM_TYPE: str
METRIC_VAR: Final = "metric"
VALUE_VAR: Final = "value"
MTYPE_VAR: Final = "mtype"
GAUGE_TYPE: Final = "gauge"
COUNTER_TYPE: Final = "counter"
HISTOGRAM_TYPE: Final = "histogram"
TIMER_TYPE: Final = "timer"
class Statsd(Logger):
prefix: str
@@ -93,4 +95,5 @@ class Statsd(Logger):
def gauge(self, name: str, value: float) -> None: ...
def increment(self, name: str, value: int, sampling_rate: float = 1.0) -> None: ...
def decrement(self, name: str, value: int, sampling_rate: float = 1.0) -> None: ...
def timer(self, name: str, value: float) -> None: ...
def histogram(self, name: str, value: float) -> None: ...
+7 -4
View File
@@ -2,12 +2,12 @@ import sys
import threading
from collections.abc import Callable, Iterable
from re import Pattern
from typing import NoReturn, TypedDict, type_check_only
from typing import Final, NoReturn, TypedDict, type_check_only
from typing_extensions import TypeAlias
COMPILED_EXT_RE: Pattern[str]
COMPILED_EXT_RE: Final[Pattern[str]]
class Reloader(threading.Thread):
class ReloaderBase(threading.Thread):
daemon: bool
def __init__(
@@ -15,18 +15,21 @@ class Reloader(threading.Thread):
) -> None: ...
def add_extra_file(self, filename: str) -> None: ...
def get_files(self) -> list[str]: ...
class Reloader(ReloaderBase):
def run(self) -> None: ...
has_inotify: bool
if sys.platform == "linux":
class InotifyReloader(threading.Thread):
class InotifyReloader(ReloaderBase):
event_mask: int
daemon: bool
def __init__(self, extra_files: Iterable[str] | None = None, callback: Callable[[str], None] | None = None) -> None: ...
def add_extra_file(self, filename: str) -> None: ...
def get_dirs(self) -> set[str]: ...
def refresh_dirs(self) -> None: ...
def run(self) -> None: ...
else:
+5 -1
View File
@@ -2,12 +2,14 @@ import socket
import sys
from collections.abc import Iterable
from ssl import SSLContext, SSLSocket
from typing import Any, ClassVar, Literal, SupportsIndex
from typing import Any, ClassVar, Final, Literal, SupportsIndex
from gunicorn.glogging import Logger as GLogger
from .config import Config
PLATFORM: Final[str]
class BaseSocket:
sock: socket.socket
@@ -16,11 +18,13 @@ class BaseSocket:
def set_options(self, sock: socket.socket, bound: bool = False) -> socket.socket: ...
def bind(self, sock: socket.socket) -> None: ...
def close(self) -> None: ...
def get_backlog(self) -> int: ...
class TCPSocket(BaseSocket):
FAMILY: ClassVar[Literal[socket.AddressFamily.AF_INET, socket.AddressFamily.AF_INET6]]
def set_options(self, sock: socket.socket, bound: bool = False) -> socket.socket: ...
def get_backlog(self) -> int: ...
class TCP6Socket(TCPSocket):
FAMILY: ClassVar[Literal[socket.AddressFamily.AF_INET6]]
+3 -1
View File
@@ -1,6 +1,8 @@
from typing import Final
from gunicorn.glogging import Logger as GLogger
SD_LISTEN_FDS_START: int
SD_LISTEN_FDS_START: Final[int]
def listen_fds(unset_environment: bool = True) -> int: ...
def sd_notify(state: str, logger: GLogger, unset_environment: bool = False) -> None: ...
@@ -0,0 +1,17 @@
from gunicorn.uwsgi.errors import (
ForbiddenUWSGIRequest as ForbiddenUWSGIRequest,
InvalidUWSGIHeader as InvalidUWSGIHeader,
UnsupportedModifier as UnsupportedModifier,
UWSGIParseException as UWSGIParseException,
)
from gunicorn.uwsgi.message import UWSGIRequest as UWSGIRequest
from gunicorn.uwsgi.parser import UWSGIParser as UWSGIParser
__all__ = [
"UWSGIRequest",
"UWSGIParser",
"UWSGIParseException",
"InvalidUWSGIHeader",
"UnsupportedModifier",
"ForbiddenUWSGIRequest",
]
+19
View File
@@ -0,0 +1,19 @@
class UWSGIParseException(Exception): ...
class InvalidUWSGIHeader(UWSGIParseException):
msg: str
code: int
def __init__(self, msg: str = "") -> None: ...
class UnsupportedModifier(UWSGIParseException):
modifier: int
code: int
def __init__(self, modifier: int) -> None: ...
class ForbiddenUWSGIRequest(UWSGIParseException):
host: str
code: int
def __init__(self, host: str) -> None: ...
+37
View File
@@ -0,0 +1,37 @@
from typing import Final, Literal
from gunicorn.config import Config
from gunicorn.http.body import Body
from gunicorn.http.unreader import Unreader
from .._types import _AddressType
MAX_UWSGI_VARS: Final = 1000
class UWSGIRequest:
cfg: Config
unreader: Unreader
peer_addr: _AddressType
remote_addr: _AddressType
req_number: int
method: str | None
uri: str | None
path: str | None
query: str | None
fragment: str | None
version: tuple[int, int]
headers: list[tuple[str, str]]
trailers: list[tuple[str, str]]
body: Body | None
scheme: Literal["https", "http"]
must_close: bool
uwsgi_vars: dict[str, str]
modifier1: int
modifier2: int
proxy_protocol_info: dict[str, str | int | None] | None # TODO: Use TypedDict
def __init__(self, cfg: Config, unreader: Unreader, peer_addr: _AddressType, req_number: int = 1) -> None: ...
def force_close(self) -> None: ...
def parse(self, unreader: Unreader) -> bytes: ...
def set_body_reader(self) -> None: ...
def should_close(self) -> bool: ...
+7
View File
@@ -0,0 +1,7 @@
from typing import ClassVar
from gunicorn.http.parser import Parser
from gunicorn.uwsgi.message import UWSGIRequest
class UWSGIParser(Parser):
mesg_class: ClassVar[type[UWSGIRequest]] # type: ignore[assignment]
@@ -9,5 +9,6 @@ class _SupportedWorkers(TypedDict):
gevent_pywsgi: str
tornado: str
gthread: str
asgi: str
SUPPORTED_WORKERS: _SupportedWorkers
+32
View File
@@ -0,0 +1,32 @@
from _typeshed import Incomplete
from asyncio.base_events import Server
from asyncio.events import AbstractEventLoop
from typing import NoReturn
from gunicorn.asgi.lifespan import LifespanManager
from gunicorn.config import Config
from gunicorn.glogging import Logger as GLogger
from gunicorn.workers import base
from .._types import _ASGIAppType
class ASGIWorker(base.Worker):
worker_connections: int
loop: AbstractEventLoop | None
servers: list[Server]
nr_conns: int
lifespan: LifespanManager | None
state: dict[Incomplete, Incomplete]
asgi: _ASGIAppType
@classmethod
def check_config(cls, cfg: Config, log: GLogger) -> None: ...
def init_process(self) -> None: ...
def load_wsgi(self) -> None: ...
def init_signals(self) -> None: ...
def handle_quit_signal(self) -> None: ...
def handle_exit_signal(self) -> None: ...
def handle_usr1_signal(self) -> None: ...
def handle_winch_signal(self) -> None: ...
def handle_abort_signal(self) -> NoReturn: ...
def run(self) -> None: ...
+2 -2
View File
@@ -1,5 +1,5 @@
from types import FrameType
from typing import Any, ClassVar
from typing import Any, ClassVar, Final
from gevent import pywsgi
from gevent.pywsgi import WSGIHandler
@@ -10,7 +10,7 @@ from gunicorn.workers.base_async import AsyncWorker
from .._types import _AddressType
VERSION: str
VERSION: Final[str]
class GeventWorker(AsyncWorker):
server_class: ClassVar[type[StreamServer] | None]
+21 -4
View File
@@ -1,5 +1,7 @@
import socket
from _typeshed import Unused
from collections import deque
from collections.abc import Callable
from concurrent.futures import Future, ThreadPoolExecutor
from selectors import DefaultSelector
from types import FrameType
@@ -25,12 +27,24 @@ class TConn:
def set_timeout(self) -> None: ...
def close(self) -> None: ...
class PollableMethodQueue:
def __init__(self) -> None: ...
def init(self) -> None: ...
def close(self) -> None: ...
def fileno(self) -> int | None: ...
# Actually, `*args` are expected to match the parameter types of `callback`.
# Ideally this would be typed using ParamSpec as:
# def defer(self, callback: Callable[_P, object], *args: _P.args) -> None
def defer(self, callback: Callable[..., object], *args: object) -> None: ...
def run_callbacks(self, _fileobj: Unused, max_callbacks: int = 50) -> None: ...
class ThreadWorker(base.Worker):
worker_connections: int
max_keepalived: int
tpool: ThreadPoolExecutor
poller: DefaultSelector
futures: deque[Future[tuple[bool, TConn]]]
method_queue: PollableMethodQueue
keepalived_conns: deque[TConn]
nr_conns: int
alive: bool
@@ -38,13 +52,16 @@ class ThreadWorker(base.Worker):
def check_config(cls, cfg: Config, log: GLogger) -> None: ...
def init_process(self) -> None: ...
def get_thread_pool(self) -> ThreadPoolExecutor: ...
def handle_exit(self, sig: int, frame: FrameType | None) -> None: ...
def handle_quit(self, sig: int, frame: FrameType | None) -> None: ...
def set_accept_enabled(self, enabled: bool | None) -> None: ...
def enqueue_req(self, conn: TConn) -> None: ...
def accept(self, server: _AddressType, listener: socket.socket) -> None: ...
def accept(self, listener: socket.socket) -> None: ...
def on_client_socket_readable(self, conn: TConn, client: socket.socket) -> None: ...
def murder_keepalived(self) -> None: ...
def is_parent_alive(self) -> bool: ...
def wait_for_and_dispatch_events(self, timeout: float | None) -> None: ...
def run(self) -> None: ...
def finish_request(self, fs: Future[tuple[bool, TConn]]) -> None: ...
def handle(self, conn: TConn) -> tuple[bool, TConn]: ...
def finish_request(self, conn: TConn, fs: Future[bool]) -> None: ...
def handle(self, conn: TConn) -> bool: ...
def handle_request(self, req: RequestParser, conn: TConn) -> bool: ...
+2 -2
View File
@@ -6,14 +6,14 @@ from gunicorn.workers.base import Worker
IOLoop: TypeAlias = Any # tornado IOLoop class
PeriodicCallback: TypeAlias = Any # tornado PeriodicCallback class
TORNADO5: bool
_HTTPServer: TypeAlias = Any # tornado httpserver.HTTPServer class
class TornadoWorker(Worker):
alive: bool
server_alive: bool
ioloop: IOLoop
callbacks: list[PeriodicCallback]
server: _HTTPServer
@classmethod
def setup(cls) -> None: ...
@@ -1,7 +1,9 @@
from typing import Final
from gunicorn.config import Config
PLATFORM: str
IS_CYGWIN: bool
PLATFORM: Final[str]
IS_CYGWIN: Final[bool]
class WorkerTmp:
def __init__(self, cfg: Config) -> None: ...