diff --git a/mypy.eest.ini b/mypy.eest.ini new file mode 100644 index 0000000000..e34c804d43 --- /dev/null +++ b/mypy.eest.ini @@ -0,0 +1,4 @@ +[mypy] +disable_error_code = import-untyped +mypy_path = src, $MYPY_CONFIG_FILE_DIR/stubs +plugins = pydantic.mypy \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 95a8a9872a..dbe6e81749 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -283,6 +283,7 @@ fill = [ "eth-abi>=5.2.0", "joblib>=1.4.2", "ckzg>=2.1.1", + "platformdirs>=4.2,<5", ] lint = [ @@ -313,6 +314,7 @@ ethereum-spec-new-fork = "ethereum_spec_tools.new_fork:main" ethereum-spec-patch = "ethereum_spec_tools.patch_tool:main" ethereum-spec-evm = "ethereum_spec_tools.evm_tools:main" ethereum-spec-fill = "cli.pytest_commands.fill:fill" +ethereum-spec-consume = "cli.pytest_commands.consume:consume" [project.entry-points."docc.plugins"] "ethereum_spec_tools.docc.discover" = "ethereum_spec_tools.docc:EthereumDiscover" @@ -517,3 +519,6 @@ check-hidden = false # Don't check hidden files (starting with .) [tool.uv] required-version = ">=0.7.0" + +[tool.mypy] +plugins = ["pydantic.mypy"] \ No newline at end of file diff --git a/ruff.eest.toml b/ruff.eest.toml new file mode 100644 index 0000000000..ee004eace0 --- /dev/null +++ b/ruff.eest.toml @@ -0,0 +1,6 @@ +line-length = 99 + +[lint] +select = ["E", "F", "B", "W", "I", "A", "N", "D", "C"] +fixable = ["I", "B", "E", "F", "W", "D", "C"] +ignore = ["D205", "D203", "D212", "D415", "C901", "A005", "C420"] \ No newline at end of file diff --git a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-check-eip-versions.ini b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-check-eip-versions.ini index aad7413ca5..adcb1c7003 100644 --- a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-check-eip-versions.ini +++ b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-check-eip-versions.ini @@ -2,7 +2,7 @@ console_output_style = count minversion = 7.0 python_files = *.py -testpaths = tests/ +testpaths = tests/eest/ markers = slow pre_alloc_modify diff --git a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute-hive.ini b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute-hive.ini index f05273a11f..7ea499aaba 100644 --- a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute-hive.ini +++ b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute-hive.ini @@ -2,7 +2,7 @@ console_output_style = count minversion = 7.0 python_files = *.py -testpaths = tests/ +testpaths = tests/eest/ markers = slow pre_alloc_modify diff --git a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute.ini b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute.ini index e360e5e4fc..1a1971a2dd 100644 --- a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute.ini +++ b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-execute.ini @@ -2,7 +2,7 @@ console_output_style = count minversion = 7.0 python_files = *.py -testpaths = tests/ +testpaths = tests/eest/ markers = slow pre_alloc_modify diff --git a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-fill.ini b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-fill.ini index 92a01ca012..0fc377d239 100644 --- a/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-fill.ini +++ b/src/ethereum_spec_tests/cli/pytest_commands/pytest_ini_files/pytest-fill.ini @@ -2,7 +2,7 @@ console_output_style = count minversion = 7.0 python_files = *.py -testpaths = tests/ +testpaths = tests/eest/ markers = slow pre_alloc_modify diff --git a/stubs/joblib/__init__.pyi b/stubs/joblib/__init__.pyi new file mode 100644 index 0000000000..7756352f49 --- /dev/null +++ b/stubs/joblib/__init__.pyi @@ -0,0 +1,5 @@ +from typing import Any, Callable + +class Memory: + def __init__(self, location: str, verbose: int = ...) -> None: ... + def cache(self, func: Callable[..., Any]) -> Callable[..., Any]: ... diff --git a/stubs/jwt/__init__.pyi b/stubs/jwt/__init__.pyi new file mode 100644 index 0000000000..dee1918afd --- /dev/null +++ b/stubs/jwt/__init__.pyi @@ -0,0 +1,3 @@ +from .encode import encode + +__all__ = ("encode",) diff --git a/stubs/jwt/encode.pyi b/stubs/jwt/encode.pyi new file mode 100644 index 0000000000..3bfe608a1a --- /dev/null +++ b/stubs/jwt/encode.pyi @@ -0,0 +1,3 @@ +from typing import Any, Dict + +def encode(payload: Dict[Any, Any], key: bytes, algorithm: str) -> str: ... diff --git a/stubs/trie/__init__.pyi b/stubs/trie/__init__.pyi new file mode 100644 index 0000000000..c7b52113ff --- /dev/null +++ b/stubs/trie/__init__.pyi @@ -0,0 +1,3 @@ +from .hexary import HexaryTrie as HexaryTrie + +__all__ = ("HexaryTrie",) diff --git a/stubs/trie/hexary.pyi b/stubs/trie/hexary.pyi new file mode 100644 index 0000000000..d464ac3564 --- /dev/null +++ b/stubs/trie/hexary.pyi @@ -0,0 +1,8 @@ +from typing import Dict + +class HexaryTrie: + db: Dict + root_hash: bytes + + def __init__(self, db: Dict) -> None: ... + def set(self, key: bytes, value: bytes) -> None: ... diff --git a/stubs/xdist/__init__.pyi b/stubs/xdist/__init__.pyi new file mode 100644 index 0000000000..1ec85655d4 --- /dev/null +++ b/stubs/xdist/__init__.pyi @@ -0,0 +1,3 @@ +from .methods import is_xdist_worker + +__all__ = ("is_xdist_worker",) diff --git a/stubs/xdist/methods.pyi b/stubs/xdist/methods.pyi new file mode 100644 index 0000000000..c3e9d5bbad --- /dev/null +++ b/stubs/xdist/methods.pyi @@ -0,0 +1,3 @@ +import pytest + +def is_xdist_worker(session: pytest.Session) -> bool: ... diff --git a/tox.ini b/tox.ini index abc9e3ef76..802a93fd53 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ min_version = 4.0 requires = tox-uv >=0.2.0 -envlist = py3,pypy3,json_infra,static +envlist = py3,pypy3,json_infra,static,eest-lint,eest-typecheck,eest-pytest,eest-tests-deployed,eest-tests-deployed-benchmark,eest-tests-develop [testenv] package = uv @@ -90,3 +90,82 @@ extras = doc commands = docc --output "{toxworkdir}/docs" python -c 'import pathlib; print("documentation available under file://\{0\}".format(pathlib.Path(r"{toxworkdir}") / "docs" / "index.html"))' + + +[eest] +runner = uv-venv-lock-runner +package = editable +wheel_build_env = .pkg +python_source_dirs = src/ethereum_spec_tests tests/eest # .github/scripts +ruff_config = ruff.eest.toml +mypy_config = mypy.eest.ini + +[testenv:eest-lint] +runner = {[eest]runner} +package = {[eest]package} +wheel_build_env = {[eest]wheel_build_env} +description = Lint and code formatting checks (ruff) +extras = lint +commands = + ruff check --config {[eest]ruff_config} --no-fix --show-fixes {[eest]python_source_dirs} + ruff format --config {[eest]ruff_config} --check {[eest]python_source_dirs} + +[testenv:eest-typecheck] +runner = {[eest]runner} +package = {[eest]package} +wheel_build_env = {[eest]wheel_build_env} +description = Run type checking (mypy) +extras = test,fill,lint +commands = mypy --config-file {[eest]mypy_config} {[eest]python_source_dirs} + + +[testenv:eest-pytest] +runner = {[eest]runner} +package = {[eest]package} +wheel_build_env = {[eest]wheel_build_env} +description = Run library and framework unit tests (pytest) +setenv = + # Use custom EELS_RESOLUTIONS_FILE if it is set via the environment (eg, in CI) + EELS_RESOLUTIONS_FILE = {env:EELS_RESOLUTIONS_FILE:} + CI = {env:CI:} +extras = + test + fill + lint # Required `gentest` for formatting tests +commands = + pytest -n auto ./src/ethereum_spec_tests + + +[forks] +develop = Osaka +eip7692 = EOFv1 + +[testenv:eest-tests-deployed] +runner = {[eest]runner} +package = {[eest]package} +wheel_build_env = {[eest]wheel_build_env} +description = Fill test cases in ./tests/ for deployed mainnet forks, except for slow/benchmark tests. +extras = test,fill +setenv = + # Use custom EELS_RESOLUTIONS_FILE if it is set via the environment (eg, in CI) + EELS_RESOLUTIONS_FILE = {env:EELS_RESOLUTIONS_FILE:} +commands = ethereum-spec-fill -n auto -m "not slow" --output=/tmp/fixtures-tox --clean + +[testenv:eest-tests-deployed-benchmark] +runner = {[eest]runner} +package = {[eest]package} +wheel_build_env = {[eest]wheel_build_env} +description = Fill benchmarking test cases in ./tests/ for deployed mainnet forks, using evmone-t8n. +extras = test,fill +commands = ethereum-spec-fill -n auto -m "benchmark" --gas-benchmark-values 5 --output=/tmp/fixtures-tox --clean --evm-bin=evmone-t8n + +[testenv:eest-tests-develop] +runner = {[eest]runner} +package = {[eest]package} +wheel_build_env = {[eest]wheel_build_env} +description = Fill test cases in ./tests/ for deployed and development mainnet forks +setenv = + # Use custom EELS_RESOLUTIONS_FILE if it is set via the environment (eg, in CI) + EELS_RESOLUTIONS_FILE = {env:EELS_RESOLUTIONS_FILE:} +extras = test,fill +commands = ethereum-spec-fill -n auto --until={[forks]develop} -k "not slow" --output=/tmp/fixtures-tox --clean diff --git a/uv.lock b/uv.lock index 497fc0728a..73de6004b6 100644 --- a/uv.lock +++ b/uv.lock @@ -536,6 +536,7 @@ fill = [ { name = "ethereum-types" }, { name = "gitpython" }, { name = "joblib" }, + { name = "platformdirs" }, { name = "pydantic" }, { name = "pyjwt" }, { name = "pytest-custom-report" }, @@ -599,6 +600,7 @@ requires-dist = [ { name = "gitpython", marker = "extra == 'test'", specifier = ">=3.1.0,<3.2" }, { name = "joblib", marker = "extra == 'fill'", specifier = ">=1.4.2" }, { name = "mypy", marker = "extra == 'lint'", specifier = "==1.17.0" }, + { name = "platformdirs", marker = "extra == 'fill'", specifier = ">=4.2,<5" }, { name = "platformdirs", marker = "extra == 'tools'", specifier = ">=4.2,<5" }, { name = "py-ecc", specifier = ">=8.0.0b2,<9" }, { name = "pycryptodome", specifier = ">=3.22,<4" },