Closed
Description
Describe the typing issue
Type checkers do not allow using isnot
in an AND
clause
To Reproduce
from sqlalchemy import Integer
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy.sql.elements import ColumnElement
from sqlalchemy.sql.expression import and_
class Base(DeclarativeBase):
...
class MyTable(Base):
state_id: Mapped[int | None] = mapped_column(Integer)
def test() -> ColumnElement[bool]:
return and_(MyTable.state_id.isnot(None))
Error
Mypy:
"ColumnOperators"; expected "Union[Literal[True], Union[ColumnElement[bool], _HasClauseElement, SQLCoreOperations[bool], ExpressionElementRole[bool], Callable[[], ColumnElement[bool]], LambdaElement]]" [arg-type])
Pyright:
error: Argument of type "ColumnOperators" cannot be assigned to parameter "clauses" of type "_ColumnExpressionArgument[bool]" in function "and_"
Type "ColumnOperators" cannot be assigned to type "_ColumnExpressionArgument[bool]"
"ColumnOperators" is incompatible with "ColumnElement[bool]"
"ColumnOperators" is incompatible with protocol "_HasClauseElement"
"__clause_element__" is not present
"ColumnOperators" is incompatible with "SQLCoreOperations[bool]"
"ColumnOperators" is incompatible with "ExpressionElementRole[bool]"
Type "ColumnOperators" cannot be assigned to type "() -> ColumnElement[bool]"
"ColumnOperators" is incompatible with "LambdaElement" (reportGeneralTypeIssues)
Versions
- OS:
- Python:
- SQLAlchemy: 2.0.0rc3
- Type checkers:
- mypy 0.991
- pyright 1.1.290
Additional context
No response
Metadata
Metadata
Assignees
Type
Projects
Relationships
Development
No branches or pull requests
Activity
CaselIT commentedon Jan 26, 2023
Hi,
have you tried using
is_not
?isnot is "soft" deprecated since 1.4
emontnemery commentedon Jan 26, 2023
That does indeed work with both mypy and pyright 👍
Thanks a lot @CaselIT !
CaselIT commentedon Jan 26, 2023
I'm not sure if this behaviour is intended or not. Let's hear mike opition @zzzeek
zzzeek commentedon Jan 26, 2023
if
isnot
is there it should be typed also. I guess it's there like an assignment right now and needs to be a full method ? Not at my computer to look right nowzzzeek commentedon Jan 26, 2023
yeah none of it is typed, doing it now
sqla-tester commentedon Jan 26, 2023
Mike Bayer has proposed a fix for this issue in the main branch:
add typing to legacy operators https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4392
CaselIT commentedon Jan 26, 2023
The types are in a TYPE_CHECKING block so we can do whatever there
1 remaining item