-
Notifications
You must be signed in to change notification settings - Fork 4
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
refactor: add proper return types to resource sequence methods #368
base: tdstein/import-typing-extensions
Are you sure you want to change the base?
refactor: add proper return types to resource sequence methods #368
Conversation
☂️ Python Coverage
Overall Coverage
New FilesNo new covered files... Modified Files
|
9a22be7
to
39e1eb0
Compare
response = self._ctx.client.post(self._path, json=attributes) | ||
result = response.json() | ||
uid = result[self._uid] | ||
path = posixpath.join(self._path, uid) | ||
return _Resource(self._ctx, path, **result) | ||
resource = self._factory(self._ctx, path, **result) | ||
resource = cast(_T, resource) |
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.
I want to avoid this cast, but I haven't figured it out yet...
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.
I couldn't either... I tried to do this locally before you opened the PR. 😜
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.
Couple typing style requests.
One question on the covariant type var.
self, | ||
ctx: Context, | ||
path: str, | ||
factory: ResourceFactory[_T_co] = _Resource, |
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.
My preference is to put uncommon args that have defaults behind some sort of "name requirement" mechanism.
factory: ResourceFactory[_T_co] = _Resource, | |
*, | |
factory: ResourceFactory[_T_co] = _Resource, |
self, | ||
ctx: Context, | ||
path: str, | ||
factory: ResourceFactory[_T_co] = _Resource, |
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.
We do not adjust factory
or uid
, but their default values are shared objects between instances: https://www.pythonmorsels.com/mutable-default-arguments/
(No changes necessary... just a thought to file away for a different debug day)
@@ -89,38 +93,50 @@ def update(self, **attributes): # type: ignore[reportIncompatibleMethodOverride | |||
super().update(**result) | |||
|
|||
|
|||
T = TypeVar("T", bound=Resource) | |||
_T = TypeVar("_T", bound=Resource) | |||
_T_co = TypeVar("_T_co", bound=Resource, covariant=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.
A perfect use case!
Linking for my own reminder: https://stackoverflow.com/a/61737894/591574
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.
But is it necessary since we're cast()
ing?
I think we might be able to get away with a invariant type.
_T_co = TypeVar("_T_co", bound=Resource, covariant=True) | |
_R = TypeVar("_R", bound=Resource) |
(R
for factory R eturn value?)
resource = self._factory(self._ctx, path, **result) | ||
resource = cast(_T, resource) |
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.
resource = self._factory(self._ctx, path, **result) | |
resource = cast(_T, resource) | |
resource: _T_co = self._factory(self._ctx, path, **result) | |
resource = cast(_T, resource) |
resource = self._factory(self._ctx, path, **result) | ||
resource = cast(_T, resource) |
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.
From other repos, I've used an explicit type expectation before casting the value.
resource: _T_co = self._factory(self._ctx, path, **result)
resource = cast(_T, resource)
While it feels redundant, it gives me confidence if we ever change ._factory()
and its return type. This way, we know we are transferring from a _T_co
to _T
(and not an Any
to a _T
).
resource = self._factory(self._ctx, path, **result) | ||
resource = cast(_T, resource) |
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.
resource = self._factory(self._ctx, path, **result) | |
resource = cast(_T, resource) | |
resource: _T_co = self._factory(self._ctx, path, **result) | |
resource = cast(_T, resource) |
resource = self._factory(self._ctx, path, **result) | ||
resource = cast(_T, resource) |
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.
resource = self._factory(self._ctx, path, **result) | |
resource = cast(_T, resource) | |
resource: _T_co = self._factory(self._ctx, path, **result) | |
resource = cast(_T, resource) |
No description provided.