Skip to content
Open
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
7 changes: 3 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ common: &common
command: |
python -m pip install --upgrade pip
python -m pip install tox
python web3/scripts/install_pre_releases.py
- run:
name: run tox
command: python -m tox run -r
Expand Down Expand Up @@ -221,7 +220,7 @@ workflows:
- common:
matrix:
parameters:
python_minor_version: ["10", "11", "12", "13"]
python_minor_version: ["10", "11", "12", "13", "14"]
tox_env: [
"lint",
"core",
Expand All @@ -234,7 +233,7 @@ workflows:
- geth:
matrix:
parameters:
python_minor_version: ["10", "11", "12", "13"]
python_minor_version: ["10", "11", "12", "13", "14"]
tox_env: [
"integration-goethereum-ipc",
"integration-goethereum-ipc_async",
Expand All @@ -252,7 +251,7 @@ workflows:
- windows-wheel:
matrix:
parameters:
python_minor_version: ["10", "11", "12", "13"]
python_minor_version: ["10", "11", "12", "13", "14"]
name: "py3<< matrix.python_minor_version >>-windows-wheel"


Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
rev: v3.21.2
hooks:
- id: pyupgrade
args: [--py38-plus]
Expand Down
9 changes: 9 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import pytest
import inspect
import time
import warnings

# Monkey-patch cached_property to use inspect.iscoroutinefunction
# instead of the deprecated asyncio.iscoroutinefunction (deprecated in Python 3.14+)
# cached_property is a dependency of py-evm, so once we remove py-evm
# or once cached_property gets a release, we can remove this.
# https://github.com/pydanny/cached-property/issues/276
import cached_property as _cached_property_module
import pytest_asyncio

from tests.utils import (
Expand All @@ -20,6 +27,8 @@
EthereumTesterProvider,
)

_cached_property_module.asyncio.iscoroutinefunction = inspect.iscoroutinefunction


@pytest.fixture()
def sleep_interval():
Expand Down
1 change: 1 addition & 0 deletions newsfragments/3779.breaking.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upgrade websockets requirement to >=14.0.
1 change: 1 addition & 0 deletions newsfragments/3779.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for Python 3.14
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"towncrier>=24,<25",
],
"test": [
"pytest-asyncio>=0.18.1,<0.23",
"pytest-asyncio>=1.0.0",
"pytest-mock>=1.10",
"pytest-xdist>=2.4.0",
"pytest>=7.0.0",
Expand All @@ -36,6 +36,7 @@
"tox>=4.0.0",
"mypy==1.10.0",
"pre-commit>=3.4.0",
"cached-property>=2.0.1",
],
}

Expand Down Expand Up @@ -78,7 +79,7 @@
"requests>=2.23.0",
"typing-extensions>=4.0.1",
"types-requests>=2.0.0",
"websockets>=10.0.0,<16.0.0",
"websockets>=14.0.0",
"pyunormalize>=15.0.0",
],
python_requires=">=3.10, <4",
Expand All @@ -99,5 +100,6 @@
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
],
)
84 changes: 64 additions & 20 deletions tests/core/contracts/test_contract_call_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@
def bytes_contract(w3, request, address_conversion_func):
bytes_contract_factory = w3.eth.contract(**BYTES_CONTRACT_DATA)
return deploy(
w3, bytes_contract_factory, address_conversion_func, args=[request.param]
w3,
bytes_contract_factory,
address_conversion_func,
args=[request.param],
)


Expand All @@ -81,7 +84,10 @@ def non_strict_bytes_contract(

@pytest.fixture
def call_transaction():
return {"data": "0x61bc221a", "to": "0xc305c901078781C232A2a521C2aF7980f8385ee9"}
return {
"data": "0x61bc221a",
"to": "0xc305c901078781C232A2a521C2aF7980f8385ee9",
}


@pytest.fixture
Expand All @@ -97,7 +103,10 @@ def bytes32_contract_factory(w3):
)
def bytes32_contract(w3, bytes32_contract_factory, request, address_conversion_func):
return deploy(
w3, bytes32_contract_factory, address_conversion_func, args=[request.param]
w3,
bytes32_contract_factory,
address_conversion_func,
args=[request.param],
)


Expand Down Expand Up @@ -134,7 +143,9 @@ def test_deploy_raises_due_to_strict_byte_checking_by_default(
)


def test_invalid_address_in_deploy_arg(contract_with_constructor_address_factory):
def test_invalid_address_in_deploy_arg(
contract_with_constructor_address_factory,
):
with pytest.raises(InvalidAddress):
contract_with_constructor_address_factory.constructor(
"0xd3cda913deb6f67967b99d67acdfa1712c293601",
Expand Down Expand Up @@ -294,15 +305,17 @@ def test_call_get_byte_const_array_strict_by_default(arrays_contract, call):

def test_call_get_byte_const_array_non_strict(non_strict_arrays_contract, call):
result = call(
contract=non_strict_arrays_contract, contract_function="getByteConstValue"
contract=non_strict_arrays_contract,
contract_function="getByteConstValue",
)
expected_byte_arr = [b"\x00", b"\x01"]
assert result == expected_byte_arr


def test_call_read_address_variable(contract_with_constructor_address, call):
result = call(
contract=contract_with_constructor_address, contract_function="testAddr"
contract=contract_with_constructor_address,
contract_function="testAddr",
)
assert result == "0xd3CdA913deB6f67967B99D67aCDFa1712C293601"

Expand Down Expand Up @@ -437,7 +450,12 @@ def test_call_address_list_reflector_with_address(
def test_call_address_reflector_single_name(address_reflector_contract, call):
with contract_ens_addresses(
address_reflector_contract,
[("dennisthepeasant.eth", "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413")],
[
(
"dennisthepeasant.eth",
"0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413",
)
],
):
result = call(
contract=address_reflector_contract,
Expand Down Expand Up @@ -817,7 +835,10 @@ def test_call_sending_ether_to_nonpayable_function(payable_tester_contract, call
"reflect(ufixed256x80)",
Decimal(2**256 - 1) / 10**80,
), # maximum allowed value
("reflect(ufixed256x80)", Decimal(1) / 10**80), # smallest non-zero value
(
"reflect(ufixed256x80)",
Decimal(1) / 10**80,
), # smallest non-zero value
# minimum value (for ufixed8x1)
("reflect_short_u", 0),
# maximum value (for ufixed8x1)
Expand Down Expand Up @@ -1334,7 +1355,7 @@ async def async_mismatched_math_contract(
return _mismatched_math_contract


@pytest_asyncio.fixture
@pytest.mark.asyncio
async def test_async_deploy_raises_due_to_strict_byte_checking_by_default(
async_w3, async_bytes_contract_factory, address_conversion_func
):
Expand Down Expand Up @@ -1454,7 +1475,8 @@ async def test_async_call_get_bytes32_array(async_arrays_contract, async_call):
@pytest.mark.asyncio
async def test_async_call_get_bytes32_const_array(async_arrays_contract, async_call):
result = await async_call(
contract=async_arrays_contract, contract_function="getBytes32ConstValue"
contract=async_arrays_contract,
contract_function="getBytes32ConstValue",
)
# expected_bytes32_array = [keccak('A'), keccak('B')]
expected_bytes32_array = [
Expand All @@ -1478,7 +1500,8 @@ async def test_async_call_get_byte_array_non_strict(
async_non_strict_arrays_contract, async_call
):
result = await async_call(
contract=async_non_strict_arrays_contract, contract_function="getByteValue"
contract=async_non_strict_arrays_contract,
contract_function="getByteValue",
)
expected_non_strict_byte_arr = [b"\xff", b"\xff", b"\xff", b"\xff"]
assert result == expected_non_strict_byte_arr
Expand All @@ -1487,15 +1510,20 @@ async def test_async_call_get_byte_array_non_strict(
@pytest.mark.asyncio
@pytest.mark.parametrize("args,expected", [([b""], [b"\x00"]), (["0x"], [b"\x00"])])
async def test_async_set_byte_array_non_strict(
async_non_strict_arrays_contract, async_call, async_transact, args, expected
async_non_strict_arrays_contract,
async_call,
async_transact,
args,
expected,
):
await async_transact(
contract=async_non_strict_arrays_contract,
contract_function="setByteValue",
func_args=[args],
)
result = await async_call(
contract=async_non_strict_arrays_contract, contract_function="getByteValue"
contract=async_non_strict_arrays_contract,
contract_function="getByteValue",
)

assert result == expected
Expand Down Expand Up @@ -1536,7 +1564,8 @@ async def test_async_call_get_byte_const_array_non_strict(
async_non_strict_arrays_contract, async_call
):
result = await async_call(
contract=async_non_strict_arrays_contract, contract_function="getByteConstValue"
contract=async_non_strict_arrays_contract,
contract_function="getByteConstValue",
)
expected_byte_arr = [b"\x00", b"\x01"]
assert result == expected_byte_arr
Expand Down Expand Up @@ -1700,7 +1729,12 @@ async def test_async_call_address_reflector_single_name(
):
with contract_ens_addresses(
async_address_reflector_contract,
[("dennisthepeasant.eth", "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413")],
[
(
"dennisthepeasant.eth",
"0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413",
)
],
):
result = await async_call(
contract=async_address_reflector_contract,
Expand Down Expand Up @@ -1757,7 +1791,8 @@ async def test_async_call_missing_function(async_mismatched_math_contract, async
expected_missing_function_error_message = "Could not decode contract function call"
with pytest.raises(BadFunctionCallOutput) as exception_info:
await async_call(
contract=async_mismatched_math_contract, contract_function="return13"
contract=async_mismatched_math_contract,
contract_function="return13",
)
assert expected_missing_function_error_message in str(exception_info.value)

Expand All @@ -1771,7 +1806,8 @@ async def test_async_call_undeployed_contract(
)
with pytest.raises(BadFunctionCallOutput) as exception_info:
await async_call(
contract=async_undeployed_math_contract, contract_function="return13"
contract=async_undeployed_math_contract,
contract_function="return13",
)
assert expected_undeployed_call_error_message in str(exception_info.value)

Expand Down Expand Up @@ -1970,7 +2006,8 @@ async def test_async_call_not_sending_ether_to_nonpayable_function(
async_payable_tester_contract, async_call
):
result = await async_call(
contract=async_payable_tester_contract, contract_function="doNoValueCall"
contract=async_payable_tester_contract,
contract_function="doNoValueCall",
)
assert result == []

Expand Down Expand Up @@ -2004,7 +2041,10 @@ async def test_async_call_sending_ether_to_nonpayable_function(
"reflect(ufixed256x80)",
Decimal(2**256 - 1) / 10**80,
), # maximum allowed value
("reflect(ufixed256x80)", Decimal(1) / 10**80), # smallest non-zero value
(
"reflect(ufixed256x80)",
Decimal(1) / 10**80,
), # smallest non-zero value
# minimum value (for ufixed8x1)
("reflect_short_u", 0),
# maximum value (for ufixed8x1)
Expand Down Expand Up @@ -2056,7 +2096,11 @@ async def test_async_reflect_fixed_value(
Decimal("25.4" + "9" * DEFAULT_DECIMALS),
NO_MATCHING_ARGUMENTS,
),
("reflect(ufixed256x80)", Decimal(1) / 10**81, MULTIPLE_MATCHING_ELEMENTS),
(
"reflect(ufixed256x80)",
Decimal(1) / 10**81,
MULTIPLE_MATCHING_ELEMENTS,
),
# floats not accepted, for floating point error concerns
("reflect_short_u", 0.1, NO_MATCHING_ARGUMENTS),
),
Expand Down
Loading