Open carlos-superior opened 1 month ago
In other words, when i cast
Any
toCassandraConnection
, Mypy does not raise any errors, even though the underlying type is stillAny
. Here's the example: [...]cast(Any, CassandraConnection)
I haven't looked at this issue closely, but just in case it was a source of confusion, I wanted to point out that cast(Any, CassandraConnection)
is a cast to Any
, not from Any
. The signature for cast is cast(<assumed type>, <runtime value>)
. When you write cast(Any, CassandraConnection)
, you get back the runtime value CassandraConnection
, but ask static type checkers to treat it as though it were an Any
. Note that this is flipped with respect to the argument order for isinstance
.
If
cast()
accepts Any without issue,isinstance()
should behave similarly
There's a big difference between cast
and isinstance
, which is that cast
only affects static type checking whereas isinstance
also has runtime behavior. Mypy rejects using Any
with isinstance
because combing the two at runtime produces a TypeError
:
>>> isinstance("foo", Any)
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
isinstance("foo", Any)
~~~~~~~~~~^^^^^^^^^^^^
File "/usr/lib/python3.13/typing.py", line 589, in __instancecheck__
raise TypeError("typing.Any cannot be used with isinstance()")
TypeError: typing.Any cannot be used with isinstance()
Context
When working with the
cassandra.cluster
module in a Python project, i had to usetype: ignore
on the import because there are no compatible MyPy stubs available for the module.Below is a simplified version of how the code is set up.
from cassandra.cluster import Session as CassandraConnection
# type: ignore (mypy will treat it just like Any)from typing import TypeAlias, cast, Any
TransactionalConnection: TypeAlias = CassandraConnection
This approach generally works, but it causes issues with type checking in MyPy.
Initial Problem
When trying to use
isinstance()
to check if a variable is an instance ofTransactionalConnection
, Mypy raises the following error:Cannot use isinstance() with Any type [misc]
This happens because MyPy is treating
CassandraConnection
asAny
due to the#type: ignore
. Here's the code that triggers the error:if isinstance(db_client, TransactionalConnection): pass
-> error occurs here: Cannot use isinstance() with Any type.Paradox
Interestingly, when using
cast(Any, CassandraConnection)
, Mypy accepts the typing without issues. In other words, when i castAny
toCassandraConnection
, Mypy does not raise any errors, even though the underlying type is stillAny
. Here's the example:TransactionalConnection: TypeAlias = cast(Any, CassandraConnection)
-> This works with no MyPy errors.This behavior is paradoxical because, in both cases: (
isinstance
andcast
), the underlying type isAny
, but Mypy handles them differently.Full Scenario Example
Here’s the part where the
isinstance
check causes the error:error: Cannot use isinstance() with Any type
But when using
cast
, MyPy doesn't raise any errors:TransactionalConnection: TypeAlias = cast(Any, CassandraConnection)
Conclusion
The inconsistent behavior between using
isinstance()
andcast
when dealing with theAny
type seems to be a bug or, at the very least, an inconsistency in Mypy. Ifcast()
acceptsAny
without issue,isinstance()
should behave similarly, as both deal with theAny
type. However, Mypy rejectsisinstance
, but acceptscast
.This inconsistent behavior can confuse developers working with modules that lack proper typing, requiring the use of
# type: ignore
. I hope this issue can be reviewed, and Mypy can offer consistent behavior betweenisinstance
and cast.Environment
--strict