sarj-python-lint 1.88.0__tar.gz → 1.88.1__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 (302) hide show
  1. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/PKG-INFO +1 -1
  2. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/pyproject.toml +1 -1
  3. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_opaque_contracts.py +96 -4
  4. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_precise_object_contract.py +2 -0
  5. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_typed_cli.py +15 -1
  6. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/.gitignore +0 -0
  7. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/LICENSE +0 -0
  8. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/README.md +0 -0
  9. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/__init__.py +0 -0
  10. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/__main__.py +0 -0
  11. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_analysis_session.py +0 -0
  12. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix.py +0 -0
  13. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_aliases.py +0 -0
  14. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_annotations.py +0 -0
  15. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_comments.py +0 -0
  16. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_declared_contracts.py +0 -0
  17. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_declared_tests.py +0 -0
  18. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_docs.py +0 -0
  19. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_enums.py +0 -0
  20. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_exhaustiveness.py +0 -0
  21. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_inert.py +0 -0
  22. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_parameters.py +0 -0
  23. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_repeated.py +0 -0
  24. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_security.py +0 -0
  25. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_sql_projection.py +0 -0
  26. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_autofix_tests.py +0 -0
  27. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_file_context.py +0 -0
  28. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_filesystem.py +0 -0
  29. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_fixes.py +0 -0
  30. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_parallel.py +0 -0
  31. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_prepared_sources.py +0 -0
  32. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_python_target.py +0 -0
  33. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_ratchet_cli.py +0 -0
  34. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_secret_names.py +0 -0
  35. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_source.py +0 -0
  36. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/_version.py +0 -0
  37. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/application_logging.py +0 -0
  38. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/autofix.py +0 -0
  39. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/benchmark.py +0 -0
  40. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/cast_access.py +0 -0
  41. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/interpreter_argv.py +0 -0
  42. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/json_boundary.py +0 -0
  43. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/py.typed +0 -0
  44. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/ratchet.py +0 -0
  45. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rule_base.py +0 -0
  46. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/__init__.py +0 -0
  47. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_annotation_origins.py +0 -0
  48. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
  49. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_ast_index.py +0 -0
  50. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_ast_names.py +0 -0
  51. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_ast_position.py +0 -0
  52. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_async_lifecycle.py +0 -0
  53. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_binding_inventory.py +0 -0
  54. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
  55. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_comment_narration.py +0 -0
  56. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_comments.py +0 -0
  57. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
  58. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
  59. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_data_union_discriminator.py +0 -0
  60. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_declared_contracts.py +0 -0
  61. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
  62. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_docstrings.py +0 -0
  63. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_exports.py +0 -0
  64. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_fastapi.py +0 -0
  65. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_first_party.py +0 -0
  66. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
  67. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_imports.py +0 -0
  68. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_inert_model_annotation.py +0 -0
  69. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_inherited_contract.py +0 -0
  70. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_local_alias_fix.py +0 -0
  71. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_local_source.py +0 -0
  72. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_logging.py +0 -0
  73. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_mapping_shape_callbacks.py +0 -0
  74. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_namespace_access.py +0 -0
  75. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_native_namespace_capability.py +0 -0
  76. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_native_object_contracts.py +0 -0
  77. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
  78. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_numeric_proof.py +0 -0
  79. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_paths.py +0 -0
  80. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_postgres.py +0 -0
  81. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_project_index.py +0 -0
  82. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
  83. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_pydantic_field_contract.py +0 -0
  84. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_pytest.py +0 -0
  85. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_registry.py +0 -0
  86. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_resolved_operation_signature.py +0 -0
  87. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
  88. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_route_shapes.py +0 -0
  89. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_runtime_bindings.py +0 -0
  90. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_service_http_callbacks.py +0 -0
  91. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_set_fields.py +0 -0
  92. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_sql.py +0 -0
  93. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_sql_aggregate_identity.py +0 -0
  94. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_sql_explain.py +0 -0
  95. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_sql_policy_source.py +0 -0
  96. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_static_json_alias.py +0 -0
  97. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_store_sql.py +0 -0
  98. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_store_writes.py +0 -0
  99. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
  100. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
  101. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_test_composition.py +0 -0
  102. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
  103. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_transactional_sql.py +0 -0
  104. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/_type_guard_symbols.py +0 -0
  105. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
  106. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/async_executor_shutdown.py +0 -0
  107. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
  108. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/async_subprocess_cancellation_cleanup.py +0 -0
  109. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/cancel_owned_task_without_join.py +0 -0
  110. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
  111. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
  112. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/delete_route_returns_no_content.py +0 -0
  113. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
  114. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
  115. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
  116. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
  117. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/duplicate_pytest_fixture_params.py +0 -0
  118. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
  119. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/failed_probe_zero_threshold.py +0 -0
  120. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
  121. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
  122. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
  123. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
  124. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
  125. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
  126. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
  127. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/nan_hidden_by_builtin_min.py +0 -0
  128. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
  129. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
  130. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
  131. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_async_function_cache.py +0 -0
  132. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
  133. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_blanket_suppression.py +0 -0
  134. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
  135. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
  136. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_conflicting_pydantic_alias_validation.py +0 -0
  137. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
  138. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_contradictory_type_guard.py +0 -0
  139. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
  140. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
  141. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_create_verb_in_post_path.py +0 -0
  142. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_custom_control_flow_exception.py +0 -0
  143. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
  144. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_defaulted_environment_setting.py +0 -0
  145. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
  146. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_discarded_tagged_outcome.py +0 -0
  147. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_discarded_validation_result.py +0 -0
  148. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_dual_shape_model_field_reader.py +0 -0
  149. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
  150. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
  151. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_duplicate_field_validator_body.py +0 -0
  152. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_exception_text_in_500_detail.py +0 -0
  153. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
  154. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
  155. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
  156. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
  157. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
  158. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
  159. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_folded_bad_request_not_found.py +0 -0
  160. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
  161. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
  162. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_hasattr.py +0 -0
  163. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
  164. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_impossible_pydantic_field_bounds.py +0 -0
  165. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
  166. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
  167. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
  168. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
  169. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_invalid_pydantic_bypass.py +0 -0
  170. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_invalid_pydantic_validator_return.py +0 -0
  171. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_loguru_exc_info.py +0 -0
  172. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_loguru_printf_format.py +0 -0
  173. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
  174. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_mutating_container_transform.py +0 -0
  175. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
  176. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
  177. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
  178. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_partial_type_is.py +0 -0
  179. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
  180. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
  181. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
  182. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
  183. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
  184. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_recording_store.py +0 -0
  185. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
  186. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_redundant_local_alias.py +0 -0
  187. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
  188. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_redundant_sql_alias.py +0 -0
  189. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
  190. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
  191. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
  192. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
  193. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_select_star.py +0 -0
  194. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
  195. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
  196. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_shallow_record_type_guard.py +0 -0
  197. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_slash_collection_root_under_prefix.py +0 -0
  198. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
  199. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
  200. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
  201. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
  202. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
  203. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
  204. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_unknown_pydantic_validator_field.py +0 -0
  205. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
  206. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
  207. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
  208. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
  209. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
  210. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
  211. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/no_work_verb_get_route.py +0 -0
  212. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
  213. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
  214. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
  215. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_application_model_joins.py +0 -0
  216. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
  217. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_bulk_upsert.py +0 -0
  218. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
  219. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
  220. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
  221. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_declarative_batch_validation.py +0 -0
  222. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_direct_import_module.py +0 -0
  223. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_discriminated_model_union.py +0 -0
  224. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
  225. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_grouped_settings.py +0 -0
  226. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
  227. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
  228. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
  229. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
  230. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
  231. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
  232. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
  233. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
  234. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
  235. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
  236. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
  237. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
  238. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
  239. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
  240. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_optional_composite.py +0 -0
  241. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
  242. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_psycopg_executemany.py +0 -0
  243. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
  244. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_pydantic_model_assertion.py +0 -0
  245. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_pytest_dependency_fixtures.py +0 -0
  246. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
  247. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
  248. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
  249. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_runtime_validation.py +0 -0
  250. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
  251. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
  252. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
  253. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
  254. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
  255. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_typed_mapping_get.py +0 -0
  256. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_typed_settings_field.py +0 -0
  257. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
  258. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
  259. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
  260. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
  261. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
  262. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
  263. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/pytest_fixture_returns_closed_resource.py +0 -0
  264. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
  265. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
  266. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
  267. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +0 -0
  268. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
  269. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
  270. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
  271. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +0 -0
  272. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_exp_on_jwt_decode.py +0 -0
  273. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
  274. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
  275. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
  276. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
  277. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
  278. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
  279. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
  280. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
  281. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
  282. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
  283. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_pydantic_for_mapping_shape.py +0 -0
  284. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
  285. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
  286. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
  287. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
  288. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/stepdown.py +0 -0
  289. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/store_field_update_reuses_upsert.py +0 -0
  290. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
  291. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/store_insert_requires_explicit_conflict_policy.py +0 -0
  292. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
  293. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/store_mutation_command_fanout.py +0 -0
  294. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
  295. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/test_without_explicit_oracle.py +0 -0
  296. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
  297. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
  298. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
  299. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
  300. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
  301. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
  302. {sarj_python_lint-1.88.0 → sarj_python_lint-1.88.1}/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.88.0
3
+ Version: 1.88.1
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.88.0"
3
+ version = "1.88.1"
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" }]
@@ -192,7 +192,7 @@ class OpaqueContractFacts:
192
192
 
193
193
  def _find_checked(self, function: _Function) -> frozenset[ast.arg]:
194
194
  found = set(self.native.namespace(function).parameters())
195
- terminal_rejection = _rejects(function.body)
195
+ terminal_rejection = self._rejects(function.body)
196
196
  for node in direct_nodes(function):
197
197
  if not self.reachable(node, function):
198
198
  continue
@@ -206,8 +206,85 @@ class OpaqueContractFacts:
206
206
  found.update(self._statement_parameters(node, terminal_rejection=terminal_rejection))
207
207
  found.update(self._identity_parameters(function))
208
208
  found.update(self._key_parameters(function))
209
+ found.update(self._model_iteration_parameters(function))
209
210
  return frozenset(found)
210
211
 
212
+ def _model_iteration_parameters(self, function: _Function) -> set[ast.arg]:
213
+ found: set[ast.arg] = set()
214
+ for parameter in (*function.args.posonlyargs, *function.args.args, *function.args.kwonlyargs):
215
+ if not self._opaque_iterable(parameter):
216
+ continue
217
+ loops = self._parameter_iterations(parameter, function)
218
+ if loops and all(self._validated_iteration(loop, function) for loop in loops):
219
+ found.add(parameter)
220
+ return found
221
+
222
+ def _opaque_iterable(self, parameter: ast.arg) -> bool:
223
+ if parameter.annotation is None:
224
+ return False
225
+ resolved = self.facts.resolve_annotation(parameter.annotation)
226
+ if resolved is None or not isinstance(resolved.expression, ast.Subscript):
227
+ return False
228
+ node = resolved.expression
229
+ return self.facts.qualified(node.value, resolved.at) in {
230
+ "collections.abc.Iterable",
231
+ "typing.Iterable",
232
+ } and _unknown_slot(node.slice, self.facts, resolved.at)
233
+
234
+ def _parameter_iterations(self, parameter: ast.arg, function: _Function) -> list[ast.For] | None:
235
+ loops: list[ast.For] = []
236
+ members = set(direct_nodes(function))
237
+ for read in self.facts.provenance.reads.get(parameter.arg, ()):
238
+ runtime = self.facts.provenance.runtime_binding(read.id, read)
239
+ if runtime is not parameter and self.facts.provenance.binding(read.id, read) is not parameter:
240
+ continue
241
+ if not self.reachable(read, function):
242
+ continue
243
+ owner = self.context.parents.get(read)
244
+ if (
245
+ runtime is not parameter
246
+ or not isinstance(owner, ast.For)
247
+ or owner not in members
248
+ or owner.iter is not read
249
+ or not isinstance(owner.target, ast.Name)
250
+ ):
251
+ return None
252
+ loops.append(owner)
253
+ return loops
254
+
255
+ def _validated_iteration(self, loop: ast.For, function: _Function) -> bool:
256
+ if not isinstance(loop.target, ast.Name):
257
+ return False
258
+ reads = [
259
+ read
260
+ for read in self.facts.provenance.reads.get(loop.target.id, ())
261
+ if (
262
+ self.facts.provenance.runtime_binding(read.id, read) is loop.target
263
+ or self.facts.provenance.binding(read.id, read) is loop.target
264
+ )
265
+ and self.reachable(read, function)
266
+ ]
267
+ members = set(direct_nodes(loop))
268
+ return bool(reads) and all(
269
+ self.facts.provenance.runtime_binding(read.id, read) is loop.target
270
+ and read in members
271
+ and self._model_element_read(read)
272
+ for read in reads
273
+ )
274
+
275
+ def _model_element_read(self, read: ast.Name) -> bool:
276
+ call = self.context.parents.get(read)
277
+ if isinstance(call, ast.keyword):
278
+ call = self.context.parents.get(call)
279
+ if not isinstance(call, ast.Call) or not isinstance(call.func, ast.Attribute):
280
+ return False
281
+ arguments = call_arguments(call, ("obj",))
282
+ if call.func.attr != "model_validate" or arguments is None or arguments.get("obj") is not read:
283
+ return False
284
+ contracts = DeclaredContracts(self.context)
285
+ model = contracts.class_type(call.func.value)
286
+ return model is not None and contracts.inherits(model, _VALIDATION_BASES)
287
+
211
288
  def _key_parameters(self, function: _Function) -> set[ast.arg]:
212
289
  found: set[ast.arg] = set()
213
290
  for parameter in (*function.args.posonlyargs, *function.args.args, *function.args.kwonlyargs):
@@ -337,7 +414,7 @@ class OpaqueContractFacts:
337
414
  return set()
338
415
 
339
416
  def _if_parameters(self, node: ast.If) -> set[ast.arg]:
340
- if _rejects(node.body):
417
+ if self._rejects(node.body):
341
418
  candidate = node.test
342
419
  if isinstance(candidate, ast.BoolOp) and isinstance(candidate.op, ast.Or):
343
420
  candidate = candidate.values[0]
@@ -345,7 +422,7 @@ class OpaqueContractFacts:
345
422
  return {parameter}
346
423
  if isinstance(candidate, ast.UnaryOp) and isinstance(candidate.op, ast.Not):
347
424
  return self._predicate(candidate.operand)
348
- return self._predicate(node.test) if _rejects(node.orelse) else set()
425
+ return self._predicate(node.test) if self._rejects(node.orelse) else set()
349
426
 
350
427
  def _match_parameters(self, node: ast.Match) -> set[ast.arg]:
351
428
  if not node.cases:
@@ -355,7 +432,7 @@ class OpaqueContractFacts:
355
432
  isinstance(last.pattern, ast.MatchAs)
356
433
  and last.pattern.name is None
357
434
  and last.guard is None
358
- and _rejects(last.body)
435
+ and self._rejects(last.body)
359
436
  ):
360
437
  return set()
361
438
  parameter = self.parameter(node.subject)
@@ -363,6 +440,21 @@ class OpaqueContractFacts:
363
440
  return {parameter}
364
441
  return set()
365
442
 
443
+ def _rejects(self, body: list[ast.stmt]) -> bool:
444
+ if _rejects(body):
445
+ return True
446
+ if not body or not isinstance(body[-1], ast.Expr) or not isinstance(body[-1].value, ast.Call):
447
+ return False
448
+ source = self._source(body[-1].value.func)
449
+ if source is None:
450
+ return False
451
+ _owner, function = source
452
+ return (
453
+ bool(function.body)
454
+ and isinstance(function.body[-1], ast.Raise)
455
+ and not any(isinstance(node, ast.Return | ast.Yield | ast.YieldFrom) for node in direct_nodes(function))
456
+ )
457
+
366
458
  def _predicate(self, expression: ast.expr) -> set[ast.arg]:
367
459
  if isinstance(expression, ast.BoolOp):
368
460
  return self._predicate(expression.values[0])
@@ -54,6 +54,8 @@ class PreferPreciseObjectContract(Rule):
54
54
  "Ordinary raw validators retain object inputs tied to builtin isinstance, exact builtin type comparisons or an actual source-resolved TypeGuard/TypeIs through rejecting branches, actual type/refinement assertions, accepting terminal branches with a rejecting fallback, or conditional expressions. Stable projections from containers with unchecked value slots retain their raw root contract when those values are validated. Source-visible local and imported validators may delegate those inputs and raw results; precise result narrowing does not justify a bare object output. Related unchecked mapping projections and transforms retain unknown values; import-proven native parsers and JSONDecoder preserve raw outputs. Universal builtin and stdlib interoperation may retain raw inputs. Independent object parameters, domain constructors and unproven parser names remain checked. Source resolution and dataflow are bounded with cycle guards; rebinding, decorators and namespace mutation invalidate delegated proof.",
55
55
  "Native opaque contracts include canonical ast.Constant.value reads and captures, FunctionType invocations, identity-only inputs and sys.getrefcount. Actual exec/eval globals and locals retain unknown values only through bounded native dict construction and alias flow; unrelated dictionaries and source domain factories do not borrow that ownership. Stub property returns on an import-proven runtime_checkable Protocol retain unchecked incoming attributes. Generic callable results, ordinary Protocol methods, application properties and unused parameters remain checked.",
56
56
  "Raw input unions may include scalar or None branches; only genuine unchecked container branches seed raw projections. Mapping consumers that inspect only keys retain uninspected value slots. Projected aliases require simple statement dominance, and precise active guards permit typed consumption after validation. Native namespace output reads require a preceding direct function-scope execution and abstain after authored mutations. Benign builtins imports do not hide builtin object contracts; explicit object shadowing and source-visible object mutations remain outside scope.",
57
+ "An import-proven Iterable of unchecked values retains its raw element contract when every input use is a direct synchronous iteration and every reachable element read directly enters source-proven Pydantic model_validate. Deferred closures, rebinding, other iterator/element uses, unknown model providers and JSON-text parsers do not establish that boundary.",
58
+ "Rejecting branches may end in a stable source-visible synchronous helper whose body ends with an unconditional raise and contains no return or yield path. Names and NoReturn annotations alone do not establish termination; decorated, mutated, asynchronous, generator and returning helpers remain unknown.",
57
59
  ),
58
60
  examples=(
59
61
  RuleExample(
@@ -42,7 +42,7 @@ class PreferTypedCli(Rule):
42
42
  category=RuleCategory.MAINTAINABILITY,
43
43
  autofix=AutofixPolicy.NONE,
44
44
  limitations=(
45
- "Checks import-proven sys.argv reads, argparse/optparse parser construction, getopt parsing and Click command construction. sys.argv[0], assignment targets and forwarding through args= to a proven local Typer application are retained.",
45
+ "Checks import-proven sys.argv reads, argparse/optparse parser construction, getopt parsing and Click command construction. sys.argv[0] and its direct nonempty guard with a literal string fallback, assignment targets and forwarding through args= to a proven local Typer application are retained.",
46
46
  "Checks parameters of source-visible functions passed directly to typer.run or registered with a stable local Typer application's command/callback decorator. Missing annotations and bare Any/object, including Annotated wrappers, are reported. Ordinary functions and unrelated command decorators are excluded.",
47
47
  "Stable local import and application aliases are followed. Shadowed or mutated imports, wildcard imports, dynamic namespaces and generated/vendor files abstain. Imported command functions, dynamic registrations and composite erased types require separate type checking.",
48
48
  "No automatic rewrite: positional/option compatibility and conversion behavior require review. This policy does not claim every argparse or Click program is incorrectly validated.",
@@ -191,6 +191,20 @@ def _retained_argv(node: ast.expr, facts: AnnotationOrigins) -> bool:
191
191
  if isinstance(parent.slice, ast.Constant) and type(parent.slice.value) is int and parent.slice.value == 0:
192
192
  return True
193
193
  parent = facts.context.parents.get(parent)
194
+ match parent:
195
+ case ast.IfExp(
196
+ test=test,
197
+ body=ast.Subscript(value=arguments, slice=ast.Constant(value=index)),
198
+ orelse=ast.Constant(value=str()),
199
+ ):
200
+ return (
201
+ test is node
202
+ and type(index) is int
203
+ and index == 0
204
+ and facts.qualified(arguments, arguments) == "sys.argv"
205
+ )
206
+ case _:
207
+ pass
194
208
  if not isinstance(parent, ast.keyword) or parent.arg != "args":
195
209
  return False
196
210
  call = facts.context.parents.get(parent)