From ee4c767bc020bd636fe02d81ceb7b98158747a17 Mon Sep 17 00:00:00 2001 From: Martin Kourim Date: Mon, 16 Mar 2026 15:55:30 +0100 Subject: [PATCH 1/3] chore(dev-deps): remove pyright dependency Removes pyright from development dependencies and pre-commit config. This streamlines the development environment by relying solely on mypy for static type checking. --- .pre-commit-config.yaml | 5 ----- pyproject.toml | 1 - uv.lock | 15 --------------- 3 files changed, 21 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 264e2622c..038d95283 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,8 +39,3 @@ repos: entry: mypy language: system types: [python] - - id: pyright - name: pyright - entry: pyright - language: system - types: [python] diff --git a/pyproject.toml b/pyproject.toml index 3ebef776c..bbe9691de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,6 @@ dev = [ "mypy (>=1.19.0,<2.0.0)", "pandas (>=2.3.3,<3.0.0)", "pre-commit (>=4.5.0,<5.0.0)", - "pyright (>=1.1.406,<1.1.407)", # Regression in 1.1.407, see #11060 "seaborn (>=0.13.2,<0.14.0)", "types-pyyaml (>=6.0.12.20250915,<7.0.0.0)", "types-requests (>=2.32.4.20250913,<3.0.0.0)", diff --git a/uv.lock b/uv.lock index b66fef561..12901a19b 100644 --- a/uv.lock +++ b/uv.lock @@ -120,7 +120,6 @@ dev = [ { name = "mypy" }, { name = "pandas" }, { name = "pre-commit" }, - { name = "pyright" }, { name = "seaborn" }, { name = "types-pyyaml" }, { name = "types-requests" }, @@ -161,7 +160,6 @@ dev = [ { name = "mypy", specifier = ">=1.19.0,<2.0.0" }, { name = "pandas", specifier = ">=2.3.3,<3.0.0" }, { name = "pre-commit", specifier = ">=4.5.0,<5.0.0" }, - { name = "pyright", specifier = ">=1.1.406,<1.1.407" }, { name = "seaborn", specifier = ">=0.13.2,<0.14.0" }, { name = "types-pyyaml", specifier = ">=6.0.12.20250915,<7.0.0.0" }, { name = "types-requests", specifier = ">=2.32.4.20250913,<3.0.0.0" }, @@ -1290,19 +1288,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] -[[package]] -name = "pyright" -version = "1.1.406" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f7/16/6b4fbdd1fef59a0292cbb99f790b44983e390321eccbc5921b4d161da5d1/pyright-1.1.406.tar.gz", hash = "sha256:c4872bc58c9643dac09e8a2e74d472c62036910b3bd37a32813989ef7576ea2c", size = 4113151, upload-time = "2025-10-02T01:04:45.488Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/a2/e309afbb459f50507103793aaef85ca4348b66814c86bc73908bdeb66d12/pyright-1.1.406-py3-none-any.whl", hash = "sha256:1d81fb43c2407bf566e97e57abb01c811973fdb21b2df8df59f870f688bdca71", size = 5980982, upload-time = "2025-10-02T01:04:43.137Z" }, -] - [[package]] name = "pytest" version = "9.0.2" From 97b0ec2c07c47156c6581260180b7a09a1246e0f Mon Sep 17 00:00:00 2001 From: Martin Kourim Date: Mon, 16 Mar 2026 15:57:12 +0100 Subject: [PATCH 2/3] chore(pyproject): add pyrefly tool configuration --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index bbe9691de..ee38e0be4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,6 +115,13 @@ warn_return_any = true pythonVersion = "3.13" reportPrivateImportUsage = false +[tool.pyrefly] +python_version = "3.13.0" +project_includes = ["cardano_node_tests", "framework_tests"] +replace_imports_with_any = ["allure.*", "hypothesis.*", "pytest.*", "pytest_subtests.*", "psycopg2.*", "requests.*"] +ignore_errors_in_generated_code = true +ignore_missing_source = true + [tool.pytest.ini_options] log_cli = true log_level = "INFO" From 3bf48a113e2f0b6072f7b6179cbf149b56008540 Mon Sep 17 00:00:00 2001 From: Martin Kourim Date: Mon, 16 Mar 2026 15:58:11 +0100 Subject: [PATCH 3/3] feat: add explicit type annotations for zuban - Add explicit type annotations (e.g., `dict`, `list`, `list[str]`) to variables assigned from potentially ambiguous expressions, such as dictionary or list lookups with fallback defaults. - Add `# type: ignore[no-any-return]` comments to fixture cache returns where necessary to satisfy type checkers. --- cardano_node_tests/tests/test_kes.py | 2 +- cardano_node_tests/tests/test_mir_certs.py | 2 +- cardano_node_tests/tests/test_native_tokens.py | 2 +- cardano_node_tests/tests/test_staking_rewards.py | 2 +- cardano_node_tests/tests/test_tx_negative.py | 2 +- cardano_node_tests/tests/tests_conway/test_committee.py | 6 ++++-- cardano_node_tests/tests/tests_conway/test_drep.py | 2 +- .../tests/tests_conway/test_pparam_update.py | 2 +- cardano_node_tests/tests/tests_plutus/test_mint_build.py | 2 +- .../tests/tests_plutus/test_spend_negative_raw.py | 4 ++-- cardano_node_tests/utils/clusterlib_utils.py | 8 ++++---- cardano_node_tests/utils/dbsync_utils.py | 6 +++--- cardano_node_tests/utils/governance_setup.py | 4 ++-- cardano_node_tests/utils/governance_utils.py | 8 ++++---- cardano_node_tests/utils/requirements.py | 4 ++-- cardano_node_tests/utils/tx_view.py | 8 ++++---- 16 files changed, 33 insertions(+), 31 deletions(-) diff --git a/cardano_node_tests/tests/test_kes.py b/cardano_node_tests/tests/test_kes.py index 8db0bd2fc..9fcd875a8 100644 --- a/cardano_node_tests/tests/test_kes.py +++ b/cardano_node_tests/tests/test_kes.py @@ -116,7 +116,7 @@ def _check_block_production( ) # Check if the pool is forging any blocks - blocks_made = ledger_state["blocksCurrent"] or {} + blocks_made: dict = ledger_state["blocksCurrent"] or {} is_forging = pool_id_dec in blocks_made return epoch, is_forging diff --git a/cardano_node_tests/tests/test_mir_certs.py b/cardano_node_tests/tests/test_mir_certs.py index b6ee03db2..47c1e928d 100644 --- a/cardano_node_tests/tests/test_mir_certs.py +++ b/cardano_node_tests/tests/test_mir_certs.py @@ -85,7 +85,7 @@ def registered_users( fixture_cache: cluster_management.FixtureCache[list[clusterlib.PoolUser] | None] with cluster_manager.cache_fixture() as fixture_cache: if fixture_cache.value is not None: - return fixture_cache.value + return fixture_cache.value # type: ignore[no-any-return] fixture_cache.value = registered for i, pool_user in enumerate(registered): diff --git a/cardano_node_tests/tests/test_native_tokens.py b/cardano_node_tests/tests/test_native_tokens.py index 5df10d2c1..4463757cb 100644 --- a/cardano_node_tests/tests/test_native_tokens.py +++ b/cardano_node_tests/tests/test_native_tokens.py @@ -1779,7 +1779,7 @@ def new_token( fixture_cache: cluster_management.FixtureCache[clusterlib_utils.NativeTokenRec | None] with cluster_manager.cache_fixture() as fixture_cache: if fixture_cache.value is not None: - return fixture_cache.value + return fixture_cache.value # type: ignore[no-any-return] rand = clusterlib.get_rand_str(4) temp_template = f"test_tx_new_token_ci{cluster_manager.cluster_instance_num}_{rand}" diff --git a/cardano_node_tests/tests/test_staking_rewards.py b/cardano_node_tests/tests/test_staking_rewards.py index b35665955..79ab5cf91 100644 --- a/cardano_node_tests/tests/test_staking_rewards.py +++ b/cardano_node_tests/tests/test_staking_rewards.py @@ -1035,7 +1035,7 @@ def test_decreasing_reward_transferred_funds( f"Incorrect balance for source address `{delegation_out.pool_user.payment.address}`" ) - rewards_rec = [] + rewards_rec: list[int] = [] # Keep withdrawing new rewards so reward balance is 0 def _withdraw(): diff --git a/cardano_node_tests/tests/test_tx_negative.py b/cardano_node_tests/tests/test_tx_negative.py index a73366bf1..169d92aba 100644 --- a/cardano_node_tests/tests/test_tx_negative.py +++ b/cardano_node_tests/tests/test_tx_negative.py @@ -330,7 +330,7 @@ def _get_validity_range( """Get validity range from a transaction body.""" tx_loaded = tx_view.load_tx_view(cluster_obj=cluster_obj, tx_body_file=tx_body_file) - validity_range = tx_loaded.get("validity range") or {} + validity_range: dict = tx_loaded.get("validity range") or {} loaded_invalid_before = validity_range.get("lower bound") loaded_invalid_hereafter = validity_range.get("upper bound") or validity_range.get( diff --git a/cardano_node_tests/tests/tests_conway/test_committee.py b/cardano_node_tests/tests/tests_conway/test_committee.py index 4780c4dd2..d3e43d83f 100644 --- a/cardano_node_tests/tests/tests_conway/test_committee.py +++ b/cardano_node_tests/tests/tests_conway/test_committee.py @@ -1150,7 +1150,9 @@ def _check_resign_dbsync(res_member: clusterlib.CCMember) -> None: xfail_ledger_4001_msgs = set() for _cc_member_key in (cc_member1_key, cc_member2_key, cc_member3_key): - rat_add_member_rec = rat_add_committee_state["committee"].get(_cc_member_key) or {} + rat_add_member_rec: dict = ( + rat_add_committee_state["committee"].get(_cc_member_key) or {} + ) if rat_add_member_rec: assert rat_add_member_rec["hotCredsAuthStatus"]["tag"] != "MemberAuthorized", ( "CC Member is still authorized" @@ -1516,7 +1518,7 @@ def _check_rat_gov_state( vote_zero_cc_epoch = cluster.g_query.get_epoch() def _check_zero_cc_state(state: dict): - pparams = state.get("curPParams") or state.get("currentPParams") or {} + pparams: dict = state.get("curPParams") or state.get("currentPParams") or {} clusterlib_utils.check_updated_params( update_proposals=zero_cc_proposal.proposals, protocol_params=pparams ) diff --git a/cardano_node_tests/tests/tests_conway/test_drep.py b/cardano_node_tests/tests/tests_conway/test_drep.py index 13fd9173c..8ca30a818 100644 --- a/cardano_node_tests/tests/tests_conway/test_drep.py +++ b/cardano_node_tests/tests/tests_conway/test_drep.py @@ -101,7 +101,7 @@ def get_custom_drep( fixture_cache: cluster_management.FixtureCache[governance_utils.DRepRegistration | None] with cluster_manager.cache_fixture(key=caching_key) as fixture_cache: if fixture_cache.value is not None: - return fixture_cache.value + return fixture_cache.value # type: ignore[no-any-return] reg_drep = create_drep( name_template=name_template, diff --git a/cardano_node_tests/tests/tests_conway/test_pparam_update.py b/cardano_node_tests/tests/tests_conway/test_pparam_update.py index 39e5f98dd..b08614f00 100644 --- a/cardano_node_tests/tests/tests_conway/test_pparam_update.py +++ b/cardano_node_tests/tests/tests_conway/test_pparam_update.py @@ -707,7 +707,7 @@ def _propose_pparams_update( prev_action_rec=prev_action_rec, ) - proposed_pparams_errors = [] + proposed_pparams_errors: list[str] = [] def _check_proposed_pparams( update_proposals: list[clusterlib_utils.UpdateProposal], protocol_params: dict diff --git a/cardano_node_tests/tests/tests_plutus/test_mint_build.py b/cardano_node_tests/tests/tests_plutus/test_mint_build.py index 859d61084..0619b4187 100644 --- a/cardano_node_tests/tests/tests_plutus/test_mint_build.py +++ b/cardano_node_tests/tests/tests_plutus/test_mint_build.py @@ -64,7 +64,7 @@ def past_horizon_funds( fixture_cache: cluster_management.FixtureCache[PHorizonFundsT | None] with cluster_manager.cache_fixture() as fixture_cache: if fixture_cache.value is not None: - return fixture_cache.value + return fixture_cache.value # type: ignore[no-any-return] temp_template = common.get_test_id(cluster) payment_addr = payment_addrs[0] diff --git a/cardano_node_tests/tests/tests_plutus/test_spend_negative_raw.py b/cardano_node_tests/tests/tests_plutus/test_spend_negative_raw.py index 1f421d4c6..cc58f1aa6 100644 --- a/cardano_node_tests/tests/tests_plutus/test_spend_negative_raw.py +++ b/cardano_node_tests/tests/tests_plutus/test_spend_negative_raw.py @@ -755,7 +755,7 @@ def fund_script_guessing_game_v1( fixture_cache: cluster_management.FixtureCache[FundTupleT | None] with cluster_manager.cache_fixture() as fixture_cache: if fixture_cache.value is not None: - return fixture_cache.value + return fixture_cache.value # type: ignore[no-any-return] temp_template = common.get_test_id(cluster) @@ -780,7 +780,7 @@ def fund_script_guessing_game_v2( fixture_cache: cluster_management.FixtureCache[FundTupleT | None] with cluster_manager.cache_fixture() as fixture_cache: if fixture_cache.value is not None: - return fixture_cache.value + return fixture_cache.value # type: ignore[no-any-return] temp_template = common.get_test_id(cluster) diff --git a/cardano_node_tests/utils/clusterlib_utils.py b/cardano_node_tests/utils/clusterlib_utils.py index 746b5a8ec..7a46fe90c 100644 --- a/cardano_node_tests/utils/clusterlib_utils.py +++ b/cardano_node_tests/utils/clusterlib_utils.py @@ -547,11 +547,11 @@ def load_registered_pool_data( pool_id = helpers.decode_bech32(pool_id) pool_state: dict = cluster_obj.g_query.get_pool_state(stake_pool_id=pool_id).pool_params - metadata = helpers.get_pool_param("spsMetadata", pool_params=pool_state) or {} + metadata: dict = helpers.get_pool_param("spsMetadata", pool_params=pool_state) or {} # TODO: extend to handle more relays records - relays_list = helpers.get_pool_param("spsRelays", pool_params=pool_state) or [] - relay = relays_list[0] if relays_list else {} + relays_list: list = helpers.get_pool_param("spsRelays", pool_params=pool_state) or [] + relay: dict = relays_list[0] if relays_list else {} relay = relay.get("single host address") or {} pool_data = clusterlib.PoolData( @@ -605,7 +605,7 @@ def _get_param(key: str) -> tp.Any: ) if pool_creation_data.pool_metadata_url and pool_creation_data.pool_metadata_hash: - metadata = _get_param("spsMetadata") or {} + metadata: dict = _get_param("spsMetadata") or {} metadata_hash = metadata.get("hash") if metadata_hash != pool_creation_data.pool_metadata_hash: diff --git a/cardano_node_tests/utils/dbsync_utils.py b/cardano_node_tests/utils/dbsync_utils.py index 0728bc2ef..0a283dacb 100644 --- a/cardano_node_tests/utils/dbsync_utils.py +++ b/cardano_node_tests/utils/dbsync_utils.py @@ -669,7 +669,7 @@ def check_pool_data( # noqa: C901 f"Expected: {sps_cost} vs Returned: {db_pool_data.fixed_cost}" ) - metadata = helpers.get_pool_param("spsMetadata", pool_params=ledger_pool_data) or {} + metadata: dict = helpers.get_pool_param("spsMetadata", pool_params=ledger_pool_data) or {} metadata_hash = metadata.get("hash") or "" if metadata_hash != db_pool_data.metadata_hash: @@ -751,7 +751,7 @@ def check_pool_off_chain_data( msg = f"no off chain data for pool {pool_id}" raise DbSyncNoResponseError(msg) - metadata = helpers.get_pool_param("spsMetadata", pool_params=ledger_pool_data) or {} + metadata: dict = helpers.get_pool_param("spsMetadata", pool_params=ledger_pool_data) or {} metadata_hash = metadata.get("hash") or "" db_metadata_hash = db_pool_off_chain_data[0].hash.hex() @@ -775,7 +775,7 @@ def check_pool_off_chain_fetch_error( raise DbSyncNoResponseError(msg) fetch_error_str = db_pool_off_chain_fetch_error[0].fetch_error or "" - metadata = helpers.get_pool_param("spsMetadata", pool_params=ledger_pool_data) or {} + metadata: dict = helpers.get_pool_param("spsMetadata", pool_params=ledger_pool_data) or {} metadata_url = metadata.get("url") or "" assert ( diff --git a/cardano_node_tests/utils/governance_setup.py b/cardano_node_tests/utils/governance_setup.py index b2d47704a..a23366d1a 100644 --- a/cardano_node_tests/utils/governance_setup.py +++ b/cardano_node_tests/utils/governance_setup.py @@ -132,7 +132,7 @@ def create_vote_stake( def load_committee(*, cluster_obj: clusterlib.ClusterLib) -> list[governance_utils.CCKeyMember]: - genesis_cc_members = cluster_obj.conway_genesis.get("committee", {}).get("members") or {} + genesis_cc_members: dict = cluster_obj.conway_genesis.get("committee", {}).get("members") or {} if not genesis_cc_members: return [] @@ -292,7 +292,7 @@ def _setup_gov() -> governance_utils.GovernanceRecords | None: fixture_cache: cluster_management.FixtureCache[governance_utils.GovernanceRecords | None] with cluster_manager.cache_fixture(key=gov_data_checksum) as fixture_cache: if fixture_cache.value is not None: - return fixture_cache.value + return fixture_cache.value # type: ignore[no-any-return] if governance_data is None: with open(gov_data_store, "rb") as in_data: diff --git a/cardano_node_tests/utils/governance_utils.py b/cardano_node_tests/utils/governance_utils.py index af9bfc8fe..74f2baa52 100644 --- a/cardano_node_tests/utils/governance_utils.py +++ b/cardano_node_tests/utils/governance_utils.py @@ -199,12 +199,12 @@ def get_vote_str(*, vote: clusterlib.Votes) -> str: def check_drep_delegation(*, deleg_state: dict, drep_id: str, stake_addr_hash: str) -> None: dstate = deleg_state["dstate"] - drep_records = dstate.get("accounts") or {} # In cardano-node >= 10.6.0 + drep_records: dict = dstate.get("accounts") or {} # In cardano-node >= 10.6.0 if not drep_records: drep_records = dstate.get("unified", {}).get("credentials") or {} stake_addr_key = f"keyHash-{stake_addr_hash}" - stake_addr_val = drep_records.get(stake_addr_key) or {} + stake_addr_val: dict = drep_records.get(stake_addr_key) or {} cred_name = get_drep_cred_name(drep_id=drep_id) expected_drep = f"drep-{cred_name}" @@ -225,11 +225,11 @@ def check_drep_stake_distribution( def get_prev_action( *, action_type: PrevGovActionIds, gov_state: dict[str, tp.Any] ) -> PrevActionRec: - prev_action_rec = ( + prev_action_rec: dict = ( gov_state["nextRatifyState"]["nextEnactState"]["prevGovActionIds"][action_type.value] or {} ) txid = prev_action_rec.get("txId") or "" - _ix = prev_action_rec.get("govActionIx", None) + _ix = prev_action_rec.get("govActionIx") ix = -1 if _ix is None else _ix return PrevActionRec(txid=txid, ix=ix) diff --git a/cardano_node_tests/utils/requirements.py b/cardano_node_tests/utils/requirements.py index 46a677e45..a3233bb4a 100644 --- a/cardano_node_tests/utils/requirements.py +++ b/cardano_node_tests/utils/requirements.py @@ -116,7 +116,7 @@ def merge_reqs(*reqs: dict[str, dict]) -> dict: for gname, greqs in report.items(): merged_group = merged.get(gname) or {} for req_id, req_data in greqs.items(): - merged_rec = merged_group.get(req_id) or {} + merged_rec: dict = merged_group.get(req_id) or {} merged_status_key = merged_rec.get("status") or "uncovered" merged_status_val = Statuses[merged_status_key].value @@ -137,7 +137,7 @@ def get_mapped_req(*, mapping: pl.Path, executed_req: dict) -> dict: # noqa: C9 errors: dict[str, set[str]] = {} for group, reqs in requirements_mapping.items(): reqs_set = set(reqs.keys()) - executed_group = executed_req.get(group) or {} + executed_group: dict = executed_req.get(group) or {} if not executed_group: executed_req[group] = executed_group diff --git a/cardano_node_tests/utils/tx_view.py b/cardano_node_tests/utils/tx_view.py index ec65d4371..889afed76 100644 --- a/cardano_node_tests/utils/tx_view.py +++ b/cardano_node_tests/utils/tx_view.py @@ -192,7 +192,7 @@ def _check_inline_datums(tx_raw_output: clusterlib.TxRawOutput, tx_loaded: dict) def _check_return_collateral(tx_raw_output: clusterlib.TxRawOutput, tx_loaded: dict) -> None: """Check return collateral in tx_view.""" - collateral_inputs = tx_loaded.get("collateral inputs") or [] + collateral_inputs: list = tx_loaded.get("collateral inputs") or [] if not collateral_inputs: return @@ -210,7 +210,7 @@ def _check_return_collateral(tx_raw_output: clusterlib.TxRawOutput, tx_loaded: d if tx_raw_output.total_collateral_amount and not tx_raw_output.return_collateral_txouts: return - return_collateral = tx_loaded.get("return collateral") or {} + return_collateral: dict = tx_loaded.get("return collateral") or {} assert return_collateral, "No return collateral in tx view" assert "lovelace" in return_collateral.get("amount", {}), ( @@ -256,7 +256,7 @@ def check_tx_view( # noqa: C901 raise AssertionError(msg) # Check outputs - tx_loaded_outputs = tx_loaded.get("outputs") or [] + tx_loaded_outputs: list = tx_loaded.get("outputs") or [] loaded_txouts: set[tuple[str, int, str]] = set() for txout in tx_loaded_outputs: address = txout["address"] @@ -280,7 +280,7 @@ def check_tx_view( # noqa: C901 raise AssertionError(msg) # Check validity intervals - validity_range = tx_loaded.get("validity range") or {} + validity_range: dict = tx_loaded.get("validity range") or {} loaded_invalid_before = validity_range.get("lower bound") if tx_raw_output.invalid_before != loaded_invalid_before: