]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fix type errors surfaced by mypy 1.16
authorFederico Caselli <cfederico87@gmail.com>
Fri, 30 May 2025 20:53:59 +0000 (22:53 +0200)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 2 Jun 2025 23:44:46 +0000 (19:44 -0400)
Change-Id: I50bbd760577ff7c865c81153041e82bba068e5d8
(cherry picked from commit 7088f7962bcdf497892da85aff16022d27662eb4)

26 files changed:
lib/sqlalchemy/dialects/mysql/aiomysql.py
lib/sqlalchemy/dialects/mysql/asyncmy.py
lib/sqlalchemy/dialects/mysql/mysqlconnector.py
lib/sqlalchemy/dialects/mysql/mysqldb.py
lib/sqlalchemy/dialects/mysql/pymysql.py
lib/sqlalchemy/dialects/postgresql/array.py
lib/sqlalchemy/dialects/postgresql/ranges.py
lib/sqlalchemy/engine/cursor.py
lib/sqlalchemy/engine/default.py
lib/sqlalchemy/ext/mutable.py
lib/sqlalchemy/orm/attributes.py
lib/sqlalchemy/orm/decl_base.py
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/relationships.py
lib/sqlalchemy/orm/util.py
lib/sqlalchemy/orm/writeonly.py
lib/sqlalchemy/pool/impl.py
lib/sqlalchemy/sql/coercions.py
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/ddl.py
lib/sqlalchemy/sql/elements.py
lib/sqlalchemy/sql/lambdas.py
lib/sqlalchemy/sql/schema.py
lib/sqlalchemy/sql/sqltypes.py
test/typing/plain_files/orm/mapped_covariant.py

index 314c78adee8c319c04b0a127bd979f54c2fdefef..e2ac70b02947d31ca7a01d3627a6d8e7f1567d86 100644 (file)
@@ -184,7 +184,7 @@ class MySQLDialect_aiomysql(MySQLDialect_pymysql):
     driver = "aiomysql"
     supports_statement_cache = True
 
-    supports_server_side_cursors = True  # type: ignore[assignment]
+    supports_server_side_cursors = True
     _sscursor = AsyncAdapt_aiomysql_ss_cursor
 
     is_async = True
index 32a45c0d35de38b846d7f51df10f51570d046cd5..750735e8f1e8243303bfbea5ca3fa92df64edd91 100644 (file)
@@ -167,7 +167,7 @@ class MySQLDialect_asyncmy(MySQLDialect_pymysql):
     driver = "asyncmy"
     supports_statement_cache = True
 
-    supports_server_side_cursors = True  # type: ignore[assignment]
+    supports_server_side_cursors = True
     _sscursor = AsyncAdapt_asyncmy_ss_cursor
 
     is_async = True
index 91d1058e9c47bb295c023a5c3af3b363cc27120a..a830cb5afefc0d2b9c9bbfe194d2bdfe7a0a2803 100644 (file)
@@ -116,13 +116,13 @@ class IdentifierPreparerCommon_mysqlconnector:
         return value
 
 
-class MySQLIdentifierPreparer_mysqlconnector(  # type:ignore[misc]
+class MySQLIdentifierPreparer_mysqlconnector(
     IdentifierPreparerCommon_mysqlconnector, MySQLIdentifierPreparer
 ):
     pass
 
 
-class MariaDBIdentifierPreparer_mysqlconnector(  # type:ignore[misc]
+class MariaDBIdentifierPreparer_mysqlconnector(
     IdentifierPreparerCommon_mysqlconnector, MariaDBIdentifierPreparer
 ):
     pass
index 52adaefab76860bdb90433fd4f411e9937e591c6..de4ae61c0477692e8567fe9e604cf402fa1e421e 100644 (file)
@@ -154,7 +154,7 @@ class MySQLDialect_mysqldb(MySQLDialect):
             return (0, 0, 0)
 
     @util.langhelpers.memoized_property
-    def supports_server_side_cursors(self) -> bool:  # type: ignore[override]
+    def supports_server_side_cursors(self) -> bool:
         try:
             cursors = __import__("MySQLdb.cursors").cursors
             self._sscursor = cursors.SSCursor
index 26fd9b038bd6d1ac8c4b6e4fb45de627a8e382cf..48b7994a82ab01c1bf56dc7bbdbeb024228bc1c4 100644 (file)
@@ -76,7 +76,7 @@ class MySQLDialect_pymysql(MySQLDialect_mysqldb):
     description_encoding = None
 
     @langhelpers.memoized_property
-    def supports_server_side_cursors(self) -> bool:  # type: ignore[override]
+    def supports_server_side_cursors(self) -> bool:
         try:
             cursors = __import__("pymysql.cursors").cursors
             self._sscursor = cursors.SSCursor
@@ -116,7 +116,7 @@ class MySQLDialect_pymysql(MySQLDialect_mysqldb):
                     not insp.defaults or insp.defaults[0] is not False
                 )
 
-    def do_ping(self, dbapi_connection: DBAPIConnection) -> Literal[True]:  # type: ignore # noqa: E501
+    def do_ping(self, dbapi_connection: DBAPIConnection) -> Literal[True]:
         if self._send_false_to_ping:
             dbapi_connection.ping(False)
         else:
index 9e094973c34ed3dcd400afefa67d188f106aa641..96f6dc21a2d35b28e9f7ce7a2fd2f0cfe3ee8af0 100644 (file)
@@ -398,7 +398,7 @@ class ARRAY(sqltypes.ARRAY[_T]):
     def _against_native_enum(self) -> bool:
         return (
             isinstance(self.item_type, sqltypes.Enum)
-            and self.item_type.native_enum  # type: ignore[attr-defined]
+            and self.item_type.native_enum
         )
 
     def literal_processor(
index 93253570c1bad57c1d93cd8f21f8606421ddee45..0ce4ea29137ed2b93f21008428e08dde035b2f7f 100644 (file)
@@ -271,9 +271,9 @@ class Range(Generic[_T]):
                     value2 += step
                     value2_inc = False
 
-        if value1 < value2:  # type: ignore
+        if value1 < value2:
             return -1
-        elif value1 > value2:  # type: ignore
+        elif value1 > value2:
             return 1
         elif only_values:
             return 0
index 54e9784e0c427132f74519cf3f9ec803246430ba..8e2348efab5c0da31ad9c282a0a7f21fd6267243 100644 (file)
@@ -1358,15 +1358,15 @@ class _NoResultMetaData(ResultMetaData):
         self._we_dont_return_rows()
 
     @property
-    def _keymap(self):
+    def _keymap(self):  # type: ignore[override]
         self._we_dont_return_rows()
 
     @property
-    def _key_to_index(self):
+    def _key_to_index(self):  # type: ignore[override]
         self._we_dont_return_rows()
 
     @property
-    def _processors(self):
+    def _processors(self):  # type: ignore[override]
         self._we_dont_return_rows()
 
     @property
index 15f758e4c2cf3189a3d5a93561f825ff1241b7e4..57759f79cfcea54b445471f0c8aec61279c6bd7f 100644 (file)
@@ -478,7 +478,7 @@ class DefaultDialect(Dialect):
         return weakref.WeakKeyDictionary()
 
     @property
-    def dialect_description(self):
+    def dialect_description(self):  # type: ignore[override]
         return self.name + "+" + self.driver
 
     @property
@@ -1627,7 +1627,7 @@ class DefaultExecutionContext(ExecutionContext):
             return "unknown"
 
     @property
-    def executemany(self):
+    def executemany(self):  # type: ignore[override]
         return self.execute_style in (
             ExecuteStyle.EXECUTEMANY,
             ExecuteStyle.INSERTMANYVALUES,
@@ -1841,6 +1841,7 @@ class DefaultExecutionContext(ExecutionContext):
         if self._rowcount is None and exec_opt.get("preserve_rowcount", False):
             self._rowcount = self.cursor.rowcount
 
+        yp: Optional[Union[int, bool]]
         if self.is_crud or self.is_text:
             result = self._setup_dml_or_text_result()
             yp = False
index ed618c3819df923487c36daeda593d376ffefcaf..3d568fc98926b893de4ed8906f31841458aaaeef 100644 (file)
@@ -524,6 +524,7 @@ class MutableBase:
             if val is not None:
                 if coerce:
                     val = cls.coerce(key, val)
+                    assert val is not None
                     state.dict[key] = val
                 val._parents[state] = key
 
index 283cbc60484693a5fd4e064a7167b3afda982e60..3c4f31645143abdb17ae0acf661cb62f568fd478 100644 (file)
@@ -630,11 +630,11 @@ def create_proxied_attribute(
             self._doc = self.__doc__ = doc
 
         @property
-        def _parententity(self):
+        def _parententity(self):  # type: ignore[override]
             return inspection.inspect(self.class_, raiseerr=False)
 
         @property
-        def parent(self):
+        def parent(self):  # type: ignore[override]
             return inspection.inspect(self.class_, raiseerr=False)
 
         _is_internal_proxy = True
index f09f4369f1b85a2f90844d1905d9bd53afb5e613..d0a78764cc80c16951507ddbe60f2346515045da 100644 (file)
@@ -2017,8 +2017,7 @@ class _DeferredMapperConfig(_ClassScanMapperConfig):
     def _early_mapping(self, mapper_kw: _MapperKwArgs) -> None:
         pass
 
-    # mypy disallows plain property override of variable
-    @property  # type: ignore
+    @property
     def cls(self) -> Type[Any]:
         return self._cls()  # type: ignore
 
index 5844854f9d03188c4d043efae5b95ec4583aa86b..ae7f8f24fc44d789784fec1e09e7c030eaa2398b 100644 (file)
@@ -1056,7 +1056,7 @@ class Mapper(
 
     """
 
-    primary_key: Tuple[Column[Any], ...]
+    primary_key: Tuple[ColumnElement[Any], ...]
     """An iterable containing the collection of :class:`_schema.Column`
     objects
     which comprise the 'primary key' of the mapped table, from the
@@ -2554,7 +2554,7 @@ class Mapper(
         if spec == "*":
             mappers = list(self.self_and_descendants)
         elif spec:
-            mapper_set = set()
+            mapper_set: Set[Mapper[Any]] = set()
             for m in util.to_list(spec):
                 m = _class_to_mapper(m)
                 if not m.isa(self):
@@ -3428,9 +3428,11 @@ class Mapper(
         return self.class_manager.mapper.base_mapper
 
     def _result_has_identity_key(self, result, adapter=None):
-        pk_cols: Sequence[ColumnClause[Any]] = self.primary_key
-        if adapter:
-            pk_cols = [adapter.columns[c] for c in pk_cols]
+        pk_cols: Sequence[ColumnElement[Any]]
+        if adapter is not None:
+            pk_cols = [adapter.columns[c] for c in self.primary_key]
+        else:
+            pk_cols = self.primary_key
         rk = result.keys()
         for col in pk_cols:
             if col not in rk:
@@ -3455,9 +3457,11 @@ class Mapper(
             for the "row" argument
 
         """
-        pk_cols: Sequence[ColumnClause[Any]] = self.primary_key
-        if adapter:
-            pk_cols = [adapter.columns[c] for c in pk_cols]
+        pk_cols: Sequence[ColumnElement[Any]]
+        if adapter is not None:
+            pk_cols = [adapter.columns[c] for c in self.primary_key]
+        else:
+            pk_cols = self.primary_key
 
         mapping: RowMapping
         if hasattr(row, "_mapping"):
index 75ad5b1ca0eb908a4555dd59001f46ed23fb9a6b..164ae009b2573d35d03295cd1d04bd904bbf1414 100644 (file)
@@ -234,7 +234,7 @@ class ColumnProperty(
             return self.strategy._have_default_expression  # type: ignore
 
         return ("deferred", True) not in self.strategy_key or (
-            self not in self.parent._readonly_props  # type: ignore
+            self not in self.parent._readonly_props
         )
 
     @util.preload_module("sqlalchemy.orm.state", "sqlalchemy.orm.strategies")
index eae00338f10db62b2d76b0a47ad1de2be4537812..15b63d1b4b4bf4120b75d7759121effe6f8b0fcb 100644 (file)
@@ -486,8 +486,7 @@ class RelationshipProperty(
         else:
             self._overlaps = ()
 
-        # mypy ignoring the @property setter
-        self.cascade = cascade  # type: ignore
+        self.cascade = cascade
 
         self.back_populates = back_populates
 
index 874c4f53b154d4a3a79c7265018eb23b3f0103d0..ca607af1be481edfc432c3e3e03c1e90895ebf86 100644 (file)
@@ -1566,7 +1566,7 @@ class Bundle(
 
     _propagate_attrs: _PropagateAttrsType = util.immutabledict()
 
-    proxy_set = util.EMPTY_SET  # type: ignore
+    proxy_set = util.EMPTY_SET
 
     exprs: List[_ColumnsClauseElement]
 
index ac034a09e0a879090b9a09941c6ace4c852a2148..fe9c8e96e895a3e6163eabe075d37a8186c3681d 100644 (file)
@@ -236,15 +236,11 @@ class WriteOnlyAttributeImpl(
         return DynamicCollectionAdapter(data)  # type: ignore[return-value]
 
     @util.memoized_property
-    def _append_token(  # type:ignore[override]
-        self,
-    ) -> attributes.AttributeEventToken:
+    def _append_token(self) -> attributes.AttributeEventToken:
         return attributes.AttributeEventToken(self, attributes.OP_APPEND)
 
     @util.memoized_property
-    def _remove_token(  # type:ignore[override]
-        self,
-    ) -> attributes.AttributeEventToken:
+    def _remove_token(self) -> attributes.AttributeEventToken:
         return attributes.AttributeEventToken(self, attributes.OP_REMOVE)
 
     def fire_append_event(
index cc597e1e62e0a3256644bd7881fec1ee6254966d..f3d53ddb84d7a0b404defab1508cca6e811328e4 100644 (file)
@@ -60,7 +60,7 @@ class QueuePool(Pool):
 
     """
 
-    _is_asyncio = False  # type: ignore[assignment]
+    _is_asyncio = False
 
     _queue_class: Type[sqla_queue.QueueCommon[ConnectionPoolEntry]] = (
         sqla_queue.Queue
@@ -269,7 +269,7 @@ class AsyncAdaptedQueuePool(QueuePool):
 
     """
 
-    _is_asyncio = True  # type: ignore[assignment]
+    _is_asyncio = True
     _queue_class: Type[sqla_queue.QueueCommon[ConnectionPoolEntry]] = (
         sqla_queue.AsyncAdaptedQueue
     )
@@ -278,7 +278,7 @@ class AsyncAdaptedQueuePool(QueuePool):
 
 
 class FallbackAsyncAdaptedQueuePool(AsyncAdaptedQueuePool):
-    _queue_class = sqla_queue.FallbackAsyncAdaptedQueue
+    _queue_class = sqla_queue.FallbackAsyncAdaptedQueue  # type: ignore[assignment] # noqa: E501
 
 
 class NullPool(Pool):
@@ -356,7 +356,7 @@ class SingletonThreadPool(Pool):
 
     """
 
-    _is_asyncio = False  # type: ignore[assignment]
+    _is_asyncio = False
 
     def __init__(
         self,
index e174833fbdc6d1f41f3a6886e5d2f49c79051764..ac0393a6056263a58e64eb495b8f41dab448156e 100644 (file)
@@ -843,7 +843,7 @@ class InElementImpl(RoleImpl):
         )
 
     @util.preload_module("sqlalchemy.sql.elements")
-    def _literal_coercion(self, element, *, expr, operator, **kw):
+    def _literal_coercion(self, element, *, expr, operator, **kw):  # type: ignore[override] # noqa: E501
         if util.is_non_string_iterable(element):
             non_literal_expressions: Dict[
                 Optional[_ColumnExpressionArgument[Any]],
index d782b019624b8dd089abc33a0e85ba79c4a5914f..2353fa39e4028e0a27a25b93081d13041b96b1ec 100644 (file)
@@ -4230,7 +4230,7 @@ class SQLCompiler(Compiled):
                 if self.preparer._requires_quotes(cte_name):
                     cte_name = self.preparer.quote(cte_name)
                 text += self.get_render_as_alias_suffix(cte_name)
-                return text
+                return text  # type: ignore[no-any-return]
             else:
                 return self.preparer.format_alias(cte, cte_name)
 
@@ -6341,7 +6341,7 @@ class SQLCompiler(Compiled):
 
         self.stack.pop(-1)
 
-        return text
+        return text  # type: ignore[no-any-return]
 
     def delete_extra_from_clause(
         self, delete_stmt, from_table, extra_froms, from_hints, **kw
index 3b2463a634bc98748d5eb63b30f98de545eef7e7..70a83cb8a73bda44fdf446ac36ff0c15a692950a 100644 (file)
@@ -439,7 +439,7 @@ class _CreateDropBase(ExecutableDDLElement, Generic[_SI]):
         self._ddl_if = getattr(element, "_ddl_if", None)
 
     @property
-    def stringify_dialect(self):
+    def stringify_dialect(self):  # type: ignore[override]
         assert not isinstance(self.element, str)
         return self.element.create_drop_stringify_dialect
 
index 37fea947afab419dfcfdca6d9372409dfd2eb2ba..2d9ee575620873b7094deab4a5f94095e49571fb 100644 (file)
@@ -461,7 +461,7 @@ class ClauseElement(
         return self
 
     @property
-    def _constructor(self):
+    def _constructor(self):  # type: ignore[override]
         """return the 'constructor' for this ClauseElement.
 
         This is for the purposes for creating a new object of
@@ -694,6 +694,7 @@ class ClauseElement(
         else:
             elem_cache_key = None
 
+        extracted_params: Optional[Sequence[BindParameter[Any]]]
         if elem_cache_key is not None:
             if TYPE_CHECKING:
                 assert compiled_cache is not None
@@ -2297,7 +2298,7 @@ class TextClause(
     _allow_label_resolve = False
 
     @property
-    def _is_star(self):
+    def _is_star(self):  # type: ignore[override]
         return self.text == "*"
 
     def __init__(self, text: str):
@@ -4789,11 +4790,11 @@ class Label(roles.LabeledColumnExprRole[_T], NamedColumn[_T]):
             return self
 
     @property
-    def primary_key(self):
+    def primary_key(self):  # type: ignore[override]
         return self.element.primary_key
 
     @property
-    def foreign_keys(self):
+    def foreign_keys(self):  # type: ignore[override]
         return self.element.foreign_keys
 
     def _copy_internals(
@@ -4926,7 +4927,7 @@ class ColumnClause(
     _is_multiparam_column = False
 
     @property
-    def _is_star(self):
+    def _is_star(self):  # type: ignore[override]
         return self.is_literal and self.name == "*"
 
     def __init__(
index ce755c1f8327678a84e8554226a1b151d63f16d3..21c69fed5af1743141eee921513eff253081f4ba 100644 (file)
@@ -300,7 +300,9 @@ class LambdaElement(elements.ClauseElement):
             while lambda_element is not None:
                 rec = lambda_element._rec
                 if rec.bindparam_trackers:
-                    tracker_instrumented_fn = rec.tracker_instrumented_fn
+                    tracker_instrumented_fn = (
+                        rec.tracker_instrumented_fn  # type:ignore [union-attr] # noqa: E501
+                    )
                     for tracker in rec.bindparam_trackers:
                         tracker(
                             lambda_element.fn,
@@ -602,7 +604,7 @@ class StatementLambdaElement(
         return self._rec_expected_expr
 
     @property
-    def _with_options(self):
+    def _with_options(self):  # type: ignore[override]
         return self._proxied._with_options
 
     @property
@@ -610,7 +612,7 @@ class StatementLambdaElement(
         return self._proxied._effective_plugin_target
 
     @property
-    def _execution_options(self):
+    def _execution_options(self):  # type: ignore[override]
         return self._proxied._execution_options
 
     @property
@@ -618,27 +620,27 @@ class StatementLambdaElement(
         return self._proxied._all_selected_columns
 
     @property
-    def is_select(self):
+    def is_select(self):  # type: ignore[override]
         return self._proxied.is_select
 
     @property
-    def is_update(self):
+    def is_update(self):  # type: ignore[override]
         return self._proxied.is_update
 
     @property
-    def is_insert(self):
+    def is_insert(self):  # type: ignore[override]
         return self._proxied.is_insert
 
     @property
-    def is_text(self):
+    def is_text(self):  # type: ignore[override]
         return self._proxied.is_text
 
     @property
-    def is_delete(self):
+    def is_delete(self):  # type: ignore[override]
         return self._proxied.is_delete
 
     @property
-    def is_dml(self):
+    def is_dml(self):  # type: ignore[override]
         return self._proxied.is_dml
 
     def spoil(self) -> NullLambdaStatement:
index 68f31de9386cccfa1da9f45e4b5c324113de0d7b..db0678a7378f456aadd1499b2100f03d7c27dac6 100644 (file)
@@ -476,7 +476,7 @@ class Table(
             table.dispatch.before_parent_attach(table, metadata)
             metadata._add_table(name, schema, table)
             try:
-                table.__init__(name, metadata, *args, _no_init=False, **kw)
+                table.__init__(name, metadata, *args, _no_init=False, **kw)  # type: ignore[misc] # noqa: E501
                 table.dispatch.after_parent_attach(table, metadata)
                 return table
             except Exception:
@@ -2242,7 +2242,7 @@ class Column(DialectKWArgs, SchemaItem, ColumnClause[_T]):
         return _DefaultDescriptionTuple._from_column_default(self.onupdate)
 
     @util.memoized_property
-    def _gen_static_annotations_cache_key(self) -> bool:  # type: ignore
+    def _gen_static_annotations_cache_key(self) -> bool:
         """special attribute used by cache key gen, if true, we will
         use a static cache key for the annotations dictionary, else we
         will generate a new cache key for annotations each time.
index 63d7c49568397ec04bc7ccaed2424bd756acf63a..fc278678b2e1834c36d6074791ac3a300a0ab94f 100644 (file)
@@ -1645,14 +1645,14 @@ class Enum(String, SchemaType, Emulated, TypeEngine[Union[str, enum.Enum]]):
         )
 
     @property
-    def sort_key_function(self):
+    def sort_key_function(self):  # type: ignore[override]
         if self._sort_key_function is NO_ARG:
             return self._db_value_for_elem
         else:
             return self._sort_key_function
 
     @property
-    def native(self):
+    def native(self):  # type: ignore[override]
         return self.native_enum
 
     def _db_value_for_elem(self, elem):
@@ -2755,7 +2755,7 @@ class JSON(Indexable, TypeEngine[Any]):
     def python_type(self):
         return dict
 
-    @property  # type: ignore  # mypy property bug
+    @property
     def should_evaluate_none(self):
         """Alias of :attr:`_types.JSON.none_as_null`"""
         return not self.none_as_null
@@ -3702,7 +3702,7 @@ class Uuid(Emulated, TypeEngine[_UUID_RETURN]):
         return _python_UUID if self.as_uuid else str
 
     @property
-    def native(self):
+    def native(self):  # type: ignore[override]
         return self.native_uuid
 
     def coerce_compared_value(self, op, value):
index 0b65073fde6eda09695cb6f883f25a8aa4dbf4ec..9eca6e9593f8396c453329f9df12c332a5ece8d3 100644 (file)
@@ -21,7 +21,10 @@ from sqlalchemy.sql.elements import SQLCoreOperations
 \r
 \r
 class ParentProtocol(Protocol):\r
-    name: Mapped[str]\r
+    # Read-only for simplicity, mutable protocol members are complicated,\r
+    # see https://mypy.readthedocs.io/en/latest/common_issues.html#covariant-subtyping-of-mutable-protocol-members-is-rejected\r
+    @property\r
+    def name(self) -> Mapped[str]: ...\r
 \r
 \r
 class ChildProtocol(Protocol):\r