We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Private functions can't have duplicate function selectors
This is an unnecessary constraint. Label names can be made unique.

```python
@private
@constant
def gfah(): pass

@private
@constant
def eexo(): pass

# error: Label with name priv_236395036 already exists!
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `vyper/signatures/interface.py`
Content:
```
1 import copy
2 import importlib
3 from pathlib import (
4     Path,
5 )
6 import pkgutil
7 from typing import (
8     Sequence,
9     Tuple,
10 )
11 
12 from vyper import ast
13 from vyper.exceptions import (
14     ParserException,
15     StructureException,
16 )
17 import vyper.interfaces
18 from vyper.parser import (
19     parser,
20 )
21 from vyper.parser.constants import (
22     Constants,
23 )
24 from vyper.signatures import (
25     sig_utils,
26 )
27 from vyper.signatures.event_signature import (
28     EventSignature,
29 )
30 from vyper.signatures.function_signature import (
31     FunctionSignature,
32 )
33 from vyper.typing import (
34     InterfaceImports,
35     SourceCode,
36 )
37 
38 
39 # Populate built-in interfaces.
40 def get_builtin_interfaces():
41     interface_names = [x.name for x in pkgutil.iter_modules(vyper.interfaces.__path__)]
42     return {
43         name: extract_sigs({
44             'type': 'vyper',
45             'code': importlib.import_module(
46                 f'vyper.interfaces.{name}',
47             ).interface_code,
48         })
49         for name in interface_names
50     }
51 
52 
53 def render_return(sig):
54     if sig.output_type:
55         return " -> " + str(sig.output_type)
56     return ""
57 
58 
59 def abi_type_to_ast(atype):
60     if atype in ('int128', 'uint256', 'bool', 'address', 'bytes32'):
61         return ast.Name(id=atype)
62     elif atype == 'decimal':
63         return ast.Name(id='int128')
64     elif atype == 'bytes':
65         return ast.Subscript(
66             value=ast.Name(id='bytes'),
67             slice=ast.Index(256)
68         )
69     elif atype == 'string':
70         return ast.Subscript(
71             value=ast.Name(id='string'),
72             slice=ast.Index(256)
73         )
74     else:
75         raise ParserException(f'Type {atype} not supported by vyper.')
76 
77 
78 def mk_full_signature_from_json(abi):
79     funcs = [func for func in abi if func['type'] == 'function']
80     sigs = []
81 
82     for func in funcs:
83         args = []
84         returns = None
85         for a in func['inputs']:
86             arg = ast.arg(
87                 arg=a['name'],
88                 annotation=abi_type_to_ast(a['type']),
89                 lineno=0,
90                 col_offset=0
91             )
92             args.append(arg)
93 
94         if len(func['outputs']) == 1:
95             returns = abi_type_to_ast(func['outputs'][0]['type'])
96         elif len(func['outputs']) > 1:
97             returns = ast.Tuple(
98                 elts=[
99                     abi_type_to_ast(a['type'])
100                     for a in func['outputs']
101                 ]
102             )
103 
104         decorator_list = [ast.Name(id='public')]
105         if func['constant']:
106             decorator_list.append(ast.Name(id='constant'))
107         if func['payable']:
108             decorator_list.append(ast.Name(id='payable'))
109 
110         sig = FunctionSignature.from_definition(
111             code=ast.FunctionDef(
112                 name=func['name'],
113                 args=ast.arguments(args=args),
114                 decorator_list=decorator_list,
115                 returns=returns,
116             ),
117             custom_units=set(),
118             custom_structs=dict(),
119             constants=Constants()
120         )
121         sigs.append(sig)
122     return sigs
123 
124 
125 def extract_sigs(sig_code):
126     if sig_code['type'] == 'vyper':
127         interface_ast = [
128             i for i in parser.parse_to_ast(sig_code['code']) if
129             isinstance(i, ast.FunctionDef) or
130             (isinstance(i, ast.AnnAssign) and i.target.id != "implements")
131         ]
132         return sig_utils.mk_full_signature(interface_ast, sig_formatter=lambda x, y: x)
133     elif sig_code['type'] == 'json':
134         return mk_full_signature_from_json(sig_code['code'])
135     else:
136         raise Exception(
137             (f"Unknown interface signature type '{sig_code['type']}' supplied. "
138              "'vyper' & 'json' are supported")
139         )
140 
141 
142 def extract_interface_str(code, contract_name, interface_codes=None):
143     sigs = sig_utils.mk_full_signature(
144         parser.parse_to_ast(code),
145         sig_formatter=lambda x, y: (x, y),
146         interface_codes=interface_codes,
147     )
148     events = [sig for sig, _ in sigs if isinstance(sig, EventSignature)]
149     functions = [sig for sig, _ in sigs if isinstance(sig, FunctionSignature)]
150     out = ""
151     # Print events.
152     for idx, event in enumerate(events):
153         if idx == 0:
154             out += "# Events\n\n"
155         event_args_str = ', '.join([arg.name + ': ' + str(arg.typ) for arg in event.args])
156         out += f"{event.name}: event({{{event_args_str}}})\n"
157 
158     # Print functions.
159     def render_decorator(sig):
160         o = "\n"
161         if sig.const:
162             o += "@constant\n"
163         if not sig.private:
164             o += "@public\n"
165         return o
166 
167     for idx, func in enumerate(functions):
168         if idx == 0:
169             out += "\n# Functions\n"
170         if not func.private and func.name != '__init__':
171             args = ", ".join([arg.name + ": " + str(arg.typ) for arg in func.args])
172             out += f"{render_decorator(func)}def {func.name}({args}){render_return(func)}:\n    pass\n"  # noqa: E501
173     out += "\n"
174 
175     return out
176 
177 
178 def extract_external_interface(code, contract_name, interface_codes=None):
179     sigs = sig_utils.mk_full_signature(
180         parser.parse_to_ast(code),
181         sig_formatter=lambda x, y: (x, y),
182         interface_codes=interface_codes,
183     )
184     functions = [sig for sig, _ in sigs if isinstance(sig, FunctionSignature)]
185     cname = Path(contract_name).stem.capitalize()
186 
187     out = ""
188     offset = 4 * " "
189     for idx, func in enumerate(functions):
190         if idx == 0:
191             out += f"\n# External Contracts\ncontract {cname}:\n"
192         if not func.private and func.name != '__init__':
193             args = ", ".join([arg.name + ": " + str(arg.typ) for arg in func.args])
194             func_type = "constant" if func.const else "modifying"
195             out += offset + f"def {func.name}({args}){render_return(func)}: {func_type}\n"
196     out += "\n"
197     return out
198 
199 
200 def extract_file_interface_imports(code: SourceCode) -> InterfaceImports:
201     ast_tree = parser.parse_to_ast(code)
202 
203     imports_dict: InterfaceImports = {}
204     for item in ast_tree:
205         if isinstance(item, ast.Import):
206             for a_name in item.names:  # type: ignore
207                 if not a_name.asname:
208                     raise StructureException(
209                         'Interface statement requires an accompanying `as` statement.',
210                         item,
211                     )
212                 if a_name.asname in imports_dict:
213                     raise StructureException(
214                         f'Interface with alias {a_name.asname} already exists',
215                         item,
216                     )
217                 imports_dict[a_name.asname] = a_name.name.replace('.', '/')
218         elif isinstance(item, ast.ImportFrom):
219             for a_name in item.names:  # type: ignore
220                 if a_name.asname:
221                     raise StructureException("From imports cannot use aliases", item)
222             level = item.level  # type: ignore
223             module = item.module or ""  # type: ignore
224             if not level and module == 'vyper.interfaces':
225                 continue
226 
227             base_path = ""
228             if level > 1:
229                 base_path = "../" * (level-1)
230             elif level == 1:
231                 base_path = "./"
232             base_path = f"{base_path}{module.replace('.','/')}/"
233 
234             for a_name in item.names:  # type: ignore
235                 if a_name.name in imports_dict:
236                     raise StructureException(
237                         f'Interface with name {a_name.name} already exists',
238                         item,
239                     )
240                 imports_dict[a_name.name] = f"{base_path}{a_name.name}"
241 
242     return imports_dict
243 
244 
245 Conflict = Tuple[FunctionSignature, FunctionSignature]
246 Conflicts = Tuple[Conflict, ...]
247 
248 
249 def find_signature_conflicts(sigs: Sequence[FunctionSignature]) -> Conflicts:
250     """
251     Takes a sequence of function signature records and returns a tuple of
252     pairs of signatures from that sequence that produce the same internal
253     method id.
254     """
255     # Consider self-comparisons as having been seen by default (they will be
256     # skipped)
257     comparisons_seen = set([frozenset((sig.sig,)) for sig in sigs])
258     conflicts = []
259 
260     for sig in sigs:
261         method_id = sig.method_id
262 
263         for other_sig in sigs:
264             comparison_id = frozenset((sig.sig, other_sig.sig))
265             if comparison_id in comparisons_seen:
266                 continue  # Don't make redundant or useless comparisons
267 
268             other_method_id = other_sig.method_id
269             if method_id == other_method_id:
270                 conflicts.append((sig, other_sig))
271 
272             comparisons_seen.add(comparison_id)
273 
274     return tuple(conflicts)
275 
276 
277 def check_valid_contract_interface(global_ctx, contract_sigs):
278     public_func_sigs = [
279         sig for sig in contract_sigs.values()
280         if isinstance(sig, FunctionSignature) and not sig.private
281     ]
282     func_conflicts = find_signature_conflicts(public_func_sigs)
283 
284     if len(func_conflicts) > 0:
285         sig_1, sig_2 = func_conflicts[0]
286 
287         raise StructureException(
288             f'Methods {sig_1.sig} and {sig_2.sig} have conflicting IDs '
289             f'(id {sig_1.method_id})',
290             sig_1.func_ast_code,
291         )
292 
293     if global_ctx._interface:
294         funcs_left = global_ctx._interface.copy()
295 
296         for sig, func_sig in contract_sigs.items():
297             if isinstance(func_sig, FunctionSignature):
298                 # Remove units, as inteface signatures should not enforce units.
299                 clean_sig_output_type = func_sig.output_type
300                 if func_sig.output_type:
301                     clean_sig_output_type = copy.deepcopy(func_sig.output_type)
302                     clean_sig_output_type.unit = {}
303                 if (
304                     sig in funcs_left and  # noqa: W504
305                     not func_sig.private and  # noqa: W504
306                     funcs_left[sig].output_type == clean_sig_output_type
307                 ):
308                     del funcs_left[sig]
309             if isinstance(func_sig, EventSignature) and func_sig.sig in funcs_left:
310                 del funcs_left[func_sig.sig]
311 
312         if funcs_left:
313             error_message = 'Contract does not comply to supplied Interface(s).\n'
314             missing_functions = [
315                 str(func_sig)
316                 for sig_name, func_sig
317                 in funcs_left.items()
318                 if isinstance(func_sig, FunctionSignature)
319             ]
320             missing_events = [
321                 sig_name
322                 for sig_name, func_sig
323                 in funcs_left.items()
324                 if isinstance(func_sig, EventSignature)
325             ]
326             if missing_functions:
327                 err_join = "\n\t".join(missing_functions)
328                 error_message += f'Missing interface functions:\n\t{err_join}'
329             if missing_events:
330                 err_join = "\n\t".join(missing_events)
331                 error_message += f'Missing interface events:\n\t{err_join}'
332             raise StructureException(error_message)
333
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/vyper/signatures/interface.py b/vyper/signatures/interface.py
--- a/vyper/signatures/interface.py
+++ b/vyper/signatures/interface.py
@@ -275,11 +275,10 @@
 
 
 def check_valid_contract_interface(global_ctx, contract_sigs):
-    public_func_sigs = [
-        sig for sig in contract_sigs.values()
-        if isinstance(sig, FunctionSignature) and not sig.private
-    ]
-    func_conflicts = find_signature_conflicts(public_func_sigs)
+    # the check for private function collisions is made to prevent future
+    # breaking changes if we switch to internal calls (@iamdefinitelyahuman)
+    func_sigs = [sig for sig in contract_sigs.values() if isinstance(sig, FunctionSignature)]
+    func_conflicts = find_signature_conflicts(func_sigs)
 
     if len(func_conflicts) > 0:
         sig_1, sig_2 = func_conflicts[0]

{"golden_diff": "diff --git a/vyper/signatures/interface.py b/vyper/signatures/interface.py\n--- a/vyper/signatures/interface.py\n+++ b/vyper/signatures/interface.py\n@@ -275,11 +275,10 @@\n \n \n def check_valid_contract_interface(global_ctx, contract_sigs):\n-    public_func_sigs = [\n-        sig for sig in contract_sigs.values()\n-        if isinstance(sig, FunctionSignature) and not sig.private\n-    ]\n-    func_conflicts = find_signature_conflicts(public_func_sigs)\n+    # the check for private function collisions is made to prevent future\n+    # breaking changes if we switch to internal calls (@iamdefinitelyahuman)\n+    func_sigs = [sig for sig in contract_sigs.values() if isinstance(sig, FunctionSignature)]\n+    func_conflicts = find_signature_conflicts(func_sigs)\n \n     if len(func_conflicts) > 0:\n         sig_1, sig_2 = func_conflicts[0]\n", "issue": "Private functions can't have duplicate function selectors\nThis is an unnecessary constraint. Label names can be made unique.\r\n\r\n```python\r\n@private\r\n@constant\r\ndef gfah(): pass\r\n\r\n@private\r\n@constant\r\ndef eexo(): pass\r\n\r\n# error: Label with name priv_236395036 already exists!\r\n```\n", "before_files": [{"content": "import copy\nimport importlib\nfrom pathlib import (\n    Path,\n)\nimport pkgutil\nfrom typing import (\n    Sequence,\n    Tuple,\n)\n\nfrom vyper import ast\nfrom vyper.exceptions import (\n    ParserException,\n    StructureException,\n)\nimport vyper.interfaces\nfrom vyper.parser import (\n    parser,\n)\nfrom vyper.parser.constants import (\n    Constants,\n)\nfrom vyper.signatures import (\n    sig_utils,\n)\nfrom vyper.signatures.event_signature import (\n    EventSignature,\n)\nfrom vyper.signatures.function_signature import (\n    FunctionSignature,\n)\nfrom vyper.typing import (\n    InterfaceImports,\n    SourceCode,\n)\n\n\n# Populate built-in interfaces.\ndef get_builtin_interfaces():\n    interface_names = [x.name for x in pkgutil.iter_modules(vyper.interfaces.__path__)]\n    return {\n        name: extract_sigs({\n            'type': 'vyper',\n            'code': importlib.import_module(\n                f'vyper.interfaces.{name}',\n            ).interface_code,\n        })\n        for name in interface_names\n    }\n\n\ndef render_return(sig):\n    if sig.output_type:\n        return \" -> \" + str(sig.output_type)\n    return \"\"\n\n\ndef abi_type_to_ast(atype):\n    if atype in ('int128', 'uint256', 'bool', 'address', 'bytes32'):\n        return ast.Name(id=atype)\n    elif atype == 'decimal':\n        return ast.Name(id='int128')\n    elif atype == 'bytes':\n        return ast.Subscript(\n            value=ast.Name(id='bytes'),\n            slice=ast.Index(256)\n        )\n    elif atype == 'string':\n        return ast.Subscript(\n            value=ast.Name(id='string'),\n            slice=ast.Index(256)\n        )\n    else:\n        raise ParserException(f'Type {atype} not supported by vyper.')\n\n\ndef mk_full_signature_from_json(abi):\n    funcs = [func for func in abi if func['type'] == 'function']\n    sigs = []\n\n    for func in funcs:\n        args = []\n        returns = None\n        for a in func['inputs']:\n            arg = ast.arg(\n                arg=a['name'],\n                annotation=abi_type_to_ast(a['type']),\n                lineno=0,\n                col_offset=0\n            )\n            args.append(arg)\n\n        if len(func['outputs']) == 1:\n            returns = abi_type_to_ast(func['outputs'][0]['type'])\n        elif len(func['outputs']) > 1:\n            returns = ast.Tuple(\n                elts=[\n                    abi_type_to_ast(a['type'])\n                    for a in func['outputs']\n                ]\n            )\n\n        decorator_list = [ast.Name(id='public')]\n        if func['constant']:\n            decorator_list.append(ast.Name(id='constant'))\n        if func['payable']:\n            decorator_list.append(ast.Name(id='payable'))\n\n        sig = FunctionSignature.from_definition(\n            code=ast.FunctionDef(\n                name=func['name'],\n                args=ast.arguments(args=args),\n                decorator_list=decorator_list,\n                returns=returns,\n            ),\n            custom_units=set(),\n            custom_structs=dict(),\n            constants=Constants()\n        )\n        sigs.append(sig)\n    return sigs\n\n\ndef extract_sigs(sig_code):\n    if sig_code['type'] == 'vyper':\n        interface_ast = [\n            i for i in parser.parse_to_ast(sig_code['code']) if\n            isinstance(i, ast.FunctionDef) or\n            (isinstance(i, ast.AnnAssign) and i.target.id != \"implements\")\n        ]\n        return sig_utils.mk_full_signature(interface_ast, sig_formatter=lambda x, y: x)\n    elif sig_code['type'] == 'json':\n        return mk_full_signature_from_json(sig_code['code'])\n    else:\n        raise Exception(\n            (f\"Unknown interface signature type '{sig_code['type']}' supplied. \"\n             \"'vyper' & 'json' are supported\")\n        )\n\n\ndef extract_interface_str(code, contract_name, interface_codes=None):\n    sigs = sig_utils.mk_full_signature(\n        parser.parse_to_ast(code),\n        sig_formatter=lambda x, y: (x, y),\n        interface_codes=interface_codes,\n    )\n    events = [sig for sig, _ in sigs if isinstance(sig, EventSignature)]\n    functions = [sig for sig, _ in sigs if isinstance(sig, FunctionSignature)]\n    out = \"\"\n    # Print events.\n    for idx, event in enumerate(events):\n        if idx == 0:\n            out += \"# Events\\n\\n\"\n        event_args_str = ', '.join([arg.name + ': ' + str(arg.typ) for arg in event.args])\n        out += f\"{event.name}: event({{{event_args_str}}})\\n\"\n\n    # Print functions.\n    def render_decorator(sig):\n        o = \"\\n\"\n        if sig.const:\n            o += \"@constant\\n\"\n        if not sig.private:\n            o += \"@public\\n\"\n        return o\n\n    for idx, func in enumerate(functions):\n        if idx == 0:\n            out += \"\\n# Functions\\n\"\n        if not func.private and func.name != '__init__':\n            args = \", \".join([arg.name + \": \" + str(arg.typ) for arg in func.args])\n            out += f\"{render_decorator(func)}def {func.name}({args}){render_return(func)}:\\n    pass\\n\"  # noqa: E501\n    out += \"\\n\"\n\n    return out\n\n\ndef extract_external_interface(code, contract_name, interface_codes=None):\n    sigs = sig_utils.mk_full_signature(\n        parser.parse_to_ast(code),\n        sig_formatter=lambda x, y: (x, y),\n        interface_codes=interface_codes,\n    )\n    functions = [sig for sig, _ in sigs if isinstance(sig, FunctionSignature)]\n    cname = Path(contract_name).stem.capitalize()\n\n    out = \"\"\n    offset = 4 * \" \"\n    for idx, func in enumerate(functions):\n        if idx == 0:\n            out += f\"\\n# External Contracts\\ncontract {cname}:\\n\"\n        if not func.private and func.name != '__init__':\n            args = \", \".join([arg.name + \": \" + str(arg.typ) for arg in func.args])\n            func_type = \"constant\" if func.const else \"modifying\"\n            out += offset + f\"def {func.name}({args}){render_return(func)}: {func_type}\\n\"\n    out += \"\\n\"\n    return out\n\n\ndef extract_file_interface_imports(code: SourceCode) -> InterfaceImports:\n    ast_tree = parser.parse_to_ast(code)\n\n    imports_dict: InterfaceImports = {}\n    for item in ast_tree:\n        if isinstance(item, ast.Import):\n            for a_name in item.names:  # type: ignore\n                if not a_name.asname:\n                    raise StructureException(\n                        'Interface statement requires an accompanying `as` statement.',\n                        item,\n                    )\n                if a_name.asname in imports_dict:\n                    raise StructureException(\n                        f'Interface with alias {a_name.asname} already exists',\n                        item,\n                    )\n                imports_dict[a_name.asname] = a_name.name.replace('.', '/')\n        elif isinstance(item, ast.ImportFrom):\n            for a_name in item.names:  # type: ignore\n                if a_name.asname:\n                    raise StructureException(\"From imports cannot use aliases\", item)\n            level = item.level  # type: ignore\n            module = item.module or \"\"  # type: ignore\n            if not level and module == 'vyper.interfaces':\n                continue\n\n            base_path = \"\"\n            if level > 1:\n                base_path = \"../\" * (level-1)\n            elif level == 1:\n                base_path = \"./\"\n            base_path = f\"{base_path}{module.replace('.','/')}/\"\n\n            for a_name in item.names:  # type: ignore\n                if a_name.name in imports_dict:\n                    raise StructureException(\n                        f'Interface with name {a_name.name} already exists',\n                        item,\n                    )\n                imports_dict[a_name.name] = f\"{base_path}{a_name.name}\"\n\n    return imports_dict\n\n\nConflict = Tuple[FunctionSignature, FunctionSignature]\nConflicts = Tuple[Conflict, ...]\n\n\ndef find_signature_conflicts(sigs: Sequence[FunctionSignature]) -> Conflicts:\n    \"\"\"\n    Takes a sequence of function signature records and returns a tuple of\n    pairs of signatures from that sequence that produce the same internal\n    method id.\n    \"\"\"\n    # Consider self-comparisons as having been seen by default (they will be\n    # skipped)\n    comparisons_seen = set([frozenset((sig.sig,)) for sig in sigs])\n    conflicts = []\n\n    for sig in sigs:\n        method_id = sig.method_id\n\n        for other_sig in sigs:\n            comparison_id = frozenset((sig.sig, other_sig.sig))\n            if comparison_id in comparisons_seen:\n                continue  # Don't make redundant or useless comparisons\n\n            other_method_id = other_sig.method_id\n            if method_id == other_method_id:\n                conflicts.append((sig, other_sig))\n\n            comparisons_seen.add(comparison_id)\n\n    return tuple(conflicts)\n\n\ndef check_valid_contract_interface(global_ctx, contract_sigs):\n    public_func_sigs = [\n        sig for sig in contract_sigs.values()\n        if isinstance(sig, FunctionSignature) and not sig.private\n    ]\n    func_conflicts = find_signature_conflicts(public_func_sigs)\n\n    if len(func_conflicts) > 0:\n        sig_1, sig_2 = func_conflicts[0]\n\n        raise StructureException(\n            f'Methods {sig_1.sig} and {sig_2.sig} have conflicting IDs '\n            f'(id {sig_1.method_id})',\n            sig_1.func_ast_code,\n        )\n\n    if global_ctx._interface:\n        funcs_left = global_ctx._interface.copy()\n\n        for sig, func_sig in contract_sigs.items():\n            if isinstance(func_sig, FunctionSignature):\n                # Remove units, as inteface signatures should not enforce units.\n                clean_sig_output_type = func_sig.output_type\n                if func_sig.output_type:\n                    clean_sig_output_type = copy.deepcopy(func_sig.output_type)\n                    clean_sig_output_type.unit = {}\n                if (\n                    sig in funcs_left and  # noqa: W504\n                    not func_sig.private and  # noqa: W504\n                    funcs_left[sig].output_type == clean_sig_output_type\n                ):\n                    del funcs_left[sig]\n            if isinstance(func_sig, EventSignature) and func_sig.sig in funcs_left:\n                del funcs_left[func_sig.sig]\n\n        if funcs_left:\n            error_message = 'Contract does not comply to supplied Interface(s).\\n'\n            missing_functions = [\n                str(func_sig)\n                for sig_name, func_sig\n                in funcs_left.items()\n                if isinstance(func_sig, FunctionSignature)\n            ]\n            missing_events = [\n                sig_name\n                for sig_name, func_sig\n                in funcs_left.items()\n                if isinstance(func_sig, EventSignature)\n            ]\n            if missing_functions:\n                err_join = \"\\n\\t\".join(missing_functions)\n                error_message += f'Missing interface functions:\\n\\t{err_join}'\n            if missing_events:\n                err_join = \"\\n\\t\".join(missing_events)\n                error_message += f'Missing interface events:\\n\\t{err_join}'\n            raise StructureException(error_message)\n", "path": "vyper/signatures/interface.py"}], "after_files": [{"content": "import copy\nimport importlib\nfrom pathlib import (\n    Path,\n)\nimport pkgutil\nfrom typing import (\n    Sequence,\n    Tuple,\n)\n\nfrom vyper import ast\nfrom vyper.exceptions import (\n    ParserException,\n    StructureException,\n)\nimport vyper.interfaces\nfrom vyper.parser import (\n    parser,\n)\nfrom vyper.parser.constants import (\n    Constants,\n)\nfrom vyper.signatures import (\n    sig_utils,\n)\nfrom vyper.signatures.event_signature import (\n    EventSignature,\n)\nfrom vyper.signatures.function_signature import (\n    FunctionSignature,\n)\nfrom vyper.typing import (\n    InterfaceImports,\n    SourceCode,\n)\n\n\n# Populate built-in interfaces.\ndef get_builtin_interfaces():\n    interface_names = [x.name for x in pkgutil.iter_modules(vyper.interfaces.__path__)]\n    return {\n        name: extract_sigs({\n            'type': 'vyper',\n            'code': importlib.import_module(\n                f'vyper.interfaces.{name}',\n            ).interface_code,\n        })\n        for name in interface_names\n    }\n\n\ndef render_return(sig):\n    if sig.output_type:\n        return \" -> \" + str(sig.output_type)\n    return \"\"\n\n\ndef abi_type_to_ast(atype):\n    if atype in ('int128', 'uint256', 'bool', 'address', 'bytes32'):\n        return ast.Name(id=atype)\n    elif atype == 'decimal':\n        return ast.Name(id='int128')\n    elif atype == 'bytes':\n        return ast.Subscript(\n            value=ast.Name(id='bytes'),\n            slice=ast.Index(256)\n        )\n    elif atype == 'string':\n        return ast.Subscript(\n            value=ast.Name(id='string'),\n            slice=ast.Index(256)\n        )\n    else:\n        raise ParserException(f'Type {atype} not supported by vyper.')\n\n\ndef mk_full_signature_from_json(abi):\n    funcs = [func for func in abi if func['type'] == 'function']\n    sigs = []\n\n    for func in funcs:\n        args = []\n        returns = None\n        for a in func['inputs']:\n            arg = ast.arg(\n                arg=a['name'],\n                annotation=abi_type_to_ast(a['type']),\n                lineno=0,\n                col_offset=0\n            )\n            args.append(arg)\n\n        if len(func['outputs']) == 1:\n            returns = abi_type_to_ast(func['outputs'][0]['type'])\n        elif len(func['outputs']) > 1:\n            returns = ast.Tuple(\n                elts=[\n                    abi_type_to_ast(a['type'])\n                    for a in func['outputs']\n                ]\n            )\n\n        decorator_list = [ast.Name(id='public')]\n        if func['constant']:\n            decorator_list.append(ast.Name(id='constant'))\n        if func['payable']:\n            decorator_list.append(ast.Name(id='payable'))\n\n        sig = FunctionSignature.from_definition(\n            code=ast.FunctionDef(\n                name=func['name'],\n                args=ast.arguments(args=args),\n                decorator_list=decorator_list,\n                returns=returns,\n            ),\n            custom_units=set(),\n            custom_structs=dict(),\n            constants=Constants()\n        )\n        sigs.append(sig)\n    return sigs\n\n\ndef extract_sigs(sig_code):\n    if sig_code['type'] == 'vyper':\n        interface_ast = [\n            i for i in parser.parse_to_ast(sig_code['code']) if\n            isinstance(i, ast.FunctionDef) or\n            (isinstance(i, ast.AnnAssign) and i.target.id != \"implements\")\n        ]\n        return sig_utils.mk_full_signature(interface_ast, sig_formatter=lambda x, y: x)\n    elif sig_code['type'] == 'json':\n        return mk_full_signature_from_json(sig_code['code'])\n    else:\n        raise Exception(\n            (f\"Unknown interface signature type '{sig_code['type']}' supplied. \"\n             \"'vyper' & 'json' are supported\")\n        )\n\n\ndef extract_interface_str(code, contract_name, interface_codes=None):\n    sigs = sig_utils.mk_full_signature(\n        parser.parse_to_ast(code),\n        sig_formatter=lambda x, y: (x, y),\n        interface_codes=interface_codes,\n    )\n    events = [sig for sig, _ in sigs if isinstance(sig, EventSignature)]\n    functions = [sig for sig, _ in sigs if isinstance(sig, FunctionSignature)]\n    out = \"\"\n    # Print events.\n    for idx, event in enumerate(events):\n        if idx == 0:\n            out += \"# Events\\n\\n\"\n        event_args_str = ', '.join([arg.name + ': ' + str(arg.typ) for arg in event.args])\n        out += f\"{event.name}: event({{{event_args_str}}})\\n\"\n\n    # Print functions.\n    def render_decorator(sig):\n        o = \"\\n\"\n        if sig.const:\n            o += \"@constant\\n\"\n        if not sig.private:\n            o += \"@public\\n\"\n        return o\n\n    for idx, func in enumerate(functions):\n        if idx == 0:\n            out += \"\\n# Functions\\n\"\n        if not func.private and func.name != '__init__':\n            args = \", \".join([arg.name + \": \" + str(arg.typ) for arg in func.args])\n            out += f\"{render_decorator(func)}def {func.name}({args}){render_return(func)}:\\n    pass\\n\"  # noqa: E501\n    out += \"\\n\"\n\n    return out\n\n\ndef extract_external_interface(code, contract_name, interface_codes=None):\n    sigs = sig_utils.mk_full_signature(\n        parser.parse_to_ast(code),\n        sig_formatter=lambda x, y: (x, y),\n        interface_codes=interface_codes,\n    )\n    functions = [sig for sig, _ in sigs if isinstance(sig, FunctionSignature)]\n    cname = Path(contract_name).stem.capitalize()\n\n    out = \"\"\n    offset = 4 * \" \"\n    for idx, func in enumerate(functions):\n        if idx == 0:\n            out += f\"\\n# External Contracts\\ncontract {cname}:\\n\"\n        if not func.private and func.name != '__init__':\n            args = \", \".join([arg.name + \": \" + str(arg.typ) for arg in func.args])\n            func_type = \"constant\" if func.const else \"modifying\"\n            out += offset + f\"def {func.name}({args}){render_return(func)}: {func_type}\\n\"\n    out += \"\\n\"\n    return out\n\n\ndef extract_file_interface_imports(code: SourceCode) -> InterfaceImports:\n    ast_tree = parser.parse_to_ast(code)\n\n    imports_dict: InterfaceImports = {}\n    for item in ast_tree:\n        if isinstance(item, ast.Import):\n            for a_name in item.names:  # type: ignore\n                if not a_name.asname:\n                    raise StructureException(\n                        'Interface statement requires an accompanying `as` statement.',\n                        item,\n                    )\n                if a_name.asname in imports_dict:\n                    raise StructureException(\n                        f'Interface with alias {a_name.asname} already exists',\n                        item,\n                    )\n                imports_dict[a_name.asname] = a_name.name.replace('.', '/')\n        elif isinstance(item, ast.ImportFrom):\n            for a_name in item.names:  # type: ignore\n                if a_name.asname:\n                    raise StructureException(\"From imports cannot use aliases\", item)\n            level = item.level  # type: ignore\n            module = item.module or \"\"  # type: ignore\n            if not level and module == 'vyper.interfaces':\n                continue\n\n            base_path = \"\"\n            if level > 1:\n                base_path = \"../\" * (level-1)\n            elif level == 1:\n                base_path = \"./\"\n            base_path = f\"{base_path}{module.replace('.','/')}/\"\n\n            for a_name in item.names:  # type: ignore\n                if a_name.name in imports_dict:\n                    raise StructureException(\n                        f'Interface with name {a_name.name} already exists',\n                        item,\n                    )\n                imports_dict[a_name.name] = f\"{base_path}{a_name.name}\"\n\n    return imports_dict\n\n\nConflict = Tuple[FunctionSignature, FunctionSignature]\nConflicts = Tuple[Conflict, ...]\n\n\ndef find_signature_conflicts(sigs: Sequence[FunctionSignature]) -> Conflicts:\n    \"\"\"\n    Takes a sequence of function signature records and returns a tuple of\n    pairs of signatures from that sequence that produce the same internal\n    method id.\n    \"\"\"\n    # Consider self-comparisons as having been seen by default (they will be\n    # skipped)\n    comparisons_seen = set([frozenset((sig.sig,)) for sig in sigs])\n    conflicts = []\n\n    for sig in sigs:\n        method_id = sig.method_id\n\n        for other_sig in sigs:\n            comparison_id = frozenset((sig.sig, other_sig.sig))\n            if comparison_id in comparisons_seen:\n                continue  # Don't make redundant or useless comparisons\n\n            other_method_id = other_sig.method_id\n            if method_id == other_method_id:\n                conflicts.append((sig, other_sig))\n\n            comparisons_seen.add(comparison_id)\n\n    return tuple(conflicts)\n\n\ndef check_valid_contract_interface(global_ctx, contract_sigs):\n    # the check for private function collisions is made to prevent future\n    # breaking changes if we switch to internal calls (@iamdefinitelyahuman)\n    func_sigs = [sig for sig in contract_sigs.values() if isinstance(sig, FunctionSignature)]\n    func_conflicts = find_signature_conflicts(func_sigs)\n\n    if len(func_conflicts) > 0:\n        sig_1, sig_2 = func_conflicts[0]\n\n        raise StructureException(\n            f'Methods {sig_1.sig} and {sig_2.sig} have conflicting IDs '\n            f'(id {sig_1.method_id})',\n            sig_1.func_ast_code,\n        )\n\n    if global_ctx._interface:\n        funcs_left = global_ctx._interface.copy()\n\n        for sig, func_sig in contract_sigs.items():\n            if isinstance(func_sig, FunctionSignature):\n                # Remove units, as inteface signatures should not enforce units.\n                clean_sig_output_type = func_sig.output_type\n                if func_sig.output_type:\n                    clean_sig_output_type = copy.deepcopy(func_sig.output_type)\n                    clean_sig_output_type.unit = {}\n                if (\n                    sig in funcs_left and  # noqa: W504\n                    not func_sig.private and  # noqa: W504\n                    funcs_left[sig].output_type == clean_sig_output_type\n                ):\n                    del funcs_left[sig]\n            if isinstance(func_sig, EventSignature) and func_sig.sig in funcs_left:\n                del funcs_left[func_sig.sig]\n\n        if funcs_left:\n            error_message = 'Contract does not comply to supplied Interface(s).\\n'\n            missing_functions = [\n                str(func_sig)\n                for sig_name, func_sig\n                in funcs_left.items()\n                if isinstance(func_sig, FunctionSignature)\n            ]\n            missing_events = [\n                sig_name\n                for sig_name, func_sig\n                in funcs_left.items()\n                if isinstance(func_sig, EventSignature)\n            ]\n            if missing_functions:\n                err_join = \"\\n\\t\".join(missing_functions)\n                error_message += f'Missing interface functions:\\n\\t{err_join}'\n            if missing_events:\n                err_join = \"\\n\\t\".join(missing_events)\n                error_message += f'Missing interface events:\\n\\t{err_join}'\n            raise StructureException(error_message)\n", "path": "vyper/signatures/interface.py"}]}