Skip to content
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

feat[lang]: export interfaces #3919

Merged
merged 17 commits into from
Apr 14, 2024

Conversation

charles-cooper
Copy link
Member

@charles-cooper charles-cooper commented Apr 7, 2024

What I did

How I did it

How to verify it

examples:

# example1.vy

from snekmate.tokens import ERC20 as base_token
initializes: base_token

exports: base_token.__interface__

@deploy
def __init__():
    base_token.__init__("My Token", "TOK", 100_000_000, "My DApp", "v0.0.1")
# example2.vy

from snekmate.tokens import ERC20 as base_token

from ethereum.ercs import IERC20

implements: base_token.IERC20
initializes: base_token

exports: base_token.IERC20

@deploy
def __init__():
    base_token.__init__("My Token", "TOK", 100_000_000, "My DApp", "v0.0.1")

Commit message

this commit allows exporting of `module.<interface>`, and also adds
`module.__interface__` which gives the interface type of the module.
in particular, this makes it easier for users to export all functions
from a module, since they do not need to list out every single function
manually.

note that since `module.__interface__` is actually an interface type, it
can theoretically be used in type expressions, e.g.,
```vyper
    x: module.__interface__ = module.__interface__(msg.sender)
```

however, it doesn't work yet as some additional work is required to
properly thread the type into the type analysis system
(see related: GH #3943).

this commit includes the restriction that only `implement`ed interfaces
can be exported, this makes the most sense from a UX / user intuition
perspective.

Description for the changelog

Cute Animal Picture

Put a link to a cute animal picture inside the parenthesis-->

@codecov-commenter
Copy link

codecov-commenter commented Apr 7, 2024

Codecov Report

Attention: Patch coverage is 77.50000% with 9 lines in your changes are missing coverage. Please review.

Project coverage is 89.10%. Comparing base (cb94068) to head (8f50fcb).

Files Patch % Lines
vyper/semantics/analysis/module.py 73.52% 5 Missing and 4 partials ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3919      +/-   ##
==========================================
- Coverage   90.85%   89.10%   -1.75%     
==========================================
  Files          95       95              
  Lines       14416    14436      +20     
  Branches     3192     3201       +9     
==========================================
- Hits        13097    12863     -234     
- Misses        913     1118     +205     
- Partials      406      455      +49     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@charles-cooper charles-cooper changed the title [wip] feat: export interfaces feat[lang]: export interfaces Apr 11, 2024
@charles-cooper charles-cooper marked this pull request as ready for review April 11, 2024 16:47
Copy link
Member

@fubuloubu fubuloubu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add at least a few tests

@cyberthirst
Copy link
Collaborator

this test crashes the compiler (btw it tries to test selector clashes when exporting via interfaces, though the issue seems unrelated)

    ifoo = """
@external
def gsf():
    ...
    """
    lib1 = """
import ifoo

@external
@view
def tgeo() -> uint256:
    return 1
    """
    main = """
import lib1

exports: lib1.ifoo
    """
    input_bundle = make_input_bundle({"lib1.vy": lib1, "ifoo.vyi": ifoo})
    c = get_contract(main, input_bundle=input_bundle)
.0 = <dict_valueiterator object at 0x120977510>

    funcs = [
>       module_exposed_fns[f.name] for f in info.typ.functions.values() if f.is_external
    ]
E   vyper.exceptions.CompilerPanic: unhandled exception 'gsf'
E   
E     line 4:0 
E          3
E     ---> 4 exports: lib1.ifoo
E     -------^
E          5
E   

@charles-cooper
Copy link
Member Author

this test crashes the compiler (btw it tries to test selector clashes when exporting via interfaces, though the issue seems unrelated)

fixed in 6650768

Copy link
Collaborator

@pcaversaccio pcaversaccio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is currently an issue wrt the __init__ handling:

During handling of the above exception, another exception occurred:

vyper.exceptions.CompilerPanic: unhandled exception '__init__'

To replicate: use my TimelockControllerMock.vy and replace the exports with:

exports: tc.__interface__

Copy link
Collaborator

@pcaversaccio pcaversaccio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested on snekmate contracts and tests pass. I recommend adding an additional test for __default__ function. Otherwise, lgtm.

@pcaversaccio
Copy link
Collaborator

There is currently an issue wrt the __init__ handling:

During handling of the above exception, another exception occurred:

vyper.exceptions.CompilerPanic: unhandled exception '__init__'

To replicate: use my TimelockControllerMock.vy and replace the exports with:

exports: tc.__interface__

Fixed via 0450173.

@charles-cooper charles-cooper enabled auto-merge (squash) April 14, 2024 02:32
@charles-cooper charles-cooper enabled auto-merge (squash) April 14, 2024 02:33
@charles-cooper charles-cooper merged commit 6f09e29 into vyperlang:master Apr 14, 2024
149 checks passed
@charles-cooper charles-cooper deleted the feat/export-all branch April 14, 2024 02:50
pcaversaccio added a commit to pcaversaccio/snekmate that referenced this pull request Apr 15, 2024
…devdoc` Sanity Check (#235)

### 🕓 Changelog

This PR refactors the existing module-friendly contracts to use the new
dunder method `__interface__` (see
vyperlang/vyper#3919), which allows you to
export all functions of a module without specifying the individual
functions.

We apply the following rules:

- Library modules keep the individual list `exports` syntax due to
explicitness (application developers can thus identify faster what is
exported within a library module),
- Mocks might use it if more than one `external` function is exported.
We do not use it in mock contracts if critical code comments for
exported functions would be lost.

Furthermore, we remove the `userdoc` and `devdoc` compilation script &
CI pipeline since it's now computed as part of the standard compilation
pipeline (vyperlang/vyper#3946).

---------

Signed-off-by: Pascal Marco Caversaccio <pascal.caversaccio@hotmail.ch>
Co-authored-by: sudo rm -rf --no-preserve-root / <pcaversaccio@users.noreply.github.com>
Co-authored-by: Pascal Marco Caversaccio <pascal.caversaccio@hotmail.ch>
electriclilies pushed a commit to electriclilies/vyper that referenced this pull request Apr 27, 2024
this commit allows exporting of `module.<interface>`, and also adds
`module.__interface__` which gives the interface type of the module.
in particular, this makes it easier for users to export all functions
from a module, since they do not need to list out every single function
manually.

note that since `module.__interface__` is actually an interface type, it
can theoretically be used in type expressions, e.g.,
```vyper
    x: module.__interface__ = module.__interface__(msg.sender)
```

however, it doesn't work yet as some additional work is required to
properly thread the type into the type analysis system
(see related: GH vyperlang#3943).

this commit includes the restriction that only `implement`ed interfaces
can be exported, this makes the most sense from a UX / user intuition
perspective.

---------

Co-authored-by: cyberthirst <cyberthirst.eth@gmail.com>
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants