vyper
vyper copied to clipboard
feat[lang]: implement export bundles
What I did
implement exports and export bundles.
export bundles are a way for library authors to group together external functions in the ABI
example:
bundle: IERC_X # declare a bundle
@internal
def foo() -> uint256:
return 10
@external
def extern1():
pass
@external
@Bundle(IERC_X)
def extern2():
pass
@external
@Bundle(IERC_X, bind=False) # extern3 ok to export on its own
def extern3():
pass
@external
@Bundle(IERC_X, bind=True) # extern4 cannot be exported on its own!
def extern4():
pass
it can be used like this:
import library
exports: library.IERC_X
@external
def library_foo() -> uint256:
return library.foo()
or like this:
import library
exports: library.extern1, library.extern2
@external
def library_foo() -> uint256:
return library.foo()
but not like this(!):
import library
exports: library.extern4 # raises StructureException
@external
def library_foo() -> uint256:
return library.foo()
How I did it
How to verify it
Commit message
Commit message for the final, squashed PR. (Optional, but reviewers will appreciate it! Please see our commit message style guide for what we would ideally like to see in a commit message.)
Description for the changelog
Cute Animal Picture
Codecov Report
Attention: 98 lines in your changes are missing coverage. Please review.
Comparison is base (
c6f457a) 84.01% compared to head (782659b) 55.74%. Report is 2 commits behind head on master.
:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@ Coverage Diff @@
## master #3698 +/- ##
===========================================
- Coverage 84.01% 55.74% -28.27%
===========================================
Files 92 92
Lines 13044 13166 +122
Branches 2928 2963 +35
===========================================
- Hits 10959 7340 -3619
- Misses 1653 5199 +3546
- Partials 432 627 +195
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Would prefer that we create less language keywords so we can namespace better:
from vyper.packaging import Bundle
IERC_X: Bundle = Bundle() # declare a bundle
@internal
def foo() -> uint256:
return 10
@external
def extern1():
pass
@external
@IERC_X.add()
def extern2():
pass
@external
@IERC_X.add(bind=False) # extern3 ok to export on its own
def extern3():
pass
@external
@IERC_X.add(bind=True) # extern4 cannot be exported on its own!
def extern4():
pass
Would prefer that we create less language keywords so we can namespace better:
from vyper.packaging import Bundle IERC_X: Bundle = Bundle() # declare a bundle @internal def foo() -> uint256: return 10 @external def extern1(): pass @external @IERC_X.add() def extern2(): pass @external @IERC_X.add(bind=False) # extern3 ok to export on its own def extern3(): pass @external @IERC_X.add(bind=True) # extern4 cannot be exported on its own! def extern4(): pass
export and bundle are not protected keywords though.
i also don't really like putting Bundle behind a namespace because:
- choosing what to expose in the ABI should be a first class concept in the language
- the proposed syntax looks like it's part of the "standard library" and like you could implement your own export semantics as a decorator. you can't, it's a compiler intrinsic
Well, would say that bundle as a keyword exists in multiple EIPs and would be careful about enshrining its use
I mean we could pick another name. But my point is it's not a keyword, you can still define variables and functions etc named bundle.
I mean we could pick another name. But my point is it's not a keyword, you can still define variables and functions etc named
bundle.
I can create a function or state variable named implements too?
I can create a function or state variable named
implementstoo?
yep
I can create a function or state variable named
implementstoo?yep
So, these two don't conflict?
# interface check
implements: ERC20
# state variable
implements: ERC20
So, these two don't conflict?
# interface check implements: ERC20 # state variable implements: ERC20
aha yea they use a similar AST node as for state variable declarations so not those, but everything else -- function names, local variables, names of things
@external
def implements():
pass
event implements:
pass
@external
def foo(implements: uint256):
pass
closing this as superseded (for now) by https://github.com/vyperlang/vyper/pull/3786 and the spec could use some polishing, will revisit in 0.4.1