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[tool]: add -Werror and -Wnone options #4447

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/unit/compiler/test_compile_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def a() -> bool:
q: Bytes[24577] = {huge_bytestring}
return True
"""
with pytest.warns(vyper.warnings.ContractSizeLimitWarning):
with pytest.warns(vyper.warnings.ContractSizeLimit):
vyper.compile_code(code, output_formats=["bytecode_runtime"])


Expand Down
11 changes: 3 additions & 8 deletions vyper/ast/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import operator
import pickle
import sys
import warnings
from typing import Any, Optional, Union

from vyper.ast.metadata import NodeMetadata
Expand All @@ -23,7 +22,6 @@
TypeMismatch,
UnfoldableNode,
VariableDeclarationException,
VyperException,
ZeroDivisionException,
)
from vyper.utils import (
Expand All @@ -34,6 +32,7 @@
quantize,
sha256sum,
)
from vyper.warnings import EnumUsage, vyper_warn

NODE_BASE_ATTRIBUTES = (
"_children",
Expand Down Expand Up @@ -133,13 +132,9 @@

node = vy_class(parent=parent, **ast_struct)

# TODO: Putting this after node creation to pretty print, remove after enum deprecation
if enum_warn:
# TODO: hack to pretty print, logic should be factored out of exception
pretty_printed_node = str(VyperException("", node))
warnings.warn(
f"enum will be deprecated in a future release, use flag instead. {pretty_printed_node}",
stacklevel=2,
vyper_warn(

Check warning on line 136 in vyper/ast/nodes.py

View check run for this annotation

Codecov / codecov/patch

vyper/ast/nodes.py#L136

Added line #L136 was not covered by tests
EnumUsage("enum will be deprecated in a future release, use flag instead.", node)
)

node.validate()
Expand Down
11 changes: 5 additions & 6 deletions vyper/ast/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from vyper.ast.pre_parser import PreParser
from vyper.compiler.settings import Settings
from vyper.exceptions import CompilerPanic, ParserException, SyntaxException
from vyper.utils import sha256sum, vyper_warn
from vyper.utils import sha256sum
from vyper.warnings import Deprecation, vyper_warn


def parse_to_ast(*args: Any, **kwargs: Any) -> vy_ast.Module:
Expand Down Expand Up @@ -434,15 +435,15 @@
return node

def visit_Call(self, node):
self.generic_visit(node)

# Convert structs declared as `Dict` node for vyper < 0.4.0 to kwargs
if len(node.args) == 1 and isinstance(node.args[0], python_ast.Dict):
msg = "Instantiating a struct using a dictionary is deprecated "
msg += "as of v0.4.0 and will be disallowed in a future release. "
msg += "Use kwargs instead e.g. Foo(a=1, b=2)"

# add full_source_code so that str(VyperException(msg, node)) works
node.full_source_code = self._source_code
vyper_warn(msg, node)
vyper_warn(Deprecation(msg, node))

Check warning on line 446 in vyper/ast/parse.py

View check run for this annotation

Codecov / codecov/patch

vyper/ast/parse.py#L446

Added line #L446 was not covered by tests

dict_ = node.args[0]
kw_list = []
Expand All @@ -458,8 +459,6 @@
node.args = []
node.keywords = kw_list

self.generic_visit(node)

return node

def visit_Constant(self, node):
Expand Down
2 changes: 1 addition & 1 deletion vyper/builtins/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@
keccak256,
method_id,
method_id_int,
vyper_warn,
)
from vyper.warnings import vyper_warn

from ._convert import convert
from ._signatures import BuiltinFunctionT, process_inputs
Expand Down
15 changes: 15 additions & 0 deletions vyper/cli/vyper_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from vyper.compiler.input_bundle import FileInput, FilesystemInputBundle
from vyper.compiler.settings import VYPER_TRACEBACK_LIMIT, OptimizationLevel, Settings
from vyper.typing import ContractPath, OutputFormats
from vyper.warnings import VyperWarning

T = TypeVar("T")

Expand Down Expand Up @@ -187,6 +188,10 @@
)
parser.add_argument("--enable-decimals", help="Enable decimals", action="store_true")

parser.add_argument(

Check warning on line 191 in vyper/cli/vyper_compile.py

View check run for this annotation

Codecov / codecov/patch

vyper/cli/vyper_compile.py#L191

Added line #L191 was not covered by tests
"-W", help="Control warnings", dest="warnings_control", choices=["error", "none"]
)

args = parser.parse_args(argv)

if args.traceback_limit is not None:
Expand All @@ -201,6 +206,16 @@
# an error occurred in a Vyper source file.
sys.tracebacklimit = 0

if args.warnings_control == "error":
warnings_filter = "error"

Check warning on line 210 in vyper/cli/vyper_compile.py

View check run for this annotation

Codecov / codecov/patch

vyper/cli/vyper_compile.py#L210

Added line #L210 was not covered by tests
elif args.warnings_control == "none":
warnings_filter = "ignore"

Check warning on line 212 in vyper/cli/vyper_compile.py

View check run for this annotation

Codecov / codecov/patch

vyper/cli/vyper_compile.py#L212

Added line #L212 was not covered by tests
else:
assert args.warnings_control is None # sanity
warnings_filter = "default"

Check warning on line 215 in vyper/cli/vyper_compile.py

View check run for this annotation

Codecov / codecov/patch

vyper/cli/vyper_compile.py#L214-L215

Added lines #L214 - L215 were not covered by tests

warnings.simplefilter(warnings_filter, category=VyperWarning)

Check warning on line 217 in vyper/cli/vyper_compile.py

View check run for this annotation

Codecov / codecov/patch

vyper/cli/vyper_compile.py#L217

Added line #L217 was not covered by tests

if args.hex_ir:
ir_node.AS_HEX_DEFAULT = True

Expand Down
8 changes: 5 additions & 3 deletions vyper/cli/vyper_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from vyper.exceptions import JSONError
from vyper.typing import StorageLayout
from vyper.utils import OrderedSet, keccak256
from vyper.warnings import Deprecation, vyper_warn

TRANSLATE_MAP = {
"abi": "abi",
Expand Down Expand Up @@ -276,9 +277,10 @@

if isinstance(optimize, bool):
# bool optimization level for backwards compatibility
warnings.warn(
"optimize: <bool> is deprecated! please use one of 'gas', 'codesize', 'none'.",
stacklevel=2,
vyper_warn(

Check warning on line 280 in vyper/cli/vyper_json.py

View check run for this annotation

Codecov / codecov/patch

vyper/cli/vyper_json.py#L280

Added line #L280 was not covered by tests
Deprecation(
"optimize: <bool> is deprecated! please use one of 'gas', 'codesize', 'none'."
)
)
optimize = OptimizationLevel.default() if optimize else OptimizationLevel.NONE
elif isinstance(optimize, str):
Expand Down
7 changes: 4 additions & 3 deletions vyper/codegen/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@
from vyper.semantics.types.bytestrings import _BytestringT
from vyper.semantics.types.function import ContractFunctionT, MemberFunctionT
from vyper.semantics.types.shortcuts import BYTES32_T, UINT256_T
from vyper.utils import DECIMAL_DIVISOR, bytes_to_int, is_checksum_encoded, vyper_warn
from vyper.utils import DECIMAL_DIVISOR, bytes_to_int, is_checksum_encoded
from vyper.warnings import VyperWarning, vyper_warn

ENVIRONMENT_VARIABLES = {"block", "msg", "tx", "chain"}

Expand Down Expand Up @@ -274,13 +275,13 @@
if not version_check(begin="paris"):
warning = "tried to use block.prevrandao in pre-Paris "
warning += "environment! Suggest using block.difficulty instead."
vyper_warn(warning, self.expr)
vyper_warn(VyperWarning(warning, self.expr))

Check warning on line 278 in vyper/codegen/expr.py

View check run for this annotation

Codecov / codecov/patch

vyper/codegen/expr.py#L278

Added line #L278 was not covered by tests
return IRnode.from_list(["prevrandao"], typ=BYTES32_T)
elif key == "block.difficulty":
if version_check(begin="paris"):
warning = "tried to use block.difficulty in post-Paris "
warning += "environment! Suggest using block.prevrandao instead."
vyper_warn(warning, self.expr)
vyper_warn(VyperWarning(warning, self.expr))

Check warning on line 284 in vyper/codegen/expr.py

View check run for this annotation

Codecov / codecov/patch

vyper/codegen/expr.py#L284

Added line #L284 was not covered by tests
return IRnode.from_list(["difficulty"], typ=UINT256_T)
elif key == "block.timestamp":
return IRnode.from_list(["timestamp"], typ=UINT256_T)
Expand Down
17 changes: 8 additions & 9 deletions vyper/compiler/output.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import base64
import warnings
from collections import deque
from pathlib import PurePath

Expand All @@ -16,8 +15,8 @@
from vyper.semantics.types.function import ContractFunctionT, FunctionVisibility, StateMutability
from vyper.semantics.types.module import InterfaceT
from vyper.typing import StorageLayout
from vyper.utils import safe_relpath, vyper_warn
from vyper.warnings import ContractSizeLimitWarning
from vyper.utils import safe_relpath
from vyper.warnings import ContractSizeLimit, vyper_warn


def build_ast_dict(compiler_data: CompilerData) -> dict:
Expand Down Expand Up @@ -441,12 +440,12 @@
def build_bytecode_runtime_output(compiler_data: CompilerData) -> str:
compiled_bytecode_runtime_length = len(compiler_data.bytecode_runtime)
if compiled_bytecode_runtime_length > EIP170_CONTRACT_SIZE_LIMIT:
warnings.warn(
f"Length of compiled bytecode is bigger than Ethereum contract size limit "
"(see EIP-170: https://eips.ethereum.org/EIPS/eip-170): "
f"{compiled_bytecode_runtime_length}b > {EIP170_CONTRACT_SIZE_LIMIT}b",
ContractSizeLimitWarning,
stacklevel=2,
vyper_warn(

Check warning on line 443 in vyper/compiler/output.py

View check run for this annotation

Codecov / codecov/patch

vyper/compiler/output.py#L443

Added line #L443 was not covered by tests
ContractSizeLimit(
f"Length of compiled bytecode is bigger than Ethereum contract size limit "
"(see EIP-170: https://eips.ethereum.org/EIPS/eip-170): "
f"{compiled_bytecode_runtime_length}b > {EIP170_CONTRACT_SIZE_LIMIT}b"
)
)
return f"0x{compiler_data.bytecode_runtime.hex()}"

Expand Down
13 changes: 7 additions & 6 deletions vyper/compiler/phases.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import copy
import json
import warnings
from functools import cached_property
from pathlib import Path, PurePath
from typing import Any, Optional
Expand All @@ -20,8 +19,9 @@
from vyper.semantics.types.function import ContractFunctionT
from vyper.semantics.types.module import ModuleT
from vyper.typing import StorageLayout
from vyper.utils import ERC5202_PREFIX, sha256sum, vyper_warn
from vyper.utils import ERC5202_PREFIX, sha256sum
from vyper.venom import generate_assembly_experimental, generate_ir
from vyper.warnings import VyperWarning, vyper_warn

DEFAULT_CONTRACT_PATH = PurePath("VyperContract.vy")

Expand Down Expand Up @@ -352,10 +352,11 @@
assembly = compile_ir.compile_to_assembly(ir_nodes, optimize=optimize)

if _find_nested_opcode(assembly, "DEBUG"):
warnings.warn(
"This code contains DEBUG opcodes! The DEBUG opcode will only work in "
"a supported EVM! It will FAIL on all other nodes!",
stacklevel=2,
vyper_warn(

Check warning on line 355 in vyper/compiler/phases.py

View check run for this annotation

Codecov / codecov/patch

vyper/compiler/phases.py#L355

Added line #L355 was not covered by tests
VyperWarning(
"This code contains DEBUG opcodes! The DEBUG opcode will only work in "
"a supported EVM! It will FAIL on all other nodes!"
)
)
return assembly

Expand Down
8 changes: 0 additions & 8 deletions vyper/semantics/types/function.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import re
import warnings
from dataclasses import dataclass
from functools import cached_property
from typing import Any, Dict, List, Optional, Tuple
Expand Down Expand Up @@ -766,13 +765,6 @@ def _parse_decorators(
state_mutability = StateMutability(decorator.id)

else:
if decorator.id == "constant":
warnings.warn(
"'@constant' decorator has been removed (see VIP2040). "
"Use `@view` instead.",
DeprecationWarning,
stacklevel=2,
)
raise FunctionDeclarationException(f"Unknown decorator: {decorator.id}", decorator)

else:
Expand Down
4 changes: 2 additions & 2 deletions vyper/semantics/types/subscriptable.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import warnings
from typing import Any, Dict, Optional, Tuple

from vyper import ast as vy_ast
Expand All @@ -9,6 +8,7 @@
from vyper.semantics.types.primitives import IntegerT
from vyper.semantics.types.shortcuts import UINT256_T
from vyper.semantics.types.utils import get_index_value, type_from_annotation
from vyper.warnings import VyperWarning, vyper_warn


class _SubscriptableT(VyperType):
Expand Down Expand Up @@ -113,7 +113,7 @@
raise InvalidType("Array length is invalid")

if length >= 2**64:
warnings.warn("Use of large arrays can be unsafe!", stacklevel=2)
vyper_warn(VyperWarning("Use of large arrays can be unsafe!"))

Check warning on line 116 in vyper/semantics/types/subscriptable.py

View check run for this annotation

Codecov / codecov/patch

vyper/semantics/types/subscriptable.py#L116

Added line #L116 was not covered by tests

super().__init__(UINT256_T, value_type)
self.length = length
Expand Down
5 changes: 3 additions & 2 deletions vyper/semantics/types/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
from vyper.semantics.types.base import VyperType
from vyper.semantics.types.subscriptable import HashMapT
from vyper.semantics.types.utils import type_from_abi, type_from_annotation
from vyper.utils import keccak256, vyper_warn
from vyper.utils import keccak256
from vyper.warnings import Deprecation, vyper_warn


# user defined type
Expand Down Expand Up @@ -303,7 +304,7 @@ def _ctor_call_return(self, node: vy_ast.Call) -> None:
msg += "in a future release. Use kwargs instead eg. "
msg += "Foo(a=1, b=2)"

vyper_warn(msg, node)
vyper_warn(Deprecation(msg, node))

validate_call_args(node, len(self.arguments))
for arg, expected in zip(node.args, self.arguments.values()):
Expand Down
10 changes: 1 addition & 9 deletions vyper/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import warnings
from typing import Generic, List, TypeVar, Union

from vyper.exceptions import CompilerPanic, DecimalOverrideException, VyperException
from vyper.exceptions import CompilerPanic, DecimalOverrideException

Check notice

Code scanning / CodeQL

Cyclic import Note

Import of module
vyper.exceptions
begins an import cycle.

_T = TypeVar("_T")

Expand Down Expand Up @@ -284,14 +284,6 @@
print("END TRACE", file=out)


# print a warning
def vyper_warn(msg, node=None):
if node is not None:
# use VyperException for its formatting abilities
msg = str(VyperException(msg, node))
warnings.warn(msg, stacklevel=2)


# converts a signature like Func(bool,uint256,address) to its 4 byte method ID
# TODO replace manual calculations in codebase with this
def method_id_int(method_sig: str) -> int:
Expand Down
39 changes: 37 additions & 2 deletions vyper/warnings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
# TODO: Create VyperWarning class similarly to what is being done with exceptinos?
class ContractSizeLimitWarning(Warning):
import warnings

from vyper.exceptions import _BaseVyperException


class VyperWarning(_BaseVyperException, Warning):
pass


# print a warning
def vyper_warn(warning: VyperWarning | str, node=None):
if isinstance(warning, str):
warning = VyperWarning(warning, node)

Check warning on line 13 in vyper/warnings.py

View check run for this annotation

Codecov / codecov/patch

vyper/warnings.py#L13

Added line #L13 was not covered by tests
warnings.warn(warning, stacklevel=2)


class ContractSizeLimit(VyperWarning):
"""
Warn if past the EIP-170 size limit
"""

pass


class EnumUsage(VyperWarning):
"""
Warn about using `enum` instead of `flag
"""

pass


class Deprecation(VyperWarning):
"""
General deprecation warning
"""

pass
Loading