sarj-python-lint 1.100.0__tar.gz → 1.101.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 (314) hide show
  1. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/PKG-INFO +2 -2
  2. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/pyproject.toml +2 -2
  3. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix.py +41 -9
  4. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_parallel.py +12 -7
  5. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_copy_on_write.py +6 -8
  6. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_namespace_access.py +1 -1
  7. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_opaque_contracts.py +12 -5
  8. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_project_index.py +19 -3
  9. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_delete_statement.py +2 -2
  10. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_direct_import_module.py +3 -2
  11. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_precise_object_contract.py +5 -2
  12. sarj_python_lint-1.101.1/src/sarj_python_lint/rules/prefer_typed_mapping_get.py +378 -0
  13. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +1 -1
  14. sarj_python_lint-1.100.0/src/sarj_python_lint/rules/prefer_typed_mapping_get.py +0 -189
  15. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/.gitignore +0 -0
  16. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/LICENSE +0 -0
  17. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/README.md +0 -0
  18. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/__init__.py +0 -0
  19. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/__main__.py +0 -0
  20. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_analysis_session.py +0 -0
  21. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_aliases.py +0 -0
  22. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_annotations.py +0 -0
  23. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_comments.py +0 -0
  24. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_declared_contracts.py +0 -0
  25. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_declared_tests.py +0 -0
  26. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_docs.py +0 -0
  27. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_enums.py +0 -0
  28. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_exhaustiveness.py +0 -0
  29. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_inert.py +0 -0
  30. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_parameters.py +0 -0
  31. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_repeated.py +0 -0
  32. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_security.py +0 -0
  33. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_sql_projection.py +0 -0
  34. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_autofix_tests.py +0 -0
  35. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_file_context.py +0 -0
  36. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_filesystem.py +0 -0
  37. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_fixes.py +0 -0
  38. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_prepared_sources.py +0 -0
  39. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_python_target.py +0 -0
  40. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_ratchet_cli.py +0 -0
  41. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_rule_descriptors.py +0 -0
  42. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_secret_names.py +0 -0
  43. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_source.py +0 -0
  44. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/_version.py +0 -0
  45. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/application_logging.py +0 -0
  46. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/autofix.py +0 -0
  47. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/benchmark.py +0 -0
  48. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/cast_access.py +0 -0
  49. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/interpreter_argv.py +0 -0
  50. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/json_boundary.py +0 -0
  51. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/py.typed +0 -0
  52. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/ratchet.py +0 -0
  53. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rule_base.py +0 -0
  54. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rule_metadata.py +0 -0
  55. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/__init__.py +0 -0
  56. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_annotation_origins.py +0 -0
  57. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
  58. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_ast_index.py +0 -0
  59. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_ast_names.py +0 -0
  60. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_ast_position.py +0 -0
  61. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_async_lifecycle.py +0 -0
  62. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_binding_inventory.py +0 -0
  63. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
  64. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_comment_narration.py +0 -0
  65. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_comments.py +0 -0
  66. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
  67. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_data_union_discriminator.py +0 -0
  68. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_declared_contracts.py +0 -0
  69. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
  70. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_docstrings.py +0 -0
  71. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_exports.py +0 -0
  72. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_fastapi.py +0 -0
  73. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_first_party.py +0 -0
  74. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
  75. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_imports.py +0 -0
  76. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_inert_model_annotation.py +0 -0
  77. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_inherited_contract.py +0 -0
  78. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_local_alias_fix.py +0 -0
  79. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_local_source.py +0 -0
  80. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_logging.py +0 -0
  81. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_mapping_shape_callbacks.py +0 -0
  82. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_native_namespace_capability.py +0 -0
  83. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_native_object_contracts.py +0 -0
  84. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
  85. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_numeric_proof.py +0 -0
  86. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_paths.py +0 -0
  87. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_postgres.py +0 -0
  88. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
  89. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_pydantic_field_contract.py +0 -0
  90. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_pytest.py +0 -0
  91. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_registry.py +0 -0
  92. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_resolved_operation_signature.py +0 -0
  93. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
  94. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_route_shapes.py +0 -0
  95. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_runtime_bindings.py +0 -0
  96. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_runtime_registry.py +0 -0
  97. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_service_http_callbacks.py +0 -0
  98. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_set_fields.py +0 -0
  99. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_sql.py +0 -0
  100. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_sql_aggregate_identity.py +0 -0
  101. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_sql_explain.py +0 -0
  102. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_sql_policy_source.py +0 -0
  103. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_static_json_alias.py +0 -0
  104. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_store_sql.py +0 -0
  105. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_store_writes.py +0 -0
  106. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
  107. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
  108. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_test_composition.py +0 -0
  109. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
  110. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_transactional_sql.py +0 -0
  111. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/_type_guard_symbols.py +0 -0
  112. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
  113. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/async_executor_shutdown.py +0 -0
  114. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
  115. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/async_subprocess_cancellation_cleanup.py +0 -0
  116. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/cancel_owned_task_without_join.py +0 -0
  117. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
  118. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
  119. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/delete_route_returns_no_content.py +0 -0
  120. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
  121. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
  122. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
  123. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
  124. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/duplicate_pytest_fixture_params.py +0 -0
  125. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
  126. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/failed_probe_zero_threshold.py +0 -0
  127. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
  128. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
  129. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
  130. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
  131. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
  132. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
  133. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
  134. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/nan_hidden_by_builtin_min.py +0 -0
  135. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
  136. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
  137. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
  138. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_async_client_in_constructor.py +0 -0
  139. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_async_function_cache.py +0 -0
  140. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
  141. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_blanket_suppression.py +0 -0
  142. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
  143. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
  144. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_conflicting_pydantic_alias_validation.py +0 -0
  145. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
  146. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_contradictory_type_guard.py +0 -0
  147. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
  148. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
  149. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_create_verb_in_post_path.py +0 -0
  150. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_custom_control_flow_exception.py +0 -0
  151. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
  152. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_defaulted_environment_setting.py +0 -0
  153. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_discarded_tagged_outcome.py +0 -0
  154. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_discarded_validation_result.py +0 -0
  155. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_dual_shape_model_field_reader.py +0 -0
  156. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
  157. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
  158. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_duplicate_field_validator_body.py +0 -0
  159. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_exception_text_in_500_detail.py +0 -0
  160. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
  161. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
  162. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
  163. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
  164. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
  165. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
  166. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_folded_bad_request_not_found.py +0 -0
  167. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
  168. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_generic_json_parser.py +0 -0
  169. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
  170. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_hasattr.py +0 -0
  171. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
  172. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_impossible_pydantic_field_bounds.py +0 -0
  173. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
  174. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
  175. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
  176. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
  177. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_invalid_pydantic_bypass.py +0 -0
  178. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_invalid_pydantic_validator_return.py +0 -0
  179. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_loguru_exc_info.py +0 -0
  180. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_loguru_printf_format.py +0 -0
  181. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
  182. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_mutating_container_transform.py +0 -0
  183. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_mutating_input_with_result.py +0 -0
  184. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
  185. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
  186. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
  187. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_partial_type_is.py +0 -0
  188. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
  189. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
  190. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
  191. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
  192. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
  193. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_recording_store.py +0 -0
  194. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_redundant_attribute_unpacking.py +0 -0
  195. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
  196. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_redundant_local_alias.py +0 -0
  197. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
  198. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_redundant_sql_alias.py +0 -0
  199. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
  200. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
  201. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
  202. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
  203. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_select_star.py +0 -0
  204. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
  205. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
  206. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_shallow_record_type_guard.py +0 -0
  207. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_slash_collection_root_under_prefix.py +0 -0
  208. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
  209. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
  210. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
  211. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_test_comments.py +0 -0
  212. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
  213. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
  214. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
  215. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_unknown_pydantic_validator_field.py +0 -0
  216. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
  217. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
  218. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
  219. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
  220. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
  221. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
  222. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/no_work_verb_get_route.py +0 -0
  223. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
  224. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
  225. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
  226. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_application_model_joins.py +0 -0
  227. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
  228. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_bulk_upsert.py +0 -0
  229. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
  230. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
  231. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
  232. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_declarative_batch_validation.py +0 -0
  233. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_discriminated_model_union.py +0 -0
  234. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
  235. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_grouped_settings.py +0 -0
  236. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
  237. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
  238. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
  239. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
  240. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
  241. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
  242. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
  243. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
  244. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
  245. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
  246. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
  247. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
  248. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
  249. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
  250. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_optional_composite.py +0 -0
  251. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
  252. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_psycopg_executemany.py +0 -0
  253. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
  254. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_pydantic_model_assertion.py +0 -0
  255. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_pytest_dependency_fixtures.py +0 -0
  256. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_pytest_fixture_contract.py +0 -0
  257. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
  258. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
  259. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
  260. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_runtime_validation.py +0 -0
  261. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
  262. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
  263. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
  264. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
  265. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
  266. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_typed_cli.py +0 -0
  267. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_typed_settings_field.py +0 -0
  268. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
  269. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
  270. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
  271. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
  272. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
  273. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
  274. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/pytest_fixture_returns_closed_resource.py +0 -0
  275. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
  276. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
  277. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
  278. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +0 -0
  279. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
  280. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
  281. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
  282. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +0 -0
  283. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_constrained_api_integer.py +0 -0
  284. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_exp_on_jwt_decode.py +0 -0
  285. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
  286. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
  287. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
  288. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
  289. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
  290. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
  291. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
  292. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
  293. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
  294. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_pydantic_for_mapping_shape.py +0 -0
  295. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
  296. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
  297. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
  298. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/service_singleton_delegates_to_bulk.py +0 -0
  299. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
  300. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/stepdown.py +0 -0
  301. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/store_field_update_reuses_upsert.py +0 -0
  302. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
  303. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/store_insert_requires_explicit_conflict_policy.py +0 -0
  304. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
  305. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/store_mutation_command_fanout.py +0 -0
  306. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
  307. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/test_without_explicit_oracle.py +0 -0
  308. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
  309. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
  310. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
  311. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
  312. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
  313. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.1}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
  314. {sarj_python_lint-1.100.0 → sarj_python_lint-1.101.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.100.0
3
+ Version: 1.101.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/
@@ -19,7 +19,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
19
19
  Requires-Python: >=3.14
20
20
  Requires-Dist: packaging==26.3
21
21
  Requires-Dist: ruff>=0.17.2
22
- Requires-Dist: sarj-rule-contracts==0.5.0
22
+ Requires-Dist: sarj-rule-contracts==0.6.0
23
23
  Requires-Dist: sqlglot==30.24.0
24
24
  Requires-Dist: typer==0.27.3
25
25
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sarj-python-lint"
3
- version = "1.100.0"
3
+ version = "1.101.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" }]
@@ -15,7 +15,7 @@ classifiers = [
15
15
  "Programming Language :: Python :: 3.14",
16
16
  "Topic :: Software Development :: Quality Assurance",
17
17
  ]
18
- dependencies = ["sarj-rule-contracts==0.5.0", "packaging==26.3", "ruff>=0.17.2", "sqlglot==30.24.0", "typer==0.27.3"]
18
+ dependencies = ["sarj-rule-contracts==0.6.0", "packaging==26.3", "ruff>=0.17.2", "sqlglot==30.24.0", "typer==0.27.3"]
19
19
 
20
20
  [project.scripts]
21
21
  sarj-python-lint = "sarj_python_lint.__main__:main"
@@ -2,13 +2,14 @@ from __future__ import annotations
2
2
 
3
3
  import ast
4
4
  from bisect import bisect_left, insort
5
+ from dataclasses import dataclass
5
6
  from functools import cached_property
6
7
  from hashlib import sha256
7
8
  from io import StringIO
8
9
  from itertools import pairwise
9
10
  import re
10
11
  import tokenize
11
- from typing import TYPE_CHECKING, Final, NamedTuple
12
+ from typing import TYPE_CHECKING, Final, Literal, NamedTuple
12
13
  from unicodedata import normalize
13
14
 
14
15
  from sarj_rule_contracts import TextEdit, apply_edits
@@ -80,6 +81,8 @@ _WALRUS_CODES = frozenset({"SARJ081", "SARJ432"})
80
81
  _JWT_POSITIONAL_PREFIX_ARGUMENTS = 3
81
82
  _STREAM_MIN_BODY_LENGTH = 3
82
83
  _CONSTANT_TRUE_DEPTH_LIMIT = 32
84
+ # Bound accepted revisions; each rule still owns its work and replacement size.
85
+ _MAX_FIX_PASSES: Final = 256
83
86
  _PURE_STRING_TRANSFORMS: Final[dict[str, str]] = {
84
87
  "strip": "stripped_value",
85
88
  "lower": "lowered_value",
@@ -1360,6 +1363,18 @@ _BUILDERS: Final[dict[str, Callable[[_Source, Diagnostic], list[TextEdit]]]] = {
1360
1363
  }
1361
1364
 
1362
1365
 
1366
+ @dataclass(frozen=True, slots=True)
1367
+ class _FixCandidate:
1368
+ code: str
1369
+ edits: tuple[TextEdit, ...]
1370
+
1371
+
1372
+ @dataclass(frozen=True, slots=True)
1373
+ class _FixPass:
1374
+ edits: tuple[TextEdit, ...]
1375
+ codes: tuple[str, ...]
1376
+
1377
+
1363
1378
  def fix_source(path: Path, source: str, *, rule_ids: Sequence[str] | None = None) -> str:
1364
1379
  from sarj_python_lint.__main__ import check_source # ruff: ignore[import-outside-top-level] -- the CLI imports this entry point lazily.
1365
1380
 
@@ -1371,6 +1386,8 @@ def fix_source(path: Path, source: str, *, rule_ids: Sequence[str] | None = None
1371
1386
  # Only the closed alias builder owns aligned physical-line buffers and token coordinates here.
1372
1387
  rules = [rule for rule in rules if rule.code == "SARJ531"]
1373
1388
  seen: set[bytes] = set()
1389
+ applied_codes: set[str] = set()
1390
+ passes = 0
1374
1391
  current = source
1375
1392
  while (fingerprint := sha256(current.encode("utf-8")).digest()) not in seen:
1376
1393
  seen.add(fingerprint)
@@ -1380,30 +1397,43 @@ def fix_source(path: Path, source: str, *, rule_ids: Sequence[str] | None = None
1380
1397
  if not candidates:
1381
1398
  return current
1382
1399
  # Batch independent candidates; overlapping candidates get fresh offsets on the next pass.
1383
- updated = apply_edits(current, _coherent_edits(candidates))
1400
+ selected_pass = _coherent_edits(candidates)
1401
+ updated = apply_edits(current, selected_pass.edits)
1384
1402
  compile(updated, str(path), "exec", dont_inherit=True)
1385
1403
  if updated == current:
1386
1404
  return current
1405
+ if passes == _MAX_FIX_PASSES:
1406
+ raise _convergence_error(path, reason="pass budget exhausted", passes=passes, codes=applied_codes)
1407
+ passes += 1
1408
+ applied_codes.update(selected_pass.codes)
1387
1409
  current = updated
1388
- msg = f"Python autofixes did not converge: {path}"
1389
- raise ValueError(msg)
1410
+ raise _convergence_error(path, reason="source cycle", passes=passes, codes=applied_codes)
1411
+
1412
+
1413
+ def _convergence_error(
1414
+ path: Path, *, reason: Literal["pass budget exhausted", "source cycle"], passes: int, codes: set[str]
1415
+ ) -> ValueError:
1416
+ participants = ", ".join(sorted(codes)) or "none"
1417
+ msg = f"Python autofixes did not converge: {path} ({reason}; passes={passes}; rules={participants})"
1418
+ return ValueError(msg)
1390
1419
 
1391
1420
 
1392
- def _candidate_edits(context: PythonFileContext, diagnostics: Sequence[Diagnostic]) -> list[list[TextEdit]]:
1421
+ def _candidate_edits(context: PythonFileContext, diagnostics: Sequence[Diagnostic]) -> list[_FixCandidate]:
1393
1422
  view = _Source(context, diagnostics)
1394
1423
  return [
1395
- edits
1424
+ _FixCandidate(diagnostic.code, tuple(edits))
1396
1425
  for diagnostic in diagnostics
1397
1426
  if (builder := _BUILDERS.get(diagnostic.code)) is not None
1398
1427
  if (edits := builder(view, diagnostic))
1399
1428
  ]
1400
1429
 
1401
1430
 
1402
- def _coherent_edits(candidates: list[list[TextEdit]]) -> list[TextEdit]:
1431
+ def _coherent_edits(candidates: list[_FixCandidate]) -> _FixPass:
1403
1432
  accepted: list[TextEdit] = []
1433
+ codes: list[str] = []
1404
1434
  known: set[TextEdit] = set()
1405
1435
  for candidate in candidates:
1406
- additions = sorted(set(candidate) - known)
1436
+ additions = sorted(set(candidate.edits) - known)
1407
1437
  if any(map(_overlap, additions, additions[1:], strict=False)):
1408
1438
  continue
1409
1439
  for edit in additions:
@@ -1416,7 +1446,9 @@ def _coherent_edits(candidates: list[list[TextEdit]]) -> list[TextEdit]:
1416
1446
  for edit in additions:
1417
1447
  insort(accepted, edit)
1418
1448
  known.update(additions)
1419
- return accepted
1449
+ if additions:
1450
+ codes.append(candidate.code)
1451
+ return _FixPass(tuple(accepted), tuple(dict.fromkeys(codes)))
1420
1452
 
1421
1453
 
1422
1454
  def _overlap(first: TextEdit, second: TextEdit) -> bool:
@@ -143,19 +143,24 @@ def check_parallel(
143
143
  for path, source in loaded.items()
144
144
  )
145
145
  for result in pool.map(_check_file, items, chunksize=1, buffersize=workers * 4):
146
- if result.needs_serial:
147
- # Drain the actual worker results so another initializer/file
148
- # failure cannot be disguised as a clean serial replay.
149
- needs_serial = True
146
+ # Drain actual results after either replay signal so a later worker
147
+ # failure cannot be disguised as a clean serial replay.
148
+ if needs_serial:
150
149
  continue
151
150
  resolutions.update(result.resolutions)
152
151
  modules.update(result.modules)
153
152
  # A worker cannot hit either order-dependent limit when the whole
154
153
  # union stays strictly below it. At the boundary, discard all output.
155
- if not needs_serial and (
156
- len(resolutions) >= LOCAL_SOURCE_CACHE_LIMIT or len(modules) >= LOCAL_SOURCE_CACHE_LIMIT
154
+ if (
155
+ result.needs_serial
156
+ or len(resolutions) >= LOCAL_SOURCE_CACHE_LIMIT
157
+ or len(modules) >= LOCAL_SOURCE_CACHE_LIMIT
157
158
  ):
158
- return None
159
+ needs_serial = True
160
+ diagnostics.clear()
161
+ resolutions.clear()
162
+ modules.clear()
163
+ continue
159
164
  diagnostics.extend(result.diagnostics)
160
165
  return None if needs_serial else diagnostics
161
166
  finally:
@@ -973,10 +973,8 @@ class CopyOnWriteAnalysis:
973
973
  summaries[key] = _summary_value(_OwnershipSummary(alternatives))
974
974
  bindings[name] = summaries[key]
975
975
 
976
- def _scan(self, statements: list[ast.stmt], bindings: dict[str, _Value]) -> None:
977
- for statement in statements:
978
- if self._statement(statement, bindings):
979
- return
976
+ def _scan(self, statements: list[ast.stmt], bindings: dict[str, _Value]) -> bool:
977
+ return any(self._statement(statement, bindings) for statement in statements)
980
978
 
981
979
  def _statement(self, statement: ast.stmt, bindings: dict[str, _Value]) -> bool:
982
980
  match statement:
@@ -991,7 +989,7 @@ class CopyOnWriteAnalysis:
991
989
  self._write(target, bindings)
992
990
  self._bind(target, None, bindings)
993
991
  case ast.If():
994
- self._branches(statement, bindings)
992
+ return self._branches(statement, bindings)
995
993
  case ast.For() | ast.AsyncFor():
996
994
  self._for(statement, bindings)
997
995
  case ast.Expr(value=ast.Call() as call):
@@ -1026,16 +1024,16 @@ class CopyOnWriteAnalysis:
1026
1024
  self._write(target, bindings)
1027
1025
  self._bind(target, value, bindings)
1028
1026
 
1029
- def _branches(self, statement: ast.If, bindings: dict[str, _Value]) -> None:
1027
+ def _branches(self, statement: ast.If, bindings: dict[str, _Value]) -> bool:
1030
1028
  self._expression(statement.test, bindings)
1031
1029
  branches: list[dict[str, _Value]] = []
1032
1030
  for positive, block in ((True, statement.body), (False, statement.orelse)):
1033
1031
  branch = dict(bindings)
1034
1032
  self._refine(statement.test, branch, positive=positive)
1035
- self._scan(block, branch)
1036
- if not block or not isinstance(block[-1], (ast.Return, ast.Raise)):
1033
+ if not self._scan(block, branch):
1037
1034
  branches.append(branch)
1038
1035
  self._join(branches, bindings)
1036
+ return not branches
1039
1037
 
1040
1038
  def _for(self, statement: ast.For | ast.AsyncFor, bindings: dict[str, _Value]) -> None:
1041
1039
  self._expression(statement.iter, bindings)
@@ -48,7 +48,7 @@ def dynamic_namespace_access(
48
48
  def _namespace_api_aliases(nodes: Iterable[ast.AST]) -> set[str]:
49
49
  aliases = set(_NAMESPACE_APIS) | {"__builtins__"}
50
50
  for node in nodes:
51
- if not isinstance(node, ast.ImportFrom) or node.module not in _MODULE_APIS:
51
+ if not isinstance(node, ast.ImportFrom) or node.level != 0 or node.module not in _MODULE_APIS:
52
52
  continue
53
53
  members = _MODULE_APIS[node.module]
54
54
  aliases.update(alias.asname or alias.name for alias in node.names if alias.name in members)
@@ -16,6 +16,7 @@ if TYPE_CHECKING:
16
16
  from pathlib import Path
17
17
 
18
18
  from sarj_python_lint._file_context import PythonFileContext
19
+ from sarj_python_lint.rules._local_source import LocalSourceFacts
19
20
 
20
21
 
21
22
  type _Function = ast.FunctionDef | ast.AsyncFunctionDef
@@ -111,11 +112,13 @@ class OpaqueContractFacts:
111
112
  context: PythonFileContext,
112
113
  facts: MappingShapeFacts,
113
114
  *,
115
+ local_source: LocalSourceFacts,
114
116
  modules: dict[Path, OpaqueContractFacts] | None = None,
115
117
  budget: _ProofBudget | None = None,
116
118
  ) -> None:
117
119
  self.context = context
118
120
  self.facts = facts
121
+ self.local_source = local_source
119
122
  self.native = NativeObjectContracts(context, facts)
120
123
  self.guards: dict[str, _Refinement | None] = {}
121
124
  self.checked: dict[_Function, frozenset[ast.arg]] = {}
@@ -712,20 +715,24 @@ class OpaqueContractFacts:
712
715
 
713
716
  def _imported_source(self, qualified: str) -> tuple[OpaqueContractFacts, ast.FunctionDef] | None:
714
717
  module, _, name = qualified.rpartition(".")
715
- path = self.context.session.local_source.resolve_module(
716
- self.context.path, module, 0, facts=self.context.session.first_party
717
- )
718
+ path = self.local_source.resolve_module(self.context.path, module, 0, facts=self.context.session.first_party)
718
719
  if path is not None and (owner := self.modules.get(path.resolve())) is not None:
719
720
  return owner.export(name)
720
721
  if len(self.modules) >= _MAX_GUARDS:
721
722
  return None
722
- loaded = self.context.session.local_source.read_module(path) if path is not None else None
723
+ loaded = self.local_source.read_module(path) if path is not None else None
723
724
  if loaded is None:
724
725
  return None
725
726
  from sarj_python_lint._file_context import PythonFileContext # ruff: ignore[import-outside-top-level] -- source loading runs after AnalysisSession initialization.
726
727
 
727
728
  context = PythonFileContext(loaded.path, loaded.source, self.context.session)
728
- owner = OpaqueContractFacts(context, MappingShapeFacts(context), modules=self.modules, budget=self.budget)
729
+ owner = OpaqueContractFacts(
730
+ context,
731
+ MappingShapeFacts(context),
732
+ local_source=self.local_source,
733
+ modules=self.modules,
734
+ budget=self.budget,
735
+ )
729
736
  return owner.export(name)
730
737
 
731
738
  def export(self, name: str) -> tuple[OpaqueContractFacts, ast.FunctionDef] | None:
@@ -156,6 +156,11 @@ class SourceUnit:
156
156
  captured: CapturedSource | None = None
157
157
 
158
158
 
159
+ @dataclass(frozen=True, slots=True)
160
+ class _AmbiguousModuleSources:
161
+ paths: tuple[Path, ...]
162
+
163
+
159
164
  @dataclass(frozen=True, slots=True)
160
165
  class LoadedSource:
161
166
  path: Path
@@ -276,8 +281,18 @@ class ProjectIndexSet:
276
281
  self._bound_value_prefixes: dict[str, bool] = {}
277
282
  self._value_origins_incomplete = False
278
283
  self.import_namespace_mutations = ImportNamespaceMutations(WeakMethod(self._namespace_write_inventory))
279
- by_module = {unit.module: unit for unit in units.values() if unit.module is not None}
280
- self._by_module = MappingProxyType(by_module)
284
+ by_module: dict[str, dict[Path, SourceUnit]] = {}
285
+ for unit in units.values():
286
+ if unit.module is not None:
287
+ by_module.setdefault(unit.module, {})[unit.path] = unit
288
+ self._by_module = MappingProxyType(
289
+ {
290
+ module: next(iter(candidates.values()))
291
+ if len(candidates) == 1
292
+ else _AmbiguousModuleSources(tuple(candidates))
293
+ for module, candidates in by_module.items()
294
+ }
295
+ )
281
296
  classes: dict[SymbolRef, ClassSummary] = {}
282
297
  nominals: dict[str, set[SymbolRef]] = {}
283
298
  _collect_unit_symbols(units, classes, nominals)
@@ -429,7 +444,8 @@ class ProjectIndexSet:
429
444
  return False
430
445
 
431
446
  def source_unit(self, module: str) -> SourceUnit | None:
432
- return self._by_module.get(module)
447
+ source = self._by_module.get(module)
448
+ return source if isinstance(source, SourceUnit) else None
433
449
 
434
450
  def _namespace_write_inventory(self) -> Mapping[str, _ImportNamespaceWrites]:
435
451
  def resolve(origin: SymbolRef) -> tuple[SymbolRef, ...] | None:
@@ -136,6 +136,6 @@ class NoDeleteStatement(Rule):
136
136
  "immutably, or add an exact SARJ442 suppression explaining why deletion is required."
137
137
  ),
138
138
  )
139
- for node in context.nodes(ast.AST)
140
- if isinstance(node, ast.Delete) and not is_suppressed(source_lines, node.lineno, self.code)
139
+ for node in context.nodes(ast.Delete)
140
+ if not is_suppressed(source_lines, node.lineno, self.code)
141
141
  ]
@@ -71,10 +71,11 @@ class PreferDirectImportModule(Rule):
71
71
  def check_context(self, context: PythonFileContext) -> list[Diagnostic]:
72
72
  if context.generated or context.tree is None or "import_module" not in context.symbol_source:
73
73
  return []
74
+ provenance = context.resource_provenance
74
75
  loader_references = {
75
76
  reference
76
77
  for call in context.nodes(ast.Call)
77
- if context.imports.resolved_qualified_name(call.func) == "importlib.import_module"
78
+ if provenance.runtime_import_name(call.func) == "importlib.import_module"
78
79
  for reference in ast.walk(call.func)
79
80
  }
80
81
  if dynamic_namespace_access(
@@ -96,7 +97,7 @@ class PreferDirectImportModule(Rule):
96
97
  if isinstance(statement, ast.Assign | ast.AnnAssign | ast.Expr)
97
98
  and isinstance(node := statement.value, ast.Call)
98
99
  and (module := _literal_module(node)) is not None
99
- and context.resource_provenance.runtime_import_name(node.func) == "importlib.import_module"
100
+ and provenance.runtime_import_name(node.func) == "importlib.import_module"
100
101
  ]
101
102
 
102
103
 
@@ -15,6 +15,7 @@ from sarj_python_lint.rule_base import (
15
15
  RuleExample,
16
16
  Severity,
17
17
  )
18
+ from sarj_python_lint.rules._local_source import LocalSourceFacts
18
19
  from sarj_python_lint.rules._native_object_contracts import builtin_object, builtin_symbol
19
20
  from sarj_python_lint.rules._opaque_contracts import REFINEMENT_TYPES, OpaqueContractFacts
20
21
  from sarj_python_lint.rules.require_pydantic_for_mapping_shape import MappingShapeFacts
@@ -48,7 +49,7 @@ class PreferPreciseObjectContract(Rule):
48
49
  "Safe fixes narrow only a bare builtin object return annotation to builtin str for a closed private nested synchronous helper returning one exact string literal, with every call used directly as an if test and all containing return contracts explicit. Existing inert/metadata/binding proofs must hold; public/domain/container/parameter/model contracts and other result uses remain review-only.",
49
50
  "Checks builtin object in function signatures and class field annotations, including supported containers, callables, optional unions and quoted annotations. Local opaque values, object() sentinels, Literal/Annotated metadata, framework hooks, proven override signatures, and registered raw Pydantic callbacks are excluded. Functions that directly validate an object parameter through a source-visible BaseModel, BaseSettings or RootModel model_validate call, positionally or with obj=, retain that raw boundary. JSON text inputs still require a text or byte contract. Aliases must resolve to their source declaration and their bodies use definition scope. Alias graphs are bounded and shared branches reuse their facts. Imported or shadowed application types named object are preserved. Genuine opaque public contracts can use an explained exact-code exception; narrowing outside the exact private truthiness-only subset remains manual.",
50
51
  "An import-proven TypeGuard or TypeIs retains bare object on its guarded positional parameter and unchecked object slots in its declared refinement result; other object parameters remain checked. Guard correctness belongs to the type-guard rules. Universal type[object] class contracts and the return of a canonical module-level PEP 562 __getattr__ hook retain their opaque runtime contracts.",
51
- "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.",
52
+ "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 use a bounded per-file proof cache, captured source inputs and cycle guards; rebinding, decorators and namespace mutation invalidate delegated proof.",
52
53
  "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.",
53
54
  "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.",
54
55
  "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.",
@@ -131,7 +132,9 @@ class PreferPreciseObjectContract(Rule):
131
132
  if facts.provenance.wildcard:
132
133
  return []
133
134
  findings: list[Diagnostic] = []
134
- opaque = OpaqueContractFacts(context, facts)
135
+ opaque = OpaqueContractFacts(
136
+ context, facts, local_source=LocalSourceFacts(source_inputs=context.session.source_inputs)
137
+ )
135
138
  for owner, annotation in _contracts(context):
136
139
  if not _has_object(annotation, context, facts, at=annotation):
137
140
  continue