sarj-python-lint 1.99.0__tar.gz → 1.100.0__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 (314) hide show
  1. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/PKG-INFO +1 -1
  2. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/pyproject.toml +1 -1
  3. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_resource_provenance.py +2 -1
  4. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_sql.py +9 -2
  5. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_store_sql.py +5 -1
  6. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +71 -38
  7. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +4 -3
  8. sarj_python_lint-1.100.0/src/sarj_python_lint/rules/no_custom_control_flow_exception.py +476 -0
  9. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_optional_composite.py +122 -19
  10. sarj_python_lint-1.99.0/src/sarj_python_lint/rules/no_custom_control_flow_exception.py +0 -251
  11. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/.gitignore +0 -0
  12. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/LICENSE +0 -0
  13. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/README.md +0 -0
  14. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/__init__.py +0 -0
  15. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/__main__.py +0 -0
  16. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_analysis_session.py +0 -0
  17. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix.py +0 -0
  18. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_aliases.py +0 -0
  19. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_annotations.py +0 -0
  20. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_comments.py +0 -0
  21. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_declared_contracts.py +0 -0
  22. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_declared_tests.py +0 -0
  23. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_docs.py +0 -0
  24. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_enums.py +0 -0
  25. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_exhaustiveness.py +0 -0
  26. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_inert.py +0 -0
  27. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_parameters.py +0 -0
  28. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_repeated.py +0 -0
  29. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_security.py +0 -0
  30. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_sql_projection.py +0 -0
  31. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_autofix_tests.py +0 -0
  32. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_file_context.py +0 -0
  33. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_filesystem.py +0 -0
  34. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_fixes.py +0 -0
  35. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_parallel.py +0 -0
  36. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_prepared_sources.py +0 -0
  37. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_python_target.py +0 -0
  38. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_ratchet_cli.py +0 -0
  39. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_rule_descriptors.py +0 -0
  40. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_secret_names.py +0 -0
  41. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_source.py +0 -0
  42. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/_version.py +0 -0
  43. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/application_logging.py +0 -0
  44. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/autofix.py +0 -0
  45. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/benchmark.py +0 -0
  46. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/cast_access.py +0 -0
  47. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/interpreter_argv.py +0 -0
  48. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/json_boundary.py +0 -0
  49. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/py.typed +0 -0
  50. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/ratchet.py +0 -0
  51. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rule_base.py +0 -0
  52. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rule_metadata.py +0 -0
  53. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/__init__.py +0 -0
  54. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_annotation_origins.py +0 -0
  55. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
  56. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_ast_index.py +0 -0
  57. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_ast_names.py +0 -0
  58. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_ast_position.py +0 -0
  59. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_async_lifecycle.py +0 -0
  60. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_binding_inventory.py +0 -0
  61. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
  62. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_comment_narration.py +0 -0
  63. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_comments.py +0 -0
  64. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
  65. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
  66. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_data_union_discriminator.py +0 -0
  67. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_declared_contracts.py +0 -0
  68. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
  69. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_docstrings.py +0 -0
  70. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_exports.py +0 -0
  71. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_fastapi.py +0 -0
  72. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_first_party.py +0 -0
  73. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
  74. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_imports.py +0 -0
  75. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_inert_model_annotation.py +0 -0
  76. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_inherited_contract.py +0 -0
  77. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_local_alias_fix.py +0 -0
  78. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_local_source.py +0 -0
  79. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_logging.py +0 -0
  80. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_mapping_shape_callbacks.py +0 -0
  81. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_namespace_access.py +0 -0
  82. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_native_namespace_capability.py +0 -0
  83. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_native_object_contracts.py +0 -0
  84. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
  85. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_numeric_proof.py +0 -0
  86. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_opaque_contracts.py +0 -0
  87. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_paths.py +0 -0
  88. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_postgres.py +0 -0
  89. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_project_index.py +0 -0
  90. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
  91. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_pydantic_field_contract.py +0 -0
  92. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_pytest.py +0 -0
  93. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_registry.py +0 -0
  94. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_resolved_operation_signature.py +0 -0
  95. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_route_shapes.py +0 -0
  96. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_runtime_bindings.py +0 -0
  97. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_runtime_registry.py +0 -0
  98. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_service_http_callbacks.py +0 -0
  99. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_set_fields.py +0 -0
  100. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_sql_aggregate_identity.py +0 -0
  101. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_sql_explain.py +0 -0
  102. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_sql_policy_source.py +0 -0
  103. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_static_json_alias.py +0 -0
  104. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_store_writes.py +0 -0
  105. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
  106. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
  107. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_test_composition.py +0 -0
  108. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
  109. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_transactional_sql.py +0 -0
  110. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/_type_guard_symbols.py +0 -0
  111. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
  112. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/async_executor_shutdown.py +0 -0
  113. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
  114. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/async_subprocess_cancellation_cleanup.py +0 -0
  115. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/cancel_owned_task_without_join.py +0 -0
  116. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
  117. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/delete_route_returns_no_content.py +0 -0
  118. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
  119. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
  120. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
  121. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
  122. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/duplicate_pytest_fixture_params.py +0 -0
  123. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
  124. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/failed_probe_zero_threshold.py +0 -0
  125. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
  126. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
  127. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
  128. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
  129. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
  130. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
  131. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
  132. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/nan_hidden_by_builtin_min.py +0 -0
  133. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
  134. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
  135. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_async_client_in_constructor.py +0 -0
  136. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_async_function_cache.py +0 -0
  137. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
  138. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_blanket_suppression.py +0 -0
  139. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
  140. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
  141. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_conflicting_pydantic_alias_validation.py +0 -0
  142. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
  143. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_contradictory_type_guard.py +0 -0
  144. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
  145. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
  146. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_create_verb_in_post_path.py +0 -0
  147. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
  148. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_defaulted_environment_setting.py +0 -0
  149. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
  150. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_discarded_tagged_outcome.py +0 -0
  151. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_discarded_validation_result.py +0 -0
  152. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_dual_shape_model_field_reader.py +0 -0
  153. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
  154. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
  155. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_duplicate_field_validator_body.py +0 -0
  156. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_exception_text_in_500_detail.py +0 -0
  157. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
  158. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
  159. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
  160. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
  161. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
  162. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
  163. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_folded_bad_request_not_found.py +0 -0
  164. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
  165. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_generic_json_parser.py +0 -0
  166. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
  167. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_hasattr.py +0 -0
  168. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
  169. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_impossible_pydantic_field_bounds.py +0 -0
  170. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
  171. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
  172. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
  173. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
  174. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_invalid_pydantic_bypass.py +0 -0
  175. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_invalid_pydantic_validator_return.py +0 -0
  176. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_loguru_exc_info.py +0 -0
  177. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_loguru_printf_format.py +0 -0
  178. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
  179. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_mutating_container_transform.py +0 -0
  180. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_mutating_input_with_result.py +0 -0
  181. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
  182. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
  183. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
  184. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_partial_type_is.py +0 -0
  185. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
  186. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
  187. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
  188. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
  189. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
  190. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_recording_store.py +0 -0
  191. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_redundant_attribute_unpacking.py +0 -0
  192. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
  193. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_redundant_local_alias.py +0 -0
  194. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
  195. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_redundant_sql_alias.py +0 -0
  196. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
  197. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
  198. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
  199. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
  200. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_select_star.py +0 -0
  201. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
  202. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
  203. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_shallow_record_type_guard.py +0 -0
  204. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_slash_collection_root_under_prefix.py +0 -0
  205. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
  206. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
  207. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
  208. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_test_comments.py +0 -0
  209. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
  210. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
  211. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
  212. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_unknown_pydantic_validator_field.py +0 -0
  213. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
  214. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
  215. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
  216. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
  217. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
  218. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
  219. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/no_work_verb_get_route.py +0 -0
  220. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
  221. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
  222. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
  223. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_application_model_joins.py +0 -0
  224. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
  225. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_bulk_upsert.py +0 -0
  226. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
  227. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
  228. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
  229. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_declarative_batch_validation.py +0 -0
  230. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_direct_import_module.py +0 -0
  231. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_discriminated_model_union.py +0 -0
  232. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
  233. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_grouped_settings.py +0 -0
  234. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
  235. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
  236. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
  237. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
  238. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
  239. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
  240. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
  241. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
  242. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
  243. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
  244. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
  245. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
  246. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
  247. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
  248. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
  249. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_precise_object_contract.py +0 -0
  250. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_psycopg_executemany.py +0 -0
  251. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
  252. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_pydantic_model_assertion.py +0 -0
  253. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_pytest_dependency_fixtures.py +0 -0
  254. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_pytest_fixture_contract.py +0 -0
  255. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
  256. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
  257. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
  258. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_runtime_validation.py +0 -0
  259. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
  260. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
  261. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
  262. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
  263. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
  264. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_typed_cli.py +0 -0
  265. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_typed_mapping_get.py +0 -0
  266. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_typed_settings_field.py +0 -0
  267. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
  268. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
  269. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
  270. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
  271. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
  272. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
  273. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/pytest_fixture_returns_closed_resource.py +0 -0
  274. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
  275. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
  276. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
  277. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +0 -0
  278. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
  279. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
  280. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
  281. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +0 -0
  282. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_constrained_api_integer.py +0 -0
  283. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_exp_on_jwt_decode.py +0 -0
  284. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
  285. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
  286. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
  287. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
  288. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
  289. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
  290. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
  291. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
  292. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
  293. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
  294. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_pydantic_for_mapping_shape.py +0 -0
  295. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
  296. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
  297. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
  298. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/service_singleton_delegates_to_bulk.py +0 -0
  299. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
  300. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/stepdown.py +0 -0
  301. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/store_field_update_reuses_upsert.py +0 -0
  302. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
  303. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/store_insert_requires_explicit_conflict_policy.py +0 -0
  304. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
  305. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/store_mutation_command_fanout.py +0 -0
  306. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
  307. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/test_without_explicit_oracle.py +0 -0
  308. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
  309. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
  310. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
  311. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
  312. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
  313. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
  314. {sarj_python_lint-1.99.0 → sarj_python_lint-1.100.0}/src/sarj_python_lint/suppression_policy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sarj-python-lint
3
- Version: 1.99.0
3
+ Version: 1.100.0
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.99.0"
3
+ version = "1.100.0"
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" }]
@@ -308,7 +308,8 @@ class ResourceProvenance:
308
308
  or (
309
309
  isinstance(parent, ast.FunctionDef | ast.AsyncFunctionDef | ast.ClassDef)
310
310
  and node in parent.decorator_list
311
- and self.context.imports.resolved_qualified_name(node) in {"typing.final", "typing_extensions.final"}
311
+ and self.context.imports.resolved_qualified_name(node)
312
+ in {"typing.final", "typing_extensions.final", "dataclasses.dataclass"}
312
313
  )
313
314
  )
314
315
 
@@ -27,11 +27,18 @@ def is_store_module(path: Path) -> bool:
27
27
 
28
28
 
29
29
  def sql_string_value(node: ast.expr, *, interpolation_placeholder: str = " ") -> str | None:
30
+ try:
31
+ return _sql_string_value(node, interpolation_placeholder=interpolation_placeholder)
32
+ except RecursionError:
33
+ return None
34
+
35
+
36
+ def _sql_string_value(node: ast.expr, *, interpolation_placeholder: str) -> str | None:
30
37
  if isinstance(node, ast.Constant) and isinstance(node.value, str):
31
38
  return node.value
32
39
  if isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add):
33
- left = sql_string_value(node.left, interpolation_placeholder=interpolation_placeholder)
34
- right = sql_string_value(node.right, interpolation_placeholder=interpolation_placeholder)
40
+ left = _sql_string_value(node.left, interpolation_placeholder=interpolation_placeholder)
41
+ right = _sql_string_value(node.right, interpolation_placeholder=interpolation_placeholder)
35
42
  if left is not None and right is not None:
36
43
  return left + right
37
44
  if isinstance(node, ast.JoinedStr):
@@ -46,7 +46,11 @@ class _MethodWrites:
46
46
 
47
47
  def store_queries(context: PythonFileContext) -> Iterator[StoreQuery]:
48
48
  if context.store_queries is None:
49
- context.store_queries = tuple(recover_store_queries(context))
49
+ try:
50
+ queries = tuple(recover_store_queries(context))
51
+ except RecursionError:
52
+ queries = ()
53
+ context.store_queries = queries
50
54
  return iter(context.store_queries)
51
55
 
52
56
 
@@ -85,7 +85,11 @@ def _is_query_context(node: ast.expr, parents: Mapping[ast.AST, ast.AST], roots:
85
85
 
86
86
 
87
87
  def _query_roots(
88
- tree: ast.Module, parents: Mapping[ast.AST, ast.AST], *, node_index: NodeIndex | None = None
88
+ tree: ast.Module,
89
+ parents: Mapping[ast.AST, ast.AST],
90
+ *,
91
+ context: PythonFileContext,
92
+ node_index: NodeIndex | None = None,
89
93
  ) -> frozenset[int]:
90
94
  binding_counts: dict[tuple[int, str], int] = {}
91
95
  binding_values: dict[tuple[int, str], ast.expr] = {}
@@ -99,11 +103,12 @@ def _query_roots(
99
103
 
100
104
  constructor_imports = _postgres_sql_constructors(tree, parents, node_index=node_index)
101
105
  _query_binding_values(tree, parents, binding_values, node_index=node_index)
106
+ has_local_classes = bool(nodes(tree, ast.ClassDef, index=node_index))
102
107
 
103
108
  roots: set[int] = set()
104
109
  for call in nodes(tree, ast.Call, index=node_index):
105
110
  argument = _query_argument(call)
106
- if argument is None:
111
+ if argument is None or (has_local_classes and _source_local_receiver(call, context)):
107
112
  continue
108
113
  owner = _scope(call, parents)
109
114
  constructors = _visible_constructors(owner, constructor_imports, parents, binding_counts, wildcard_scopes)
@@ -151,6 +156,21 @@ def _query_argument(call: ast.Call) -> ast.expr | None:
151
156
  return next((keyword.value for keyword in call.keywords if keyword.arg in _QUERY_KEYWORDS), None)
152
157
 
153
158
 
159
+ def _source_local_receiver(call: ast.Call, context: PythonFileContext) -> bool:
160
+ if not isinstance(call.func, ast.Attribute) or not isinstance(call.func.value, (ast.Name, ast.Call)):
161
+ return False
162
+ provenance = context.static_resource_provenance
163
+ receiver: ast.expr | None = call.func.value
164
+ if isinstance(receiver, ast.Name):
165
+ binding = provenance.runtime_binding(receiver.id, call)
166
+ receiver = provenance.assignment_value(binding, call) if isinstance(binding, ast.Name) else None
167
+ return (
168
+ isinstance(receiver, ast.Call)
169
+ and isinstance(receiver.func, ast.Name)
170
+ and isinstance(provenance.runtime_binding(receiver.func.id, receiver), ast.ClassDef)
171
+ )
172
+
173
+
154
174
  def _postgres_sql_constructors(
155
175
  tree: ast.Module, parents: Mapping[ast.AST, ast.AST], *, node_index: NodeIndex | None = None
156
176
  ) -> frozenset[_ConstructorImport]:
@@ -261,13 +281,16 @@ class ComplexPostgresQueryRequiresArchitectureReview(Rule):
261
281
  autofix=AutofixPolicy.NONE,
262
282
  limitations=(
263
283
  "Only statically recoverable SQL passed to execute, executemany, fetch, fetchrow, fetchval, or prepare in non-test modules with explicit PostgreSQL imports is analyzed, regardless of module filename.",
264
- "Execution receivers use a conventional database name or import-proven Psycopg ownership. Native execution additionally follows stable module/local SQL bindings and direct same-class query-forwarding wrappers; unknown receivers abstain.",
284
+ "Execution receivers use a conventional database name or import-proven Psycopg ownership. Conventional names are a heuristic and can warn on unrelated objects with matching methods. Native execution additionally follows stable module/local SQL bindings and direct same-class query-forwarding wrappers; unknown receivers abstain.",
285
+ "Modules mixing SQLite and PostgreSQL abstain for conventional receivers; import-proven Psycopg execution remains eligible.",
286
+ "Stable source-local class construction abstains from conventional receiver inference, including custom delegating instances unless native recovery independently proves execution.",
265
287
  "Conventional receivers follow one direct, unambiguous same-scope binding. Native Psycopg recovery may follow bounded stable lexical bindings, including module constants. Unexecuted constants, branch-local assignments, mutable attributes, containers and unknown dynamic composition abstain.",
266
- "Review covers derived relations in every SELECT (including LATERAL, CTEs, predicates and writes), four explicit or comma joins, six query stages, three joins plus four stages, or 25 projections plus two joins. A self join over the same explicit table also merits review at 16 projected expressions.",
288
+ "Review covers derived relations in every SELECT (including LATERAL, CTEs, predicates and writes), four explicit or comma joins (including parenthesized joined tables), six query stages, three joins plus four stages, or 25 projections plus two joins. A self join over the same explicit table also merits review at 16 projected expressions.",
267
289
  "Derived-relation review requires grouping, HAVING or windowing combined with joins or nested reads; expression density is not a separate trigger.",
268
- "Projection width alone is accepted, and UNION branches are measured independently; execution plans and production cardinality remain authoritative.",
269
- "ClickHouse and BigQuery syntax is excluded per query, including in mixed-backend modules.",
290
+ "Projection width alone is accepted, and UNION branches are measured independently. Set operators do not add read stages beyond their SELECT blocks; execution plans and production cardinality remain authoritative.",
291
+ "Conventional receivers exclude ClickHouse and BigQuery syntax per query, including in mixed-backend modules. Import-proven Psycopg execution uses PostgreSQL parsing even when identifiers or function names overlap another dialect.",
270
292
  "The rule does not infer optimizer behavior, materialization, performance, data-model quality, or datastore placement.",
293
+ "SQL parsing and static query recovery abstain on recursion limits; deeply nested source can withhold native recovery for the file.",
271
294
  ),
272
295
  examples=(
273
296
  RuleExample(
@@ -351,12 +374,17 @@ class ComplexPostgresQueryRequiresArchitectureReview(Rule):
351
374
  tree = context.tree
352
375
  if tree is None:
353
376
  return []
354
- if not _is_postgres_module(tree, node_index=context.node_index):
377
+ imports = _import_names(tree, node_index=context.node_index)
378
+ if not _has_import_prefix(imports, _POSTGRES_IMPORT_PREFIXES):
355
379
  return []
356
380
 
357
- diagnostics = _conventional_findings(context, self.code)
381
+ diagnostics = (
382
+ []
383
+ if _has_import_prefix(imports, _AMBIGUOUS_RELATIONAL_IMPORT_PREFIXES)
384
+ else _conventional_findings(context, self.code)
385
+ )
358
386
  for query in store_queries(context):
359
- signal = _query_architecture_signal(query.sql, path)
387
+ signal = _query_architecture_signal(query.sql, path, native_postgres=True)
360
388
  if signal is None:
361
389
  continue
362
390
  node = query.node
@@ -372,7 +400,7 @@ def _conventional_findings(context: PythonFileContext, code: str) -> list[Diagno
372
400
  tree = context.tree
373
401
  if tree is None:
374
402
  return []
375
- query_roots = _query_roots(tree, parents, node_index=context.node_index)
403
+ query_roots = _query_roots(tree, parents, context=context, node_index=context.node_index)
376
404
  diagnostics: list[Diagnostic] = []
377
405
  consumed: set[int] = set()
378
406
  for node in context.nodes(ast.Constant, ast.BinOp, ast.JoinedStr):
@@ -477,14 +505,13 @@ def _record_sql_constructors(
477
505
  )
478
506
 
479
507
 
480
- def _query_architecture_signal(text_value: str, path: Path) -> str | None:
508
+ def _query_architecture_signal(text_value: str, path: Path, *, native_postgres: bool = False) -> str | None:
481
509
  sql_without_noise = strip_sql_noise(text_value)
482
- if (
483
- _QUERY_SHAPE.search(sql_without_noise) is None
484
- or _CLICKHOUSE_SQL.search(sql_without_noise)
485
- or _BIGQUERY_SQL.search(sql_without_noise)
486
- or (is_store_module(path) and analytical_signal(sql_without_noise) is not None)
487
- ):
510
+ if _QUERY_SHAPE.search(sql_without_noise) is None:
511
+ return None
512
+ if not native_postgres and (_CLICKHOUSE_SQL.search(sql_without_noise) or _BIGQUERY_SQL.search(sql_without_noise)):
513
+ return None
514
+ if is_store_module(path) and analytical_signal(sql_without_noise) is not None:
488
515
  return None
489
516
  return _parse_signal(text_value)
490
517
 
@@ -512,8 +539,8 @@ def _architecture_signal(statement: exp.Expr) -> str | None:
512
539
  maximum_joins = _maximum_query_joins(statement)
513
540
  if maximum_joins >= _JOIN_LIMIT:
514
541
  return f"SELECT block has {maximum_joins} JOINs (4+ explicit JOINs or comma relations)"
515
- nested_queries = sum(1 for query in statement.walk() if isinstance(query, (exp.Select, exp.SetOperation)))
516
- nested_queries -= isinstance(statement, (exp.Select, exp.SetOperation))
542
+ nested_queries = sum(1 for query in statement.walk() if isinstance(query, exp.Select))
543
+ nested_queries -= isinstance(_derived_query(statement), exp.Select)
517
544
  if (derived_signal := _derived_architecture_signal(statement)) is not None:
518
545
  return derived_signal
519
546
  if nested_queries >= _STAGE_LIMIT:
@@ -528,7 +555,7 @@ def _projection_width_signal(statement: exp.Expr) -> str | None:
528
555
 
529
556
  for select in statement.find_all(exp.Select):
530
557
  projections = tuple(_expression_args(select, "expressions"))
531
- joins = tuple(join for join in _expression_args(select, "joins") if isinstance(join, exp.Join))
558
+ joins = _select_joins(select)
532
559
  if len(projections) >= _WIDE_PROJECTION_LIMIT and len(joins) >= _WIDE_PROJECTION_JOIN_LIMIT:
533
560
  return f"Joined query block has {len(projections)} projected expressions"
534
561
  if len(projections) >= _WIDE_SELF_JOIN_PROJECTION_LIMIT and _self_join(select, joins):
@@ -559,7 +586,10 @@ def _self_join(select: exp.Select, joins: tuple[exp.Join, ...]) -> bool:
559
586
  relations.extend(_expression_arg(join, "this") for join in joins)
560
587
  seen: set[tuple[str, ...]] = set()
561
588
  for relation in relations:
562
- key = relation_key(relation)
589
+ base = relation
590
+ while isinstance(base, (exp.Paren, exp.Subquery)):
591
+ base = _expression_arg(base, "this")
592
+ key = relation_key(base)
563
593
  if key is None or any(_SQL_HOLE in name for name in key):
564
594
  continue
565
595
  if key in seen:
@@ -572,9 +602,7 @@ def _derived_architecture_signal(statement: exp.Expr) -> str | None:
572
602
  from sqlglot import exp # ruff: ignore[import-outside-top-level] -- keep parser startup off unrelated lint runs
573
603
 
574
604
  for select in statement.find_all(exp.Select):
575
- for join in _expression_args(select, "joins"):
576
- if not isinstance(join, exp.Join):
577
- continue
605
+ for join in _select_joins(select):
578
606
  if (derived := _derived_query(_expression_arg(join, "this"))) is not None and _has_complex_body(derived):
579
607
  return "JOIN-derived query combines grouping, HAVING or windowing with joins or nested reads"
580
608
  from_clause = _expression_arg(select, "from_")
@@ -597,11 +625,11 @@ def _has_complex_body(query: exp.Query) -> bool:
597
625
  if not isinstance(query, exp.Select):
598
626
  return False
599
627
  if _has_row_transform(query) and (
600
- _expression_args(query, "joins") or any(select is not query for select in query.find_all(exp.Select))
628
+ _select_joins(query) or any(select is not query for select in query.find_all(exp.Select))
601
629
  ):
602
630
  return True
603
- for relation in query.find_all(exp.From, exp.Join):
604
- if relation.parent is not query:
631
+ for relation in (_expression_arg(query, "from_"), *_select_joins(query)):
632
+ if not isinstance(relation, (exp.From, exp.Join)):
605
633
  continue
606
634
  child = _derived_query(_expression_arg(relation, "this"))
607
635
  if child is not None and (_has_row_transform(child) or _has_complex_body(child)):
@@ -624,14 +652,26 @@ def _maximum_query_joins(statement: exp.Expr) -> int:
624
652
  from sqlglot import exp # ruff: ignore[import-outside-top-level] -- keep parser startup off unrelated lint runs
625
653
 
626
654
  return max(
627
- (
628
- sum(isinstance(join, exp.Join) for join in _expression_args(select, "joins"))
629
- for select in statement.find_all(exp.Select)
630
- ),
655
+ (len(_select_joins(select)) for select in statement.find_all(exp.Select)),
631
656
  default=0,
632
657
  )
633
658
 
634
659
 
660
+ def _select_joins(select: exp.Select) -> tuple[exp.Join, ...]:
661
+ from sqlglot import exp # ruff: ignore[import-outside-top-level] -- grouped joined tables retain their SELECT owner.
662
+
663
+ relations = (_expression_arg(select, "from_"), *_expression_args(select, "joins"))
664
+ return tuple(
665
+ node
666
+ for relation in relations
667
+ if relation is not None
668
+ for node in relation.walk(
669
+ prune=lambda node: isinstance(node, (exp.Select, exp.SetOperation, exp.Insert, exp.Update, exp.Delete))
670
+ )
671
+ if isinstance(node, exp.Join)
672
+ )
673
+
674
+
635
675
  def _count_import_bindings(
636
676
  tree: ast.Module,
637
677
  parents: Mapping[ast.AST, ast.AST],
@@ -671,13 +711,6 @@ def _query_review_guidance(text_value: str) -> str:
671
711
  )
672
712
 
673
713
 
674
- def _is_postgres_module(tree: ast.Module, *, node_index: NodeIndex | None = None) -> bool:
675
- imports = _import_names(tree, node_index=node_index)
676
- return _has_import_prefix(imports, _POSTGRES_IMPORT_PREFIXES) and not _has_import_prefix(
677
- imports, _AMBIGUOUS_RELATIONAL_IMPORT_PREFIXES
678
- )
679
-
680
-
681
714
  def _has_import_prefix(imports: frozenset[str], prefixes: tuple[str, ...]) -> bool:
682
715
  return any(name == prefix or name.startswith(f"{prefix}.") for name in imports for prefix in prefixes)
683
716
 
@@ -60,15 +60,16 @@ def analytical_signal(sql: str) -> str | None:
60
60
 
61
61
 
62
62
  def _grouped_reporting_signal(sql: str) -> str | None:
63
- import sqlglot # ruff: ignore[import-outside-top-level] -- parse only aggregate-shaped SQL after cheap gates
64
63
  from sqlglot import exp # ruff: ignore[import-outside-top-level] -- paired with lazy parser import
65
64
  from sqlglot.errors import SqlglotError # ruff: ignore[import-outside-top-level] -- paired with lazy parser import
66
65
 
66
+ from sarj_python_lint.rules._postgres import parse_postgres # ruff: ignore[import-outside-top-level] -- unsupported private SQL must not enter dependency logs.
67
+
67
68
  if _GROUP_BY.search(sql) is None or _COMMON_AGGREGATE.search(sql) is None:
68
69
  return None
69
70
  try:
70
- statements = sqlglot.parse(_PLACEHOLDER.sub("?", sql), read="postgres")
71
- except SqlglotError:
71
+ statements = parse_postgres(_PLACEHOLDER.sub("?", sql))
72
+ except SqlglotError, RecursionError:
72
73
  return None
73
74
  for statement in statements:
74
75
  if not isinstance(statement, exp.Query):