sarj-python-lint 0.87.4__tar.gz → 0.87.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/PKG-INFO +1 -1
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/pyproject.toml +1 -1
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_ast_index.py +9 -15
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_registry.py +2 -0
- sarj_python_lint-0.87.7/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +225 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +3 -3
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +4 -3
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +4 -4
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/.gitignore +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/LICENSE +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/README.md +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/__main__.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_docstrings.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_fastapi.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_project_index.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_sql.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/require_typed_http_test_response.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sarj-python-lint
|
|
3
|
-
Version: 0.87.
|
|
3
|
+
Version: 0.87.7
|
|
4
4
|
Summary: Custom Python lint rules — AST-based, pre-commit-friendly, hypermodern defaults
|
|
5
5
|
Project-URL: Homepage, https://code-standards.sarj.ai/rules/python/
|
|
6
6
|
Project-URL: Documentation, https://code-standards.sarj.ai/rules/python/
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import ast
|
|
6
|
-
from typing import TYPE_CHECKING, final
|
|
6
|
+
from typing import TYPE_CHECKING, TypeIs, final
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
@@ -13,12 +13,16 @@ if TYPE_CHECKING:
|
|
|
13
13
|
_AST = ast.AST
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
def object_list(value: object) -> TypeIs[list[object]]:
|
|
17
|
+
return isinstance(value, list)
|
|
18
|
+
|
|
19
|
+
|
|
16
20
|
def children(node: ast.AST) -> list[ast.AST]:
|
|
17
21
|
out: list[ast.AST] = []
|
|
18
22
|
for name in node._fields:
|
|
19
23
|
value: object = getattr(node, name, None)
|
|
20
|
-
if
|
|
21
|
-
out += [item for item in value if isinstance(item, _AST)]
|
|
24
|
+
if object_list(value):
|
|
25
|
+
out += [item for item in value if isinstance(item, _AST)]
|
|
22
26
|
elif isinstance(value, _AST):
|
|
23
27
|
out.append(value)
|
|
24
28
|
return out
|
|
@@ -30,12 +34,7 @@ def walk(node: ast.AST) -> Iterator[ast.AST]:
|
|
|
30
34
|
while i < len(queue):
|
|
31
35
|
current = queue[i]
|
|
32
36
|
i += 1
|
|
33
|
-
|
|
34
|
-
value: object = getattr(current, name, None)
|
|
35
|
-
if isinstance(value, list):
|
|
36
|
-
queue += [item for item in value if isinstance(item, _AST)] # pyright: ignore[reportUnknownVariableType] — element narrowed by isinstance
|
|
37
|
-
elif isinstance(value, _AST):
|
|
38
|
-
queue.append(value)
|
|
37
|
+
queue += children(current)
|
|
39
38
|
yield current
|
|
40
39
|
|
|
41
40
|
|
|
@@ -56,12 +55,7 @@ class _NodeIndex:
|
|
|
56
55
|
buckets[cls] = [current]
|
|
57
56
|
else:
|
|
58
57
|
bucket.append(current)
|
|
59
|
-
|
|
60
|
-
value: object = getattr(current, name, None)
|
|
61
|
-
if isinstance(value, list):
|
|
62
|
-
flat += [item for item in value if isinstance(item, _AST)] # pyright: ignore[reportUnknownVariableType] — element narrowed by isinstance
|
|
63
|
-
elif isinstance(value, _AST):
|
|
64
|
-
flat.append(value)
|
|
58
|
+
flat += children(current)
|
|
65
59
|
self._buckets: dict[type[ast.AST], list[ast.AST]] = buckets
|
|
66
60
|
self._flat: list[ast.AST] = flat
|
|
67
61
|
self._queries: dict[tuple[type[ast.AST], ...], list[ast.AST]] = {}
|
|
@@ -47,6 +47,7 @@ from sarj_python_lint.rules.no_file_level_escape_hatch_suppression import (
|
|
|
47
47
|
from sarj_python_lint.rules.no_first_party_private_import import (
|
|
48
48
|
NoFirstPartyPrivateImport,
|
|
49
49
|
)
|
|
50
|
+
from sarj_python_lint.rules.no_fixed_sleep_before_assert import NoFixedSleepBeforeAssert
|
|
50
51
|
from sarj_python_lint.rules.no_frozen_after_validator_field_write import (
|
|
51
52
|
NoFrozenAfterValidatorFieldWrite,
|
|
52
53
|
)
|
|
@@ -204,6 +205,7 @@ REGISTRY: Mapping[str, type[Rule]] = MappingProxyType(
|
|
|
204
205
|
NoRawSourceTextTestOracle.id: NoRawSourceTextTestOracle,
|
|
205
206
|
IacSourceCoupledTest.id: IacSourceCoupledTest,
|
|
206
207
|
NoRawConnectionInTests.id: NoRawConnectionInTests,
|
|
208
|
+
NoFixedSleepBeforeAssert.id: NoFixedSleepBeforeAssert,
|
|
207
209
|
NoAnalyticalAggregationInPostgresStore.id: NoAnalyticalAggregationInPostgresStore,
|
|
208
210
|
NoSelectStar.id: NoSelectStar,
|
|
209
211
|
NoServiceBehaviorInSettings.id: NoServiceBehaviorInSettings,
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import ast
|
|
4
|
+
from itertools import pairwise
|
|
5
|
+
from pathlib import PurePosixPath
|
|
6
|
+
import re
|
|
7
|
+
from typing import TYPE_CHECKING, ClassVar, Final, final, override
|
|
8
|
+
|
|
9
|
+
from sarj_python_lint.rule_base import (
|
|
10
|
+
AutofixPolicy,
|
|
11
|
+
Diagnostic,
|
|
12
|
+
ExampleFile,
|
|
13
|
+
ExampleOutcome,
|
|
14
|
+
Rule,
|
|
15
|
+
RuleCategory,
|
|
16
|
+
RuleDocumentation,
|
|
17
|
+
RuleExample,
|
|
18
|
+
Severity,
|
|
19
|
+
parse_or_none,
|
|
20
|
+
)
|
|
21
|
+
from sarj_python_lint.rules._imports import ImportIndex
|
|
22
|
+
from sarj_python_lint.rules._paths import is_generated
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from collections.abc import Iterator
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
_ASYNC_SLEEPS: Final = frozenset({"asyncio.sleep", "anyio.sleep", "trio.sleep"})
|
|
31
|
+
_DURATION_KEYWORDS: Final = frozenset({"delay", "seconds"})
|
|
32
|
+
_CONSTANT_NAME: Final = re.compile(r"_*[A-Z][A-Z0-9_]*")
|
|
33
|
+
_MESSAGE: Final = (
|
|
34
|
+
"fixed sleep before an assertion guesses how long the code under test needs; await its signal or poll "
|
|
35
|
+
"the condition with a deadline"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
type _TestFunction = ast.FunctionDef | ast.AsyncFunctionDef
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@final
|
|
42
|
+
class NoFixedSleepBeforeAssert(Rule):
|
|
43
|
+
id = "no-fixed-sleep-before-assert"
|
|
44
|
+
code = "SARJ455"
|
|
45
|
+
documentation: ClassVar[RuleDocumentation | None] = RuleDocumentation(
|
|
46
|
+
default_level=Severity.WARNING,
|
|
47
|
+
summary="Do not sleep for a fixed interval and then assert in a test.",
|
|
48
|
+
rationale=(
|
|
49
|
+
"A fixed sleep followed by an assertion guesses how long the code under test needs. On a loaded CI "
|
|
50
|
+
"runner the guess is too short and the test flakes; on an idle one every run pays the whole interval."
|
|
51
|
+
),
|
|
52
|
+
remediation=(
|
|
53
|
+
"Await the signal the code exposes, such as an event, future, queue item, or fake callback, or poll the "
|
|
54
|
+
"condition with a deadline. When the test deliberately proves that nothing happens during a quiet "
|
|
55
|
+
"window, keep the sleep with an exact SARJ455 suppression that names the window."
|
|
56
|
+
),
|
|
57
|
+
category=RuleCategory.TESTING,
|
|
58
|
+
autofix=AutofixPolicy.NONE,
|
|
59
|
+
limitations=(
|
|
60
|
+
"Only pytest-collected test functions in test_*.py and *_test.py modules are inspected; fixtures, helpers, nested functions, and conftest.py are not.",
|
|
61
|
+
"A sleep is reported only when the next statement in the same block is an assert, so an assert placed after the enclosing with, if, or try block is not reported.",
|
|
62
|
+
"A duration is fixed only when built from numeric literals and UPPER_CASE constants; durations read from other names or from calls are not reported.",
|
|
63
|
+
"Sleeps inside loops are treated as polling, and time.sleep in an async test is left to Ruff ASYNC251.",
|
|
64
|
+
),
|
|
65
|
+
examples=(
|
|
66
|
+
RuleExample(
|
|
67
|
+
example_id="test-sleeps-then-asserts",
|
|
68
|
+
title="A test waits a guessed interval before asserting",
|
|
69
|
+
outcome=ExampleOutcome.MATCH,
|
|
70
|
+
files=(
|
|
71
|
+
ExampleFile.python(
|
|
72
|
+
"tests/test_monitor.py",
|
|
73
|
+
"import asyncio\n\n\nasync def test_reports_silence(monitor):\n monitor.start()\n"
|
|
74
|
+
" await asyncio.sleep(0.5)\n assert monitor.reason == 'silence'\n",
|
|
75
|
+
),
|
|
76
|
+
),
|
|
77
|
+
focus_path=PurePosixPath("tests/test_monitor.py"),
|
|
78
|
+
expected_count=1,
|
|
79
|
+
public=True,
|
|
80
|
+
),
|
|
81
|
+
RuleExample(
|
|
82
|
+
example_id="test-awaits-signal-then-asserts",
|
|
83
|
+
title="A test awaits the signal with a deadline before asserting",
|
|
84
|
+
outcome=ExampleOutcome.NO_MATCH,
|
|
85
|
+
files=(
|
|
86
|
+
ExampleFile.python(
|
|
87
|
+
"tests/test_monitor.py",
|
|
88
|
+
"import asyncio\n\n\nasync def test_reports_silence(monitor):\n monitor.start()\n"
|
|
89
|
+
" await asyncio.wait_for(monitor.fired.wait(), timeout=5)\n"
|
|
90
|
+
" assert monitor.reason == 'silence'\n",
|
|
91
|
+
),
|
|
92
|
+
),
|
|
93
|
+
focus_path=PurePosixPath("tests/test_monitor.py"),
|
|
94
|
+
expected_count=0,
|
|
95
|
+
public=True,
|
|
96
|
+
),
|
|
97
|
+
RuleExample(
|
|
98
|
+
example_id="test-blocks-then-asserts",
|
|
99
|
+
title="A synchronous test blocks for a guessed interval before asserting",
|
|
100
|
+
outcome=ExampleOutcome.MATCH,
|
|
101
|
+
files=(
|
|
102
|
+
ExampleFile.python(
|
|
103
|
+
"tests/test_worker.py",
|
|
104
|
+
"import time\n\n\ndef test_worker_drains_queue(worker, queue):\n worker.start()\n"
|
|
105
|
+
" time.sleep(1)\n assert queue.pending() == 0\n",
|
|
106
|
+
),
|
|
107
|
+
),
|
|
108
|
+
focus_path=PurePosixPath("tests/test_worker.py"),
|
|
109
|
+
expected_count=1,
|
|
110
|
+
scenario="blocking-sleep",
|
|
111
|
+
public=True,
|
|
112
|
+
),
|
|
113
|
+
RuleExample(
|
|
114
|
+
example_id="test-polls-with-deadline-then-asserts",
|
|
115
|
+
title="A synchronous test polls the condition with a deadline before asserting",
|
|
116
|
+
outcome=ExampleOutcome.NO_MATCH,
|
|
117
|
+
files=(
|
|
118
|
+
ExampleFile.python(
|
|
119
|
+
"tests/test_worker.py",
|
|
120
|
+
"import time\n\n\ndef test_worker_drains_queue(worker, queue):\n worker.start()\n"
|
|
121
|
+
" deadline = time.monotonic() + 5\n"
|
|
122
|
+
" while queue.pending() and time.monotonic() < deadline:\n time.sleep(0.01)\n"
|
|
123
|
+
" assert queue.pending() == 0\n",
|
|
124
|
+
),
|
|
125
|
+
),
|
|
126
|
+
focus_path=PurePosixPath("tests/test_worker.py"),
|
|
127
|
+
expected_count=0,
|
|
128
|
+
scenario="blocking-sleep",
|
|
129
|
+
public=True,
|
|
130
|
+
),
|
|
131
|
+
),
|
|
132
|
+
)
|
|
133
|
+
description = documentation.summary
|
|
134
|
+
|
|
135
|
+
@override
|
|
136
|
+
def check(self, path: Path, source: str) -> list[Diagnostic]:
|
|
137
|
+
if not _is_collected_test_module(path) or "sleep" not in source or is_generated(path, source):
|
|
138
|
+
return []
|
|
139
|
+
tree = parse_or_none(path, source)
|
|
140
|
+
if tree is None:
|
|
141
|
+
return []
|
|
142
|
+
imports = ImportIndex.from_tree(tree)
|
|
143
|
+
diagnostics = [
|
|
144
|
+
Diagnostic(path=path, line=statement.lineno, col=statement.col_offset + 1, code=self.code, message=_MESSAGE)
|
|
145
|
+
for test in _collected_tests(tree.body)
|
|
146
|
+
for statement, following in _adjacent_statements(test.body)
|
|
147
|
+
if isinstance(following, ast.Assert) and _is_fixed_sleep(statement, test, imports)
|
|
148
|
+
]
|
|
149
|
+
return sorted(diagnostics, key=lambda item: (item.line, item.col))
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _is_collected_test_module(path: Path) -> bool:
|
|
153
|
+
return path.suffix == ".py" and (path.stem.startswith("test_") or path.stem.endswith("_test"))
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _collected_tests(statements: list[ast.stmt]) -> Iterator[_TestFunction]:
|
|
157
|
+
for statement in statements:
|
|
158
|
+
match statement:
|
|
159
|
+
case ast.FunctionDef() | ast.AsyncFunctionDef() if statement.name.startswith("test"):
|
|
160
|
+
yield statement
|
|
161
|
+
case ast.ClassDef() if statement.name.startswith("Test"):
|
|
162
|
+
yield from _collected_tests(statement.body)
|
|
163
|
+
case _:
|
|
164
|
+
pass
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _adjacent_statements(block: list[ast.stmt]) -> Iterator[tuple[ast.stmt, ast.stmt]]:
|
|
168
|
+
yield from pairwise(block)
|
|
169
|
+
for statement in block:
|
|
170
|
+
for nested in _straight_line_blocks(statement):
|
|
171
|
+
yield from _adjacent_statements(nested)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _straight_line_blocks(statement: ast.stmt) -> list[list[ast.stmt]]:
|
|
175
|
+
match statement:
|
|
176
|
+
case ast.If(body=body, orelse=orelse):
|
|
177
|
+
return [body, orelse]
|
|
178
|
+
case ast.With(body=body) | ast.AsyncWith(body=body):
|
|
179
|
+
return [body]
|
|
180
|
+
case (
|
|
181
|
+
ast.Try(body=body, handlers=handlers, orelse=orelse, finalbody=finalbody)
|
|
182
|
+
| ast.TryStar(body=body, handlers=handlers, orelse=orelse, finalbody=finalbody)
|
|
183
|
+
):
|
|
184
|
+
return [body, *(handler.body for handler in handlers), orelse, finalbody]
|
|
185
|
+
case ast.Match(cases=cases):
|
|
186
|
+
return [case.body for case in cases]
|
|
187
|
+
case _:
|
|
188
|
+
return []
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _is_fixed_sleep(statement: ast.stmt, test: _TestFunction, imports: ImportIndex) -> bool:
|
|
192
|
+
match statement:
|
|
193
|
+
case ast.Expr(value=ast.Await(value=ast.Call() as call)):
|
|
194
|
+
return imports.resolved_qualified_name(call.func) in _ASYNC_SLEEPS and _has_fixed_duration(call)
|
|
195
|
+
case ast.Expr(value=ast.Call() as call) if isinstance(test, ast.FunctionDef):
|
|
196
|
+
return imports.resolved_qualified_name(call.func) == "time.sleep" and _has_fixed_duration(call)
|
|
197
|
+
case _:
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _has_fixed_duration(call: ast.Call) -> bool:
|
|
202
|
+
duration = (
|
|
203
|
+
call.args[0]
|
|
204
|
+
if call.args
|
|
205
|
+
else next((keyword.value for keyword in call.keywords if keyword.arg in _DURATION_KEYWORDS), None)
|
|
206
|
+
)
|
|
207
|
+
match duration:
|
|
208
|
+
case None | ast.Constant(value=0):
|
|
209
|
+
return False
|
|
210
|
+
case _:
|
|
211
|
+
return _is_fixed(duration)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _is_fixed(node: ast.expr) -> bool:
|
|
215
|
+
match node:
|
|
216
|
+
case ast.Constant(value=int() | float()):
|
|
217
|
+
return True
|
|
218
|
+
case ast.Name(id=name) | ast.Attribute(attr=name):
|
|
219
|
+
return _CONSTANT_NAME.fullmatch(name) is not None
|
|
220
|
+
case ast.UnaryOp(op=ast.UAdd() | ast.USub(), operand=operand):
|
|
221
|
+
return _is_fixed(operand)
|
|
222
|
+
case ast.BinOp(left=left, op=ast.Add() | ast.Sub() | ast.Mult() | ast.Div() | ast.FloorDiv(), right=right):
|
|
223
|
+
return _is_fixed(left) and _is_fixed(right)
|
|
224
|
+
case _:
|
|
225
|
+
return False
|
|
@@ -19,7 +19,7 @@ from sarj_python_lint.rule_base import (
|
|
|
19
19
|
Severity,
|
|
20
20
|
parse_or_none,
|
|
21
21
|
)
|
|
22
|
-
from sarj_python_lint.rules._ast_index import nodes
|
|
22
|
+
from sarj_python_lint.rules._ast_index import nodes, object_list
|
|
23
23
|
from sarj_python_lint.rules._logging import LOG_METHODS, is_logger_expr
|
|
24
24
|
|
|
25
25
|
|
|
@@ -308,9 +308,9 @@ def _analysis_facts(tree: ast.Module) -> _AnalysisFacts:
|
|
|
308
308
|
|
|
309
309
|
|
|
310
310
|
def _statement_list(value: object) -> list[ast.stmt] | None:
|
|
311
|
-
if not
|
|
311
|
+
if not object_list(value):
|
|
312
312
|
return None
|
|
313
|
-
ast_items: list[ast.AST] = [item for item in value if isinstance(item, ast.AST)]
|
|
313
|
+
ast_items: list[ast.AST] = [item for item in value if isinstance(item, ast.AST)]
|
|
314
314
|
if not ast_items or not all(isinstance(item, ast.stmt) for item in ast_items):
|
|
315
315
|
return None
|
|
316
316
|
return [item for item in ast_items if isinstance(item, ast.stmt)]
|
|
@@ -20,6 +20,7 @@ from sarj_python_lint.rule_base import (
|
|
|
20
20
|
is_suppressed,
|
|
21
21
|
parse_or_none,
|
|
22
22
|
)
|
|
23
|
+
from sarj_python_lint.rules._ast_index import object_list
|
|
23
24
|
from sarj_python_lint.rules._paths import is_generated
|
|
24
25
|
|
|
25
26
|
|
|
@@ -314,11 +315,11 @@ def _statement_lists(tree: ast.AST) -> list[list[ast.stmt]]:
|
|
|
314
315
|
result: list[list[ast.stmt]] = []
|
|
315
316
|
for node in ast.walk(tree):
|
|
316
317
|
for field in ("body", "orelse", "finalbody"):
|
|
317
|
-
value = getattr(node, field, None)
|
|
318
|
-
if not
|
|
318
|
+
value: object = getattr(node, field, None)
|
|
319
|
+
if not object_list(value):
|
|
319
320
|
continue
|
|
320
321
|
statements: list[ast.stmt] = []
|
|
321
|
-
for item in value:
|
|
322
|
+
for item in value:
|
|
322
323
|
if not isinstance(item, ast.stmt):
|
|
323
324
|
break
|
|
324
325
|
statements.append(item)
|
|
@@ -18,7 +18,7 @@ from sarj_python_lint.rule_base import (
|
|
|
18
18
|
is_suppressed,
|
|
19
19
|
parse_or_none,
|
|
20
20
|
)
|
|
21
|
-
from sarj_python_lint.rules._ast_index import children, nodes, walk
|
|
21
|
+
from sarj_python_lint.rules._ast_index import children, nodes, object_list, walk
|
|
22
22
|
from sarj_python_lint.rules._paths import is_generated, is_test_path
|
|
23
23
|
|
|
24
24
|
|
|
@@ -148,10 +148,10 @@ class PreferWalrusRegexMatch(Rule):
|
|
|
148
148
|
)
|
|
149
149
|
|
|
150
150
|
for node in walk(tree):
|
|
151
|
-
raw_body = getattr(node, "body", None)
|
|
152
|
-
if not
|
|
151
|
+
raw_body: object = getattr(node, "body", None)
|
|
152
|
+
if not object_list(raw_body):
|
|
153
153
|
continue
|
|
154
|
-
body: list[ast.stmt] = [st for st in raw_body if isinstance(st, ast.stmt)]
|
|
154
|
+
body: list[ast.stmt] = [st for st in raw_body if isinstance(st, ast.stmt)]
|
|
155
155
|
diags.extend(_check_body(node, body, context))
|
|
156
156
|
|
|
157
157
|
return sorted(diags, key=lambda d: (d.line, d.col))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/_analysis_session.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_fixed_record.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_prose_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/mock_without_spec.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_comment_cruft.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_dunder_all.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_secret_in_log.py
RENAMED
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/no_select_star.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/over_mocked_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_class_row.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_or_pattern.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/prefer_str_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-0.87.4 → sarj_python_lint-0.87.7}/src/sarj_python_lint/rules/unused_mock_setup.py
RENAMED
|
File without changes
|
|
File without changes
|