From 1e76344033dadd915a5e3c7fba4080affecf8004 Mon Sep 17 00:00:00 2001 From: Stefan Urbanek Date: Sat, 18 Mar 2017 21:38:00 -0700 Subject: [PATCH 1/3] Added SQLAlchemy annotations * Made Connection and Engine sublcasses of Connectable (python/typeshed#1018) * Moved execute() from Connection to Connectable * Made RowProxy a Mapping and removed Mapping inherited methods * Made ResultProxy an Iterator of RowProxy * Added most relevant methods for fetching of ResultProxy * Added where(), group_by(), order_by() and limit() to Select --- third_party/2and3/sqlalchemy/engine/base.pyi | 28 ++++++++++++------- .../2and3/sqlalchemy/sql/selectable.pyi | 8 +++++- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/third_party/2and3/sqlalchemy/engine/base.pyi b/third_party/2and3/sqlalchemy/engine/base.pyi index 71f6e196afb0..01fd9c3340ec 100644 --- a/third_party/2and3/sqlalchemy/engine/base.pyi +++ b/third_party/2and3/sqlalchemy/engine/base.pyi @@ -1,20 +1,28 @@ -from typing import Any, List, Tuple +from typing import Any, Iterable, Iterator, List, Mapping, Optional, Tuple # Dummy until I figure out something better. class Connectable: - pass + def execute(self, object, *multiparams, **params) -> ResultProxy: ... -class Connection: +class Connection(Connectable): def begin(self): ... - def execute(self, object, *multiparams, **params): ... -class Engine(object): ... +class Engine(Connectable): ... + +class RowProxy(Mapping[str, Any]): + pass -class RowProxy: - def items(self) -> List[Tuple[Any, Any]]: ... - def keys(self) -> List[Any]: ... - def values(self) -> List[Any]: ... - def __getitem__(self, key: str): ... +class ResultProxy(Iterator[RowProxy]): + def keys(self) -> List[str]: ... + def close(self) -> None: ... + def __iter__(self) -> Iterator[RowProxy]: ... + def fetchall(self) -> Iterator[RowProxy]: ... + def fetchmany(self, size: int=None) -> Iterator[RowProxy]: ... + def fetchone(self) -> Optional[RowProxy]: ... + def first(self) -> Optional[RowProxy]: ... + def scalar(self): ... + @property + def rowcount(self) -> int: ... class Transaction: def commit(self): ... diff --git a/third_party/2and3/sqlalchemy/sql/selectable.pyi b/third_party/2and3/sqlalchemy/sql/selectable.pyi index 543349d64c8f..b12feb47eaa4 100644 --- a/third_party/2and3/sqlalchemy/sql/selectable.pyi +++ b/third_party/2and3/sqlalchemy/sql/selectable.pyi @@ -69,7 +69,13 @@ class ForUpdateArg(ClauseElement): ... class SelectBase(Executable, FromClause): ... class GenerativeSelect(SelectBase): ... class CompoundSelect(GenerativeSelect): ... -class Select(HasPrefixes, HasSuffixes, GenerativeSelect): ... + +class Select(HasPrefixes, HasSuffixes, GenerativeSelect): + def where(self, whereclause) -> Select: ... + def group_by(self, *clauses) -> Select: ... + def order_by(self, *clauses) -> Select: ... + def limit(self, limit: int) -> Select: ... + class ScalarSelect(Generative, Grouping): ... class Exists(UnaryExpression): ... class TextAsFrom(SelectBase): ... From 9aecf400301c625ae09edd3604ac64ddf17a8df6 Mon Sep 17 00:00:00 2001 From: Stefan Urbanek Date: Sun, 19 Mar 2017 14:47:43 -0700 Subject: [PATCH 2/3] Follow squalchemy module structure * Created sqlalchemy.engine.result and moved ResultProxy and RowProxy there * Created sqlalchemy.engine.interfaces and moved Connectable there * Added non-deprecated methods to Connectable: connect, contextual_connect and scalar * Fixed return type of scalar() to Any --- .../2and3/sqlalchemy/engine/__init__.pyi | 2 +- third_party/2and3/sqlalchemy/engine/base.pyi | 21 +----------------- .../2and3/sqlalchemy/engine/interfaces.pyi | 13 +++++++++++ .../2and3/sqlalchemy/engine/result.pyi | 22 +++++++++++++++++++ 4 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 third_party/2and3/sqlalchemy/engine/interfaces.pyi create mode 100644 third_party/2and3/sqlalchemy/engine/result.pyi diff --git a/third_party/2and3/sqlalchemy/engine/__init__.pyi b/third_party/2and3/sqlalchemy/engine/__init__.pyi index 49eca6d67b16..396cac5ca32c 100644 --- a/third_party/2and3/sqlalchemy/engine/__init__.pyi +++ b/third_party/2and3/sqlalchemy/engine/__init__.pyi @@ -4,8 +4,8 @@ from .base import Connection as Connection from .base import Engine as Engine -from .base import RowProxy as RowProxy from .base import Transaction as Transaction +from .result import RowProxy as RowProxy def create_engine(*args, **kwargs): ... def engine_from_config(configuration, prefix=..., **kwargs): ... diff --git a/third_party/2and3/sqlalchemy/engine/base.pyi b/third_party/2and3/sqlalchemy/engine/base.pyi index 01fd9c3340ec..af3cf8c5454a 100644 --- a/third_party/2and3/sqlalchemy/engine/base.pyi +++ b/third_party/2and3/sqlalchemy/engine/base.pyi @@ -1,29 +1,10 @@ -from typing import Any, Iterable, Iterator, List, Mapping, Optional, Tuple - -# Dummy until I figure out something better. -class Connectable: - def execute(self, object, *multiparams, **params) -> ResultProxy: ... +from .interfaces import Connectable class Connection(Connectable): def begin(self): ... class Engine(Connectable): ... -class RowProxy(Mapping[str, Any]): - pass - -class ResultProxy(Iterator[RowProxy]): - def keys(self) -> List[str]: ... - def close(self) -> None: ... - def __iter__(self) -> Iterator[RowProxy]: ... - def fetchall(self) -> Iterator[RowProxy]: ... - def fetchmany(self, size: int=None) -> Iterator[RowProxy]: ... - def fetchone(self) -> Optional[RowProxy]: ... - def first(self) -> Optional[RowProxy]: ... - def scalar(self): ... - @property - def rowcount(self) -> int: ... - class Transaction: def commit(self): ... def rollback(self): ... diff --git a/third_party/2and3/sqlalchemy/engine/interfaces.pyi b/third_party/2and3/sqlalchemy/engine/interfaces.pyi new file mode 100644 index 000000000000..c35c05a8e073 --- /dev/null +++ b/third_party/2and3/sqlalchemy/engine/interfaces.pyi @@ -0,0 +1,13 @@ +from typing import Any, TYPE_CHECKING +from .result import ResultProxy + +if TYPE_CHECKING: + from .base import Connection + +class Connectable: + def execute(self, object, *multiparams: Any, **params: Any) -> ResultProxy: ... + def connect(self, **kwargs: Any) -> Connection: ... + def contextual_connect(self) -> Connection: ... + # Note: The return type `Any` should be a DB API 2 value type once defined + # TODO: See #1037 + def scalar(self, object, *multiparams: Any, **params: Any) -> Any: ... diff --git a/third_party/2and3/sqlalchemy/engine/result.pyi b/third_party/2and3/sqlalchemy/engine/result.pyi new file mode 100644 index 000000000000..08f98b8ffc5e --- /dev/null +++ b/third_party/2and3/sqlalchemy/engine/result.pyi @@ -0,0 +1,22 @@ +from typing import Any, Iterator, List, Mapping, Optional + +# Note: The value type `Any` should be a DB API 2 value type once defined +# TODO: See #1037 + +class RowProxy(Mapping[str, Any]): ... + +class ResultProxy(Iterator[RowProxy]): + def keys(self) -> List[str]: ... + def close(self) -> None: ... + def __iter__(self) -> Iterator[RowProxy]: ... + def fetchall(self) -> Iterator[RowProxy]: ... + def fetchmany(self, size: Optional[int]=None) -> Iterator[RowProxy]: ... + def fetchone(self) -> Optional[RowProxy]: ... + def first(self) -> Optional[RowProxy]: ... + + # Note: The return type `Any` should be a DB API 2 value type once defined + # TODO: See #1037 + def scalar(self): ... + + @property + def rowcount(self) -> int: ... From 906b628430f24420852afef496a1964efc199620 Mon Sep 17 00:00:00 2001 From: Stefan Urbanek Date: Sun, 19 Mar 2017 14:58:34 -0700 Subject: [PATCH 3/3] Missed ResultProxy scalar return ... had it in Connectable only. --- third_party/2and3/sqlalchemy/engine/result.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/2and3/sqlalchemy/engine/result.pyi b/third_party/2and3/sqlalchemy/engine/result.pyi index 08f98b8ffc5e..0361ee05ec32 100644 --- a/third_party/2and3/sqlalchemy/engine/result.pyi +++ b/third_party/2and3/sqlalchemy/engine/result.pyi @@ -16,7 +16,7 @@ class ResultProxy(Iterator[RowProxy]): # Note: The return type `Any` should be a DB API 2 value type once defined # TODO: See #1037 - def scalar(self): ... + def scalar(self) -> Any: ... @property def rowcount(self) -> int: ...