-
-
Notifications
You must be signed in to change notification settings - Fork 901
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
Add type to get_or_404, update tests #1208
Conversation
@@ -730,8 +732,8 @@ def get_binds(self) -> dict[sa.Table, sa.engine.Engine]: | |||
} | |||
|
|||
def get_or_404( | |||
self, entity: type[t.Any], ident: t.Any, *, description: str | None = None | |||
) -> t.Any: | |||
self, entity: type[_O], ident: t.Any, *, description: str | None = None |
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.
Change based on how it's done in SQLAlchemy for session.get():
def get(
self,
entity: _EntityBindKey[_O],
ident: _PKIdentityArgument,
*,
options: Optional[Sequence[ORMOption]] = None,
populate_existing: bool = False,
with_for_update: ForUpdateParameter = None,
identity_token: Optional[Any] = None,
execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
bind_arguments: Optional[_BindArguments] = None,
) -> Optional[_O]:
I left off the _EntityBindKey, as that didn't seem necessary for the expected developer experience.
src/flask_sqlalchemy/extension.py
Outdated
@@ -23,6 +23,8 @@ | |||
from .session import Session | |||
from .table import _Table | |||
|
|||
_O = t.TypeVar("_O", bound=object) |
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.
What does bound=object
do for this variable? The original type was type[t.Any]
so effectively boundless.
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.
Good question! I'm attempting to copy SQLAlchemy, but now I realize that they bind to Any for this case:
https://github.com/sqlalchemy/sqlalchemy/blob/2dced78f33010d4a6a6276f4e8c5665bd08d01c0/lib/sqlalchemy/orm/_typing.py#L63
There are other cases where they bind to object (_OO
) but it's unclear why they make that distinction. I asked in the python discussion forum about the differences:
https://discuss.python.org/t/differences-in-bound-object-vs-bound-any/27052/2
I may ask in the SQLAlchemy forum as well.
I'm updating this diff now to bind to t.Any.
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.
And now, thanks to this discussion and the related threads, sqlalchemy updated the Any to object, so I've changed it back to object. Bit more bounded now!
LGTM 👍 |
Update: Figured out how to use assert_type in 3.11 with mypy to test this change. |
@pamelafox amazing - thank you for doing this! One question - shouldn't the return type be |
@jdimmerman Right you are! I discovered the issue once I merged 3.0.4 into main, as a new test there happened to fail mypy check. |
@pamelafox once step ahead - thanks!! |
This PR fixes a typing issue brought up by @jdimmerman in this comment:
#1140 (comment)
Specifically:
While making/testing that change, I realized that the only tests of the *_or_404 functions are in test_legacy_query.py, despite them also being available with the non-legacy API. So I copied them into a new test file and adjusted them to use the current API. That does mean there's some redundancy in the tests, but also makes it easy to delete the legacy tests at some point if that becomes fully deprecated.
In terms of testing this change, I added a test that demonstrates the typing and passes
pdm run mypy
, but that test also pass mypy before, since the typing has gone fromt.Any
tot.Optional[ModelRef]
.Python 3.11 has an explicit typing.assert_type function for use by type checkers, so I modified tox.ini to run mypy for both 3.7 and 3.11, and put assert_type behind a hasattr guard in the test. That fails before the change and succeeds after!
Here's what it looks like in VS Code:
Checklist:
Add or update relevant docs, in the docs folder and in code.CHANGES.rst
summarizing the change and linking to the issue.Add.. versionchanged::
entries in any relevant code docs.pre-commit
hooks and fix any issues.pytest
andtox
, no tests failed.(I struck out tasks that don't seem warranted for a typing change)