sarj-python-lint 1.77.0__tar.gz → 1.77.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.77.0 → sarj_python_lint-1.77.2}/PKG-INFO +1 -1
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/pyproject.toml +1 -1
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_fixes.py +3 -1
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_fastapi.py +136 -44
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +2 -1
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/.gitignore +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/LICENSE +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/README.md +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/__main__.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_aliases.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_annotations.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_comments.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_declared_contracts.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_declared_tests.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_docs.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_enums.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_exhaustiveness.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_inert.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_parameters.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_repeated.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_security.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_sql_projection.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_tests.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_file_context.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_parallel.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_source.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/autofix.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/benchmark.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/cast_access.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/interpreter_argv.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_annotation_origins.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_ast_index.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_ast_names.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_data_union_discriminator.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_declared_contracts.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_docstrings.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_exports.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_inert_model_annotation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_inherited_contract.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_local_alias_fix.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_local_source.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_mapping_shape_callbacks.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_namespace_access.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_native_namespace_capability.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_project_index.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_pydantic_field_contract.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_registry.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_resolved_operation_signature.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_route_shapes.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_runtime_bindings.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_set_fields.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_sql.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_static_json_alias.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_store_writes.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_test_composition.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_type_guard_symbols.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/delete_route_returns_no_content.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/duplicate_pytest_fixture_params.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_async_function_cache.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_blanket_suppression.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_conflicting_pydantic_alias_validation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_contradictory_type_guard.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_create_verb_in_post_path.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_defaulted_environment_setting.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_discarded_validation_result.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_dual_shape_model_field_reader.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_duplicate_field_validator_body.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_exception_text_in_500_detail.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_folded_bad_request_not_found.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_hasattr.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_impossible_pydantic_field_bounds.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_invalid_pydantic_bypass.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_invalid_pydantic_validator_return.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_loguru_exc_info.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_loguru_printf_format.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_mutating_container_transform.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_partial_type_is.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_redundant_local_alias.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_shallow_record_type_guard.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_slash_collection_root_under_prefix.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_unknown_pydantic_validator_field.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_work_verb_get_route.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_bulk_upsert.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_declarative_batch_validation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_direct_import_module.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_discriminated_model_union.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_grouped_settings.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_precise_object_contract.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_psycopg_executemany.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_pydantic_model_assertion.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_pytest_dependency_fixtures.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_typed_settings_field.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/pytest_fixture_returns_closed_resource.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_exp_on_jwt_decode.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_pydantic_for_mapping_shape.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/store_field_update_reuses_upsert.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/test_without_explicit_oracle.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
- {sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/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.77.
|
|
3
|
+
Version: 1.77.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/
|
|
@@ -54,12 +54,14 @@ def apply_fixes(source: str, fixes: Sequence[Fix]) -> str:
|
|
|
54
54
|
edits.sort()
|
|
55
55
|
result: list[bytes] = []
|
|
56
56
|
previous = 0
|
|
57
|
+
previous_start: int | None = None
|
|
57
58
|
for start, end, replacement in edits:
|
|
58
|
-
if start < previous:
|
|
59
|
+
if start < previous or start == previous_start:
|
|
59
60
|
msg = "fix groups overlap"
|
|
60
61
|
raise ValueError(msg)
|
|
61
62
|
result.extend((raw[previous:start], replacement))
|
|
62
63
|
previous = end
|
|
64
|
+
previous_start = start
|
|
63
65
|
result.append(raw[previous:])
|
|
64
66
|
fixed = b"".join(result).decode("utf-8")
|
|
65
67
|
tree = ast.parse(fixed)
|
|
@@ -11,6 +11,7 @@ from sarj_python_lint.rules._imports import ImportIndex
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Sequence
|
|
14
15
|
from pathlib import Path
|
|
15
16
|
|
|
16
17
|
|
|
@@ -81,6 +82,12 @@ class _ReceiverKey(NamedTuple):
|
|
|
81
82
|
name: str
|
|
82
83
|
|
|
83
84
|
|
|
85
|
+
class _ScopeFrame(NamedTuple):
|
|
86
|
+
node: ast.AST
|
|
87
|
+
scope: int
|
|
88
|
+
class_owner: int | None
|
|
89
|
+
|
|
90
|
+
|
|
84
91
|
class _DecoratorBinding(NamedTuple):
|
|
85
92
|
receiver: str
|
|
86
93
|
method: str
|
|
@@ -109,6 +116,24 @@ def _binding_name(node: ast.expr) -> str:
|
|
|
109
116
|
return ""
|
|
110
117
|
|
|
111
118
|
|
|
119
|
+
def _binding_targets(node: ast.AST) -> Sequence[ast.expr]:
|
|
120
|
+
match node:
|
|
121
|
+
case ast.Assign(targets=targets) | ast.Delete(targets=targets):
|
|
122
|
+
return targets
|
|
123
|
+
case (
|
|
124
|
+
ast.AnnAssign(target=target)
|
|
125
|
+
| ast.AugAssign(target=target)
|
|
126
|
+
| ast.For(target=target)
|
|
127
|
+
| ast.AsyncFor(target=target)
|
|
128
|
+
| ast.NamedExpr(target=target)
|
|
129
|
+
):
|
|
130
|
+
return (target,)
|
|
131
|
+
case ast.With(items=items) | ast.AsyncWith(items=items):
|
|
132
|
+
return tuple(item.optional_vars for item in items if item.optional_vars is not None)
|
|
133
|
+
case _:
|
|
134
|
+
return ()
|
|
135
|
+
|
|
136
|
+
|
|
112
137
|
class FastapiIndex:
|
|
113
138
|
def __init__(self, tree: ast.Module, *, path: Path | None = None) -> None:
|
|
114
139
|
self.tree: ast.Module = tree
|
|
@@ -136,26 +161,81 @@ class FastapiIndex:
|
|
|
136
161
|
self._route_scopes: dict[int, int] = {}
|
|
137
162
|
self._scope_parents: dict[int, int | None] = {0: None}
|
|
138
163
|
self._class_scopes: set[int] = set()
|
|
164
|
+
self._comprehension_scopes: set[int] = set()
|
|
139
165
|
self._index_scopes(tree)
|
|
140
166
|
self._read_imports(tree)
|
|
141
167
|
self._read_aliases(tree)
|
|
142
168
|
|
|
143
169
|
def _index_scopes(self, tree: ast.Module) -> None:
|
|
144
|
-
pending
|
|
170
|
+
pending = [_ScopeFrame(tree, 0, None)]
|
|
145
171
|
while pending:
|
|
146
172
|
node, scope, class_owner = pending.pop()
|
|
147
173
|
self._node_scopes[id(node)] = scope
|
|
148
|
-
if isinstance(node, ast.ClassDef):
|
|
149
|
-
class_owner = node.lineno
|
|
150
|
-
self._class_scopes.add(node.lineno)
|
|
151
|
-
self._scope_parents[node.lineno] = scope
|
|
152
|
-
scope = node.lineno
|
|
153
174
|
self._node_classes[id(node)] = class_owner
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
175
|
+
match node:
|
|
176
|
+
case ast.ClassDef() | ast.FunctionDef() | ast.AsyncFunctionDef():
|
|
177
|
+
self._index_definition(node, scope, class_owner, pending)
|
|
178
|
+
case ast.Lambda():
|
|
179
|
+
self._index_lambda(node, scope, class_owner, pending)
|
|
180
|
+
case ast.ListComp() | ast.SetComp() | ast.DictComp() | ast.GeneratorExp():
|
|
181
|
+
self._index_comprehension(node, scope, class_owner, pending)
|
|
182
|
+
case _:
|
|
183
|
+
pending.extend(
|
|
184
|
+
_ScopeFrame(child, scope, class_owner) for child in reversed(tuple(ast.iter_child_nodes(node)))
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
def _index_definition(
|
|
188
|
+
self,
|
|
189
|
+
node: ast.ClassDef | ast.FunctionDef | ast.AsyncFunctionDef,
|
|
190
|
+
scope: int,
|
|
191
|
+
class_owner: int | None,
|
|
192
|
+
pending: list[_ScopeFrame],
|
|
193
|
+
) -> None:
|
|
194
|
+
body = set(node.body)
|
|
195
|
+
owner = class_owner
|
|
196
|
+
self._scope_parents[node.lineno] = scope
|
|
197
|
+
if isinstance(node, ast.ClassDef):
|
|
198
|
+
owner = node.lineno
|
|
199
|
+
self._class_scopes.add(node.lineno)
|
|
200
|
+
self._node_classes[id(node)] = owner
|
|
201
|
+
else:
|
|
202
|
+
self._route_scopes[id(node)] = scope
|
|
203
|
+
pending.extend(
|
|
204
|
+
_ScopeFrame(child, node.lineno, owner) if child in body else _ScopeFrame(child, scope, class_owner)
|
|
205
|
+
for child in reversed(tuple(ast.iter_child_nodes(node)))
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
def _index_lambda(self, node: ast.Lambda, scope: int, class_owner: int | None, pending: list[_ScopeFrame]) -> None:
|
|
209
|
+
implicit_scope = -id(node)
|
|
210
|
+
self._scope_parents[implicit_scope] = scope
|
|
211
|
+
self._bind_arguments(node.args, implicit_scope)
|
|
212
|
+
pending.extend(
|
|
213
|
+
(_ScopeFrame(node.args, scope, class_owner), _ScopeFrame(node.body, implicit_scope, class_owner))
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
def _index_comprehension(
|
|
217
|
+
self,
|
|
218
|
+
node: ast.ListComp | ast.SetComp | ast.DictComp | ast.GeneratorExp,
|
|
219
|
+
outer_scope: int,
|
|
220
|
+
class_owner: int | None,
|
|
221
|
+
pending: list[_ScopeFrame],
|
|
222
|
+
) -> None:
|
|
223
|
+
scope = -id(node)
|
|
224
|
+
self._scope_parents[scope] = outer_scope
|
|
225
|
+
self._comprehension_scopes.add(scope)
|
|
226
|
+
for index, generator in enumerate(node.generators):
|
|
227
|
+
self._node_scopes[id(generator)] = scope
|
|
228
|
+
self._node_classes[id(generator)] = class_owner
|
|
229
|
+
self.bound_names.update(_ReceiverKey(scope, name) for name in self._target_names(generator.target))
|
|
230
|
+
pending.extend(
|
|
231
|
+
_ScopeFrame(child, outer_scope if index == 0 and child is generator.iter else scope, class_owner)
|
|
232
|
+
for child in ast.iter_child_nodes(generator)
|
|
233
|
+
)
|
|
234
|
+
pending.extend(
|
|
235
|
+
_ScopeFrame(child, scope, class_owner)
|
|
236
|
+
for child in ast.iter_child_nodes(node)
|
|
237
|
+
if not isinstance(child, ast.comprehension)
|
|
238
|
+
)
|
|
159
239
|
|
|
160
240
|
def _read_imports(self, tree: ast.Module) -> None:
|
|
161
241
|
for node in walk_ast(tree):
|
|
@@ -222,7 +302,17 @@ class FastapiIndex:
|
|
|
222
302
|
changed = True
|
|
223
303
|
|
|
224
304
|
def _read_bound_names(self, node: ast.AST) -> None:
|
|
225
|
-
if
|
|
305
|
+
if targets := _binding_targets(node):
|
|
306
|
+
self.bound_names.update(
|
|
307
|
+
_ReceiverKey(self._binding_scope(node), name)
|
|
308
|
+
for target in targets
|
|
309
|
+
for name in self._target_names(target)
|
|
310
|
+
)
|
|
311
|
+
elif isinstance(node, (ast.MatchAs, ast.MatchStar)) and node.name is not None:
|
|
312
|
+
self.bound_names.add(_ReceiverKey(self._node_scopes[id(node)], node.name))
|
|
313
|
+
elif isinstance(node, ast.MatchMapping) and node.rest is not None:
|
|
314
|
+
self.bound_names.add(_ReceiverKey(self._node_scopes[id(node)], node.rest))
|
|
315
|
+
elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
226
316
|
self._bind_function_names(node)
|
|
227
317
|
elif isinstance(node, ast.ClassDef):
|
|
228
318
|
self.bound_names.add(_ReceiverKey(self._node_scopes[id(node)], node.name))
|
|
@@ -231,34 +321,30 @@ class FastapiIndex:
|
|
|
231
321
|
_ReceiverKey(self._node_scopes[id(node)], alias.asname or alias.name.split(".")[0])
|
|
232
322
|
for alias in node.names
|
|
233
323
|
)
|
|
234
|
-
elif isinstance(node, (ast.For, ast.AsyncFor)):
|
|
235
|
-
self.bound_names.update(
|
|
236
|
-
_ReceiverKey(self._node_scopes[id(node)], name) for name in self._target_names(node.target)
|
|
237
|
-
)
|
|
238
|
-
elif isinstance(node, ast.With):
|
|
239
|
-
self._bind_with_targets(node)
|
|
240
324
|
elif isinstance(node, ast.ExceptHandler) and node.name is not None:
|
|
241
325
|
self.bound_names.add(_ReceiverKey(self._node_scopes[id(node)], node.name))
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
326
|
+
|
|
327
|
+
def _binding_scope(self, node: ast.AST) -> int:
|
|
328
|
+
scope = self._node_scopes[id(node)]
|
|
329
|
+
if isinstance(node, ast.NamedExpr):
|
|
330
|
+
while scope in self._comprehension_scopes:
|
|
331
|
+
parent = self._scope_parents[scope]
|
|
332
|
+
if parent is None:
|
|
333
|
+
break
|
|
334
|
+
scope = parent
|
|
335
|
+
return scope
|
|
246
336
|
|
|
247
337
|
def _bind_function_names(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None:
|
|
248
338
|
self.bound_names.add(_ReceiverKey(self._node_scopes[id(node)], node.name))
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
for
|
|
258
|
-
if item.optional_vars is not None:
|
|
259
|
-
self.bound_names.update(
|
|
260
|
-
_ReceiverKey(self._node_scopes[id(node)], name) for name in self._target_names(item.optional_vars)
|
|
261
|
-
)
|
|
339
|
+
self._bind_arguments(node.args, node.lineno)
|
|
340
|
+
|
|
341
|
+
def _bind_arguments(self, arguments: ast.arguments, scope: int) -> None:
|
|
342
|
+
names = [*arguments.posonlyargs, *arguments.args, *arguments.kwonlyargs]
|
|
343
|
+
if arguments.vararg is not None:
|
|
344
|
+
names.append(arguments.vararg)
|
|
345
|
+
if arguments.kwarg is not None:
|
|
346
|
+
names.append(arguments.kwarg)
|
|
347
|
+
self.bound_names.update(_ReceiverKey(scope, argument.arg) for argument in names)
|
|
262
348
|
|
|
263
349
|
def _alias_assignment(self, node: ast.AST) -> tuple[int, str, ast.expr] | None:
|
|
264
350
|
if isinstance(node, ast.Assign) and len(node.targets) == 1:
|
|
@@ -309,11 +395,15 @@ class FastapiIndex:
|
|
|
309
395
|
self.hidden_receivers.add(key)
|
|
310
396
|
|
|
311
397
|
def _target_names(self, node: ast.expr) -> tuple[str, ...]:
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
398
|
+
match node:
|
|
399
|
+
case ast.Name(id=name):
|
|
400
|
+
return (name,)
|
|
401
|
+
case ast.Starred(value=value):
|
|
402
|
+
return self._target_names(value)
|
|
403
|
+
case ast.Tuple(elts=items) | ast.List(elts=items):
|
|
404
|
+
return tuple(name for item in items for name in self._target_names(item))
|
|
405
|
+
case _:
|
|
406
|
+
return ()
|
|
317
407
|
|
|
318
408
|
def _assignment_scope(self, node: ast.Assign | ast.AnnAssign, name: str) -> int:
|
|
319
409
|
if name.startswith("self."):
|
|
@@ -526,11 +616,13 @@ class FastapiIndex:
|
|
|
526
616
|
if isinstance(node, ast.Attribute):
|
|
527
617
|
root = self._root_name(node)
|
|
528
618
|
node_scope = self._node_scopes.get(id(node), 0)
|
|
529
|
-
#
|
|
530
|
-
#
|
|
531
|
-
scope: int | None =
|
|
619
|
+
# The index records where the annotation is evaluated. A method body
|
|
620
|
+
# does not close over an intervening class namespace.
|
|
621
|
+
scope: int | None = node_scope
|
|
532
622
|
while scope is not None and scope != 0:
|
|
533
|
-
if
|
|
623
|
+
if (scope == node_scope or scope not in self._class_scopes) and _ReceiverKey(
|
|
624
|
+
scope, root
|
|
625
|
+
) in self.bound_names:
|
|
534
626
|
return True
|
|
535
627
|
scope = self._scope_parents.get(scope)
|
|
536
628
|
return False
|
|
@@ -927,11 +927,12 @@ def _check_operation_ids(routes: list[tuple[int, Route]], parents: Mapping[ast.A
|
|
|
927
927
|
seen: dict[tuple[int, str, str], Route] = {}
|
|
928
928
|
reported: set[int] = set()
|
|
929
929
|
for scope, route in sorted(routes, key=lambda item: item[1].decorator.lineno):
|
|
930
|
+
schema_override = route.has_unpack or "openapi_extra" in route.keywords
|
|
930
931
|
if (
|
|
931
932
|
route.is_hidden
|
|
932
933
|
or route.path is None
|
|
933
934
|
or route.method == "*"
|
|
934
|
-
or
|
|
935
|
+
or schema_override
|
|
935
936
|
or _conditional_registration(route.decorator, parents)
|
|
936
937
|
):
|
|
937
938
|
continue
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_analysis_session.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_aliases.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_annotations.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_comments.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_declared_tests.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_exhaustiveness.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_parameters.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_repeated.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_security.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/_autofix_sql_projection.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
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/interpreter_argv.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
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_ast_names.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_closed_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_copy_on_write.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_dict_key_views.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_fixed_record.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_local_alias_fix.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_local_source.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_namespace_access.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_nominal_project.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_prose_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_route_shapes.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_runtime_bindings.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_set_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_static_json_alias.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_store_writes.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_test_composition.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/_test_provenance.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.77.0 → sarj_python_lint-1.77.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.77.0 → sarj_python_lint-1.77.2}/src/sarj_python_lint/rules/no_dunder_all.py
RENAMED
|
File without changes
|
|
File without changes
|