-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Async web3 #2819
Async web3 #2819
Conversation
4ae59ac
to
d44bb72
Compare
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.
Hooray! 🚀 I left some comments around adding a new TypeVar
instead of Union["ContractFunction", "AsyncContractFunction"]
, that I think can help avoid some of the cast
ing we're doing in the contract
/async_contract
files. It was sort of hard to figure out where to put the comments, so lmk if they don't make sense and we can hop on a call!
) | ||
|
||
# TODO: The no_extra_call method gets around the fact that we can't call | ||
# the full async method from within a class's __init__ method. We need |
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 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 __await__
magic method allows for things to be awaited at creation. There are a few examples of it in the codebase.
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.
@kclowes I addressed your comments in the latest commit. It looks like some typing broke for [nevermind, fixed 🎉]filter_builder.args
when I added the TypeVar
suggestion. I ignored those for now. It's not immediately obvious to me where that broke.
from web3.eth import AsyncEth # noqa: F401 | ||
from web3.main import ( # noqa: F401 |
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.
Here it's from web3.main import
, but we also use from web3 import
all over the place and I can't find a pattern. Can we just use one or the other?
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.
Yeah. I guess from web3.main
might be "best" since the web3/__init__.py
imports it from web3.main
so it's a bit of a hand-off. I don't think it matters too much how it's imported internally. There may be some things that are defined in web3.main
that we don't expose via web3/__init__.py
at some point too. For example, I'm not sure that it makes much sense to expose BaseWeb3
there since that's not a complete class that is ready for use.
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 left a couple comments, but overall lookin' good! I love all those # type: ignore
s going away.
9562800
to
7bb1440
Compare
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.
LGTM! 🚢 ! Just had a tiny nit.
- Create ``AsyncWeb3`` since ambiguity when instantiating modules with ``Union`` types leads to typing issues. Python's static typing forces us to make the async library a first class citizen. - Refactor appropriately down the tree, accounting for the newly expected ``AsyncWeb3`` class in things like middlewares and modules, including ``ens``. - Be more explicit within modules which type of ``w3`` is expected, ``Web3`` or ``AsyncWeb3``, as in the ``EthPM`` module, for example. - Resolve some ``type: ignore`` cases along the way as some of the typing gets tightened.
- ``BaseContractCaller`` used the sync version of ``parse_block_identifier`` which would render any calls inside it useless for ``AsyncContractCaller`` which inherits from it. I'm assuming we don't test all cases here. This commit splits the bulk of that logic out to the sync and async __init__ methods for contract caller and calls a more appropriate method for parsing the block identifier that doesn't involve an extra call. This reduces some of the intended functionality, but that wasn't working to begin with. This will need to be revised at some point to see if we can account for all desired cases within the async contract caller __init__.
- Improve typing by using `TypeVar` over `Union` in certain places to prevent casting - Update links for geth namespaced api docs
What was wrong?
Related to Issue #1416
AsyncWeb3
fromWeb3
in an effort to make async a first class citizen of the library. Ideally we refactor the structure of the files so they are organized as such for developers. I feel like there are enough changes here where re-organization should be a separate PR, which will be quite large as well.AsyncMiddleware
type that expectsAsyncWeb3
rather thanWeb3
. Account for this change down the tree through async middlewares and middleware onion.type: ignore
that were fixed by the tighter typing for async web3 and related modules.Things to note:
AsyncContractCaller
inherits fromBaseContractCaller
which used the synchronous methodparse_block_identifier
in its__init__()
method. This leads me to think we weren't testing all cases for initialization of the contract caller. This came up as an issue with typing and was addressed using the simplerparse_block_identifier_no_extra_call()
method which technically shouldn't break anything since the previous structure would return a coroutine and also not work. This may need to be addressed in the future if we want to try to account for all elif cases thatContractCaller
accounts for.How was it fixed?
Todo:
Update documentation + document new async flow(separate PR, see Async web3 docs #2821)Cute Animal Picture