-
Notifications
You must be signed in to change notification settings - Fork 2k
Use WalletProtocol to constrain wallet function type signatures #14991
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
base: main
Are you sure you want to change the base?
Conversation
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.
There are some reasons in @altendky's mind why we shouldn't inherit from a Protocol
(Something because its a metaclass and thats bad for some reason). I can't tell you more about that but what i can tell is that we have
chia-blockchain/chia/pools/pool_wallet.py
Lines 993 to 996 in 2c25a79
if TYPE_CHECKING: | |
from chia.wallet.wallet_protocol import WalletProtocol | |
_dummy: WalletProtocol = cast(PoolWallet, None) |
WalletProtocol
. I guess thats what you wanted to archive with this PR?
As I recall, inheriting from a I did have a decorator that could be used to check stuff like this, but mypy doesn't presently output the detailed info that would be more helpful with debugging when using the hint checking mechanism the decorator does. I've got a PR at python/mypy#13878 where I had started to work on that. Needs tests though, if I remember correctly. It does have an example of the decorator tooling. The primary upside of the decorator is that it keeps the expression of following the protocol in the area that people expect to see it. Right new the |
Hmm, so if we use quotes with https://mypy-play.net/?mypy=1.1.1&python=3.11&gist=4456b7f7f773465169b70c3113082311 from __future__ import annotations
from typing import TYPE_CHECKING, Protocol, cast
class P(Protocol):
def m(self) -> int:
...
if TYPE_CHECKING:
__protocol_check: P = cast("C", None)
class C:
def m(self) -> str:
return ""
Or maybe better yet, right inside the class. class C:
if TYPE_CHECKING:
_protocol_check: P = cast("C", None)
def m(self) -> str:
return "" |
Bother, I keep fiddling a little more and realizing that I missed all this in my first exploration. No need for quotes inside the class. class C:
if TYPE_CHECKING:
_protocol_check: P = cast(C, None)
def m(self) -> str:
return "" This is brief, well located, doesn't pollute the global namespace since |
Maybe #15134 is a satisfactory replacement? |
@@ -102,7 +103,7 @@ def from_json_dict(cls, json_dict: Dict[str, Any]) -> "Mirror": | |||
|
|||
|
|||
@final | |||
class DataLayerWallet: | |||
class DataLayerWallet(WalletProtocol): |
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.
to repeat what kyle said. This is not how you declare that you implement a protocol, this is how you declare a new protocol that subsumes another.
My understanding is that whether a type implements a protocol is essentially duck-typing in mypy
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.
also known as structural subtyping, in case you see that floating around. i still intend to get a smaller pattern working someday but at the moment mypy doesn't provide verbose output clarifying in what way the protocol is not satisfied when you do it my 'better' way.
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
This PR has been flagged as stale due to no activity for over 60 days. It will not be automatically closed, but it has been given a stale-pr label and should be manually reviewed by the relevant parties. |
Code changes - no user visible changes