sarj-python-lint 1.15.0__tar.gz → 1.15.2__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.
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/PKG-INFO +1 -1
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/pyproject.toml +1 -1
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_sql.py +11 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +77 -9
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/.gitignore +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/LICENSE +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/README.md +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/__main__.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_file_context.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/benchmark.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_ast_index.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_docstrings.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_fastapi.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_local_source.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_project_index.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_registry.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_set_fields.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_test_composition.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/discourage_nullable_constructor_parameters.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sarj-python-lint
|
|
3
|
-
Version: 1.15.
|
|
3
|
+
Version: 1.15.2
|
|
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/
|
|
@@ -64,8 +64,17 @@ def strip_sql_noise(
|
|
|
64
64
|
|
|
65
65
|
def _quoted_sql_end(text: str, start: int) -> int:
|
|
66
66
|
quote = text[start]
|
|
67
|
+
escape_string = (
|
|
68
|
+
quote == "'"
|
|
69
|
+
and start > 0
|
|
70
|
+
and text[start - 1] in {"E", "e"}
|
|
71
|
+
and (start == 1 or not (text[start - 2].isalnum() or text[start - 2] in {"_", "$"}))
|
|
72
|
+
)
|
|
67
73
|
i = start + 1
|
|
68
74
|
while i < len(text):
|
|
75
|
+
if escape_string and text[i] == "\\" and i + 1 < len(text):
|
|
76
|
+
i += 2
|
|
77
|
+
continue
|
|
69
78
|
if text[i] != quote:
|
|
70
79
|
i += 1
|
|
71
80
|
continue
|
|
@@ -107,6 +116,8 @@ def _block_comment_end(text: str, start: int) -> int:
|
|
|
107
116
|
|
|
108
117
|
|
|
109
118
|
def _dollar_quote_end(text: str, start: int) -> int | None:
|
|
119
|
+
if start > 0 and (text[start - 1].isalnum() or text[start - 1] in {"_", "$"}):
|
|
120
|
+
return None
|
|
110
121
|
delimiter_end = text.find("$", start + 1)
|
|
111
122
|
if delimiter_end == -1:
|
|
112
123
|
return None
|
|
@@ -118,13 +118,15 @@ class PreferPytestFixtureInjection(Rule):
|
|
|
118
118
|
):
|
|
119
119
|
return []
|
|
120
120
|
tree = context.tree
|
|
121
|
+
helpers = _resource_helpers(context)
|
|
122
|
+
if not helpers:
|
|
123
|
+
return []
|
|
121
124
|
module_bindings = _scope_bindings(tree)
|
|
122
125
|
if "__test__" in module_bindings or any(
|
|
123
126
|
isinstance(node, ast.Attribute) and node.attr == "__test__" and isinstance(node.ctx, (ast.Store, ast.Del))
|
|
124
127
|
for node in ast.walk(tree)
|
|
125
128
|
):
|
|
126
129
|
return []
|
|
127
|
-
helpers = _resource_helpers(context)
|
|
128
130
|
diagnostics: list[Diagnostic] = []
|
|
129
131
|
for statement in tree.body:
|
|
130
132
|
if (
|
|
@@ -156,9 +158,12 @@ def _resource_helpers(context: PythonFileContext) -> frozenset[str]:
|
|
|
156
158
|
tree = context.tree
|
|
157
159
|
if tree is None:
|
|
158
160
|
return frozenset()
|
|
161
|
+
references = tuple(_helper_imports(tree))
|
|
162
|
+
if not references:
|
|
163
|
+
return frozenset()
|
|
159
164
|
bindings = _scope_bindings(tree)
|
|
160
165
|
helpers: set[str] = set()
|
|
161
|
-
for reference in
|
|
166
|
+
for reference in references:
|
|
162
167
|
if bindings[reference.local] != 1 or _root_mutated(tree, reference.local):
|
|
163
168
|
continue
|
|
164
169
|
target = context.session.local_source.resolve_module(
|
|
@@ -175,15 +180,19 @@ def _resource_helpers(context: PythonFileContext) -> frozenset[str]:
|
|
|
175
180
|
|
|
176
181
|
|
|
177
182
|
def _helper_imports(tree: ast.Module) -> Iterator[_HelperImport]:
|
|
178
|
-
|
|
179
|
-
return
|
|
183
|
+
candidates: list[_HelperImport] = []
|
|
180
184
|
for statement in tree.body:
|
|
181
|
-
if not isinstance(statement, ast.ImportFrom)
|
|
185
|
+
if not isinstance(statement, ast.ImportFrom):
|
|
182
186
|
continue
|
|
183
|
-
|
|
187
|
+
module = statement.module
|
|
188
|
+
if module is None or module.rsplit(".", 1)[-1] != "conftest":
|
|
184
189
|
continue
|
|
185
|
-
|
|
186
|
-
|
|
190
|
+
candidates.extend(
|
|
191
|
+
_HelperImport(alias.asname or alias.name, alias.name, module, statement.level) for alias in statement.names
|
|
192
|
+
)
|
|
193
|
+
if not candidates or _has_wildcard(tree):
|
|
194
|
+
return
|
|
195
|
+
yield from candidates
|
|
187
196
|
|
|
188
197
|
|
|
189
198
|
def _is_resource_helper(module: LocalModule, symbol: str) -> bool:
|
|
@@ -261,7 +270,25 @@ def _assigned_dependency_call(
|
|
|
261
270
|
def _pytest_mark(context: PythonFileContext, decorator: ast.expr) -> bool:
|
|
262
271
|
target = decorator.func if isinstance(decorator, ast.Call) else decorator
|
|
263
272
|
qualified = context.module_imports.resolved_qualified_name(target)
|
|
264
|
-
|
|
273
|
+
tree = context.tree
|
|
274
|
+
root = _root_name(target)
|
|
275
|
+
if (
|
|
276
|
+
qualified is None
|
|
277
|
+
or not qualified.startswith("pytest.mark.")
|
|
278
|
+
or tree is None
|
|
279
|
+
or root is None
|
|
280
|
+
or _scope_bindings(tree)[root] != 1
|
|
281
|
+
):
|
|
282
|
+
return False
|
|
283
|
+
for node in ast.walk(tree):
|
|
284
|
+
if not isinstance(node, (ast.Attribute, ast.Subscript)) or not isinstance(node.ctx, (ast.Store, ast.Del)):
|
|
285
|
+
continue
|
|
286
|
+
if isinstance(node, ast.Subscript) and _root_name(node.value) == root:
|
|
287
|
+
return False
|
|
288
|
+
changed = context.module_imports.resolved_qualified_name(node)
|
|
289
|
+
if changed is not None and (qualified == changed or qualified.startswith(f"{changed}.")):
|
|
290
|
+
return False
|
|
291
|
+
return True
|
|
265
292
|
|
|
266
293
|
|
|
267
294
|
def _unshadowed_consumer(context: PythonFileContext, call: ast.Call, bindings: Counter[str]) -> bool:
|
|
@@ -338,15 +365,46 @@ def _scope_bindings(scope: ast.Module | Function) -> Counter[str]:
|
|
|
338
365
|
names.update(arg.arg for arg in (arguments.vararg, arguments.kwarg) if arg is not None)
|
|
339
366
|
for statement in scope.body:
|
|
340
367
|
_collect_bindings(statement, names)
|
|
368
|
+
if isinstance(scope, ast.Module):
|
|
369
|
+
names.update(_global_writes(scope))
|
|
341
370
|
return names
|
|
342
371
|
|
|
343
372
|
|
|
373
|
+
def _global_writes(tree: ast.Module) -> Counter[str]:
|
|
374
|
+
if not any(isinstance(node, ast.Global) for node in ast.walk(tree)):
|
|
375
|
+
return Counter()
|
|
376
|
+
writes: Counter[str] = Counter()
|
|
377
|
+
for node in ast.walk(tree):
|
|
378
|
+
if not isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
|
|
379
|
+
continue
|
|
380
|
+
names: Counter[str] = Counter()
|
|
381
|
+
declarations: set[str] = set()
|
|
382
|
+
for statement in node.body:
|
|
383
|
+
_collect_bindings(statement, names)
|
|
384
|
+
declarations.update(_global_names(statement))
|
|
385
|
+
writes.update(dict.fromkeys(declarations & names.keys(), 2))
|
|
386
|
+
return writes
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def _global_names(node: ast.AST) -> Iterator[str]:
|
|
390
|
+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
|
|
391
|
+
return
|
|
392
|
+
if isinstance(node, ast.Global):
|
|
393
|
+
yield from node.names
|
|
394
|
+
for child in ast.iter_child_nodes(node):
|
|
395
|
+
yield from _global_names(child)
|
|
396
|
+
|
|
397
|
+
|
|
344
398
|
def _collect_bindings(node: ast.AST, names: Counter[str]) -> None:
|
|
345
399
|
match node:
|
|
346
400
|
case ast.FunctionDef(name=name) | ast.AsyncFunctionDef(name=name) | ast.ClassDef(name=name):
|
|
347
401
|
names[name] += 1
|
|
402
|
+
for expression in _definition_expressions(node):
|
|
403
|
+
_collect_bindings(expression, names)
|
|
348
404
|
return
|
|
349
405
|
case ast.Lambda():
|
|
406
|
+
for expression in _definition_expressions(node):
|
|
407
|
+
_collect_bindings(expression, names)
|
|
350
408
|
return
|
|
351
409
|
case ast.Import(names=aliases) | ast.ImportFrom(names=aliases):
|
|
352
410
|
names.update(alias.asname or alias.name.partition(".")[0] for alias in aliases)
|
|
@@ -369,6 +427,16 @@ def _collect_bindings(node: ast.AST, names: Counter[str]) -> None:
|
|
|
369
427
|
_collect_bindings(child, names)
|
|
370
428
|
|
|
371
429
|
|
|
430
|
+
def _definition_expressions(node: ast.FunctionDef | ast.AsyncFunctionDef | ast.ClassDef | ast.Lambda) -> list[ast.AST]:
|
|
431
|
+
if isinstance(node, ast.ClassDef):
|
|
432
|
+
return [*node.decorator_list, *node.bases, *node.keywords]
|
|
433
|
+
defaults: list[ast.AST] = [
|
|
434
|
+
*node.args.defaults,
|
|
435
|
+
*(default for default in node.args.kw_defaults if default is not None),
|
|
436
|
+
]
|
|
437
|
+
return defaults if isinstance(node, ast.Lambda) else [*node.decorator_list, *defaults]
|
|
438
|
+
|
|
439
|
+
|
|
372
440
|
def _has_wildcard(tree: ast.Module) -> bool:
|
|
373
441
|
return any(
|
|
374
442
|
isinstance(node, ast.ImportFrom) and any(alias.name == "*" for alias in node.names) for node in ast.walk(tree)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/_analysis_session.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_dict_key_views.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_fixed_record.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_local_source.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_nominal_project.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_prose_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_set_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/_test_composition.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/mock_without_spec.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_comment_cruft.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_dunder_all.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_secret_in_log.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/no_select_star.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/over_mocked_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_class_row.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_or_pattern.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/prefer_str_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.15.0 → sarj_python_lint-1.15.2}/src/sarj_python_lint/rules/unused_mock_setup.py
RENAMED
|
File without changes
|
|
File without changes
|