Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stubs/gunicorn/METADATA.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "23.0.*"
version = "24.1.0"
upstream_repository = "https://github.com/benoitc/gunicorn"
requires = ["types-gevent"]

Expand Down
10 changes: 6 additions & 4 deletions stubs/gunicorn/gunicorn/__init__.pyi
Original file line number Diff line number Diff line change
@@ -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]
11 changes: 7 additions & 4 deletions stubs/gunicorn/gunicorn/arbiter.pyi
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from queue import SimpleQueue
from types import FrameType
from typing import ClassVar

Expand All @@ -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
Expand All @@ -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: ...
Expand All @@ -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: ...
Expand Down
5 changes: 5 additions & 0 deletions stubs/gunicorn/gunicorn/asgi/__init__.pyi
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions stubs/gunicorn/gunicorn/asgi/lifespan.pyi
Original file line number Diff line number Diff line change
@@ -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 changes: 50 additions & 0 deletions stubs/gunicorn/gunicorn/asgi/message.pyi
Original file line number Diff line number Diff line change
@@ -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 changes: 27 additions & 0 deletions stubs/gunicorn/gunicorn/asgi/protocol.pyi
Original file line number Diff line number Diff line change
@@ -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 changes: 13 additions & 0 deletions stubs/gunicorn/gunicorn/asgi/unreader.pyi
Original file line number Diff line number Diff line change
@@ -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: ...
41 changes: 41 additions & 0 deletions stubs/gunicorn/gunicorn/asgi/websocket.pyi
Original file line number Diff line number Diff line change
@@ -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: ...
75 changes: 71 additions & 4 deletions stubs/gunicorn/gunicorn/config.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -74,6 +77,9 @@ _ValidatorType: TypeAlias = ( # noqa: Y047
| _UserGroupValidatorType
| _AddressValidatorType
| _CallableValidatorType
| _ProxyProtocolValidatorType
| _ASGILoopValidatorType
| _ASGILifespanValidatorType
)

KNOWN_SETTINGS: list[Setting]
Expand Down Expand Up @@ -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: ...
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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):
Expand All @@ -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]
Expand Down Expand Up @@ -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]
13 changes: 12 additions & 1 deletion stubs/gunicorn/gunicorn/http/__init__.pyi
Original file line number Diff line number Diff line change
@@ -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

from .._types import _AddressType

def get_parser(
cfg: Config, source: socket.socket | Iterable[bytes], source_addr: _AddressType
) -> UWSGIParser | RequestParser: ...

__all__ = ["Message", "Request", "RequestParser"]
__all__ = ["Message", "Request", "RequestParser", "get_parser"]
6 changes: 6 additions & 0 deletions stubs/gunicorn/gunicorn/http/errors.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading