sarj-python-lint 1.25.1__tar.gz → 1.25.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 (182) hide show
  1. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/PKG-INFO +1 -1
  2. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/pyproject.toml +1 -1
  3. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +13 -5
  4. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_port_for_service.py +10 -3
  5. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/.gitignore +0 -0
  6. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/LICENSE +0 -0
  7. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/README.md +0 -0
  8. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/__init__.py +0 -0
  9. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/__main__.py +0 -0
  10. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/_analysis_session.py +0 -0
  11. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/_file_context.py +0 -0
  12. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/_filesystem.py +0 -0
  13. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/_python_target.py +0 -0
  14. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/_ratchet_cli.py +0 -0
  15. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/_secret_names.py +0 -0
  16. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/_version.py +0 -0
  17. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/benchmark.py +0 -0
  18. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/json_boundary.py +0 -0
  19. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/py.typed +0 -0
  20. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/ratchet.py +0 -0
  21. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rule_base.py +0 -0
  22. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/__init__.py +0 -0
  23. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
  24. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_ast_index.py +0 -0
  25. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_ast_position.py +0 -0
  26. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_comments.py +0 -0
  27. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
  28. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
  29. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
  30. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_docstrings.py +0 -0
  31. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_fastapi.py +0 -0
  32. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_first_party.py +0 -0
  33. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
  34. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_imports.py +0 -0
  35. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_local_source.py +0 -0
  36. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_logging.py +0 -0
  37. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
  38. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_paths.py +0 -0
  39. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_project_index.py +0 -0
  40. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
  41. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_pytest.py +0 -0
  42. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_registry.py +0 -0
  43. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
  44. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_set_fields.py +0 -0
  45. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_sql.py +0 -0
  46. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
  47. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
  48. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_test_composition.py +0 -0
  49. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
  50. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
  51. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
  52. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
  53. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
  54. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
  55. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
  56. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
  57. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
  58. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
  59. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
  60. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
  61. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
  62. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
  63. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
  64. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
  65. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
  66. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
  67. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
  68. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
  69. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
  70. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
  71. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
  72. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
  73. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
  74. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
  75. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
  76. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
  77. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
  78. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
  79. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
  80. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
  81. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
  82. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
  83. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
  84. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
  85. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
  86. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
  87. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
  88. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
  89. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
  90. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
  91. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
  92. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
  93. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
  94. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
  95. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
  96. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
  97. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
  98. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
  99. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
  100. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
  101. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
  102. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
  103. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_select_star.py +0 -0
  104. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
  105. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
  106. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
  107. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
  108. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
  109. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
  110. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
  111. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
  112. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
  113. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
  114. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
  115. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
  116. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
  117. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
  118. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
  119. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
  120. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
  121. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
  122. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
  123. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
  124. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
  125. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
  126. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
  127. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
  128. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
  129. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
  130. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
  131. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
  132. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
  133. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
  134. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
  135. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
  136. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
  137. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
  138. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
  139. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
  140. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
  141. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
  142. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
  143. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
  144. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
  145. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
  146. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
  147. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
  148. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
  149. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
  150. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
  151. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
  152. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
  153. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
  154. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
  155. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
  156. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
  157. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
  158. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
  159. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
  160. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
  161. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
  162. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
  163. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
  164. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
  165. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
  166. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
  167. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
  168. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
  169. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
  170. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
  171. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
  172. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
  173. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/stepdown.py +0 -0
  174. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
  175. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
  176. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
  177. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
  178. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
  179. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
  180. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
  181. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.3}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
  182. {sarj_python_lint-1.25.1 → sarj_python_lint-1.25.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.25.1
3
+ Version: 1.25.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/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sarj-python-lint"
3
- version = "1.25.1"
3
+ version = "1.25.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" }]
@@ -113,7 +113,8 @@ class PreferCollectionComprehension(Rule):
113
113
  "Comments, loop-target leakage, try blocks, aliases, complex projections, and replacements that "
114
114
  "do not fit a 120-column line or a simple formatter-style multiline comprehension are excluded. "
115
115
  "Namespace observers, explicit inspect/sys frame access, and collections referenced by nested functions "
116
- "are excluded. No autofix is offered because dict key/value evaluation order can differ."
116
+ "are excluded. Dynamic function aliases and helper-hidden frame reads are not resolved. "
117
+ "No autofix is offered because dict key/value evaluation order can differ."
117
118
  ),
118
119
  (
119
120
  "Attribute projections can invoke properties or descriptors, so reviewers should keep the loop "
@@ -675,7 +676,7 @@ def _owner_bindings(owner: _Callable, namespace_observers: frozenset[int]) -> _O
675
676
  def _namespace_observer_calls(context: PythonFileContext) -> frozenset[int]:
676
677
  observers = {
677
678
  "builtins": {"locals", "vars", "eval", "exec"},
678
- "inspect": {"currentframe"},
679
+ "inspect": {"currentframe", "stack", "trace", "getouterframes", "getinnerframes", "getargvalues"},
679
680
  "sys": {"_getframe"},
680
681
  }
681
682
  # Explicit aliases remain conservative exclusions even when another scope shadows them.
@@ -686,14 +687,21 @@ def _namespace_observer_calls(context: PythonFileContext) -> frozenset[int]:
686
687
  if alias.name in observers:
687
688
  modules[alias.asname or alias.name].update(observers[alias.name])
688
689
  for node in context.nodes(ast.ImportFrom):
689
- if node.module not in observers:
690
- continue
691
- symbols.update(alias.asname or alias.name for alias in node.names if alias.name in observers[node.module])
690
+ symbols.update(_observer_import_symbols(node, observers))
692
691
  return frozenset(
693
692
  id(call) for call in context.nodes(ast.Call) if _is_namespace_observer(call.func, symbols, modules)
694
693
  )
695
694
 
696
695
 
696
+ def _observer_import_symbols(node: ast.ImportFrom, observers: dict[str, set[str]]) -> set[str]:
697
+ if node.level or node.module not in observers:
698
+ return set()
699
+ # These inspect observers are public wildcard exports; sys._getframe is not.
700
+ if node.module == "inspect" and any(alias.name == "*" for alias in node.names):
701
+ return observers["inspect"]
702
+ return {alias.asname or alias.name for alias in node.names if alias.name in observers[node.module]}
703
+
704
+
697
705
  def _is_namespace_observer(function: ast.expr, symbols: set[str], modules: dict[str, set[str]]) -> bool:
698
706
  match function:
699
707
  case ast.Name(id=name):
@@ -369,7 +369,7 @@ class RequirePortForService(ProjectRule):
369
369
  source_lines = context.source_lines
370
370
  data_names = {node.name for node in classes if is_data_type(node)}
371
371
  local_class_names = {node.name for node in classes}
372
- local_port_names = _local_port_names(classes)
372
+ local_port_names = _local_port_names(classes, imports)
373
373
  factory_facts = _factory_class_facts(tree, classes, context.module_imports)
374
374
 
375
375
  diags: list[Diagnostic] = []
@@ -823,7 +823,9 @@ def _factory_class_identity(node: ast.ClassDef, imports: ImportIndex) -> bool:
823
823
 
824
824
  def _factory_interface(node: ast.ClassDef, imports: ImportIndex) -> bool:
825
825
  return any(
826
- imports.resolves(base, sources=TYPING_SOURCES, symbol="Protocol")
826
+ imports.resolves(
827
+ base.value if isinstance(base, ast.Subscript) else base, sources=TYPING_SOURCES, symbol="Protocol"
828
+ )
827
829
  or imports.resolves(base, sources=ABC_SOURCES, symbol="ABC")
828
830
  for base in node.bases
829
831
  ) or any(
@@ -1246,12 +1248,17 @@ def _dotted_tail(node: ast.expr) -> str | None:
1246
1248
  return None
1247
1249
 
1248
1250
 
1249
- def _local_port_names(classes: list[ast.ClassDef]) -> set[str]:
1251
+ def _local_port_names(classes: list[ast.ClassDef], imports: ImportIndex) -> set[str]:
1250
1252
  local_port_names = {
1251
1253
  node.name
1252
1254
  for node in classes
1253
1255
  if _BASE_NAME_RE.match(node.name)
1254
1256
  or _declares_interface(node)
1257
+ or _factory_interface(node, imports)
1258
+ or any(
1259
+ keyword.arg == "metaclass" and imports.resolves(keyword.value, sources=ABC_SOURCES, symbol="ABCMeta")
1260
+ for keyword in node.keywords
1261
+ )
1255
1262
  or any(_dotted_tail(base) in {"ABC", "Protocol"} for base in node.bases)
1256
1263
  or any(keyword.arg == "metaclass" and _dotted_tail(keyword.value) == "ABCMeta" for keyword in node.keywords)
1257
1264
  }