sarj-python-lint 1.14.2__tar.gz → 1.14.3__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-1.14.2 → sarj_python_lint-1.14.3}/PKG-INFO +1 -1
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/pyproject.toml +1 -1
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_injected_module_loader.py +14 -10
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +78 -16
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +13 -12
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/.gitignore +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/LICENSE +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/README.md +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/__main__.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/_file_context.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/benchmark.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_ast_index.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_docstrings.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_fastapi.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_project_index.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_registry.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_set_fields.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_sql.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_test_composition.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/discourage_nullable_constructor_parameters.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/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: 1.14.
|
|
3
|
+
Version: 1.14.3
|
|
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/
|
|
@@ -185,17 +185,21 @@ def _shadowed(default: ast.expr, function: ast.AST, context: PythonFileContext)
|
|
|
185
185
|
parent = context.parents.get(child)
|
|
186
186
|
class_scope_visible = True
|
|
187
187
|
while parent is not None:
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if isinstance(parent, (ast.FunctionDef, ast.AsyncFunctionDef, ast.Lambda)):
|
|
191
|
-
if _in_scope_body(parent, child):
|
|
192
|
-
if root.id in scope_bindings(parent):
|
|
193
|
-
return True
|
|
194
|
-
class_scope_visible = False
|
|
195
|
-
elif isinstance(parent, ast.ClassDef) and _in_scope_body(parent, child):
|
|
196
|
-
if class_scope_visible and _class_prefix_shadows(parent, child, root.id):
|
|
188
|
+
match parent:
|
|
189
|
+
case ast.ListComp() | ast.SetComp() | ast.DictComp() | ast.GeneratorExp():
|
|
197
190
|
return True
|
|
198
|
-
|
|
191
|
+
case ast.FunctionDef() | ast.AsyncFunctionDef() | ast.Lambda():
|
|
192
|
+
if _in_scope_body(parent, child):
|
|
193
|
+
if root.id in scope_bindings(parent):
|
|
194
|
+
return True
|
|
195
|
+
class_scope_visible = False
|
|
196
|
+
case ast.ClassDef():
|
|
197
|
+
if _in_scope_body(parent, child):
|
|
198
|
+
if class_scope_visible and _class_prefix_shadows(parent, child, root.id):
|
|
199
|
+
return True
|
|
200
|
+
class_scope_visible = False
|
|
201
|
+
case _:
|
|
202
|
+
pass
|
|
199
203
|
child = parent
|
|
200
204
|
parent = context.parents.get(parent)
|
|
201
205
|
return False
|
|
@@ -100,6 +100,7 @@ class PreferMatchTypeDispatch(Rule):
|
|
|
100
100
|
autofix=AutofixPolicy.NONE,
|
|
101
101
|
limitations=(
|
|
102
102
|
"General dispatch requires three or more adjacent, unguarded `isinstance` branches over the same simple name. Two arms are checked only for an exact `ast.Name.id` / `ast.Attribute.attr` projection followed by a None-returning fallback.",
|
|
103
|
+
"A terminating sibling prefix may precede a two-arm if/elif tail whose bodies can fall through. Preserve nested checks inside case bodies rather than moving them into case guards.",
|
|
103
104
|
"The checked types must be unshadowed builtins, unshadowed module-local classes, or proven stdlib ast classes; unresolved imports, runtime type groups, repeated type references, generated files, and non-terminating sibling checks are excluded.",
|
|
104
105
|
"Nested attribute-validation guards are excluded: converting them to keyword class patterns can turn attribute errors into match fallthrough, and an imported isinstance operand may be a runtime tuple rather than a class.",
|
|
105
106
|
"A terminal-looking context-manager body does not prove a sibling branch terminates: exceptions can be suppressed. An unconditional return or raise after the context manager remains eligible.",
|
|
@@ -194,6 +195,36 @@ class PreferMatchTypeDispatch(Rule):
|
|
|
194
195
|
expected_count=0,
|
|
195
196
|
public=True,
|
|
196
197
|
),
|
|
198
|
+
RuleExample(
|
|
199
|
+
example_id="terminal-prefix-with-conditional-tail",
|
|
200
|
+
title="A terminating prefix and conditional if/elif tail dispatch on the same AST node",
|
|
201
|
+
outcome=ExampleOutcome.MATCH,
|
|
202
|
+
scenario="mixed-type-dispatch",
|
|
203
|
+
files=(
|
|
204
|
+
ExampleFile.python(
|
|
205
|
+
"app/bindings.py",
|
|
206
|
+
"import ast\ndef has_binding(node, name):\n if isinstance(node, ast.ListComp):\n return True\n if isinstance(node, ast.FunctionDef):\n if name in bindings(node):\n return True\n elif isinstance(node, ast.ClassDef):\n if name in bindings(node):\n return True\n return False\n",
|
|
207
|
+
),
|
|
208
|
+
),
|
|
209
|
+
focus_path=PurePosixPath("app/bindings.py"),
|
|
210
|
+
expected_count=1,
|
|
211
|
+
public=True,
|
|
212
|
+
),
|
|
213
|
+
RuleExample(
|
|
214
|
+
example_id="class-patterns-with-nested-checks",
|
|
215
|
+
title="Class patterns preserve the nested checks within their case bodies",
|
|
216
|
+
outcome=ExampleOutcome.NO_MATCH,
|
|
217
|
+
scenario="mixed-type-dispatch",
|
|
218
|
+
files=(
|
|
219
|
+
ExampleFile.python(
|
|
220
|
+
"app/bindings.py",
|
|
221
|
+
"import ast\ndef has_binding(node, name):\n match node:\n case ast.ListComp():\n return True\n case ast.FunctionDef():\n if name in bindings(node):\n return True\n case ast.ClassDef():\n if name in bindings(node):\n return True\n return False\n",
|
|
222
|
+
),
|
|
223
|
+
),
|
|
224
|
+
focus_path=PurePosixPath("app/bindings.py"),
|
|
225
|
+
expected_count=0,
|
|
226
|
+
public=True,
|
|
227
|
+
),
|
|
197
228
|
),
|
|
198
229
|
)
|
|
199
230
|
description: str = documentation.summary
|
|
@@ -330,24 +361,23 @@ def _sibling_findings(
|
|
|
330
361
|
def collect_block(statements: list[ast.stmt]) -> None:
|
|
331
362
|
index = 0
|
|
332
363
|
while index < len(statements):
|
|
333
|
-
run
|
|
334
|
-
cursor = index
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if branch is None or (subject is not None and branch.subject != subject) or bool(seen & branch.types):
|
|
343
|
-
break
|
|
344
|
-
run.append(statement)
|
|
345
|
-
subject = branch.subject
|
|
346
|
-
seen.update(branch.types)
|
|
347
|
-
cursor += 1
|
|
364
|
+
run = _terminal_prefix(statements, index, imports, local_classes, unsafe_bindings)
|
|
365
|
+
cursor = index + len(run)
|
|
366
|
+
if run and cursor < len(statements):
|
|
367
|
+
tail_statement = statements[cursor]
|
|
368
|
+
if isinstance(tail_statement, ast.If):
|
|
369
|
+
tail = _two_arm_ladder(tail_statement)
|
|
370
|
+
if tail and _dispatch([*run, *tail], imports, local_classes, unsafe_bindings) is not None:
|
|
371
|
+
run.extend(tail)
|
|
372
|
+
cursor += 1
|
|
348
373
|
dispatch = _dispatch(run, imports, local_classes, unsafe_bindings)
|
|
349
374
|
if dispatch is not None:
|
|
350
|
-
|
|
375
|
+
shape = (
|
|
376
|
+
"terminating isinstance prefix with if/elif tail"
|
|
377
|
+
if run[-2].orelse
|
|
378
|
+
else "terminating isinstance sequence"
|
|
379
|
+
)
|
|
380
|
+
findings.append(_diagnostic(path, code, run[0], dispatch, shape))
|
|
351
381
|
index = max(cursor, index + 1)
|
|
352
382
|
|
|
353
383
|
for owner in all_nodes:
|
|
@@ -356,6 +386,38 @@ def _sibling_findings(
|
|
|
356
386
|
return findings
|
|
357
387
|
|
|
358
388
|
|
|
389
|
+
def _terminal_prefix(
|
|
390
|
+
statements: list[ast.stmt],
|
|
391
|
+
index: int,
|
|
392
|
+
imports: ImportIndex,
|
|
393
|
+
local_classes: frozenset[str],
|
|
394
|
+
unsafe_bindings: frozenset[str],
|
|
395
|
+
) -> list[ast.If]:
|
|
396
|
+
run: list[ast.If] = []
|
|
397
|
+
subject: str | None = None
|
|
398
|
+
seen: set[str] = set()
|
|
399
|
+
for cursor in range(index, len(statements)):
|
|
400
|
+
statement = statements[cursor]
|
|
401
|
+
if not isinstance(statement, ast.If) or statement.orelse or not _body_terminates(statement.body):
|
|
402
|
+
break
|
|
403
|
+
branch = _type_branch(statement.test, imports, local_classes, unsafe_bindings)
|
|
404
|
+
if branch is None or (subject is not None and branch.subject != subject) or bool(seen & branch.types):
|
|
405
|
+
break
|
|
406
|
+
run.append(statement)
|
|
407
|
+
subject = branch.subject
|
|
408
|
+
seen.update(branch.types)
|
|
409
|
+
return run
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def _two_arm_ladder(statement: ast.If) -> tuple[ast.If, ast.If] | None:
|
|
413
|
+
if len(statement.orelse) != 1 or not isinstance(statement.orelse[0], ast.If):
|
|
414
|
+
return None
|
|
415
|
+
second = statement.orelse[0]
|
|
416
|
+
if len(second.orelse) == 1 and isinstance(second.orelse[0], ast.If):
|
|
417
|
+
return None
|
|
418
|
+
return statement, second
|
|
419
|
+
|
|
420
|
+
|
|
359
421
|
def _dispatch(
|
|
360
422
|
branches: list[ast.If],
|
|
361
423
|
imports: ImportIndex,
|
|
@@ -324,18 +324,19 @@ def _module_rebound_names(tree: ast.Module) -> frozenset[str]:
|
|
|
324
324
|
def _suite_rebound_names(statements: list[ast.stmt]) -> frozenset[str]:
|
|
325
325
|
names: set[str] = set()
|
|
326
326
|
for statement in statements:
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
327
|
+
match statement:
|
|
328
|
+
case ast.FunctionDef() | ast.AsyncFunctionDef():
|
|
329
|
+
continue
|
|
330
|
+
case ast.ClassDef():
|
|
331
|
+
names.add(statement.name)
|
|
332
|
+
case ast.Import() | ast.ImportFrom():
|
|
333
|
+
names.update(alias.asname or alias.name.partition(".")[0] for alias in statement.names)
|
|
334
|
+
case _:
|
|
335
|
+
names.update(
|
|
336
|
+
node.id
|
|
337
|
+
for node in walk_ast(statement)
|
|
338
|
+
if isinstance(node, ast.Name) and isinstance(node.ctx, ast.Store)
|
|
339
|
+
)
|
|
339
340
|
return frozenset(names)
|
|
340
341
|
|
|
341
342
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/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
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_dict_key_views.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_fixed_record.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_nominal_project.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_prose_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_set_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/_test_composition.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
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/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-1.14.2 → sarj_python_lint-1.14.3}/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
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/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
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/no_secret_in_log.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/over_mocked_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/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-1.14.2 → sarj_python_lint-1.14.3}/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
|
|
File without changes
|
{sarj_python_lint-1.14.2 → sarj_python_lint-1.14.3}/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
|
|
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-1.14.2 → sarj_python_lint-1.14.3}/src/sarj_python_lint/rules/unused_mock_setup.py
RENAMED
|
File without changes
|
|
File without changes
|