sarj-python-lint 1.28.2__tar.gz → 1.28.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.
Files changed (192) hide show
  1. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/PKG-INFO +2 -2
  2. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/pyproject.toml +2 -2
  3. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_file_context.py +4 -0
  4. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +4 -3
  5. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +1 -8
  6. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +1 -10
  7. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +1 -9
  8. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +1 -9
  9. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +4 -1
  10. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +2 -0
  11. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/.gitignore +0 -0
  12. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/LICENSE +0 -0
  13. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/README.md +0 -0
  14. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/__init__.py +0 -0
  15. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/__main__.py +0 -0
  16. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_analysis_session.py +0 -0
  17. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_filesystem.py +0 -0
  18. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_python_target.py +0 -0
  19. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_ratchet_cli.py +0 -0
  20. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_secret_names.py +0 -0
  21. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_source.py +0 -0
  22. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/_version.py +0 -0
  23. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/benchmark.py +0 -0
  24. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/interpreter_argv.py +0 -0
  25. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/json_boundary.py +0 -0
  26. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/py.typed +0 -0
  27. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/ratchet.py +0 -0
  28. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rule_base.py +0 -0
  29. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/__init__.py +0 -0
  30. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
  31. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_ast_index.py +0 -0
  32. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_ast_position.py +0 -0
  33. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
  34. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_comments.py +0 -0
  35. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
  36. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
  37. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
  38. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_docstrings.py +0 -0
  39. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_fastapi.py +0 -0
  40. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_first_party.py +0 -0
  41. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
  42. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_imports.py +0 -0
  43. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_local_source.py +0 -0
  44. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_logging.py +0 -0
  45. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
  46. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_paths.py +0 -0
  47. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_project_index.py +0 -0
  48. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
  49. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_pytest.py +0 -0
  50. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_registry.py +0 -0
  51. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
  52. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_set_fields.py +0 -0
  53. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_sql.py +0 -0
  54. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
  55. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
  56. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_test_composition.py +0 -0
  57. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
  58. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
  59. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
  60. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
  61. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
  62. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
  63. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
  64. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
  65. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
  66. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
  67. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
  68. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
  69. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
  70. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
  71. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
  72. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
  73. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
  74. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
  75. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
  76. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
  77. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
  78. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
  79. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
  80. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
  81. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
  82. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
  83. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
  84. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
  85. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
  86. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
  87. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
  88. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
  89. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
  90. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
  91. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
  92. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
  93. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
  94. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
  95. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
  96. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
  97. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
  98. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
  99. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
  100. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
  101. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
  102. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
  103. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
  104. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
  105. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
  106. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
  107. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
  108. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
  109. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
  110. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
  111. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
  112. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
  113. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
  114. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_select_star.py +0 -0
  115. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
  116. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
  117. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
  118. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
  119. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
  120. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
  121. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
  122. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
  123. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
  124. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
  125. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
  126. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
  127. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
  128. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
  129. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
  130. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
  131. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
  132. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
  133. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
  134. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
  135. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
  136. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
  137. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
  138. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
  139. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
  140. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
  141. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
  142. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
  143. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
  144. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
  145. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
  146. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
  147. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
  148. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
  149. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
  150. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
  151. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
  152. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
  153. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
  154. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
  155. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
  156. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
  157. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
  158. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
  159. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
  160. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
  161. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
  162. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
  163. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
  164. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
  165. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
  166. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
  167. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
  168. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
  169. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
  170. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
  171. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
  172. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
  173. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
  174. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
  175. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
  176. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
  177. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
  178. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
  179. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
  180. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
  181. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
  182. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
  183. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/stepdown.py +0 -0
  184. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
  185. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
  186. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
  187. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
  188. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
  189. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
  190. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
  191. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.3}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
  192. {sarj_python_lint-1.28.2 → sarj_python_lint-1.28.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.28.2
3
+ Version: 1.28.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/
@@ -19,7 +19,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
19
19
  Requires-Python: >=3.14
20
20
  Requires-Dist: packaging==26.3
21
21
  Requires-Dist: ruff>=0.16.10
22
- Requires-Dist: sarj-rule-contracts==0.2.2
22
+ Requires-Dist: sarj-rule-contracts==0.2.3
23
23
  Requires-Dist: sqlglot==30.19.0
24
24
  Requires-Dist: typer==0.27.2
25
25
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sarj-python-lint"
3
- version = "1.28.2"
3
+ version = "1.28.3"
4
4
  description = "Custom Python lint rules — AST-based, pre-commit-friendly, hypermodern defaults"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "sarj-ai" }]
@@ -15,7 +15,7 @@ classifiers = [
15
15
  "Programming Language :: Python :: 3.14",
16
16
  "Topic :: Software Development :: Quality Assurance",
17
17
  ]
18
- dependencies = ["sarj-rule-contracts==0.2.2", "packaging==26.3", "ruff>=0.16.10", "sqlglot==30.19.0", "typer==0.27.2"]
18
+ dependencies = ["sarj-rule-contracts==0.2.3", "packaging==26.3", "ruff>=0.16.10", "sqlglot==30.19.0", "typer==0.27.2"]
19
19
 
20
20
  [project.scripts]
21
21
  sarj-python-lint = "sarj_python_lint.__main__:main"
@@ -57,6 +57,10 @@ class PythonFileContext:
57
57
  def nodes[NodeT: ast.AST](self, *types: type[NodeT]) -> list[NodeT]:
58
58
  return [node for node in self.node_index.query(types) if isinstance(node, types)]
59
59
 
60
+ @cached_property
61
+ def has_wildcard_import(self) -> bool:
62
+ return any(alias.name == "*" for node in self.nodes(ast.ImportFrom) for alias in node.names)
63
+
60
64
  @property
61
65
  def parents(self) -> Mapping[ast.AST, ast.AST]:
62
66
  return self.node_index.parents
@@ -131,11 +131,12 @@ def _pytest_plugin_test_targets(tree: ast.Module) -> list[_PluginTarget]:
131
131
  for statement in tree.body:
132
132
  value: ast.expr | None = None
133
133
  match statement:
134
- case (
135
- ast.Assign(targets=[ast.Name(id="pytest_plugins")])
136
- | ast.AnnAssign(target=ast.Name(id="pytest_plugins"))
134
+ case ast.Assign(targets=targets) if any(
135
+ isinstance(target, ast.Name) and target.id == "pytest_plugins" for target in targets
137
136
  ):
138
137
  value = statement.value
138
+ case ast.AnnAssign(target=ast.Name(id="pytest_plugins")):
139
+ value = statement.value
139
140
  case _:
140
141
  continue
141
142
  findings.extend(
@@ -177,7 +177,7 @@ class PreferMatchExceptionDispatch(Rule):
177
177
  imports = context.imports
178
178
  if (
179
179
  not imports.builtin_is_unshadowed("isinstance")
180
- or _has_wildcard_import(tree, node_index=context.node_index)
180
+ or context.has_wildcard_import
181
181
  or _has_local_import(tree, node_index=context.node_index)
182
182
  ):
183
183
  return []
@@ -412,13 +412,6 @@ def _body_terminates(body: list[ast.stmt]) -> bool:
412
412
  return False
413
413
 
414
414
 
415
- def _has_wildcard_import(tree: ast.Module, *, node_index: NodeIndex | None = None) -> bool:
416
- return any(
417
- isinstance(node, ast.ImportFrom) and any(alias.name == "*" for alias in node.names)
418
- for node in walk_ast(tree, index=node_index)
419
- )
420
-
421
-
422
415
  def _has_local_import(tree: ast.Module, *, node_index: NodeIndex | None = None) -> bool:
423
416
  module_imports = {id(statement) for statement in tree.body if isinstance(statement, (ast.Import, ast.ImportFrom))}
424
417
  return any(
@@ -16,12 +16,10 @@ from sarj_python_lint.rule_base import (
16
16
  Severity,
17
17
  parse_or_none,
18
18
  )
19
- from sarj_python_lint.rules._ast_index import walk as walk_ast
20
19
 
21
20
 
22
21
  if TYPE_CHECKING:
23
22
  from sarj_python_lint._file_context import PythonFileContext
24
- from sarj_python_lint.rules._ast_index import NodeIndex
25
23
  from sarj_python_lint.rules._imports import ImportIndex
26
24
 
27
25
 
@@ -101,7 +99,7 @@ class PreferNamedtupleOverTupleReturn(Rule):
101
99
  if context.generated or _is_documentation_path(path):
102
100
  return []
103
101
  tree = context.tree
104
- if tree is None or _has_wildcard_import(tree, node_index=context.node_index):
102
+ if tree is None or context.has_wildcard_import:
105
103
  return []
106
104
  imports = context.imports
107
105
  diagnostics: list[Diagnostic] = []
@@ -127,13 +125,6 @@ def _is_documentation_path(path: Path) -> bool:
127
125
  return any(part.lower() in _DOCUMENTATION_DIR_NAMES for part in path.parts)
128
126
 
129
127
 
130
- def _has_wildcard_import(tree: ast.Module, *, node_index: NodeIndex | None = None) -> bool:
131
- return any(
132
- isinstance(node, ast.ImportFrom) and any(alias.name == "*" for alias in node.names)
133
- for node in walk_ast(tree, index=node_index)
134
- )
135
-
136
-
137
128
  def _is_public_record_tuple(annotation: ast.expr, imports: ImportIndex) -> bool:
138
129
  annotation = _unwrap_return_annotation(annotation, imports)
139
130
  if not isinstance(annotation, ast.Subscript) or not isinstance(annotation.slice, ast.Tuple):
@@ -27,7 +27,6 @@ if TYPE_CHECKING:
27
27
  from pathlib import Path
28
28
 
29
29
  from sarj_python_lint._file_context import PythonFileContext
30
- from sarj_python_lint.rules._ast_index import NodeIndex
31
30
  from sarj_python_lint.rules._imports import ImportIndex
32
31
 
33
32
 
@@ -221,7 +220,7 @@ class PreferNominalIdTypes(Rule):
221
220
  if _is_excluded_path(path) or context.generated:
222
221
  return []
223
222
  tree = context.tree
224
- if tree is None or _has_wildcard_import(tree, node_index=context.node_index):
223
+ if tree is None or context.has_wildcard_import:
225
224
  return []
226
225
 
227
226
  imports = context.imports
@@ -311,13 +310,6 @@ def _is_excluded_path(path: Path) -> bool:
311
310
  )
312
311
 
313
312
 
314
- def _has_wildcard_import(tree: ast.Module, *, node_index: NodeIndex | None = None) -> bool:
315
- return any(
316
- isinstance(node, ast.ImportFrom) and any(alias.name == "*" for alias in node.names)
317
- for node in walk_ast(tree, index=node_index)
318
- )
319
-
320
-
321
313
  def _boundary_nodes(
322
314
  tree: ast.Module,
323
315
  imports: ImportIndex,
@@ -23,7 +23,6 @@ if TYPE_CHECKING:
23
23
  from collections.abc import Iterator
24
24
 
25
25
  from sarj_python_lint._file_context import PythonFileContext
26
- from sarj_python_lint.rules._ast_index import NodeIndex
27
26
  from sarj_python_lint.rules._imports import ImportIndex
28
27
 
29
28
 
@@ -99,7 +98,7 @@ class PreferNonNullableCollection(Rule):
99
98
  if is_test_path(path) or is_test_support_path(path) or context.generated:
100
99
  return []
101
100
  tree = context.tree
102
- if tree is None or _has_wildcard_import(tree, node_index=context.node_index):
101
+ if tree is None or context.has_wildcard_import:
103
102
  return []
104
103
 
105
104
  imports = context.imports
@@ -125,13 +124,6 @@ class PreferNonNullableCollection(Rule):
125
124
  return sorted(diagnostics, key=lambda diagnostic: (diagnostic.line, diagnostic.col))
126
125
 
127
126
 
128
- def _has_wildcard_import(tree: ast.Module, *, node_index: NodeIndex | None = None) -> bool:
129
- return any(
130
- isinstance(node, ast.ImportFrom) and any(alias.name == "*" for alias in node.names)
131
- for node in walk_ast(tree, index=node_index)
132
- )
133
-
134
-
135
127
  def _eligible_functions(tree: ast.Module, imports: ImportIndex) -> list[ast.FunctionDef | ast.AsyncFunctionDef]:
136
128
  functions: list[ast.FunctionDef | ast.AsyncFunctionDef] = []
137
129
  for statement in tree.body:
@@ -61,7 +61,10 @@ class RedundantTestConstructorForwarder(ProjectRule):
61
61
  example_id=name,
62
62
  title=title,
63
63
  outcome=outcome,
64
- files=(ExampleFile.python("tests/test_record.py", source),),
64
+ files=(
65
+ ExampleFile.python("tests/__init__.py", "# Example test package.\n"),
66
+ ExampleFile.python("tests/test_record.py", source),
67
+ ),
65
68
  focus_path=PurePosixPath("tests/test_record.py"),
66
69
  expected_count=count,
67
70
  public=True,
@@ -60,6 +60,7 @@ class RepeatedUnimplementedTestContract(ProjectRule):
60
60
  title="Two test fakes repeat one unconfigured operation",
61
61
  outcome=ExampleOutcome.MATCH,
62
62
  files=(
63
+ ExampleFile.python("tests/__init__.py", "# Example test package.\n"),
63
64
  ExampleFile.python(
64
65
  "tests/test_store.py",
65
66
  "from abc import ABC, abstractmethod\nclass Store(ABC):\n @abstractmethod\n def read(self, key: str) -> str:\n pass\nclass First(Store):\n def read(self, key: str) -> str:\n raise NotImplementedError\nclass Second(Store):\n def read(self, key: str) -> str:\n raise NotImplementedError\n",
@@ -74,6 +75,7 @@ class RepeatedUnimplementedTestContract(ProjectRule):
74
75
  title="Configured fake behavior belongs to the leaf",
75
76
  outcome=ExampleOutcome.NO_MATCH,
76
77
  files=(
78
+ ExampleFile.python("tests/__init__.py", "# Example test package.\n"),
77
79
  ExampleFile.python(
78
80
  "tests/test_store.py",
79
81
  "from abc import ABC, abstractmethod\nclass Store(ABC):\n @abstractmethod\n def read(self, key: str) -> str:\n pass\nclass First(Store):\n def read(self, key: str) -> str:\n raise NotImplementedError\nclass Second(Store):\n def read(self, key: str) -> str:\n return key\n",