-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type annotations for sqlalchemy.sql.elements #9143
base: main
Are you sure you want to change the base?
Type annotations for sqlalchemy.sql.elements #9143
Conversation
@@ -1837,7 +1853,7 @@ def _dedupe_anon_label_idx(self, idx: int) -> str: | |||
return self._dedupe_anon_tq_label_idx(idx) | |||
|
|||
@property | |||
def _proxy_key(self): | |||
def _proxy_key(self) -> Optional[str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing @property
to @HasMemoized.memoized_attribute
(superclass definition has it) removes the error. This isn't the only case, guessing there's an access-related conflict somewhere between @property
, @HasMemoized.memoized_attribute
and @util.memoized_property
from mypy's point of view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the @property
situation with mypy is very difficult. it's not in general safe to change a @property
to a memoized so I'd have to look at this.
return True | ||
|
||
@HasMemoized.memoized_attribute | ||
def _non_anon_label(self): | ||
def _non_anon_label(self) -> Optional[str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replacing @HasMemoized.memoized_attribute
with @property
resolves the error.
lib/sqlalchemy/sql/elements.py
Outdated
self, against: Optional[OperatorType] = None | ||
) -> ClauseElement: | ||
if ( | ||
against |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the self_group()
overrides require against
argument because of a call to is_precedent()
, which conflicts with Optional
arg annotation - added against
to the conditional to deal with that without changing the function signature.
@@ -2223,13 +2264,13 @@ def _select_iterable(self) -> _SelectIterable: | |||
_allow_label_resolve = False | |||
|
|||
@property | |||
def _is_star(self): | |||
def _is_star(self) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mypy doesn't like overriding writable attribute with read-only property. My first thought was that it's mypy's general weirdness with @property
, or a bug - but looks like this has been fixed. Here a guy makes a point about how this might become a legitimate problem. Anyway, not sure how to proceed, and this isn't the only case.
@@ -4155,7 +4267,7 @@ def over(self, partition_by=None, order_by=None, range_=None, rows=None): | |||
) | |||
|
|||
@util.memoized_property | |||
def type(self): | |||
def type(self) -> TypeEngine[_T]: | |||
wgt = self.element.within_group_type(self) | |||
if wgt is not None: | |||
return wgt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
within_group_type()
returns None
by default, it's likely meant to be overridden - so mypy infers Any
for wgt
here.
@@ -3869,7 +3955,7 @@ def __init__(self, start, stop, step, _name=None): | |||
) | |||
self.type = type_api.NULLTYPE | |||
|
|||
def self_group(self, against=None): | |||
def self_group(self, against: Optional[OperatorType] = None) -> Slice: | |||
assert against is operator.getitem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting a non-overlapping identity check in the assert. operator.getitem()
is interpreted as an overloaded function by mypy. Hovewer the overloads it sees are from typeshed-fallback/stdlib/_operator.pyi
stub. Guess it shouldn't work that way
return self | ||
|
||
def _negate(self): | ||
def _negate(self) -> Union[AsBoolean, False_, True_]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In _negate()
return mypy infers Optional[OperatorType]
for the 3rd argument to AsBoolean
when OperatorType
is expected. There is no Optional
in AsBoolean.__init__
, so guessing mypy treats it that way because of superclass UnaryExpression
Optional
annotation.
lib/sqlalchemy/sql/elements.py
Outdated
def columns(self, *cols, **types): | ||
def columns( | ||
self, *cols: ColumnElement[Any], **types: TypeEngine[_T] | ||
) -> util.preloaded.sql_selectable.TextualSelect: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 2546: mypy expects List[ColumnClause[Any]]
for TextualSelect.__init__
- as per recently merged sql.selectable
annotations. However, a columns()
description says its *cols
argument is "a series of _expression.ColumnElement
objects, typically". Not sure which is the best way to resolve this.
Lines 3150-3151: for |
Didn't Also, mypy showed a few issues inside |
a lot of these require that I think pretty long and hard about what should be done, so I would say if you have most everything annotated here, just hand off to me and I can figure out what to do with the thorny issues because these are right at the core of things I really had to spend a lot of time getting to work originally, and there may need to be bigger changes. |
@zzzeek Sure - that's my thoughts exactly, so I didn't touch a lot of these. Still, I am interested in knowing how some of these issues are going to be resolved, especially |
Hi @jazzthief sorry for the delay. Can you update the change to remove the conflicts? thanks! |
2d84434
to
cb068fd
Compare
@CaselIT The conflicts are resolved, left other changes as-is like we discussed with Mike above |
great thank you. I'll move it to gerrit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision cb068fd of this pull request into gerrit so we can run tests and reviews and stuff
New Gerrit review created for change cb068fd: https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512 |
Federico Caselli (CaselIT) wrote: Mike I think this is at the point where you can take it over to fix the last type errors View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
just some notes so far
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512
lib/sqlalchemy/sql/elements.py
Outdated
@@ -80,12 +79,20 @@ | |||
from ..util.typing import Self | |||
|
|||
if typing.TYPE_CHECKING: | |||
from re import Match | |||
|
|||
from mypy_extensions import NoReturn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
NoReturn should be in typing or sqlalchemy.util.typing
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512
lib/sqlalchemy/sql/elements.py
Outdated
|
||
from mypy_extensions import NoReturn | ||
|
||
from ._py_util import cache_anon_map |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
import this from visitors
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512
lib/sqlalchemy/sql/elements.py
Outdated
anon_map: cache_anon_map, | ||
bindparams: List[BindParameter[_T]], | ||
) -> Optional[ | ||
Union[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
this whole thing I think overall is just Tuple[Any]
, it wasn't intended to be specific to what's in the tuple.
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512
lib/sqlalchemy/sql/elements.py
Outdated
self, against: Optional[OperatorType] = None | ||
) -> ClauseElement: | ||
if ( | ||
against |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
this is a logic change
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512
lib/sqlalchemy/sql/elements.py
Outdated
if ( | ||
self.group | ||
against |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mike bayer (zzzeek) wrote:
this looks like a logic change
there's a lot of sudden test failures so I'd guess these changes are why
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, removed it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision c85b4b9 of this pull request into gerrit so we can run tests and reviews and stuff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision c85b4b9 of this pull request into gerrit so we can run tests and reviews and stuff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision c85b4b9 of this pull request into gerrit so we can run tests and reviews and stuff
Patchset c85b4b9 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision c85b4b9 of this pull request into gerrit so we can run tests and reviews and stuff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision c85b4b9 of this pull request into gerrit so we can run tests and reviews and stuff
Patchset c85b4b9 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4512 |
Description
Added type annotations for
sql.elements
(issue #6810).There is also a tiny change to
sql.base
- it solves a problem inelements
.Checklist
This pull request is:
must include a complete example of the issue. one line code fixes without an
issue and demonstration will not be accepted.
Fixes: #<issue number>
in the commit messageinclude a complete example of how the feature would look.
Fixes: #<issue number>
in the commit messageHave a nice day!