Skip to content

Commit 0bf7e02

Browse files
dlaxsqla-tester
authored andcommitted
Complement type annotations for ARRAY
### Description This complements the type annotations of the `ARRAY` class, in preparation of sqlalchemy#12384. ### Checklist This pull request is: - [ ] A documentation / typographical / small typing error fix - Good to go, no issue or tests are needed - [ ] A short code fix - please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted. - Please include: `Fixes: #<issue number>` in the commit message - please include tests. one line code fixes without tests will not be accepted. - [x] A new feature implementation - please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look. - Please include: `Fixes: #<issue number>` in the commit message - please include tests. Related to sqlalchemy#6810 Closes: sqlalchemy#12386 Pull-request: sqlalchemy#12386 Pull-request-sha: c9513ce Change-Id: If9df4708c8e597eedc79ee3990792fa6c72f1afe
1 parent 9b9e1e1 commit 0bf7e02

2 files changed

Lines changed: 53 additions & 16 deletions

File tree

lib/sqlalchemy/sql/elements.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3798,15 +3798,19 @@ def _create_all(
37983798
# operate and reverse_operate are hardwired to
37993799
# dispatch onto the type comparator directly, so that we can
38003800
# ensure "reversed" behavior.
3801-
def operate(self, op, *other, **kwargs):
3801+
def operate(
3802+
self, op: OperatorType, *other: Any, **kwargs: Any
3803+
) -> ColumnElement[_T]:
38023804
if not operators.is_comparison(op):
38033805
raise exc.ArgumentError(
38043806
"Only comparison operators may be used with ANY/ALL"
38053807
)
38063808
kwargs["reverse"] = True
38073809
return self.comparator.operate(operators.mirror(op), *other, **kwargs)
38083810

3809-
def reverse_operate(self, op, other, **kwargs):
3811+
def reverse_operate(
3812+
self, op: OperatorType, other: Any, **kwargs: Any
3813+
) -> ColumnElement[_T]:
38103814
# comparison operators should never call reverse_operate
38113815
assert not operators.is_comparison(op)
38123816
raise exc.ArgumentError(

lib/sqlalchemy/sql/sqltypes.py

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from typing import cast
2323
from typing import Dict
2424
from typing import Generic
25+
from typing import Iterable
2526
from typing import List
2627
from typing import Optional
2728
from typing import overload
@@ -69,17 +70,20 @@
6970
if TYPE_CHECKING:
7071
from ._typing import _ColumnExpressionArgument
7172
from ._typing import _TypeEngineArgument
73+
from .elements import ColumnElement
7274
from .operators import OperatorType
7375
from .schema import MetaData
7476
from .type_api import _BindProcessorType
7577
from .type_api import _ComparatorFactory
78+
from .type_api import _LiteralProcessorType
7679
from .type_api import _MatchedOnType
7780
from .type_api import _ResultProcessorType
7881
from ..engine.interfaces import Dialect
7982

8083
_T = TypeVar("_T", bound="Any")
8184
_CT = TypeVar("_CT", bound=Any)
8285
_TE = TypeVar("_TE", bound="TypeEngine[Any]")
86+
_P = TypeVar("_P")
8387

8488

8589
class HasExpressionLookup(TypeEngineMixin):
@@ -2987,7 +2991,20 @@ class Comparator(
29872991

29882992
type: ARRAY
29892993

2990-
def _setup_getitem(self, index):
2994+
@overload
2995+
def _setup_getitem(
2996+
self, index: int
2997+
) -> Tuple[OperatorType, int, TypeEngine[Any]]: ...
2998+
2999+
@overload
3000+
def _setup_getitem(
3001+
self, index: slice
3002+
) -> Tuple[OperatorType, Slice, TypeEngine[Any]]: ...
3003+
3004+
def _setup_getitem(self, index: Union[int, slice]) -> Union[
3005+
Tuple[OperatorType, int, TypeEngine[Any]],
3006+
Tuple[OperatorType, Slice, TypeEngine[Any]],
3007+
]:
29913008
arr_type = self.type
29923009

29933010
return_type: TypeEngine[Any]
@@ -3013,7 +3030,7 @@ def _setup_getitem(self, index):
30133030

30143031
return operators.getitem, index, return_type
30153032

3016-
def contains(self, *arg, **kw):
3033+
def contains(self, *arg: Any, **kw: Any) -> ColumnElement[bool]:
30173034
"""``ARRAY.contains()`` not implemented for the base ARRAY type.
30183035
Use the dialect-specific ARRAY type.
30193036
@@ -3027,7 +3044,9 @@ def contains(self, *arg, **kw):
30273044
)
30283045

30293046
@util.preload_module("sqlalchemy.sql.elements")
3030-
def any(self, other, operator=None):
3047+
def any(
3048+
self, other: Any, operator: Optional[OperatorType] = None
3049+
) -> ColumnElement[bool]:
30313050
"""Return ``other operator ANY (array)`` clause.
30323051
30333052
.. legacy:: This method is an :class:`_types.ARRAY` - specific
@@ -3074,7 +3093,9 @@ def any(self, other, operator=None):
30743093
)
30753094

30763095
@util.preload_module("sqlalchemy.sql.elements")
3077-
def all(self, other, operator=None):
3096+
def all(
3097+
self, other: Any, operator: Optional[OperatorType] = None
3098+
) -> ColumnElement[bool]:
30783099
"""Return ``other operator ALL (array)`` clause.
30793100
30803101
.. legacy:: This method is an :class:`_types.ARRAY` - specific
@@ -3123,49 +3144,61 @@ def all(self, other, operator=None):
31233144
comparator_factory = Comparator
31243145

31253146
@property
3126-
def hashable(self):
3147+
def hashable(self) -> bool: # type: ignore[override]
31273148
return self.as_tuple
31283149

31293150
@property
3130-
def python_type(self):
3151+
def python_type(self) -> Type[Any]:
31313152
return list
31323153

3133-
def compare_values(self, x, y):
3134-
return x == y
3154+
def compare_values(self, x: Any, y: Any) -> bool:
3155+
return x == y # type: ignore[no-any-return]
31353156

3136-
def _set_parent(self, parent, outer=False, **kw):
3157+
def _set_parent(
3158+
self, parent: SchemaEventTarget, outer: bool = False, **kw: Any
3159+
) -> None:
31373160
"""Support SchemaEventTarget"""
31383161

31393162
if not outer and isinstance(self.item_type, SchemaEventTarget):
31403163
self.item_type._set_parent(parent, **kw)
31413164

3142-
def _set_parent_with_dispatch(self, parent, **kw):
3165+
def _set_parent_with_dispatch(
3166+
self, parent: SchemaEventTarget, **kw: Any
3167+
) -> None:
31433168
"""Support SchemaEventTarget"""
31443169

31453170
super()._set_parent_with_dispatch(parent, outer=True)
31463171

31473172
if isinstance(self.item_type, SchemaEventTarget):
31483173
self.item_type._set_parent_with_dispatch(parent)
31493174

3150-
def literal_processor(self, dialect):
3175+
def literal_processor(
3176+
self, dialect: Dialect
3177+
) -> Optional[_LiteralProcessorType[_T]]:
31513178
item_proc = self.item_type.dialect_impl(dialect).literal_processor(
31523179
dialect
31533180
)
31543181
if item_proc is None:
31553182
return None
31563183

3157-
def to_str(elements):
3184+
def to_str(elements: Iterable[Any]) -> str:
31583185
return f"[{', '.join(elements)}]"
31593186

3160-
def process(value):
3187+
def process(value: Sequence[Any]) -> str:
31613188
inner = self._apply_item_processor(
31623189
value, item_proc, self.dimensions, to_str
31633190
)
31643191
return inner
31653192

31663193
return process
31673194

3168-
def _apply_item_processor(self, arr, itemproc, dim, collection_callable):
3195+
def _apply_item_processor(
3196+
self,
3197+
arr: Sequence[Any],
3198+
itemproc: Optional[Callable[[Any], Any]],
3199+
dim: Optional[int],
3200+
collection_callable: Callable[[Iterable[Any]], _P],
3201+
) -> _P:
31693202
"""Helper method that can be used by bind_processor(),
31703203
literal_processor(), etc. to apply an item processor to elements of
31713204
an array value, taking into account the 'dimensions' for this

0 commit comments

Comments
 (0)