-
Notifications
You must be signed in to change notification settings - Fork 29
fix: improve type safety and error handling in tests #3326
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
Conversation
- Use enum.StrEnum instead of str, enum.Enum for TableCondition and ColumnCondition for better type safety. - Use getattr for subtest scenario names to avoid AttributeError if __name__ is missing. - Add type: ignore comments to suppress mypy/pyright warnings where function signatures are not fully compatible. - Use tp.cast for type casting in test_ledger_state and test_staking_rewards for clarity and type safety. - Simplify conditional expressions using `or` instead of ternary operators. - Add missing psycopg2.extensions import for type checking. - Add type: ignore for possibly missing LockNotAvailable attribute in dbsync_queries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR focuses on improving type safety and making test utilities more robust to edge-cases in naming/introspection, while also simplifying a set of conditional expressions.
Changes:
- Replaced multiple
x if x else ypatterns withx or yacross utils/tests. - Improved robustness of subtest scenario naming using
getattr(..., "__name__", ...). - Added/adjusted typing aids (casts, imports for type checking, and type-ignore comments).
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| cardano_node_tests/utils/governance_utils.py | Simplifies list defaulting logic when building governance action data. |
| cardano_node_tests/utils/dbsync_queries.py | Adds psycopg2 typing import and suppresses type-checker warning on a psycopg2 error attribute. |
| cardano_node_tests/utils/dbsync_conn.py | Adds psycopg2 typing import to support type checking. |
| cardano_node_tests/utils/clusterlib_utils.py | Adjusts type-ignore comment for record_cli_coverage call. |
| cardano_node_tests/utils/cluster_nodes.py | Simplifies defaulting of service_names argument. |
| cardano_node_tests/tests/tests_plutus_v2/test_mint_raw.py | Simplifies defaulting of datum hash file argument. |
| cardano_node_tests/tests/tests_plutus_v2/test_mint_build.py | Simplifies defaulting of inline datum file argument. |
| cardano_node_tests/tests/tests_plutus_v2/mint_raw.py | Simplifies defaulting of datum hash file argument. |
| cardano_node_tests/tests/tests_plutus_v2/mint_build.py | Simplifies defaulting of inline datum file argument. |
| cardano_node_tests/tests/tests_plutus/test_spend_build.py | Simplifies multiple optional file/value arguments to empty-string defaults. |
| cardano_node_tests/tests/tests_plutus/spend_raw.py | Simplifies multiple optional file/value arguments to empty-string defaults. |
| cardano_node_tests/tests/tests_plutus/spend_build.py | Simplifies multiple optional file/value arguments to empty-string defaults. |
| cardano_node_tests/tests/tests_conway/test_guardrails.py | Simplifies limit fallback logic and makes subtest naming resilient to missing __name__. |
| cardano_node_tests/tests/test_staking_rewards.py | Adds explicit cast for snapshot record typing. |
| cardano_node_tests/tests/test_pools.py | Makes subtest naming resilient to missing __name__. |
| cardano_node_tests/tests/test_mnemonic.py | Adds type-ignore comments for Hypothesis composite-strategy call patterns. |
| cardano_node_tests/tests/test_ledger_state.py | Adds explicit cast for snapshot record typing. |
| cardano_node_tests/tests/test_dbsync_config.py | Uses enum.StrEnum for stronger string-enum typing; makes subtest naming resilient. |
| cardano_node_tests/tests/test_dbsync.py | Simplifies tx_count summation defaulting to 0. |
| cardano_node_tests/tests/conftest.py | Changes type-check suppression style for xdist NodeManager EXIT_TIMEOUT override. |
| agent_docs/subtests.md | Updates docs to reflect safer subtest scenario naming. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| type_upper_limit = param.param_upper_limit or get_upper_limit_according_to_type( | ||
| param_predicates["type"] | ||
| ) |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using or here changes semantics when the limit is a valid falsy value (e.g., 0). If param.param_lower_limit or param.param_upper_limit can be 0, this code will incorrectly fall back to the default. Prefer an explicit is not None check (or use a sentinel) so that 0 is preserved.
| type_upper_limit = param.param_upper_limit or get_upper_limit_according_to_type( | |
| param_predicates["type"] | |
| ) | |
| if param.param_upper_limit is not None: | |
| type_upper_limit = param.param_upper_limit | |
| else: | |
| type_upper_limit = get_upper_limit_according_to_type(param_predicates["type"]) |
| custom_clusterlib.record_cli_coverage( | ||
| cli_args=cardano_cli_args, | ||
| coverage_dict=cluster_obj.cli_coverage, # pyright: ignore [reportAttributeAccessIssue] | ||
| coverage_dict=cluster_obj.cli_coverage, # type: ignore[invalid-argument-type] |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ignore code invalid-argument-type is not a mypy error code (mypy typically uses arg-type for this case), and pyright won’t recognize it as a targeted suppression either. Use a correct mypy code (e.g., # type: ignore[arg-type]) and/or keep a # pyright: ignore[...] directive that matches the actual pyright diagnostic to ensure this suppression works with the intended type checker(s).
| coverage_dict=cluster_obj.cli_coverage, # type: ignore[invalid-argument-type] | |
| coverage_dict=cluster_obj.cli_coverage, # type: ignore[arg-type] |
| try: | ||
| result = cur.fetchone() | ||
| except psycopg2.errors.LockNotAvailable as e: | ||
| except psycopg2.errors.LockNotAvailable as e: # type: ignore[possibly-missing-attribute] |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ignore code possibly-missing-attribute is unlikely to be recognized by mypy (common mypy codes here are attr-defined/union-attr) and won’t map to a pyright rule name either. If the goal is to silence type-checking about LockNotAvailable not existing in some psycopg2 stubs, prefer a supported suppression (e.g., a mypy-compatible # type: ignore[attr-defined], or a # pyright: ignore[reportAttributeAccessIssue]) so CI type checks don’t regress.
| except psycopg2.errors.LockNotAvailable as e: # type: ignore[possibly-missing-attribute] | |
| except psycopg2.errors.LockNotAvailable as e: # type: ignore[attr-defined] |
| tokens = draw(word_sequence(count=count, ensure_invalid=False)) # type: ignore[missing-argument] | ||
| line = draw(join_with_weirdness(tokens=tokens)) # type: ignore[missing-argument] |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The targeted ignore code missing-argument is not a standard mypy error code (mypy typically reports these as call-arg). If these functions are Hypothesis @st.composite strategies, the runtime calling pattern is fine, but the suppression should use a code that your type checker actually understands (or fall back to plain # type: ignore / an appropriate # pyright: ignore[...]). Otherwise, the warnings you intended to suppress may still fail CI.
| wrong_count_files(), # type: ignore[missing-argument] | ||
| unknown_word_files(), # type: ignore[missing-argument] | ||
| separator_mess_files(), # type: ignore[missing-argument] | ||
| encoding_garbage_files(), # type: ignore[missing-argument] |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The targeted ignore code missing-argument is not a standard mypy error code (mypy typically reports these as call-arg). If these functions are Hypothesis @st.composite strategies, the runtime calling pattern is fine, but the suppression should use a code that your type checker actually understands (or fall back to plain # type: ignore / an appropriate # pyright: ignore[...]). Otherwise, the warnings you intended to suppress may still fail CI.
| wrong_count_files(), # type: ignore[missing-argument] | |
| unknown_word_files(), # type: ignore[missing-argument] | |
| separator_mess_files(), # type: ignore[missing-argument] | |
| encoding_garbage_files(), # type: ignore[missing-argument] | |
| wrong_count_files(), # type: ignore[call-arg] | |
| unknown_word_files(), # type: ignore[call-arg] | |
| separator_mess_files(), # type: ignore[call-arg] | |
| encoding_garbage_files(), # type: ignore[call-arg] |
|
|
||
| for subt in get_subtests(): | ||
| with subtests.test(scenario=subt.__name__): | ||
| with subtests.test(scenario=getattr(subt, "__name__", "")): |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Falling back to an empty string makes subtest output harder to interpret when __name__ is missing. Consider using a more informative fallback (e.g., repr(subt) or subt.__class__.__name__) so failures still include a meaningful scenario label. The same pattern appears in other tests updated in this PR.
| with subtests.test(scenario=getattr(subt, "__name__", "")): | |
| with subtests.test(scenario=getattr(subt, "__name__", repr(subt))): |
|
|
||
|
|
||
| class TableCondition(str, enum.Enum): | ||
| class TableCondition(enum.StrEnum): |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum.StrEnum is only available on Python 3.11+. If this project (or any of its supported environments) still runs on Python 3.10 or earlier, this will fail at import time. If older versions are supported, keep class X(str, enum.Enum) or add a compatibility shim/backport strategy.
|
|
||
|
|
||
| class ColumnCondition(str, enum.Enum): | ||
| class ColumnCondition(enum.StrEnum): |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum.StrEnum is only available on Python 3.11+. If this project (or any of its supported environments) still runs on Python 3.10 or earlier, this will fail at import time. If older versions are supported, keep class X(str, enum.Enum) or add a compatibility shim/backport strategy.
orinstead of ternary operators.