From f4af7f4bd5192be937cd4ff1502817f38e9f0166 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Wed, 20 Sep 2023 00:18:44 +0530 Subject: [PATCH 01/26] Added stubs for Flask-SocketIO --- pyrightconfig.stricter.json | 1 + stubs/Flask-SocketIO/METADATA.toml | 2 + .../flask_socketio/__init__.pyi | 85 +++++++++++++++++++ .../flask_socketio/namespace.pyi | 46 ++++++++++ .../flask_socketio/test_client.pyi | 29 +++++++ 5 files changed, 163 insertions(+) create mode 100644 stubs/Flask-SocketIO/METADATA.toml create mode 100644 stubs/Flask-SocketIO/flask_socketio/__init__.pyi create mode 100644 stubs/Flask-SocketIO/flask_socketio/namespace.pyi create mode 100644 stubs/Flask-SocketIO/flask_socketio/test_client.pyi diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index d26c3764d717..74bef90cde2b 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -35,6 +35,7 @@ "stubs/dateparser", "stubs/docutils", "stubs/Flask-Migrate", + "stubs/Flask-SocketIO", "stubs/fpdf2", "stubs/google-cloud-ndb", "stubs/html5lib", diff --git a/stubs/Flask-SocketIO/METADATA.toml b/stubs/Flask-SocketIO/METADATA.toml new file mode 100644 index 000000000000..069b391397b1 --- /dev/null +++ b/stubs/Flask-SocketIO/METADATA.toml @@ -0,0 +1,2 @@ +version = "5.3.*" +upstream_repository = "https://github.com/miguelgrinberg/flask-socketio" diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi new file mode 100644 index 000000000000..020263cf677f --- /dev/null +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -0,0 +1,85 @@ +from _typeshed import Incomplete +from typing import Any, Callable, Literal, TypeVar +from collections import MutableMapping +from threading import Thread + +from typing_extensions import TypeAlias +import socketio +import pywsgi +from flask import Flask +from flask.sessions import SessionMixin +from socketio import socketio_manage as socketio_manage + +from .namespace import Namespace +from .test_client import SocketIOTestClient + +_ExceptionHandler = TypeVar('_ExceptionHandler', Callable) +_Handler = TypeVar('Handler', Callable) +_Environ = TypeVar('Environ', MutableMapping[str, Any]) + +_HandlerDecorator: TypeAlias = Callable[_Handler, _Handler] + +gevent_socketio_found: bool + +class _SocketIOMiddleware(socketio.WSGIApp): + flask_app: Incomplete + def __init__(self, socketio_app: socketio.Server, flask_app: Flask, socketio_path: str = "socket.io") -> None: ... + def __call__(self, environ: _Environ, start_response: Callable[[str, list[tuple[str, str]]]]): ... + +class _ManagedSession(dict, SessionMixin): ... + +class SocketIO: + server: socketio.Server | None + server_options: dict[str, Any] + wsgi_server: pywsgi.WSGIServer | None + handlers: list[_Handler] + namespace_handlers: list + exception_handlers: list[_ExceptionHandler] + default_exception_handler: None | _ExceptionHandler + manage_session: bool + def __init__(self, app: Flask | None = None, **kwargs) -> None: ... + async_mode: Literal['threading', 'eventlet', 'gevent', 'gevent_uwsgi'] + sockio_mw: _SocketIOMiddleware | None + def init_app(self, app: Flask, **kwargs): ... + def on(self, message: str, namespace=None) -> _HandlerDecorator: ... + def on_error(self, namespace=None) -> Callable[_ExceptionHandler, _ExceptionHandler]: ... + def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[_ExceptionHandler, _ExceptionHandler]: ... + def on_event(self, message: str, handler: _Handler, namespace=None) -> None: ... + def event(self, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... + def on_namespace(self, namespace_handler: Namespace) -> None: ... + def emit(self, event: str, *args, **kwargs) -> None: ... + def call(self, event: str, *args, **kwargs): ... + def send( + self, + data: Any, + json: bool = False, + namespace=None, + to=None, + callback: Callable | None = None, + include_self: bool = True, + skip_sid: list[str] | str | None = None, + **kwargs, + ) -> None: ... + def close_room(self, room, namespace=None) -> None: ... + def run(self, app, host: str | None = None, port: int | str | None = None, **kwargs) -> None: ... + def stop(self) -> None: ... + def start_background_task(self, target: Callable, *args, **kwargs) -> Thread: ... + def sleep(self, seconds: int = 0): ... + def test_client( + self, + app: Flask, + namespace=None, + query_string: str | None = None, + headers: dict[str, Any] | None = None, + auth: dict[str, Any] | None = None, + flask_test_client: Incomplete | None = None, + ) -> SocketIOTestClient: ... + +def emit(event, *args, **kwargs) -> None: ... +def call(event, *args, **kwargs): ... +def send(message: str, **kwargs) -> None: ... +def join_room(room, sid: str | None = None, namespace=None) -> None: ... +def leave_room(room, sid: str | None = None, namespace=None) -> None: ... +def close_room(room, namespace=None) -> None: ... +def rooms(sid: str | None = None, namespace=None) -> list[str]: ... +def disconnect(sid: str | None = None, namespace=None, silent: bool = False) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi new file mode 100644 index 000000000000..e7ade4a275fc --- /dev/null +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -0,0 +1,46 @@ +from _typeshed import Incomplete +from typing import Any, Callable, TypedDict, TypeVar + +from typing_extensions import TypeAlias +from socketio import Namespace as _Namespace + +from .socketio import SocketIO + +_T = TypeVar('T') +_Json: TypeAlias = dict[str, _Json] | list[_Json] | int | str | float | bool | None + +class _Acks(TypedDict): + args: Any + namespace: Any + +class Namespace(_Namespace): + acks: Acks | None + socketio: SocketIO | None + + def __init__(self, namespace=None) -> None: ... + def trigger_event(self, event: Incomplete, *args): ... + def emit( + self, + event: Incomplete, + data: Incomplete | None = None, + room: str | None = None, + include_self: bool = True, + namespace: str | None = None, + callback: Callable[..., _T] | None = None, + ) -> _T | tuple[str, int]: ... + def send( + self, + data: str | list[_Json] | dict[str, _Json], + room: str | None = None, + include_self: bool = True, + namespace=None, + callback: Callable | None = None, + ) -> None: ... + def close_room(self, room: str, namespace=None) -> None: ... + def disconnect(self, namespace: str | None = None) -> None: ... + def emit(self, event: str, *args, **kwargs): ... + def send( + self, + data: _Json, + json: bool = False, + callback=False, namespace=None) -> None: diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi new file mode 100644 index 000000000000..4a2511b12972 --- /dev/null +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -0,0 +1,29 @@ +from __future__ import annotations +from _typeshed import Incomplete +from typing import Any + +from flask import Flask +from flask.testing import FlaskClient + +from .namespace import Namespace + +class SocketIOTestClient(object): + clients: dict[str, SocketIOTestClient] + + def __init__( + self, + app: Flask, + socketio, + namespace: str | None = None, + query_string: str | None = None, + headers: dict[str, Any] = None, + auth: dict[str, Any] | None = None, + flask_test_client: FlaskClient | None = None): ... + def is_connected(self, namespace: str | None = None) -> bool: ... + def connect( + self, + namespace: str | None = None, + query_string: str | None = None, + headers: dict[str, Any] = None, + auth: dict[str, Any] | None = None) -> None: ... + From 885a3ce3671cfde9ff42732c957a431e41759170 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 18:50:45 +0000 Subject: [PATCH 02/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 16 ++++++++-------- .../Flask-SocketIO/flask_socketio/namespace.pyi | 2 +- .../flask_socketio/test_client.pyi | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 020263cf677f..233d402ad921 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -1,11 +1,11 @@ from _typeshed import Incomplete -from typing import Any, Callable, Literal, TypeVar -from collections import MutableMapping +from collections.abc import MutableMapping from threading import Thread - +from typing import Any, Callable, Literal, TypeVar from typing_extensions import TypeAlias -import socketio + import pywsgi +import socketio from flask import Flask from flask.sessions import SessionMixin from socketio import socketio_manage as socketio_manage @@ -13,9 +13,9 @@ from socketio import socketio_manage as socketio_manage from .namespace import Namespace from .test_client import SocketIOTestClient -_ExceptionHandler = TypeVar('_ExceptionHandler', Callable) -_Handler = TypeVar('Handler', Callable) -_Environ = TypeVar('Environ', MutableMapping[str, Any]) +_ExceptionHandler = TypeVar("_ExceptionHandler", Callable) +_Handler = TypeVar("Handler", Callable) +_Environ = TypeVar("Environ", MutableMapping[str, Any]) _HandlerDecorator: TypeAlias = Callable[_Handler, _Handler] @@ -38,7 +38,7 @@ class SocketIO: default_exception_handler: None | _ExceptionHandler manage_session: bool def __init__(self, app: Flask | None = None, **kwargs) -> None: ... - async_mode: Literal['threading', 'eventlet', 'gevent', 'gevent_uwsgi'] + async_mode: Literal["threading", "eventlet", "gevent", "gevent_uwsgi"] sockio_mw: _SocketIOMiddleware | None def init_app(self, app: Flask, **kwargs): ... def on(self, message: str, namespace=None) -> _HandlerDecorator: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index e7ade4a275fc..28563192df8a 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -1,7 +1,7 @@ from _typeshed import Incomplete from typing import Any, Callable, TypedDict, TypeVar - from typing_extensions import TypeAlias + from socketio import Namespace as _Namespace from .socketio import SocketIO diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index 4a2511b12972..420f490572e4 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,13 +1,12 @@ from __future__ import annotations -from _typeshed import Incomplete + from typing import Any from flask import Flask from flask.testing import FlaskClient -from .namespace import Namespace -class SocketIOTestClient(object): +class SocketIOTestClient: clients: dict[str, SocketIOTestClient] def __init__( @@ -18,12 +17,13 @@ class SocketIOTestClient(object): query_string: str | None = None, headers: dict[str, Any] = None, auth: dict[str, Any] | None = None, - flask_test_client: FlaskClient | None = None): ... + flask_test_client: FlaskClient | None = None, + ): ... def is_connected(self, namespace: str | None = None) -> bool: ... def connect( self, namespace: str | None = None, query_string: str | None = None, headers: dict[str, Any] = None, - auth: dict[str, Any] | None = None) -> None: ... - + auth: dict[str, Any] | None = None, + ) -> None: ... From 7c4e3f97f562ff218254563f902146d4b053954c Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Wed, 20 Sep 2023 00:47:40 +0530 Subject: [PATCH 03/26] Removed all Incomplete type stubs --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 5 +++-- stubs/Flask-SocketIO/flask_socketio/namespace.pyi | 14 ++++++-------- .../Flask-SocketIO/flask_socketio/test_client.pyi | 3 --- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 233d402ad921..9ea9f8278819 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -7,6 +7,7 @@ from typing_extensions import TypeAlias import pywsgi import socketio from flask import Flask +from flask.testing import FlaskClient from flask.sessions import SessionMixin from socketio import socketio_manage as socketio_manage @@ -22,7 +23,7 @@ _HandlerDecorator: TypeAlias = Callable[_Handler, _Handler] gevent_socketio_found: bool class _SocketIOMiddleware(socketio.WSGIApp): - flask_app: Incomplete + flask_app: Flask def __init__(self, socketio_app: socketio.Server, flask_app: Flask, socketio_path: str = "socket.io") -> None: ... def __call__(self, environ: _Environ, start_response: Callable[[str, list[tuple[str, str]]]]): ... @@ -72,7 +73,7 @@ class SocketIO: query_string: str | None = None, headers: dict[str, Any] | None = None, auth: dict[str, Any] | None = None, - flask_test_client: Incomplete | None = None, + flask_test_client: FlaskClient | None = None, ) -> SocketIOTestClient: ... def emit(event, *args, **kwargs) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index 28563192df8a..ea8c4d47e184 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -1,4 +1,3 @@ -from _typeshed import Incomplete from typing import Any, Callable, TypedDict, TypeVar from typing_extensions import TypeAlias @@ -7,7 +6,6 @@ from socketio import Namespace as _Namespace from .socketio import SocketIO _T = TypeVar('T') -_Json: TypeAlias = dict[str, _Json] | list[_Json] | int | str | float | bool | None class _Acks(TypedDict): args: Any @@ -18,11 +16,11 @@ class Namespace(_Namespace): socketio: SocketIO | None def __init__(self, namespace=None) -> None: ... - def trigger_event(self, event: Incomplete, *args): ... + def trigger_event(self, event: str, *args): ... def emit( self, - event: Incomplete, - data: Incomplete | None = None, + event: str, + data: Any = None, room: str | None = None, include_self: bool = True, namespace: str | None = None, @@ -30,7 +28,7 @@ class Namespace(_Namespace): ) -> _T | tuple[str, int]: ... def send( self, - data: str | list[_Json] | dict[str, _Json], + data: Any, room: str | None = None, include_self: bool = True, namespace=None, @@ -41,6 +39,6 @@ class Namespace(_Namespace): def emit(self, event: str, *args, **kwargs): ... def send( self, - data: _Json, + data: Any, json: bool = False, - callback=False, namespace=None) -> None: + callback=False, namespace=None) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index 420f490572e4..2d7140424aa8 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,11 +1,8 @@ -from __future__ import annotations - from typing import Any from flask import Flask from flask.testing import FlaskClient - class SocketIOTestClient: clients: dict[str, SocketIOTestClient] From d0c057cf9841ddd556eec27403e3cff0662d0274 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 19:22:48 +0000 Subject: [PATCH 04/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 3 +-- .../Flask-SocketIO/flask_socketio/namespace.pyi | 16 +++------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 9ea9f8278819..d79807f3cb42 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -1,4 +1,3 @@ -from _typeshed import Incomplete from collections.abc import MutableMapping from threading import Thread from typing import Any, Callable, Literal, TypeVar @@ -7,8 +6,8 @@ from typing_extensions import TypeAlias import pywsgi import socketio from flask import Flask -from flask.testing import FlaskClient from flask.sessions import SessionMixin +from flask.testing import FlaskClient from socketio import socketio_manage as socketio_manage from .namespace import Namespace diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index ea8c4d47e184..68f374d1d96a 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -1,11 +1,10 @@ from typing import Any, Callable, TypedDict, TypeVar -from typing_extensions import TypeAlias from socketio import Namespace as _Namespace from .socketio import SocketIO -_T = TypeVar('T') +_T = TypeVar("T") class _Acks(TypedDict): args: Any @@ -27,18 +26,9 @@ class Namespace(_Namespace): callback: Callable[..., _T] | None = None, ) -> _T | tuple[str, int]: ... def send( - self, - data: Any, - room: str | None = None, - include_self: bool = True, - namespace=None, - callback: Callable | None = None, + self, data: Any, room: str | None = None, include_self: bool = True, namespace=None, callback: Callable | None = None ) -> None: ... def close_room(self, room: str, namespace=None) -> None: ... def disconnect(self, namespace: str | None = None) -> None: ... def emit(self, event: str, *args, **kwargs): ... - def send( - self, - data: Any, - json: bool = False, - callback=False, namespace=None) -> None: ... + def send(self, data: Any, json: bool = False, callback=False, namespace=None) -> None: ... From 981ccc58bffb385b089baec71c9ee606711fbf23 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Wed, 20 Sep 2023 00:55:34 +0530 Subject: [PATCH 05/26] Type hint namespace as str --- .../flask_socketio/__init__.pyi | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index d79807f3cb42..fec6742862e4 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -41,10 +41,10 @@ class SocketIO: async_mode: Literal["threading", "eventlet", "gevent", "gevent_uwsgi"] sockio_mw: _SocketIOMiddleware | None def init_app(self, app: Flask, **kwargs): ... - def on(self, message: str, namespace=None) -> _HandlerDecorator: ... - def on_error(self, namespace=None) -> Callable[_ExceptionHandler, _ExceptionHandler]: ... + def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... + def on_error(self, namespace: str | None = None) -> Callable[_ExceptionHandler, _ExceptionHandler]: ... def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[_ExceptionHandler, _ExceptionHandler]: ... - def on_event(self, message: str, handler: _Handler, namespace=None) -> None: ... + def on_event(self, message: str, handler: _Handler, namespace: str | None = None) -> None: ... def event(self, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... def on_namespace(self, namespace_handler: Namespace) -> None: ... def emit(self, event: str, *args, **kwargs) -> None: ... @@ -53,14 +53,14 @@ class SocketIO: self, data: Any, json: bool = False, - namespace=None, + namespace: str | None = None, to=None, callback: Callable | None = None, include_self: bool = True, skip_sid: list[str] | str | None = None, **kwargs, ) -> None: ... - def close_room(self, room, namespace=None) -> None: ... + def close_room(self, room, namespace: str | None = None) -> None: ... def run(self, app, host: str | None = None, port: int | str | None = None, **kwargs) -> None: ... def stop(self) -> None: ... def start_background_task(self, target: Callable, *args, **kwargs) -> Thread: ... @@ -68,7 +68,7 @@ class SocketIO: def test_client( self, app: Flask, - namespace=None, + namespace: str | None = None, query_string: str | None = None, headers: dict[str, Any] | None = None, auth: dict[str, Any] | None = None, @@ -78,8 +78,8 @@ class SocketIO: def emit(event, *args, **kwargs) -> None: ... def call(event, *args, **kwargs): ... def send(message: str, **kwargs) -> None: ... -def join_room(room, sid: str | None = None, namespace=None) -> None: ... -def leave_room(room, sid: str | None = None, namespace=None) -> None: ... -def close_room(room, namespace=None) -> None: ... -def rooms(sid: str | None = None, namespace=None) -> list[str]: ... -def disconnect(sid: str | None = None, namespace=None, silent: bool = False) -> None: ... +def join_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... +def leave_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... +def close_room(room, namespace: str | None = None) -> None: ... +def rooms(sid: str | None = None, namespace: str | None = None) -> list[str]: ... +def disconnect(sid: str | None = None, namespace: str | None = None, silent: bool = False) -> None: ... From 4d6db8b94c8d1f4930e0df546562916da53d1252 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Wed, 20 Sep 2023 07:55:27 +0530 Subject: [PATCH 06/26] Removed private classes and attributes, added kwargs types --- .../flask_socketio/__init__.pyi | 91 +++++++++++-------- .../flask_socketio/namespace.pyi | 32 +++---- .../flask_socketio/test_client.pyi | 16 +++- 3 files changed, 75 insertions(+), 64 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index fec6742862e4..800b16474903 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -1,69 +1,82 @@ -from collections.abc import MutableMapping +from collections.abc import Callable from threading import Thread -from typing import Any, Callable, Literal, TypeVar -from typing_extensions import TypeAlias +from typing import Any, ParamSpec, TypedDict +from logging import Logger -import pywsgi -import socketio +from socketio.base_manager import BaseManager from flask import Flask -from flask.sessions import SessionMixin from flask.testing import FlaskClient -from socketio import socketio_manage as socketio_manage +from typing_extensions import TypeAlias, Unpack, NotRequired from .namespace import Namespace from .test_client import SocketIOTestClient -_ExceptionHandler = TypeVar("_ExceptionHandler", Callable) -_Handler = TypeVar("Handler", Callable) -_Environ = TypeVar("Environ", MutableMapping[str, Any]) +_P = ParamSpec("_P") +_ExceptionHandler: TypeAlias = Callable[[Exception], Any] +_Handler: TypeAlias = Callable[[Any], Any] -_HandlerDecorator: TypeAlias = Callable[_Handler, _Handler] +_HandlerDecorator: TypeAlias = Callable[[_Handler], _Handler] gevent_socketio_found: bool -class _SocketIOMiddleware(socketio.WSGIApp): - flask_app: Flask - def __init__(self, socketio_app: socketio.Server, flask_app: Flask, socketio_path: str = "socket.io") -> None: ... - def __call__(self, environ: _Environ, start_response: Callable[[str, list[tuple[str, str]]]]): ... -class _ManagedSession(dict, SessionMixin): ... +class _SocketIOConfig(TypedDict, total=False): + manage_session: NotRequired[bool] + message_queue: NotRequired[str] + channel: NotRequired[str] + path: NotRequired[str] + resource: NotRequired[str] + + # SocketIO.Server options + client_manager: NotRequired[BaseManager] + logger: NotRequired[bool | Logger] + json: NotRequired[Any] + async_handlers: NotRequired[bool] + always_connect: NotRequired[bool] + +class _SocketIOCallArgs(TypedDict, total=False): + namespace: NotRequired[str] + to: NotRequired[str] + room: NotRequired[str] + +class _SocketIOEmitArgs(_SocketIOCallArgs, total=False): + include_self: NotRequired[bool] + skip_sid: NotRequired[str | list[str]] + callback: NotRequired[Callable[..., Any]] + +class _SocketIORunArgs(TypedDict, total=False): + debug: NotRequired[bool] + use_reloader: NotRequired[bool] + reloader_options: dict[str, Any] + log_output: NotRequired[bool] + allow_unsafe_werkzeug: NotRequired[bool] class SocketIO: - server: socketio.Server | None - server_options: dict[str, Any] - wsgi_server: pywsgi.WSGIServer | None - handlers: list[_Handler] - namespace_handlers: list - exception_handlers: list[_ExceptionHandler] - default_exception_handler: None | _ExceptionHandler - manage_session: bool - def __init__(self, app: Flask | None = None, **kwargs) -> None: ... - async_mode: Literal["threading", "eventlet", "gevent", "gevent_uwsgi"] - sockio_mw: _SocketIOMiddleware | None - def init_app(self, app: Flask, **kwargs): ... + def __init__(self, app: Flask | None = None, **kwargs: Unpack[_SocketIOConfig]) -> None: ... + def init_app(self, app: Flask, **kwargs: Unpack[_SocketIOConfig]): ... def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... - def on_error(self, namespace: str | None = None) -> Callable[_ExceptionHandler, _ExceptionHandler]: ... - def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[_ExceptionHandler, _ExceptionHandler]: ... + def on_error(self, namespace: str | None = None) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... + def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... def on_event(self, message: str, handler: _Handler, namespace: str | None = None) -> None: ... - def event(self, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... + def event(self, namespace: str | None = None, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... def on_namespace(self, namespace_handler: Namespace) -> None: ... - def emit(self, event: str, *args, **kwargs) -> None: ... - def call(self, event: str, *args, **kwargs): ... + def emit(self, event: str, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... + def call(self, event: str, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... def send( self, data: Any, json: bool = False, namespace: str | None = None, - to=None, + to: str | None = None, callback: Callable | None = None, include_self: bool = True, skip_sid: list[str] | str | None = None, **kwargs, ) -> None: ... - def close_room(self, room, namespace: str | None = None) -> None: ... - def run(self, app, host: str | None = None, port: int | str | None = None, **kwargs) -> None: ... + def close_room(self, room: str, namespace: str | None = None) -> None: ... + def run(self, app, host: str | None = None, port: int | None = None, **kwargs: _SocketIORunArgs) -> None: ... def stop(self) -> None: ... - def start_background_task(self, target: Callable, *args, **kwargs) -> Thread: ... + def start_background_task(self, target: Callable[_P, None], *args: _P.args, **kwargs: _P.kwargs) -> Thread: ... def sleep(self, seconds: int = 0): ... def test_client( self, @@ -75,8 +88,8 @@ class SocketIO: flask_test_client: FlaskClient | None = None, ) -> SocketIOTestClient: ... -def emit(event, *args, **kwargs) -> None: ... -def call(event, *args, **kwargs): ... +def emit(event, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... +def call(event, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... def send(message: str, **kwargs) -> None: ... def join_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... def leave_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index 68f374d1d96a..b89267aed3c9 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -1,20 +1,10 @@ -from typing import Any, Callable, TypedDict, TypeVar +from typing import Any, TypeVar +from collections.abc import Callable -from socketio import Namespace as _Namespace +_T = TypeVar("_T") -from .socketio import SocketIO - -_T = TypeVar("T") - -class _Acks(TypedDict): - args: Any - namespace: Any - -class Namespace(_Namespace): - acks: Acks | None - socketio: SocketIO | None - - def __init__(self, namespace=None) -> None: ... +class Namespace: + def __init__(self, namespace: str | None = None) -> None: ... def trigger_event(self, event: str, *args): ... def emit( self, @@ -26,9 +16,11 @@ class Namespace(_Namespace): callback: Callable[..., _T] | None = None, ) -> _T | tuple[str, int]: ... def send( - self, data: Any, room: str | None = None, include_self: bool = True, namespace=None, callback: Callable | None = None + self, + data: Any, + room: str | None = None, + include_self: bool = True, + namespace: str | None = None, + callback: Callable[..., Any] | None = None ) -> None: ... - def close_room(self, room: str, namespace=None) -> None: ... - def disconnect(self, namespace: str | None = None) -> None: ... - def emit(self, event: str, *args, **kwargs): ... - def send(self, data: Any, json: bool = False, callback=False, namespace=None) -> None: ... + def close_room(self, room: str, namespace: str | None = None) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index 2d7140424aa8..20cb3d061e8e 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,18 +1,21 @@ -from typing import Any +from typing import Any, TypedDict from flask import Flask from flask.testing import FlaskClient -class SocketIOTestClient: - clients: dict[str, SocketIOTestClient] +class _Packet(TypedDict, total=False): + name: str + args: Any + namespace: str +class SocketIOTestClient: def __init__( self, app: Flask, socketio, namespace: str | None = None, query_string: str | None = None, - headers: dict[str, Any] = None, + headers: dict[str, Any] | None = None, auth: dict[str, Any] | None = None, flask_test_client: FlaskClient | None = None, ): ... @@ -21,6 +24,9 @@ class SocketIOTestClient: self, namespace: str | None = None, query_string: str | None = None, - headers: dict[str, Any] = None, + headers: dict[str, Any] | None = None, auth: dict[str, Any] | None = None, ) -> None: ... + def disconnect(self, namespace: str | None = None) -> None: ... + def emit(self, event: str, *args, callback: bool = True, namespace: str | None = None): ... + def get_recieved(self, namespace: str | None = None) -> list[_Packet]: ... From 9c8610e1f5fa41ae555147a8b26e57c06e8f2b13 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 02:26:17 +0000 Subject: [PATCH 07/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 7 +++---- stubs/Flask-SocketIO/flask_socketio/namespace.pyi | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 800b16474903..5d8d6d6f5f6e 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -1,12 +1,12 @@ from collections.abc import Callable +from logging import Logger from threading import Thread from typing import Any, ParamSpec, TypedDict -from logging import Logger +from typing_extensions import NotRequired, TypeAlias, Unpack -from socketio.base_manager import BaseManager from flask import Flask from flask.testing import FlaskClient -from typing_extensions import TypeAlias, Unpack, NotRequired +from socketio.base_manager import BaseManager from .namespace import Namespace from .test_client import SocketIOTestClient @@ -19,7 +19,6 @@ _HandlerDecorator: TypeAlias = Callable[[_Handler], _Handler] gevent_socketio_found: bool - class _SocketIOConfig(TypedDict, total=False): manage_session: NotRequired[bool] message_queue: NotRequired[str] diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index b89267aed3c9..aefa3a504d9d 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -1,5 +1,5 @@ -from typing import Any, TypeVar from collections.abc import Callable +from typing import Any, TypeVar _T = TypeVar("_T") @@ -21,6 +21,6 @@ class Namespace: room: str | None = None, include_self: bool = True, namespace: str | None = None, - callback: Callable[..., Any] | None = None + callback: Callable[..., Any] | None = None, ) -> None: ... def close_room(self, room: str, namespace: str | None = None) -> None: ... From f694170eefa3a76c2b8d2fcd7e63ba260b2e28fb Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Wed, 20 Sep 2023 08:14:44 +0530 Subject: [PATCH 08/26] Deal with mypy errors --- .../flask_socketio/__init__.pyi | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 5d8d6d6f5f6e..c478dfb49939 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -4,6 +4,7 @@ from threading import Thread from typing import Any, ParamSpec, TypedDict from typing_extensions import NotRequired, TypeAlias, Unpack +from socketio.base_manager import BaseManager # type: ignore from flask import Flask from flask.testing import FlaskClient from socketio.base_manager import BaseManager @@ -19,6 +20,7 @@ _HandlerDecorator: TypeAlias = Callable[[_Handler], _Handler] gevent_socketio_found: bool + class _SocketIOConfig(TypedDict, total=False): manage_session: NotRequired[bool] message_queue: NotRequired[str] @@ -51,16 +53,24 @@ class _SocketIORunArgs(TypedDict, total=False): allow_unsafe_werkzeug: NotRequired[bool] class SocketIO: - def __init__(self, app: Flask | None = None, **kwargs: Unpack[_SocketIOConfig]) -> None: ... - def init_app(self, app: Flask, **kwargs: Unpack[_SocketIOConfig]): ... + def __init__(self, app: Flask | None = None, + **kwargs: Unpack[_SocketIOConfig] # type: ignore + ) -> None: ... + def init_app(self, app: Flask, + **kwargs: Unpack[_SocketIOConfig] # type: ignore + ): ... def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... def on_error(self, namespace: str | None = None) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... def on_event(self, message: str, handler: _Handler, namespace: str | None = None) -> None: ... def event(self, namespace: str | None = None, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... def on_namespace(self, namespace_handler: Namespace) -> None: ... - def emit(self, event: str, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... - def call(self, event: str, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... + def emit(self, event: str, *args, + **kwargs: Unpack[_SocketIOEmitArgs] # type: ignore + ) -> None: ... + def call(self, event: str, *args, + **kwargs: Unpack[_SocketIOCallArgs] # type: ignore + ): ... def send( self, data: Any, @@ -87,8 +97,12 @@ class SocketIO: flask_test_client: FlaskClient | None = None, ) -> SocketIOTestClient: ... -def emit(event, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... -def call(event, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... +def emit(event, *args, + **kwargs: Unpack[_SocketIOEmitArgs] # type: ignore +) -> None: ... +def call(event, *args, + **kwargs: Unpack[_SocketIOCallArgs] # type: ignore +): ... def send(message: str, **kwargs) -> None: ... def join_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... def leave_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... From 5d8fa96591722cefec6486aec86802c2b661187e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 02:48:51 +0000 Subject: [PATCH 09/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- .../flask_socketio/__init__.pyi | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index c478dfb49939..422fdfeca4f7 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -4,10 +4,9 @@ from threading import Thread from typing import Any, ParamSpec, TypedDict from typing_extensions import NotRequired, TypeAlias, Unpack -from socketio.base_manager import BaseManager # type: ignore from flask import Flask from flask.testing import FlaskClient -from socketio.base_manager import BaseManager +from socketio.base_manager import BaseManager # type: ignore from .namespace import Namespace from .test_client import SocketIOTestClient @@ -20,7 +19,6 @@ _HandlerDecorator: TypeAlias = Callable[[_Handler], _Handler] gevent_socketio_found: bool - class _SocketIOConfig(TypedDict, total=False): manage_session: NotRequired[bool] message_queue: NotRequired[str] @@ -53,24 +51,16 @@ class _SocketIORunArgs(TypedDict, total=False): allow_unsafe_werkzeug: NotRequired[bool] class SocketIO: - def __init__(self, app: Flask | None = None, - **kwargs: Unpack[_SocketIOConfig] # type: ignore - ) -> None: ... - def init_app(self, app: Flask, - **kwargs: Unpack[_SocketIOConfig] # type: ignore - ): ... + def __init__(self, app: Flask | None = None, **kwargs: Unpack[_SocketIOConfig]) -> None: ... # type: ignore + def init_app(self, app: Flask, **kwargs: Unpack[_SocketIOConfig]): ... # type: ignore def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... def on_error(self, namespace: str | None = None) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... def on_event(self, message: str, handler: _Handler, namespace: str | None = None) -> None: ... def event(self, namespace: str | None = None, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... def on_namespace(self, namespace_handler: Namespace) -> None: ... - def emit(self, event: str, *args, - **kwargs: Unpack[_SocketIOEmitArgs] # type: ignore - ) -> None: ... - def call(self, event: str, *args, - **kwargs: Unpack[_SocketIOCallArgs] # type: ignore - ): ... + def emit(self, event: str, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... # type: ignore + def call(self, event: str, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... # type: ignore def send( self, data: Any, @@ -97,12 +87,8 @@ class SocketIO: flask_test_client: FlaskClient | None = None, ) -> SocketIOTestClient: ... -def emit(event, *args, - **kwargs: Unpack[_SocketIOEmitArgs] # type: ignore -) -> None: ... -def call(event, *args, - **kwargs: Unpack[_SocketIOCallArgs] # type: ignore -): ... +def emit(event, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... # type: ignore +def call(event, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... # type: ignore def send(message: str, **kwargs) -> None: ... def join_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... def leave_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... From ece6efa8961dbf53e26dcfdea76237141c8c5f06 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Wed, 20 Sep 2023 08:43:51 +0530 Subject: [PATCH 10/26] Add method send in test_client.py --- stubs/Flask-SocketIO/flask_socketio/test_client.pyi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index 20cb3d061e8e..7213d12b1abb 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,4 +1,5 @@ from typing import Any, TypedDict +from collections.abc import Callable from flask import Flask from flask.testing import FlaskClient @@ -30,3 +31,12 @@ class SocketIOTestClient: def disconnect(self, namespace: str | None = None) -> None: ... def emit(self, event: str, *args, callback: bool = True, namespace: str | None = None): ... def get_recieved(self, namespace: str | None = None) -> list[_Packet]: ... + def send( + self, + data: Any, + json: bool = False, + namespace: str | None = None, + include_self: bool = True, + skip_sid: list[str] | str | None = None, + callback: Callable[..., Any] | None = None, + **kwargs): ... From acd1a60bae1565b3c208a3616cb679a26e9e1e1d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 03:14:37 +0000 Subject: [PATCH 11/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/Flask-SocketIO/flask_socketio/test_client.pyi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index 7213d12b1abb..5eed62099a03 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,5 +1,5 @@ -from typing import Any, TypedDict from collections.abc import Callable +from typing import Any, TypedDict from flask import Flask from flask.testing import FlaskClient @@ -39,4 +39,5 @@ class SocketIOTestClient: include_self: bool = True, skip_sid: list[str] | str | None = None, callback: Callable[..., Any] | None = None, - **kwargs): ... + **kwargs, + ): ... From b7e18e3110fb91411e46984113cff156139e0b6e Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Wed, 20 Sep 2023 09:04:23 +0530 Subject: [PATCH 12/26] test_client: Corrected type hints --- stubs/Flask-SocketIO/flask_socketio/test_client.pyi | 10 +++------- tests/stubtest_allowlists/py3_common.txt | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index 5eed62099a03..bf9acc371f82 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,5 +1,5 @@ -from collections.abc import Callable from typing import Any, TypedDict +from collections.abc import Callable from flask import Flask from flask.testing import FlaskClient @@ -35,9 +35,5 @@ class SocketIOTestClient: self, data: Any, json: bool = False, - namespace: str | None = None, - include_self: bool = True, - skip_sid: list[str] | str | None = None, - callback: Callable[..., Any] | None = None, - **kwargs, - ): ... + callback: Callable[..., Any] | Any = False, + namespace: str | None = None): ... diff --git a/tests/stubtest_allowlists/py3_common.txt b/tests/stubtest_allowlists/py3_common.txt index a7db8a2a877e..6a6572b14d86 100644 --- a/tests/stubtest_allowlists/py3_common.txt +++ b/tests/stubtest_allowlists/py3_common.txt @@ -39,6 +39,7 @@ ctypes.memmove # CFunctionType ctypes.memset # CFunctionType ctypes.string_at # docstring argument name is wrong ctypes.wstring_at # docstring argument name is wrong +flask_socketio.test_client.SocketIOTestClient.clients # private attribute, not present in docs fractions.Fraction.__new__ # overload is too complicated for stubtest to resolve ftplib.FTP.trust_server_pasv_ipv4_address # Dangerous to use, intentionally undocumented, intentionally missing from typeshed. #6154 functools.cached_property.__set__ # Stub is a white lie; see comments in the stub From 405251cd5cbc92caef18af59842e4f17804897be Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 03:35:08 +0000 Subject: [PATCH 13/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/Flask-SocketIO/flask_socketio/test_client.pyi | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index bf9acc371f82..d9462d3737d7 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,5 +1,5 @@ -from typing import Any, TypedDict from collections.abc import Callable +from typing import Any, TypedDict from flask import Flask from flask.testing import FlaskClient @@ -31,9 +31,4 @@ class SocketIOTestClient: def disconnect(self, namespace: str | None = None) -> None: ... def emit(self, event: str, *args, callback: bool = True, namespace: str | None = None): ... def get_recieved(self, namespace: str | None = None) -> list[_Packet]: ... - def send( - self, - data: Any, - json: bool = False, - callback: Callable[..., Any] | Any = False, - namespace: str | None = None): ... + def send(self, data: Any, json: bool = False, callback: Callable[..., Any] | Any = False, namespace: str | None = None): ... From 59158cc413fae408cd476ab157271b4a67cf04e7 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Thu, 21 Sep 2023 00:34:35 +0100 Subject: [PATCH 14/26] Fix some obvious stuff --- stubs/Flask-SocketIO/METADATA.toml | 2 ++ stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 4 ++-- tests/stubtest_allowlists/py3_common.txt | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/stubs/Flask-SocketIO/METADATA.toml b/stubs/Flask-SocketIO/METADATA.toml index 069b391397b1..8906c5ad259e 100644 --- a/stubs/Flask-SocketIO/METADATA.toml +++ b/stubs/Flask-SocketIO/METADATA.toml @@ -1,2 +1,4 @@ version = "5.3.*" +# Requires a version of flask with a `py.typed` file +requires = ["Flask>=2.0.0"] upstream_repository = "https://github.com/miguelgrinberg/flask-socketio" diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 422fdfeca4f7..4288152772be 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -1,8 +1,8 @@ from collections.abc import Callable from logging import Logger from threading import Thread -from typing import Any, ParamSpec, TypedDict -from typing_extensions import NotRequired, TypeAlias, Unpack +from typing import Any +from typing_extensions import NotRequired, ParamSpec, TypeAlias, TypedDict, Unpack from flask import Flask from flask.testing import FlaskClient diff --git a/tests/stubtest_allowlists/py3_common.txt b/tests/stubtest_allowlists/py3_common.txt index 6a6572b14d86..a7db8a2a877e 100644 --- a/tests/stubtest_allowlists/py3_common.txt +++ b/tests/stubtest_allowlists/py3_common.txt @@ -39,7 +39,6 @@ ctypes.memmove # CFunctionType ctypes.memset # CFunctionType ctypes.string_at # docstring argument name is wrong ctypes.wstring_at # docstring argument name is wrong -flask_socketio.test_client.SocketIOTestClient.clients # private attribute, not present in docs fractions.Fraction.__new__ # overload is too complicated for stubtest to resolve ftplib.FTP.trust_server_pasv_ipv4_address # Dangerous to use, intentionally undocumented, intentionally missing from typeshed. #6154 functools.cached_property.__set__ # Stub is a white lie; see comments in the stub From dc7d2b5945da1d4a18265a7ef96da17e26c17dc8 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Thu, 21 Sep 2023 00:36:05 +0100 Subject: [PATCH 15/26] add the new allowlist --- stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt diff --git a/stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt b/stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt new file mode 100644 index 000000000000..1a4e31cf9285 --- /dev/null +++ b/stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt @@ -0,0 +1 @@ +flask_socketio.test_client.SocketIOTestClient.clients # private attribute, not present in docs From 9131d85153a4d8e63a69944f57679521d2555faf Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 21 Sep 2023 00:39:30 +0100 Subject: [PATCH 16/26] Update test_client.pyi --- stubs/Flask-SocketIO/flask_socketio/test_client.pyi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index d9462d3737d7..c3980d609fd1 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,5 +1,6 @@ from collections.abc import Callable -from typing import Any, TypedDict +from typing import Any +from typing_extensions import TypedDict from flask import Flask from flask.testing import FlaskClient From e1ca93529b34ed0bdbb63d2f4e879ab04a97ced3 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 21 Sep 2023 00:41:52 +0100 Subject: [PATCH 17/26] Update __init__.pyi --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 4288152772be..52c3cf6bb78a 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -6,7 +6,7 @@ from typing_extensions import NotRequired, ParamSpec, TypeAlias, TypedDict, Unpa from flask import Flask from flask.testing import FlaskClient -from socketio.base_manager import BaseManager # type: ignore +from socketio.base_manager import BaseManager # type: ignore[import] # pyright: ignore[reportMissingImports] from .namespace import Namespace from .test_client import SocketIOTestClient From b6e8910ef24a76483e48ecc3d27d69fc6f41c442 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Fri, 22 Sep 2023 11:07:22 +0530 Subject: [PATCH 18/26] test_client.py: Corrected spelling mistake in method name get_received() --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 2 +- stubs/Flask-SocketIO/flask_socketio/test_client.pyi | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 52c3cf6bb78a..fad40c774333 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -67,7 +67,7 @@ class SocketIO: json: bool = False, namespace: str | None = None, to: str | None = None, - callback: Callable | None = None, + callback: Callable[..., Any] | None = None, include_self: bool = True, skip_sid: list[str] | str | None = None, **kwargs, diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index c3980d609fd1..fc57a44f6bae 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,11 +1,10 @@ from collections.abc import Callable -from typing import Any -from typing_extensions import TypedDict +from typing import Any, TypedDict from flask import Flask from flask.testing import FlaskClient -class _Packet(TypedDict, total=False): +class _Packet(TypedDict): name: str args: Any namespace: str @@ -31,5 +30,5 @@ class SocketIOTestClient: ) -> None: ... def disconnect(self, namespace: str | None = None) -> None: ... def emit(self, event: str, *args, callback: bool = True, namespace: str | None = None): ... - def get_recieved(self, namespace: str | None = None) -> list[_Packet]: ... + def get_received(self, namespace: str | None = None) -> list[_Packet]: ... def send(self, data: Any, json: bool = False, callback: Callable[..., Any] | Any = False, namespace: str | None = None): ... From a4aaefb2dd78c2e8751696b94e2d63a6c3b436f1 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Sun, 24 Sep 2023 12:57:15 +0530 Subject: [PATCH 19/26] Explicit type hints for kwargs --- .../@tests/stubtest_allowlist.txt | 5 +- stubs/Flask-SocketIO/METADATA.toml | 3 +- .../flask_socketio/__init__.pyi | 94 +++++++++++-------- .../flask_socketio/test_client.pyi | 5 +- 4 files changed, 65 insertions(+), 42 deletions(-) diff --git a/stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt b/stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt index 1a4e31cf9285..6e232db3142d 100644 --- a/stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt +++ b/stubs/Flask-SocketIO/@tests/stubtest_allowlist.txt @@ -1 +1,4 @@ -flask_socketio.test_client.SocketIOTestClient.clients # private attribute, not present in docs +# private attributes / methods, not present in docs +flask_socketio.test_client.SocketIOTestClient.clients +flask_socketio.gevent_socketio_found +flask_socketio.call diff --git a/stubs/Flask-SocketIO/METADATA.toml b/stubs/Flask-SocketIO/METADATA.toml index 8906c5ad259e..4d9b99ae7398 100644 --- a/stubs/Flask-SocketIO/METADATA.toml +++ b/stubs/Flask-SocketIO/METADATA.toml @@ -1,4 +1,3 @@ version = "5.3.*" -# Requires a version of flask with a `py.typed` file -requires = ["Flask>=2.0.0"] +requires = ["Flask >= 0.9"] upstream_repository = "https://github.com/miguelgrinberg/flask-socketio" diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index fad40c774333..48918a57ec5e 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -2,65 +2,70 @@ from collections.abc import Callable from logging import Logger from threading import Thread from typing import Any -from typing_extensions import NotRequired, ParamSpec, TypeAlias, TypedDict, Unpack +from typing_extensions import NotRequired, ParamSpec, TypeAlias from flask import Flask from flask.testing import FlaskClient -from socketio.base_manager import BaseManager # type: ignore[import] # pyright: ignore[reportMissingImports] from .namespace import Namespace from .test_client import SocketIOTestClient + +# Actually socketio.base_manager.BaseManager, +# but socketio isn't py.typed and typeshed has no stubs for it +BaseManager: TypeAlias = Any + _P = ParamSpec("_P") _ExceptionHandler: TypeAlias = Callable[[Exception], Any] _Handler: TypeAlias = Callable[[Any], Any] _HandlerDecorator: TypeAlias = Callable[[_Handler], _Handler] -gevent_socketio_found: bool - -class _SocketIOConfig(TypedDict, total=False): - manage_session: NotRequired[bool] - message_queue: NotRequired[str] - channel: NotRequired[str] - path: NotRequired[str] - resource: NotRequired[str] - # SocketIO.Server options - client_manager: NotRequired[BaseManager] - logger: NotRequired[bool | Logger] - json: NotRequired[Any] - async_handlers: NotRequired[bool] - always_connect: NotRequired[bool] +class SocketIO: + def __init__( + self, app: Flask | None = None, *, -class _SocketIOCallArgs(TypedDict, total=False): - namespace: NotRequired[str] - to: NotRequired[str] - room: NotRequired[str] + # SocketIO options + manage_session: bool = True, + message_queue: str | None = None, + channel: str = 'flask-socketio', + path: str = 'socket.io', + resource: str = 'socket.io', -class _SocketIOEmitArgs(_SocketIOCallArgs, total=False): - include_self: NotRequired[bool] - skip_sid: NotRequired[str | list[str]] - callback: NotRequired[Callable[..., Any]] + **kwargs # TODO: Socket.IO server options, Engine.IO server config + ) -> None: ... + def init_app( + self, app: Flask, *, -class _SocketIORunArgs(TypedDict, total=False): - debug: NotRequired[bool] - use_reloader: NotRequired[bool] - reloader_options: dict[str, Any] - log_output: NotRequired[bool] - allow_unsafe_werkzeug: NotRequired[bool] + # SocketIO options + manage_session: bool = True, + message_queue: str | None = None, + channel: str = 'flask-socketio', + path: str = 'socket.io', + resource: str = 'socket.io', -class SocketIO: - def __init__(self, app: Flask | None = None, **kwargs: Unpack[_SocketIOConfig]) -> None: ... # type: ignore - def init_app(self, app: Flask, **kwargs: Unpack[_SocketIOConfig]): ... # type: ignore + **kwargs # TODO: Socket.IO server options, Engine.IO server config: ... + ) -> None: ... def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... def on_error(self, namespace: str | None = None) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... def on_event(self, message: str, handler: _Handler, namespace: str | None = None) -> None: ... def event(self, namespace: str | None = None, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... def on_namespace(self, namespace_handler: Namespace) -> None: ... - def emit(self, event: str, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... # type: ignore - def call(self, event: str, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... # type: ignore + def emit( + self, event: str, *args, + namespace: str = '/', # / is the default (global) namespace + to: str | None = None, + include_self: bool = True, + skip_sid: str | list[str] | None = None, + callback: Callable[..., Any] | None = None) -> None: ... + def call( + self, event: str, *args, + namespace: str = '/', # / is the default (global) namespace + to: str | None = None, + timeout: int = 60, # seconds + ignore_queue: bool = False): ... def send( self, data: Any, @@ -73,7 +78,14 @@ class SocketIO: **kwargs, ) -> None: ... def close_room(self, room: str, namespace: str | None = None) -> None: ... - def run(self, app, host: str | None = None, port: int | None = None, **kwargs: _SocketIORunArgs) -> None: ... + def run( + self, app, host: str | None = None, port: int | None = None, *, + debug: bool = True, + use_reloader: bool, + reloader_options: dict[str, Any] = {}, + log_output: bool, + allow_unsafe_werkzeug: bool = False, + **kwargs) -> None: ... def stop(self) -> None: ... def start_background_task(self, target: Callable[_P, None], *args: _P.args, **kwargs: _P.kwargs) -> Thread: ... def sleep(self, seconds: int = 0): ... @@ -87,8 +99,14 @@ class SocketIO: flask_test_client: FlaskClient | None = None, ) -> SocketIOTestClient: ... -def emit(event, *args, **kwargs: Unpack[_SocketIOEmitArgs]) -> None: ... # type: ignore -def call(event, *args, **kwargs: Unpack[_SocketIOCallArgs]): ... # type: ignore +def emit( + event, *args, + namespace: str = '/', # / is the default (global) namespace + to: str | None = None, + include_self: bool = True, + skip_sid: str | list[str] | None = None, + callback: Callable[..., Any] | None = None, + broadcast: bool = False) -> None: ... def send(message: str, **kwargs) -> None: ... def join_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... def leave_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index fc57a44f6bae..65c6872087c0 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,14 +1,17 @@ from collections.abc import Callable -from typing import Any, TypedDict +from typing import Any from flask import Flask from flask.testing import FlaskClient +from typing_extensions import TypedDict + class _Packet(TypedDict): name: str args: Any namespace: str + class SocketIOTestClient: def __init__( self, From b9af134af575aed05543f428049b281533a61e8e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 24 Sep 2023 07:29:19 +0000 Subject: [PATCH 20/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- .../flask_socketio/__init__.pyi | 70 +++++++++++-------- .../flask_socketio/test_client.pyi | 4 +- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 48918a57ec5e..b9ce0639d991 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -1,8 +1,7 @@ from collections.abc import Callable -from logging import Logger from threading import Thread from typing import Any -from typing_extensions import NotRequired, ParamSpec, TypeAlias +from typing_extensions import ParamSpec, TypeAlias from flask import Flask from flask.testing import FlaskClient @@ -10,7 +9,6 @@ from flask.testing import FlaskClient from .namespace import Namespace from .test_client import SocketIOTestClient - # Actually socketio.base_manager.BaseManager, # but socketio isn't py.typed and typeshed has no stubs for it BaseManager: TypeAlias = Any @@ -21,31 +19,30 @@ _Handler: TypeAlias = Callable[[Any], Any] _HandlerDecorator: TypeAlias = Callable[[_Handler], _Handler] - class SocketIO: def __init__( - self, app: Flask | None = None, *, - + self, + app: Flask | None = None, + *, # SocketIO options manage_session: bool = True, message_queue: str | None = None, - channel: str = 'flask-socketio', - path: str = 'socket.io', - resource: str = 'socket.io', - - **kwargs # TODO: Socket.IO server options, Engine.IO server config + channel: str = "flask-socketio", + path: str = "socket.io", + resource: str = "socket.io", + **kwargs, # TODO: Socket.IO server options, Engine.IO server config ) -> None: ... def init_app( - self, app: Flask, *, - + self, + app: Flask, + *, # SocketIO options manage_session: bool = True, message_queue: str | None = None, - channel: str = 'flask-socketio', - path: str = 'socket.io', - resource: str = 'socket.io', - - **kwargs # TODO: Socket.IO server options, Engine.IO server config: ... + channel: str = "flask-socketio", + path: str = "socket.io", + resource: str = "socket.io", + **kwargs, # TODO: Socket.IO server options, Engine.IO server config: ... ) -> None: ... def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... def on_error(self, namespace: str | None = None) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... @@ -54,18 +51,24 @@ class SocketIO: def event(self, namespace: str | None = None, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... def on_namespace(self, namespace_handler: Namespace) -> None: ... def emit( - self, event: str, *args, - namespace: str = '/', # / is the default (global) namespace + self, + event: str, + *args, + namespace: str = "/", # / is the default (global) namespace to: str | None = None, include_self: bool = True, skip_sid: str | list[str] | None = None, - callback: Callable[..., Any] | None = None) -> None: ... + callback: Callable[..., Any] | None = None, + ) -> None: ... def call( - self, event: str, *args, - namespace: str = '/', # / is the default (global) namespace + self, + event: str, + *args, + namespace: str = "/", # / is the default (global) namespace to: str | None = None, - timeout: int = 60, # seconds - ignore_queue: bool = False): ... + timeout: int = 60, # seconds + ignore_queue: bool = False, + ): ... def send( self, data: Any, @@ -79,13 +82,18 @@ class SocketIO: ) -> None: ... def close_room(self, room: str, namespace: str | None = None) -> None: ... def run( - self, app, host: str | None = None, port: int | None = None, *, + self, + app, + host: str | None = None, + port: int | None = None, + *, debug: bool = True, use_reloader: bool, reloader_options: dict[str, Any] = {}, log_output: bool, allow_unsafe_werkzeug: bool = False, - **kwargs) -> None: ... + **kwargs, + ) -> None: ... def stop(self) -> None: ... def start_background_task(self, target: Callable[_P, None], *args: _P.args, **kwargs: _P.kwargs) -> Thread: ... def sleep(self, seconds: int = 0): ... @@ -100,13 +108,15 @@ class SocketIO: ) -> SocketIOTestClient: ... def emit( - event, *args, - namespace: str = '/', # / is the default (global) namespace + event, + *args, + namespace: str = "/", # / is the default (global) namespace to: str | None = None, include_self: bool = True, skip_sid: str | list[str] | None = None, callback: Callable[..., Any] | None = None, - broadcast: bool = False) -> None: ... + broadcast: bool = False, +) -> None: ... def send(message: str, **kwargs) -> None: ... def join_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... def leave_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index 65c6872087c0..a0bb6d202b90 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,17 +1,15 @@ from collections.abc import Callable from typing import Any +from typing_extensions import TypedDict from flask import Flask from flask.testing import FlaskClient -from typing_extensions import TypedDict - class _Packet(TypedDict): name: str args: Any namespace: str - class SocketIOTestClient: def __init__( self, From c5b2e44b3e494e9a5b246dc3c30d4826bb813a26 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Sun, 24 Sep 2023 13:15:28 +0530 Subject: [PATCH 21/26] removed space in requirements --- stubs/Flask-SocketIO/METADATA.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/Flask-SocketIO/METADATA.toml b/stubs/Flask-SocketIO/METADATA.toml index 4d9b99ae7398..19f709209c88 100644 --- a/stubs/Flask-SocketIO/METADATA.toml +++ b/stubs/Flask-SocketIO/METADATA.toml @@ -1,3 +1,3 @@ version = "5.3.*" -requires = ["Flask >= 0.9"] +requires = ["Flask>=0.9"] upstream_repository = "https://github.com/miguelgrinberg/flask-socketio" From 41d2fce38c8b5da5183267ee87a26fbfd743d0f8 Mon Sep 17 00:00:00 2001 From: Sohang Chopra Date: Sun, 24 Sep 2023 13:22:43 +0530 Subject: [PATCH 22/26] Removed BaseManager as its not needed any more --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 3 --- 1 file changed, 3 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index b9ce0639d991..a14d8ab096b5 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -9,9 +9,6 @@ from flask.testing import FlaskClient from .namespace import Namespace from .test_client import SocketIOTestClient -# Actually socketio.base_manager.BaseManager, -# but socketio isn't py.typed and typeshed has no stubs for it -BaseManager: TypeAlias = Any _P = ParamSpec("_P") _ExceptionHandler: TypeAlias = Callable[[Exception], Any] From 17fe22d5f2df4bee82f447adc2a2d705e0401ad5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 24 Sep 2023 07:53:25 +0000 Subject: [PATCH 23/26] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/Flask-SocketIO/flask_socketio/__init__.pyi | 1 - 1 file changed, 1 deletion(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index a14d8ab096b5..1c6ad516f7c9 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -9,7 +9,6 @@ from flask.testing import FlaskClient from .namespace import Namespace from .test_client import SocketIOTestClient - _P = ParamSpec("_P") _ExceptionHandler: TypeAlias = Callable[[Exception], Any] _Handler: TypeAlias = Callable[[Any], Any] From f21404835fccccee5aa02906ac61ea54d77b7cfe Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 25 Sep 2023 09:30:10 +0100 Subject: [PATCH 24/26] many fixes --- .../flask_socketio/__init__.pyi | 40 ++++++++----- .../flask_socketio/namespace.pyi | 60 +++++++++++++++++-- .../flask_socketio/test_client.pyi | 22 ++++--- 3 files changed, 94 insertions(+), 28 deletions(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi index 1c6ad516f7c9..093762f3be8d 100644 --- a/stubs/Flask-SocketIO/flask_socketio/__init__.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -1,6 +1,7 @@ +from _typeshed import Incomplete from collections.abc import Callable from threading import Thread -from typing import Any +from typing import Any, Protocol, TypeVar, overload from typing_extensions import ParamSpec, TypeAlias from flask import Flask @@ -10,12 +11,20 @@ from .namespace import Namespace from .test_client import SocketIOTestClient _P = ParamSpec("_P") -_ExceptionHandler: TypeAlias = Callable[[Exception], Any] -_Handler: TypeAlias = Callable[[Any], Any] +_R_co = TypeVar("_R_co", covariant=True) +_ExceptionHandler: TypeAlias = Callable[[BaseException], _R_co] +_Handler: TypeAlias = Callable[_P, _R_co] -_HandlerDecorator: TypeAlias = Callable[[_Handler], _Handler] +class _HandlerDecorator(Protocol): + def __call__(self, handler: _Handler[_P, _R_co]) -> _Handler[_P, _R_co]: ... + +class _ExceptionHandlerDecorator(Protocol): + def __call__(self, exception_handler: _ExceptionHandler[_R_co]) -> _ExceptionHandler[_R_co]: ... class SocketIO: + # Many instance attributes are deliberately not included here, + # as the maintainer of Flask-SocketIO considers them private, internal details: + # https://github.com/python/typeshed/pull/10735#discussion_r1330768869 def __init__( self, app: Flask | None = None, @@ -41,10 +50,13 @@ class SocketIO: **kwargs, # TODO: Socket.IO server options, Engine.IO server config: ... ) -> None: ... def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... - def on_error(self, namespace: str | None = None) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... - def on_error_default(self, exception_handler: _ExceptionHandler) -> Callable[[_ExceptionHandler], _ExceptionHandler]: ... - def on_event(self, message: str, handler: _Handler, namespace: str | None = None) -> None: ... - def event(self, namespace: str | None = None, *args, **kwargs) -> _Handler | Callable[[_Handler], _HandlerDecorator]: ... + def on_error(self, namespace: str | None = None) -> _ExceptionHandlerDecorator: ... + def on_error_default(self, exception_handler: _ExceptionHandler[_R_co]) -> _ExceptionHandler[_R_co]: ... + def on_event(self, message: str, handler: _Handler[[Incomplete], object], namespace: str | None = None) -> None: ... + @overload + def event(self, __event_handler: _Handler[_P, _R_co]) -> _Handler[_P, _R_co]: ... + @overload + def event(self, namespace: str | None = None, *args, **kwargs) -> _HandlerDecorator: ... def on_namespace(self, namespace_handler: Namespace) -> None: ... def emit( self, @@ -54,7 +66,7 @@ class SocketIO: to: str | None = None, include_self: bool = True, skip_sid: str | list[str] | None = None, - callback: Callable[..., Any] | None = None, + callback: Callable[..., Incomplete] | None = None, ) -> None: ... def call( self, @@ -71,7 +83,7 @@ class SocketIO: json: bool = False, namespace: str | None = None, to: str | None = None, - callback: Callable[..., Any] | None = None, + callback: Callable[..., Incomplete] | None = None, include_self: bool = True, skip_sid: list[str] | str | None = None, **kwargs, @@ -85,7 +97,7 @@ class SocketIO: *, debug: bool = True, use_reloader: bool, - reloader_options: dict[str, Any] = {}, + reloader_options: dict[str, Incomplete] = {}, log_output: bool, allow_unsafe_werkzeug: bool = False, **kwargs, @@ -98,8 +110,8 @@ class SocketIO: app: Flask, namespace: str | None = None, query_string: str | None = None, - headers: dict[str, Any] | None = None, - auth: dict[str, Any] | None = None, + headers: dict[str, Incomplete] | None = None, + auth: dict[str, Incomplete] | None = None, flask_test_client: FlaskClient | None = None, ) -> SocketIOTestClient: ... @@ -110,7 +122,7 @@ def emit( to: str | None = None, include_self: bool = True, skip_sid: str | list[str] | None = None, - callback: Callable[..., Any] | None = None, + callback: Callable[..., Incomplete] | None = None, broadcast: bool = False, ) -> None: ... def send(message: str, **kwargs) -> None: ... diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index aefa3a504d9d..a6560e369ac3 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -1,23 +1,71 @@ +from _typeshed import Incomplete from collections.abc import Callable -from typing import Any, TypeVar +from typing import Any, Protocol, TypeVar _T = TypeVar("_T") -class Namespace: - def __init__(self, namespace: str | None = None) -> None: ... +# at runtime, socketio.namespace.BaseNamespace, but socketio isn't py.typed +class _BaseNamespace(Protocol): + def is_asyncio_based(self) -> bool: ... def trigger_event(self, event: str, *args): ... + +# at runtime, socketio.namespace.BaseNamespace, but socketio isn't py.typed +class _Namespace(_BaseNamespace, Protocol): def emit( self, event: str, - data: Any = None, + data: Incomplete | None = None, + to=None, + room: str | None = None, + skip_sid=None, + namespace: str | None = None, + callback: Callable[..., _T] | None = None, + ignore_queue: bool = False, + ): ... + def send( + self, + data: Incomplete, + to=None, + room: str | None = None, + skip_sid=None, + namespace: str | None = None, + callback: Callable[..., Incomplete] | None = None, + ignore_queue: bool = False, + ) -> None: ... + def call( + self, + event: str, + data: Incomplete | None = None, + to=None, + sid=None, + namespace: str | None = None, + timeout=None, + ignore_queue: bool = False, + ): ... + def enter_room(self, sid, room: str, namespace: str | None = None): ... + def leave_room(self, sid, room: str, namespace: str | None = None): ... + def close_room(self, room: str, namespace: str | None = None): ... + def rooms(self, sid, namespace: str | None = None): ... + def get_session(self, sid, namespace: str | None = None): ... + def save_session(self, sid, session, namespace: str | None = None): ... + def session(self, sid, namespace: str | None = None): ... + def disconnect(self, sid, namespace: str | None = None): ... + +class Namespace(_Namespace): + def __init__(self, namespace: str | None = None) -> None: ... + def trigger_event(self, event: str, *args): ... + def emit( # type: ignore[override] + self, + event: str, + data: Incomplete | None = None, room: str | None = None, include_self: bool = True, namespace: str | None = None, callback: Callable[..., _T] | None = None, ) -> _T | tuple[str, int]: ... - def send( + def send( # type: ignore[override] self, - data: Any, + data: Incomplete, room: str | None = None, include_self: bool = True, namespace: str | None = None, diff --git a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi index a0bb6d202b90..977aa361ce8e 100644 --- a/stubs/Flask-SocketIO/flask_socketio/test_client.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -1,4 +1,4 @@ -from collections.abc import Callable +from _typeshed import Incomplete from typing import Any from typing_extensions import TypedDict @@ -17,19 +17,25 @@ class SocketIOTestClient: socketio, namespace: str | None = None, query_string: str | None = None, - headers: dict[str, Any] | None = None, - auth: dict[str, Any] | None = None, + headers: dict[str, Incomplete] | None = None, + auth: dict[str, Incomplete] | None = None, flask_test_client: FlaskClient | None = None, - ): ... + ) -> None: ... def is_connected(self, namespace: str | None = None) -> bool: ... def connect( self, namespace: str | None = None, query_string: str | None = None, - headers: dict[str, Any] | None = None, - auth: dict[str, Any] | None = None, + headers: dict[str, Incomplete] | None = None, + auth: dict[str, Incomplete] | None = None, ) -> None: ... def disconnect(self, namespace: str | None = None) -> None: ... - def emit(self, event: str, *args, callback: bool = True, namespace: str | None = None): ... + def emit(self, event: str, *args, callback: bool = True, namespace: str | None = None) -> Incomplete | None: ... + def send( + self, + data: str | dict[str, Incomplete] | list[Incomplete], + json: bool = False, + callback: bool = False, + namespace: str | None = None, + ): ... def get_received(self, namespace: str | None = None) -> list[_Packet]: ... - def send(self, data: Any, json: bool = False, callback: Callable[..., Any] | Any = False, namespace: str | None = None): ... From 7b67a6012daec13668b0d966f84ae3c9a4f1d58a Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 25 Sep 2023 09:32:25 +0100 Subject: [PATCH 25/26] another fix --- stubs/Flask-SocketIO/flask_socketio/namespace.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index a6560e369ac3..c28b50c90765 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -19,7 +19,7 @@ class _Namespace(_BaseNamespace, Protocol): room: str | None = None, skip_sid=None, namespace: str | None = None, - callback: Callable[..., _T] | None = None, + callback: Callable[..., _Incomplete] | None = None, ignore_queue: bool = False, ): ... def send( From 844214bbfa9c4d32cce0267591bf57e73b06a050 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 25 Sep 2023 09:36:37 +0100 Subject: [PATCH 26/26] . --- stubs/Flask-SocketIO/flask_socketio/namespace.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi index c28b50c90765..1886d2306037 100644 --- a/stubs/Flask-SocketIO/flask_socketio/namespace.pyi +++ b/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -19,7 +19,7 @@ class _Namespace(_BaseNamespace, Protocol): room: str | None = None, skip_sid=None, namespace: str | None = None, - callback: Callable[..., _Incomplete] | None = None, + callback: Callable[..., Incomplete] | None = None, ignore_queue: bool = False, ): ... def send(