From 3fe10339af90543ae5293935b06f7c64c52ca6ab Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 3 Nov 2023 15:17:10 -0400 Subject: [PATCH 1/7] Complete Flask-Migrate and mark as Strict --- pyrightconfig.stricter.json | 1 - .../@tests/stubtest_allowlist.txt | 2 ++ stubs/Flask-Migrate/METADATA.toml | 8 ++--- .../Flask-Migrate/flask_migrate/__init__.pyi | 31 ++++++++++++++----- 4 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 stubs/Flask-Migrate/@tests/stubtest_allowlist.txt diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index dc3b64c46171..5c6cc0963d46 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -35,7 +35,6 @@ "stubs/commonmark", "stubs/dateparser", "stubs/docutils", - "stubs/Flask-Migrate", "stubs/Flask-SocketIO", "stubs/fpdf2", "stubs/google-cloud-ndb", diff --git a/stubs/Flask-Migrate/@tests/stubtest_allowlist.txt b/stubs/Flask-Migrate/@tests/stubtest_allowlist.txt new file mode 100644 index 000000000000..05ab57df9c75 --- /dev/null +++ b/stubs/Flask-Migrate/@tests/stubtest_allowlist.txt @@ -0,0 +1,2 @@ +# Flask-Migrate users don't need to interact with this undocumented module from within python +flask_migrate.cli diff --git a/stubs/Flask-Migrate/METADATA.toml b/stubs/Flask-Migrate/METADATA.toml index 7b8e26c3cc26..be7b27d0a509 100644 --- a/stubs/Flask-Migrate/METADATA.toml +++ b/stubs/Flask-Migrate/METADATA.toml @@ -1,8 +1,4 @@ version = "4.0.*" -upstream_repository = "https://github.com/miguelgrinberg/flask-migrate" +upstream_repository = "https://github.com/miguelgrinberg/Flask-Migrate" # Requires versions of flask and Flask-SQLAlchemy with `py.typed` files -requires = ["Flask>=2.0.0", "Flask-SQLAlchemy>=3.0.1"] -partial_stub = true - -[tool.stubtest] -ignore_missing_stub = true +requires = ["Flask-SQLAlchemy>=3.0.1", "Flask>=2.0.0"] diff --git a/stubs/Flask-Migrate/flask_migrate/__init__.pyi b/stubs/Flask-Migrate/flask_migrate/__init__.pyi index 5f60a5080dbc..998737fd9c64 100644 --- a/stubs/Flask-Migrate/flask_migrate/__init__.pyi +++ b/stubs/Flask-Migrate/flask_migrate/__init__.pyi @@ -1,6 +1,9 @@ +import sys +from _typeshed import StrPath, SupportsKeysAndGetItem +from argparse import Namespace from collections.abc import Callable, Iterable, Sequence from logging import Logger -from typing import Any, TypeVar +from typing import Any, TextIO, TypeVar from typing_extensions import ParamSpec, TypeAlias import flask @@ -9,20 +12,33 @@ from flask_sqlalchemy import SQLAlchemy _T = TypeVar("_T") _P = ParamSpec("_P") _ConfigureCallback: TypeAlias = Callable[[Config], Config] +_AlembicConfigValue: TypeAlias = Any alembic_version: tuple[int, int, int] log: Logger class Config: # should inherit from alembic.config.Config which is not possible yet template_directory: str | None - def __init__(self, *args, **kwargs) -> None: ... + # Same as alembic.config.Config + template_directory kwarg + def __init__( + self, + file_: StrPath | None = None, + ini_section: str = "alembic", + output_buffer: TextIO | None = None, + stdout: TextIO = sys.stdout, + cmd_opts: Namespace | None = None, + config_args: SupportsKeysAndGetItem[str, _AlembicConfigValue] | Iterable[tuple[str, _AlembicConfigValue]] = ..., + attributes: SupportsKeysAndGetItem[str, _AlembicConfigValue] | Iterable[tuple[str, _AlembicConfigValue]] | None = None, + *, + template_directory: str | None = None, + ) -> None: ... def get_template_directory(self) -> str: ... class Migrate: configure_callbacks: list[_ConfigureCallback] db: SQLAlchemy | None directory: str - alembic_ctx_kwargs: dict[str, Any] + alembic_ctx_kwargs: dict[str, _AlembicConfigValue] def __init__( self, app: flask.Flask | None = None, @@ -31,7 +47,7 @@ class Migrate: command: str = "db", compare_type: bool = True, render_as_batch: bool = True, - **kwargs, + **kwargs: _AlembicConfigValue, ) -> None: ... def init_app( self, @@ -41,13 +57,13 @@ class Migrate: command: str | None = None, compare_type: bool | None = None, render_as_batch: bool | None = None, - **kwargs, + **kwargs: _AlembicConfigValue, ) -> None: ... def configure(self, f: _ConfigureCallback) -> _ConfigureCallback: ... - def call_configure_callbacks(self, config: Config): ... + def call_configure_callbacks(self, config: Config) -> Config: ... def get_config( self, directory: str | None = None, x_arg: str | Sequence[str] | None = None, opts: Iterable[str] | None = None - ): ... + ) -> Config: ... def catch_errors(f: Callable[_P, _T]) -> Callable[_P, _T]: ... def list_templates() -> None: ... @@ -104,3 +120,4 @@ def heads(directory: str | None = None, verbose: bool = False, resolve_dependenc def branches(directory: str | None = None, verbose: bool = False) -> None: ... def current(directory: str | None = None, verbose: bool = False) -> None: ... def stamp(directory: str | None = None, revision: str = "head", sql: bool = False, tag: str | None = None) -> None: ... +def check(directory: str | None = None) -> None: ... From 053f140f83d11b9717ca00bf6df5a9ef4df18bce Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 3 Nov 2023 16:25:39 -0400 Subject: [PATCH 2/7] attributes key is also arbitrary --- stubs/Flask-Migrate/flask_migrate/__init__.pyi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stubs/Flask-Migrate/flask_migrate/__init__.pyi b/stubs/Flask-Migrate/flask_migrate/__init__.pyi index 998737fd9c64..dd21a81eb6ce 100644 --- a/stubs/Flask-Migrate/flask_migrate/__init__.pyi +++ b/stubs/Flask-Migrate/flask_migrate/__init__.pyi @@ -28,7 +28,9 @@ class Config: # should inherit from alembic.config.Config which is not possible stdout: TextIO = sys.stdout, cmd_opts: Namespace | None = None, config_args: SupportsKeysAndGetItem[str, _AlembicConfigValue] | Iterable[tuple[str, _AlembicConfigValue]] = ..., - attributes: SupportsKeysAndGetItem[str, _AlembicConfigValue] | Iterable[tuple[str, _AlembicConfigValue]] | None = None, + attributes: SupportsKeysAndGetItem[_AlembicConfigValue, _AlembicConfigValue] + | Iterable[tuple[_AlembicConfigValue, _AlembicConfigValue]] + | None = None, *, template_directory: str | None = None, ) -> None: ... From 9898538033a32ca840c1f83c86386109a32f783d Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 8 Nov 2023 19:35:08 -0500 Subject: [PATCH 3/7] More flexible output_buffer and stdout --- stubs/Flask-Migrate/flask_migrate/__init__.pyi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/stubs/Flask-Migrate/flask_migrate/__init__.pyi b/stubs/Flask-Migrate/flask_migrate/__init__.pyi index dd21a81eb6ce..064a22f7bf1d 100644 --- a/stubs/Flask-Migrate/flask_migrate/__init__.pyi +++ b/stubs/Flask-Migrate/flask_migrate/__init__.pyi @@ -1,9 +1,9 @@ import sys -from _typeshed import StrPath, SupportsKeysAndGetItem +from _typeshed import StrPath, SupportsFlush, SupportsKeysAndGetItem, SupportsWrite from argparse import Namespace from collections.abc import Callable, Iterable, Sequence from logging import Logger -from typing import Any, TextIO, TypeVar +from typing import IO, Any, TypeVar from typing_extensions import ParamSpec, TypeAlias import flask @@ -17,6 +17,8 @@ _AlembicConfigValue: TypeAlias = Any alembic_version: tuple[int, int, int] log: Logger +class _SupportsWriteAndFlush(SupportsWrite[_T], SupportsFlush): ... + class Config: # should inherit from alembic.config.Config which is not possible yet template_directory: str | None # Same as alembic.config.Config + template_directory kwarg @@ -24,8 +26,10 @@ class Config: # should inherit from alembic.config.Config which is not possible self, file_: StrPath | None = None, ini_section: str = "alembic", - output_buffer: TextIO | None = None, - stdout: TextIO = sys.stdout, + # Same as buffer argument in TextIOWrapper.__init__ + output_buffer: IO[bytes] | None = None, + # Same as stream argument in alembic.util.messaging + stdout: SupportsWrite[str] = sys.stdout, cmd_opts: Namespace | None = None, config_args: SupportsKeysAndGetItem[str, _AlembicConfigValue] | Iterable[tuple[str, _AlembicConfigValue]] = ..., attributes: SupportsKeysAndGetItem[_AlembicConfigValue, _AlembicConfigValue] From 87fcd156dc40c932099e8f55a0e49a79f6d53126 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 8 Nov 2023 19:36:12 -0500 Subject: [PATCH 4/7] Remove unused --- stubs/Flask-Migrate/flask_migrate/__init__.pyi | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stubs/Flask-Migrate/flask_migrate/__init__.pyi b/stubs/Flask-Migrate/flask_migrate/__init__.pyi index 064a22f7bf1d..238e3e21f415 100644 --- a/stubs/Flask-Migrate/flask_migrate/__init__.pyi +++ b/stubs/Flask-Migrate/flask_migrate/__init__.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import StrPath, SupportsFlush, SupportsKeysAndGetItem, SupportsWrite +from _typeshed import StrPath, SupportsKeysAndGetItem, SupportsWrite from argparse import Namespace from collections.abc import Callable, Iterable, Sequence from logging import Logger @@ -17,8 +17,6 @@ _AlembicConfigValue: TypeAlias = Any alembic_version: tuple[int, int, int] log: Logger -class _SupportsWriteAndFlush(SupportsWrite[_T], SupportsFlush): ... - class Config: # should inherit from alembic.config.Config which is not possible yet template_directory: str | None # Same as alembic.config.Config + template_directory kwarg From 883d8ebe4dfd5877b16ac014d3aabf6859d35983 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 8 Nov 2023 20:08:57 -0500 Subject: [PATCH 5/7] _SupportsWriteAndFlush needs to be contravariant to work --- stubs/Flask-Migrate/flask_migrate/__init__.pyi | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/stubs/Flask-Migrate/flask_migrate/__init__.pyi b/stubs/Flask-Migrate/flask_migrate/__init__.pyi index 238e3e21f415..863e59bd5775 100644 --- a/stubs/Flask-Migrate/flask_migrate/__init__.pyi +++ b/stubs/Flask-Migrate/flask_migrate/__init__.pyi @@ -1,15 +1,18 @@ +# pyright: reportInvalidStubStatement=none + import sys -from _typeshed import StrPath, SupportsKeysAndGetItem, SupportsWrite +from _typeshed import StrPath, SupportsFlush, SupportsKeysAndGetItem, SupportsWrite from argparse import Namespace from collections.abc import Callable, Iterable, Sequence from logging import Logger -from typing import IO, Any, TypeVar +from typing import Any, Protocol, TypeVar from typing_extensions import ParamSpec, TypeAlias import flask from flask_sqlalchemy import SQLAlchemy _T = TypeVar("_T") +_T_contra = TypeVar("_T_contra", contravariant=True) _P = ParamSpec("_P") _ConfigureCallback: TypeAlias = Callable[[Config], Config] _AlembicConfigValue: TypeAlias = Any @@ -17,6 +20,8 @@ _AlembicConfigValue: TypeAlias = Any alembic_version: tuple[int, int, int] log: Logger +class _SupportsWriteAndFlush(SupportsWrite[_T_contra], SupportsFlush, Protocol): ... + class Config: # should inherit from alembic.config.Config which is not possible yet template_directory: str | None # Same as alembic.config.Config + template_directory kwarg @@ -24,8 +29,8 @@ class Config: # should inherit from alembic.config.Config which is not possible self, file_: StrPath | None = None, ini_section: str = "alembic", - # Same as buffer argument in TextIOWrapper.__init__ - output_buffer: IO[bytes] | None = None, + # Same as buffer argument in TextIOWrapper.__init__.buffer + output_buffer: _SupportsWriteAndFlush[str] | None = None, # Same as stream argument in alembic.util.messaging stdout: SupportsWrite[str] = sys.stdout, cmd_opts: Namespace | None = None, From 99d7c077258ea1811f4dd65551c1e89dd90f8e2c Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 9 Nov 2023 11:37:59 -0500 Subject: [PATCH 6/7] Update stubs/Flask-Migrate/flask_migrate/__init__.pyi Co-authored-by: Sebastian Rittau --- stubs/Flask-Migrate/flask_migrate/__init__.pyi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stubs/Flask-Migrate/flask_migrate/__init__.pyi b/stubs/Flask-Migrate/flask_migrate/__init__.pyi index 863e59bd5775..0c87c89f37ad 100644 --- a/stubs/Flask-Migrate/flask_migrate/__init__.pyi +++ b/stubs/Flask-Migrate/flask_migrate/__init__.pyi @@ -20,7 +20,9 @@ _AlembicConfigValue: TypeAlias = Any alembic_version: tuple[int, int, int] log: Logger -class _SupportsWriteAndFlush(SupportsWrite[_T_contra], SupportsFlush, Protocol): ... +# TODO: Use _typeshed.SupportsFlush when it's available in type checkers. +class _SupportsWriteAndFlush(SupportsWrite[_T_contra], Protocol): + def flush(self) -> object: ... class Config: # should inherit from alembic.config.Config which is not possible yet template_directory: str | None From d963bc5f0182f0c20055380e98d19bceafc0fb02 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 16:39:57 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/Flask-Migrate/flask_migrate/__init__.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/Flask-Migrate/flask_migrate/__init__.pyi b/stubs/Flask-Migrate/flask_migrate/__init__.pyi index 0c87c89f37ad..388708e7187f 100644 --- a/stubs/Flask-Migrate/flask_migrate/__init__.pyi +++ b/stubs/Flask-Migrate/flask_migrate/__init__.pyi @@ -1,7 +1,7 @@ # pyright: reportInvalidStubStatement=none import sys -from _typeshed import StrPath, SupportsFlush, SupportsKeysAndGetItem, SupportsWrite +from _typeshed import StrPath, SupportsKeysAndGetItem, SupportsWrite from argparse import Namespace from collections.abc import Callable, Iterable, Sequence from logging import Logger