diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b416a4414..b943b5d31d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,27 +1,33 @@ repos: - repo: https://github.com/pycqa/isort - rev: 5.9.3 + rev: 5.13.2 hooks: - id: isort name: isort - repo: https://github.com/psf/black - rev: 21.9b0 + rev: 23.12.0 hooks: - id: black name: black - repo: https://github.com/PyCQA/flake8 - rev: 3.9.2 + rev: 6.1.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.910 + rev: v1.7.1 hooks: - id: mypy additional_dependencies: - "types-setuptools" + args: # settings from tox.ini + - --install-types + - --non-interactive + - --follow-imports=silent + - --ignore-missing-imports + - --implicit-optional default_language_version: python: python3.10 diff --git a/setup.py b/setup.py index 431c50b74b..f5d643ad88 100644 --- a/setup.py +++ b/setup.py @@ -22,12 +22,12 @@ "eth-stdlib==0.2.6", ], "lint": [ - "black==23.3.0", - "flake8==3.9.2", - "flake8-bugbear==20.1.4", - "flake8-use-fstring==1.1", - "isort==5.9.3", - "mypy==0.982", + "black==23.12.0", + "flake8==6.1.0", + "flake8-bugbear==23.12.2", + "flake8-use-fstring==1.4", + "isort==5.13.2", + "mypy==1.5", ], "docs": ["recommonmark", "sphinx>=6.0,<7.0", "sphinx_rtd_theme>=1.2,<1.3"], "dev": ["ipython", "pre-commit", "pyinstaller", "twine"], diff --git a/tests/functional/builtins/codegen/test_extract32.py b/tests/functional/builtins/codegen/test_extract32.py index c1a333ae32..6e4ee09abc 100644 --- a/tests/functional/builtins/codegen/test_extract32.py +++ b/tests/functional/builtins/codegen/test_extract32.py @@ -36,7 +36,7 @@ def extrakt32_storage(index: uint256, inp: Bytes[100]) -> bytes32: for S, i in test_cases: expected_result = S[i : i + 32] if 0 <= i <= len(S) - 32 else None if expected_result is None: - assert_tx_failed(lambda: c.extrakt32(S, i)) + assert_tx_failed(lambda p=(S, i): c.extrakt32(*p)) else: assert c.extrakt32(S, i) == expected_result assert c.extrakt32_mem(S, i) == expected_result diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 4ad68697ac..f7eef21af7 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -143,7 +143,7 @@ def _call_with_bytes(hexstr): for i in range(4, 36): # match the full 4 selector bytes, but revert due to malformed (short) calldata - assert_tx_failed(lambda: _call_with_bytes("0x" + "00" * i)) + assert_tx_failed(lambda p="0x" + "00" * i: _call_with_bytes(p)) def test_another_zero_method_id(w3, get_logs, get_contract, assert_tx_failed): diff --git a/tests/functional/codegen/features/decorators/test_payable.py b/tests/functional/codegen/features/decorators/test_payable.py index 55c60236f4..4858a7df0d 100644 --- a/tests/functional/codegen/features/decorators/test_payable.py +++ b/tests/functional/codegen/features/decorators/test_payable.py @@ -352,7 +352,7 @@ def __default__(): """ c = get_contract(code) - w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}), + w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) def test_nonpayable_default_func_invalid_calldata(get_contract, w3, assert_tx_failed): @@ -391,5 +391,7 @@ def __default__(): for i in range(5): calldata = "0x" + data[:i].hex() assert_tx_failed( - lambda: w3.eth.send_transaction({"to": c.address, "value": 100, "data": calldata}) + lambda data=calldata: w3.eth.send_transaction( + {"to": c.address, "value": 100, "data": data} + ) ) diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index ad7ea32b1e..08ad349c09 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -118,8 +118,11 @@ def foo(s: bytes{n}) -> bytes{n}: c = get_contract(code, evm_version=evm_version) for v in values: # munge for `_make_tx` - v = int.from_bytes(v, byteorder="big") - assert_tx_failed(lambda: _make_tx(w3, c.address, f"foo(bytes{n})", [v])) + assert_tx_failed( + lambda val=int.from_bytes(v, byteorder="big"): _make_tx( + w3, c.address, f"foo(bytes{n})", [val] + ) + ) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -153,7 +156,7 @@ def foo(s: int{bits}) -> int{bits}: c = get_contract(code, evm_version=evm_version) for v in values: - assert_tx_failed(lambda: _make_tx(w3, c.address, f"foo(int{bits})", [v])) + assert_tx_failed(lambda val=v: _make_tx(w3, c.address, f"foo(int{bits})", [val])) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -250,7 +253,7 @@ def foo(s: uint{bits}) -> uint{bits}: """ c = get_contract(code, evm_version=evm_version) for v in values: - assert_tx_failed(lambda: _make_tx(w3, c.address, f"foo(uint{bits})", [v])) + assert_tx_failed(lambda val=v: _make_tx(w3, c.address, f"foo(uint{bits})", [val])) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) diff --git a/tests/functional/codegen/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index 161cd480fd..abea81ced4 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -600,7 +600,7 @@ def __default__(): else: hexstr = (method_id + argsdata).hex() txdata = {"to": c.address, "data": hexstr, "value": 1} - assert_tx_failed(lambda: w3.eth.send_transaction(txdata)) + assert_tx_failed(lambda d=txdata: w3.eth.send_transaction(d)) # now do calldatasize check # strip some bytes @@ -610,7 +610,7 @@ def __default__(): if n_calldata_words == 0 and j == 0: # no args, hit default function if default_fn_mutability == "": - assert_tx_failed(lambda: w3.eth.send_transaction(tx_params)) + assert_tx_failed(lambda p=tx_params: w3.eth.send_transaction(p)) elif default_fn_mutability == "@payable": # we should be able to send eth to it tx_params["value"] = 1 @@ -628,8 +628,8 @@ def __default__(): # check default function reverts tx_params["value"] = 1 - assert_tx_failed(lambda: w3.eth.send_transaction(tx_params)) + assert_tx_failed(lambda p=tx_params: w3.eth.send_transaction(p)) else: - assert_tx_failed(lambda: w3.eth.send_transaction(tx_params)) + assert_tx_failed(lambda p=tx_params: w3.eth.send_transaction(p)) _test() diff --git a/tests/functional/codegen/types/numbers/test_signed_ints.py b/tests/functional/codegen/types/numbers/test_signed_ints.py index 281aab429c..3e44beb826 100644 --- a/tests/functional/codegen/types/numbers/test_signed_ints.py +++ b/tests/functional/codegen/types/numbers/test_signed_ints.py @@ -116,7 +116,7 @@ def foo(x: {typ}) -> {typ}: test_cases = [0, 1, 3, 4, 126, 127, -1, lo, hi] for x in test_cases: if x * 2 >= typ.bits or x < 0: # out of bounds - assert_tx_failed(lambda: c.foo(x)) + assert_tx_failed(lambda p=x: c.foo(p)) else: assert c.foo(x) == 4**x @@ -304,15 +304,17 @@ def foo() -> {typ}: assert get_contract(code_3).foo(y) == expected assert get_contract(code_4).foo() == expected elif div_by_zero: - assert_tx_failed(lambda: c.foo(x, y)) - assert_compile_failed(lambda: get_contract(code_2), ZeroDivisionException) - assert_tx_failed(lambda: get_contract(code_3).foo(y)) - assert_compile_failed(lambda: get_contract(code_4), ZeroDivisionException) + assert_tx_failed(lambda p=(x, y): c.foo(*p)) + assert_compile_failed(lambda code=code_2: get_contract(code), ZeroDivisionException) + assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) + assert_compile_failed(lambda code=code_4: get_contract(code), ZeroDivisionException) else: - assert_tx_failed(lambda: c.foo(x, y)) - assert_tx_failed(lambda: get_contract(code_2).foo(x)) - assert_tx_failed(lambda: get_contract(code_3).foo(y)) - assert_compile_failed(lambda: get_contract(code_4), (InvalidType, OverflowException)) + assert_tx_failed(lambda p=(x, y): c.foo(*p)) + assert_tx_failed(lambda p=x, code=code_2: get_contract(code).foo(p)) + assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) + assert_compile_failed( + lambda code=code_4: get_contract(code), (InvalidType, OverflowException) + ) COMPARISON_OPS = { diff --git a/tests/functional/codegen/types/numbers/test_unsigned_ints.py b/tests/functional/codegen/types/numbers/test_unsigned_ints.py index 683684e6be..6c8d114f29 100644 --- a/tests/functional/codegen/types/numbers/test_unsigned_ints.py +++ b/tests/functional/codegen/types/numbers/test_unsigned_ints.py @@ -148,15 +148,17 @@ def foo() -> {typ}: assert get_contract(code_3).foo(y) == expected assert get_contract(code_4).foo() == expected elif div_by_zero: - assert_tx_failed(lambda: c.foo(x, y)) - assert_compile_failed(lambda: get_contract(code_2), ZeroDivisionException) - assert_tx_failed(lambda: get_contract(code_3).foo(y)) - assert_compile_failed(lambda: get_contract(code_4), ZeroDivisionException) + assert_tx_failed(lambda p=(x, y): c.foo(*p)) + assert_compile_failed(lambda code=code_2: get_contract(code), ZeroDivisionException) + assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) + assert_compile_failed(lambda code=code_4: get_contract(code), ZeroDivisionException) else: - assert_tx_failed(lambda: c.foo(x, y)) - assert_tx_failed(lambda: get_contract(code_2).foo(x)) - assert_tx_failed(lambda: get_contract(code_3).foo(y)) - assert_compile_failed(lambda: get_contract(code_4), (InvalidType, OverflowException)) + assert_tx_failed(lambda p=(x, y): c.foo(*p)) + assert_tx_failed(lambda code=code_2, p=x: get_contract(code).foo(p)) + assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) + assert_compile_failed( + lambda code=code_4: get_contract(code), (InvalidType, OverflowException) + ) COMPARISON_OPS = { @@ -213,7 +215,7 @@ def test() -> {typ}: assert c.test() == val for val in bad_cases: - assert_compile_failed(lambda: get_contract(code_template.format(typ=typ, val=val))) + assert_compile_failed(lambda v=val: get_contract(code_template.format(typ=typ, val=v))) @pytest.mark.parametrize("typ", types) diff --git a/tests/functional/codegen/types/test_node_types.py b/tests/functional/codegen/types/test_node_types.py index b6561ae8eb..8a2b1681d7 100644 --- a/tests/functional/codegen/types/test_node_types.py +++ b/tests/functional/codegen/types/test_node_types.py @@ -63,5 +63,5 @@ def test_type_storage_sizes(): assert struct_.storage_size_in_words == 2 # Don't allow unknown types. - with raises(Exception): + with raises(AttributeError): _ = int.storage_size_in_words diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index 70ba5cbbf7..fa6ed20117 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -125,7 +125,6 @@ def test_address_code_compile_error( ): with pytest.raises(error_type) as excinfo: compiler.compile_code(bad_code) - assert type(excinfo.value) == error_type assert excinfo.value.message == error_message diff --git a/tests/functional/syntax/test_immutables.py b/tests/functional/syntax/test_immutables.py index ab38f6b56d..1027d9fe66 100644 --- a/tests/functional/syntax/test_immutables.py +++ b/tests/functional/syntax/test_immutables.py @@ -63,7 +63,7 @@ def __init__(_value: uint256): @pytest.mark.parametrize("bad_code", fail_list) def test_compilation_fails_with_exception(bad_code): - with pytest.raises(Exception): + with pytest.raises(VyperException): compile_code(bad_code) diff --git a/tests/functional/syntax/test_no_none.py b/tests/functional/syntax/test_no_none.py index 24c32a46a4..085ce395ab 100644 --- a/tests/functional/syntax/test_no_none.py +++ b/tests/functional/syntax/test_no_none.py @@ -72,7 +72,9 @@ def foo(): ] for contract in contracts: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), InvalidLiteral) + assert_compile_failed( + lambda c=contract: get_contract_with_gas_estimation(c), InvalidLiteral + ) def test_no_is_none(assert_compile_failed, get_contract_with_gas_estimation): @@ -116,7 +118,9 @@ def foo(): ] for contract in contracts: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), SyntaxException) + assert_compile_failed( + lambda c=contract: get_contract_with_gas_estimation(c), SyntaxException + ) def test_no_eq_none(assert_compile_failed, get_contract_with_gas_estimation): @@ -160,7 +164,9 @@ def foo(): ] for contract in contracts: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), InvalidLiteral) + assert_compile_failed( + lambda c=contract: get_contract_with_gas_estimation(c), InvalidLiteral + ) def test_struct_none(assert_compile_failed, get_contract_with_gas_estimation): @@ -195,4 +201,6 @@ def foo(): ] for contract in contracts: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), InvalidLiteral) + assert_compile_failed( + lambda c=contract: get_contract_with_gas_estimation(c), InvalidLiteral + ) diff --git a/tests/unit/abi_types/test_invalid_abi_types.py b/tests/unit/abi_types/test_invalid_abi_types.py index c8566e066f..1a8a7db884 100644 --- a/tests/unit/abi_types/test_invalid_abi_types.py +++ b/tests/unit/abi_types/test_invalid_abi_types.py @@ -23,4 +23,4 @@ def test_invalid_abi_types(assert_compile_failed, typ, params_variants): # double parametrization cannot work because the 2nd dimension is variable for params in params_variants: - assert_compile_failed(lambda: typ(*params), InvalidABIType) + assert_compile_failed(lambda p=params: typ(*p), InvalidABIType) diff --git a/vyper/cli/vyper_json.py b/vyper/cli/vyper_json.py index 63da2e0643..032d7ebe64 100755 --- a/vyper/cli/vyper_json.py +++ b/vyper/cli/vyper_json.py @@ -262,7 +262,8 @@ def compile_from_input_dict( if isinstance(optimize, bool): # bool optimization level for backwards compatibility warnings.warn( - "optimize: is deprecated! please use one of 'gas', 'codesize', 'none'." + "optimize: is deprecated! please use one of 'gas', 'codesize', 'none'.", + stacklevel=2, ) optimize = OptimizationLevel.default() if optimize else OptimizationLevel.NONE elif isinstance(optimize, str): diff --git a/vyper/compiler/phases.py b/vyper/compiler/phases.py index 199bbbc3e5..b9b2df6ae8 100644 --- a/vyper/compiler/phases.py +++ b/vyper/compiler/phases.py @@ -343,7 +343,8 @@ def generate_assembly(ir_nodes: IRnode, optimize: Optional[OptimizationLevel] = 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!" + "a supported EVM! It will FAIL on all other nodes!", + stacklevel=2, ) return assembly diff --git a/vyper/semantics/types/base.py b/vyper/semantics/types/base.py index d22d9bfff9..6ecfe78be3 100644 --- a/vyper/semantics/types/base.py +++ b/vyper/semantics/types/base.py @@ -92,7 +92,7 @@ def __hash__(self): def __eq__(self, other): return ( - type(self) == type(other) and self._get_equality_attrs() == other._get_equality_attrs() + type(self) is type(other) and self._get_equality_attrs() == other._get_equality_attrs() ) def __lt__(self, other): diff --git a/vyper/semantics/types/function.py b/vyper/semantics/types/function.py index ec30ac85d6..34206546fd 100644 --- a/vyper/semantics/types/function.py +++ b/vyper/semantics/types/function.py @@ -644,6 +644,7 @@ def _parse_decorators( "'@constant' decorator has been removed (see VIP2040). " "Use `@view` instead.", DeprecationWarning, + stacklevel=2, ) raise FunctionDeclarationException(f"Unknown decorator: {decorator.id}", decorator) diff --git a/vyper/semantics/types/module.py b/vyper/semantics/types/module.py index 4622482951..b0d7800011 100644 --- a/vyper/semantics/types/module.py +++ b/vyper/semantics/types/module.py @@ -232,14 +232,17 @@ def from_ModuleT(cls, module_t: "ModuleT") -> "InterfaceT": @classmethod def from_InterfaceDef(cls, node: vy_ast.InterfaceDef) -> "InterfaceT": functions = [] - for node in node.body: - if not isinstance(node, vy_ast.FunctionDef): - raise StructureException("Interfaces can only contain function definitions", node) - if len(node.decorator_list) > 0: + for func_ast in node.body: + if not isinstance(func_ast, vy_ast.FunctionDef): raise StructureException( - "Function definition in interface cannot be decorated", node.decorator_list[0] + "Interfaces can only contain function definitions", func_ast ) - functions.append((node.name, ContractFunctionT.from_InterfaceDef(node))) + if len(func_ast.decorator_list) > 0: + raise StructureException( + "Function definition in interface cannot be decorated", + func_ast.decorator_list[0], + ) + functions.append((func_ast.name, ContractFunctionT.from_InterfaceDef(func_ast))) # no structs or events in InterfaceDefs events: list = [] diff --git a/vyper/semantics/types/subscriptable.py b/vyper/semantics/types/subscriptable.py index 46dffbdec4..0c8e9fddd8 100644 --- a/vyper/semantics/types/subscriptable.py +++ b/vyper/semantics/types/subscriptable.py @@ -112,7 +112,7 @@ def __init__(self, value_type: VyperType, length: int): raise InvalidType("Array length is invalid") if length >= 2**64: - warnings.warn("Use of large arrays can be unsafe!") + warnings.warn("Use of large arrays can be unsafe!", stacklevel=2) super().__init__(UINT256_T, value_type) self.length = length diff --git a/vyper/utils.py b/vyper/utils.py index a778a4e31b..2349731b97 100644 --- a/vyper/utils.py +++ b/vyper/utils.py @@ -70,7 +70,9 @@ def __setattr__(self, name, value): raise DecimalOverrideException("Overriding decimal precision disabled") elif value > 78: # not sure it's incorrect, might not be end of the world - warnings.warn("Changing decimals precision could have unintended side effects!") + warnings.warn( + "Changing decimals precision could have unintended side effects!", stacklevel=2 + ) # else: no-op, is ok super().__setattr__(name, value)