vyper
vyper copied to clipboard
cannot import structs
Suppose I have a simple contract that records a user input in a struct.
# @version ^0.3.0
struct A_Struct:
a: uint256
b: uint256
struct_map: public(HashMap[uint256, A_Struct])
struct_idx: uint256
@external
def __init__():
pass
@external
def add_struct(_a: uint256, _b: uint256):
struct_inst: A_Struct = A_Struct({a: _a, b:_b})
self.struct_map[self.struct_idx] = struct_inst
self.struct_idx += 1
Now if I export the interface for this contract such that another contract can use it
vyper -f interface contracts/MyContract.vy
# Functions
@external
def add_struct(_a: uint256, _b: uint256):
pass
@view
@external
def struct_map(arg0: uint256) -> A_Struct:
pass
If I save this output into an interface file called MyInterface.vy
and then write a second contract
# @version ^0.3.0
import interfaces.MyInterface as MC
my_contract: MC
@external
def __init__(mc_address: address):
self.my_contract = MC(mc_address)
@external
def other_add_struct(_a: uint256, _b: uint256):
self.my_contract.add_struct(_a, _b)
Then when I try and compile this I get an error
Unhandled exception in 'contracts/MyOtherContract.vy':
UnknownType: Compilation failed with the following errors:
UnknownType: No builtin or user-defined type named 'A_Struct'
contract "MC", function "struct_map", line 9:33
8 @external
---> 9 def struct_map(arg0: uint256) -> A_Struct:
----------------------------------------^
10 pass
This error can be removed if I delete A_Struct
as the return type for struct_map
in MyInterface.vy
. Is this expected behaviour or am I misunderstanding something around structs and interfaces?
@mhorsley30896 struct definitions aren't exported from interface definitions. right now the thing to do is redefine struct A_Struct
again from MyOtherContract.vy
-
import interfaces.MyInterface as MC
# ...
struct A_Struct:
a: uint256
b: uint256
# ...
my_contract: MC
I'm leaving this issue open though so we can track a discussion about changing the semantics here.
@charles-cooper you also have to define A_Struct
in the interface as well? It does seem like overkill (and a little unpythonic) to have to keep copying and pasting struct
definitions into arbitrary numbers of files
@charles-cooper you also have to define
A_Struct
in the interface as well? It does seem like overkill (and a little unpythonic) to have to keep copying and pastingstruct
definitions into arbitrary numbers of files
yep you need to define in both places -- and I agree about the overkill part
A side note: ABI encoding defines structs as tuples of their members (although there is some undefined behavior with tight packing), so one way to handle this might to implicitly convert structs to and from tuples, so that the interfaces matched up
meeting notes: we should allow this, A_Struct
would probably be referenced like MC.A_Struct
+1 for ability to import structs -- would be very helpful!
implemented in https://github.com/vyperlang/vyper/pull/3663