sarj-python-lint 1.72.1__tar.gz → 1.74.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.
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/PKG-INFO +1 -1
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/pyproject.toml +1 -1
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_local_alias_fix.py +4 -9
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_resource_provenance.py +3 -3
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_redundant_local_alias.py +105 -22
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/.gitignore +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/LICENSE +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/README.md +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/__main__.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_file_context.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_fixes.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_parallel.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_source.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/benchmark.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/cast_access.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/interpreter_argv.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_annotation_origins.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_ast_index.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_ast_names.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_data_union_discriminator.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_declared_contracts.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_docstrings.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_exports.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_fastapi.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_inert_model_annotation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_inherited_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_local_source.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_mapping_shape_callbacks.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_namespace_access.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_native_namespace_capability.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_project_index.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_pydantic_field_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_registry.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_resolved_operation_signature.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_route_shapes.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_runtime_bindings.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_set_fields.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_sql.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_static_json_alias.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_store_writes.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_test_composition.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_type_guard_symbols.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/delete_route_returns_no_content.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/duplicate_pytest_fixture_params.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_async_function_cache.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_blanket_suppression.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_conflicting_pydantic_alias_validation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_contradictory_type_guard.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_create_verb_in_post_path.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_defaulted_environment_setting.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_discarded_validation_result.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_dual_shape_model_field_reader.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_duplicate_field_validator_body.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_exception_text_in_500_detail.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_folded_bad_request_not_found.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_hasattr.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_impossible_pydantic_field_bounds.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_invalid_pydantic_bypass.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_invalid_pydantic_validator_return.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_loguru_exc_info.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_loguru_printf_format.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_mutating_container_transform.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_partial_type_is.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_shallow_record_type_guard.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_slash_collection_root_under_prefix.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_unknown_pydantic_validator_field.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_work_verb_get_route.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_bulk_upsert.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_declarative_batch_validation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_direct_import_module.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_discriminated_model_union.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_precise_object_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_psycopg_executemany.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_pydantic_model_assertion.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_pytest_dependency_fixtures.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_typed_settings_field.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/pytest_fixture_returns_closed_resource.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_exp_on_jwt_decode.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_pydantic_for_mapping_shape.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/store_field_update_reuses_upsert.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/test_without_explicit_oracle.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
- {sarj_python_lint-1.72.1 → sarj_python_lint-1.74.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.
|
|
3
|
+
Version: 1.74.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/
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_local_alias_fix.py
RENAMED
|
@@ -16,6 +16,7 @@ if TYPE_CHECKING:
|
|
|
16
16
|
from sarj_python_lint._file_context import PythonFileContext
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
_ALIAS_RETURN_LENGTH = 2
|
|
19
20
|
_NAMESPACE_MUTATORS = frozenset(
|
|
20
21
|
{
|
|
21
22
|
"setattr",
|
|
@@ -86,9 +87,9 @@ class LocalAliasFixes:
|
|
|
86
87
|
if not isinstance(source, ast.Name) or parameters[0].arg != source.id:
|
|
87
88
|
return ()
|
|
88
89
|
body = owner.body[1:] if ast.get_docstring(owner) is not None else owner.body
|
|
89
|
-
if body
|
|
90
|
+
if len(body) != _ALIAS_RETURN_LENGTH or body[0] is not assignment or not isinstance(body[1], ast.Return):
|
|
90
91
|
return ()
|
|
91
|
-
call = body[
|
|
92
|
+
call = body[1].value
|
|
92
93
|
if not isinstance(call, ast.Call) or not isinstance(call.func, ast.Name) or call.func.id != "dict":
|
|
93
94
|
return ()
|
|
94
95
|
if call.args or len(call.keywords) != 1 or call.keywords[0].value is not use or not self._available:
|
|
@@ -110,14 +111,8 @@ class LocalAliasFixes:
|
|
|
110
111
|
return ()
|
|
111
112
|
if assignment.end_lineno != assignment.lineno:
|
|
112
113
|
return ()
|
|
113
|
-
line = self.context.source_lines[assignment.lineno - 1]
|
|
114
114
|
raw = self._lines[assignment.lineno - 1]
|
|
115
|
-
if (
|
|
116
|
-
raw[: assignment.col_offset].strip()
|
|
117
|
-
or raw[assignment.end_col_offset :].strip()
|
|
118
|
-
or ";" in line
|
|
119
|
-
or "\\" in line
|
|
120
|
-
):
|
|
115
|
+
if raw[: assignment.col_offset].strip() or raw[assignment.end_col_offset :].strip():
|
|
121
116
|
return ()
|
|
122
117
|
return (
|
|
123
118
|
TextEdit(assignment.lineno, 1, assignment.lineno + 1, 1, ""),
|
|
@@ -428,7 +428,7 @@ class ResourceProvenance:
|
|
|
428
428
|
name = binding.id if isinstance(binding, ast.Name) else binding.name
|
|
429
429
|
if name in self.mutated or name in self.external_bindings:
|
|
430
430
|
return False
|
|
431
|
-
for read in self.
|
|
431
|
+
for read in self.binding_reads(name, binding):
|
|
432
432
|
alias = self._function_alias(read)
|
|
433
433
|
if alias is not None:
|
|
434
434
|
pending.append(alias)
|
|
@@ -469,7 +469,7 @@ class ResourceProvenance:
|
|
|
469
469
|
and any(self.imported(constructor.func, f"contextlib.{kind}") for kind in ("ExitStack", "AsyncExitStack"))
|
|
470
470
|
)
|
|
471
471
|
|
|
472
|
-
def
|
|
472
|
+
def binding_reads(self, name: str, binding: ast.AST) -> list[ast.Name]:
|
|
473
473
|
return self._indexed_reads(name, binding, cache=self._reads_by_binding, resolve=self.binding)
|
|
474
474
|
|
|
475
475
|
def _indexed_reads(
|
|
@@ -496,7 +496,7 @@ class ResourceProvenance:
|
|
|
496
496
|
if key not in self.escape_cache:
|
|
497
497
|
self.escape_cache[key] = all(
|
|
498
498
|
self._method_or_context_read(read, allow_context=allow_context)
|
|
499
|
-
for read in self.
|
|
499
|
+
for read in self.binding_reads(name.id, binding)
|
|
500
500
|
)
|
|
501
501
|
return self.escape_cache[key]
|
|
502
502
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ast
|
|
4
|
-
from collections import defaultdict
|
|
5
4
|
from pathlib import PurePosixPath
|
|
6
5
|
import re
|
|
7
6
|
from typing import TYPE_CHECKING, ClassVar, final, override
|
|
@@ -24,7 +23,7 @@ from sarj_python_lint.rules._suppression_comments import comment_lines
|
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
if TYPE_CHECKING:
|
|
27
|
-
from collections.abc import Mapping
|
|
26
|
+
from collections.abc import Iterator, Mapping
|
|
28
27
|
|
|
29
28
|
from sarj_python_lint._file_context import PythonFileContext
|
|
30
29
|
from sarj_python_lint.rules._resource_provenance import ResourceProvenance
|
|
@@ -32,7 +31,7 @@ if TYPE_CHECKING:
|
|
|
32
31
|
|
|
33
32
|
_FUNCTIONS = (ast.FunctionDef, ast.AsyncFunctionDef)
|
|
34
33
|
_SUITES = (*_FUNCTIONS, ast.With, ast.AsyncWith)
|
|
35
|
-
|
|
34
|
+
_NESTED_SCOPES = (
|
|
36
35
|
*_FUNCTIONS,
|
|
37
36
|
ast.ClassDef,
|
|
38
37
|
ast.Lambda,
|
|
@@ -40,6 +39,9 @@ _UNCERTAIN = (
|
|
|
40
39
|
ast.SetComp,
|
|
41
40
|
ast.DictComp,
|
|
42
41
|
ast.GeneratorExp,
|
|
42
|
+
)
|
|
43
|
+
_UNCERTAIN = (
|
|
44
|
+
*_NESTED_SCOPES,
|
|
43
45
|
ast.If,
|
|
44
46
|
ast.For,
|
|
45
47
|
ast.AsyncFor,
|
|
@@ -89,7 +91,8 @@ class NoRedundantLocalAlias(Rule):
|
|
|
89
91
|
limitations=(
|
|
90
92
|
"Only unannotated, single-target `alias = original` assignments with one binding and one read at `alias=alias` are checked.",
|
|
91
93
|
"The original must be a parameter or an earlier initialized local with one binding; reassignment, deletion, imports, alias chains and uncertain initialization are excluded.",
|
|
92
|
-
"
|
|
94
|
+
"Completed function-body if prefixes and their Boolean tests are supported only before a fresh, uniquely initialized local and alias in that same body. Parameters, earlier source bindings and aliases nested in with bodies after such prefixes are excluded.",
|
|
95
|
+
"Loops, try statements, asserts, other Boolean short-circuiting, nested scopes, global/nonlocal declarations and type aliases are excluded. Ordinary and async with bodies require ordered enclosing-suite binding evidence.",
|
|
93
96
|
"A conditional expression is admitted only when its test is a bare name bound once as a parameter, and neither local is read within the expression.",
|
|
94
97
|
"Typed aliases, files with type comments, same-scope quoted references and conditional reads of either local are excluded. Captured bindings and module/class aliases are preserved.",
|
|
95
98
|
"Files with wildcard imports, Pydantic imports or references to known namespace readers, dynamic attribute getters or reference-count observers are excluded. Wildcard exports cannot establish builtin identity; computed type names can consume caller-local bindings without a Name read in the AST.",
|
|
@@ -145,6 +148,36 @@ class NoRedundantLocalAlias(Rule):
|
|
|
145
148
|
expected_count=0,
|
|
146
149
|
public=True,
|
|
147
150
|
),
|
|
151
|
+
RuleExample(
|
|
152
|
+
example_id="completed-guard-prefix",
|
|
153
|
+
scenario="completed-guard",
|
|
154
|
+
title="Initialize the original after the completed guard",
|
|
155
|
+
outcome=ExampleOutcome.MATCH,
|
|
156
|
+
files=(
|
|
157
|
+
ExampleFile.python(
|
|
158
|
+
"case.py",
|
|
159
|
+
"def render(enabled):\n if not enabled:\n return None\n item = make_item()\n payload = item\n return build(payload=payload)\n",
|
|
160
|
+
),
|
|
161
|
+
),
|
|
162
|
+
focus_path=PurePosixPath("case.py"),
|
|
163
|
+
expected_count=1,
|
|
164
|
+
public=True,
|
|
165
|
+
),
|
|
166
|
+
RuleExample(
|
|
167
|
+
example_id="direct-after-guard",
|
|
168
|
+
scenario="completed-guard",
|
|
169
|
+
title="Pass the fresh original directly",
|
|
170
|
+
outcome=ExampleOutcome.NO_MATCH,
|
|
171
|
+
files=(
|
|
172
|
+
ExampleFile.python(
|
|
173
|
+
"case.py",
|
|
174
|
+
"def render(enabled):\n if not enabled:\n return None\n item = make_item()\n return build(payload=item)\n",
|
|
175
|
+
),
|
|
176
|
+
),
|
|
177
|
+
focus_path=PurePosixPath("case.py"),
|
|
178
|
+
expected_count=0,
|
|
179
|
+
public=True,
|
|
180
|
+
),
|
|
148
181
|
),
|
|
149
182
|
)
|
|
150
183
|
description = documentation.summary
|
|
@@ -159,7 +192,6 @@ class NoRedundantLocalAlias(Rule):
|
|
|
159
192
|
return []
|
|
160
193
|
provenance = context.resource_provenance
|
|
161
194
|
names = {node.targets[0].id for node in candidates if isinstance(node.targets[0], ast.Name)}
|
|
162
|
-
reads = _scope_reads(provenance, names)
|
|
163
195
|
conditional_sources = _conditional_sources(context)
|
|
164
196
|
quoted = _quoted_references(context, provenance, names)
|
|
165
197
|
positions = {statement: i for owner in context.nodes(*_SUITES) for i, statement in enumerate(owner.body)}
|
|
@@ -172,7 +204,7 @@ class NoRedundantLocalAlias(Rule):
|
|
|
172
204
|
continue
|
|
173
205
|
if (provenance.scope(assignment), target.id) in quoted:
|
|
174
206
|
continue
|
|
175
|
-
use = _single_keyword_read(target, provenance,
|
|
207
|
+
use = _single_keyword_read(target, provenance, keywords)
|
|
176
208
|
if use is None:
|
|
177
209
|
continue
|
|
178
210
|
if not _dominates(assignment, use, context.parents, positions):
|
|
@@ -237,12 +269,13 @@ def _local_assignments(context: PythonFileContext, names: set[str]) -> list[ast.
|
|
|
237
269
|
if not candidates or context.has_wildcard_import:
|
|
238
270
|
return []
|
|
239
271
|
provenance = context.resource_provenance
|
|
240
|
-
|
|
241
|
-
blocked.update(
|
|
242
|
-
provenance.scope(node) for node in context.nodes(ast.IfExp) if not _parameter_choice(node, provenance)
|
|
243
|
-
)
|
|
272
|
+
boundaries = _scope_boundaries(context, provenance)
|
|
244
273
|
eligible = [
|
|
245
|
-
node
|
|
274
|
+
node
|
|
275
|
+
for node in candidates
|
|
276
|
+
if isinstance(scope := provenance.scope(node), _FUNCTIONS)
|
|
277
|
+
and (boundary := boundaries.get(scope, 0)) is not None
|
|
278
|
+
and _after_prefix(node, boundary, provenance)
|
|
246
279
|
]
|
|
247
280
|
if not eligible or context.dynamic_namespace or _observes_references(context):
|
|
248
281
|
return []
|
|
@@ -251,6 +284,63 @@ def _local_assignments(context: PythonFileContext, names: set[str]) -> list[ast.
|
|
|
251
284
|
return eligible
|
|
252
285
|
|
|
253
286
|
|
|
287
|
+
def _scope_boundaries(context: PythonFileContext, provenance: ResourceProvenance) -> dict[ast.AST | None, int | None]:
|
|
288
|
+
prefixes = _prefix_bounds(context)
|
|
289
|
+
boundaries: dict[ast.AST | None, int | None] = {}
|
|
290
|
+
for node in context.nodes(*_UNCERTAIN):
|
|
291
|
+
scope = provenance.scope(node)
|
|
292
|
+
prefix = prefixes.get(node)
|
|
293
|
+
if prefix is None or context.parents.get(prefix) is not scope:
|
|
294
|
+
boundaries[scope] = None
|
|
295
|
+
elif (boundary := boundaries.get(scope, 0)) is not None:
|
|
296
|
+
boundaries[scope] = max(boundary, prefix.end_lineno or prefix.lineno)
|
|
297
|
+
for node in context.nodes(ast.IfExp):
|
|
298
|
+
if not _parameter_choice(node, provenance):
|
|
299
|
+
boundaries[provenance.scope(node)] = None
|
|
300
|
+
return boundaries
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def _prefix_bounds(context: PythonFileContext) -> dict[ast.AST, ast.If]:
|
|
304
|
+
bounds: dict[ast.AST, ast.If] = {}
|
|
305
|
+
for function in context.nodes(*_FUNCTIONS):
|
|
306
|
+
for root in function.body:
|
|
307
|
+
if isinstance(root, ast.If):
|
|
308
|
+
for node in _prefix_conditions(root):
|
|
309
|
+
bounds[node] = root
|
|
310
|
+
return bounds
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def _prefix_conditions(root: ast.If) -> Iterator[ast.AST]:
|
|
314
|
+
pending: list[tuple[ast.AST, bool]] = [(root, False)]
|
|
315
|
+
while pending:
|
|
316
|
+
node, inside_test = pending.pop()
|
|
317
|
+
if isinstance(node, _NESTED_SCOPES):
|
|
318
|
+
continue
|
|
319
|
+
if isinstance(node, ast.If) or (isinstance(node, ast.BoolOp) and inside_test):
|
|
320
|
+
yield node
|
|
321
|
+
pending.extend(
|
|
322
|
+
(child, inside_test or (isinstance(node, ast.If) and child is node.test)) for child in children(node)
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def _after_prefix(assignment: ast.Assign, boundary: int, provenance: ResourceProvenance) -> bool:
|
|
327
|
+
if not boundary:
|
|
328
|
+
return True
|
|
329
|
+
if not isinstance(assignment.value, ast.Name):
|
|
330
|
+
return False
|
|
331
|
+
scope = provenance.scope(assignment)
|
|
332
|
+
bindings = provenance.bindings.get(scope, {}).get(assignment.value.id, ())
|
|
333
|
+
if len(bindings) != 1 or not isinstance(bindings[0], ast.Name):
|
|
334
|
+
return False
|
|
335
|
+
initializer = provenance.parents.get(bindings[0])
|
|
336
|
+
return (
|
|
337
|
+
isinstance(initializer, ast.Assign | ast.AnnAssign)
|
|
338
|
+
and provenance.parents.get(initializer) is scope
|
|
339
|
+
and provenance.parents.get(assignment) is scope
|
|
340
|
+
and initializer.lineno > boundary
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
|
|
254
344
|
def _compiles(context: PythonFileContext) -> bool:
|
|
255
345
|
if context.tree is None:
|
|
256
346
|
return False
|
|
@@ -272,14 +362,6 @@ def _parameter_choice(node: ast.IfExp, provenance: ResourceProvenance) -> bool:
|
|
|
272
362
|
return len(bindings) == 1 and isinstance(bindings[0], ast.arg)
|
|
273
363
|
|
|
274
364
|
|
|
275
|
-
def _scope_reads(provenance: ResourceProvenance, names: set[str]) -> dict[tuple[ast.AST | None, str], list[ast.Name]]:
|
|
276
|
-
reads: dict[tuple[ast.AST | None, str], list[ast.Name]] = defaultdict(list)
|
|
277
|
-
for name in names:
|
|
278
|
-
for read in provenance.reads.get(name, ()):
|
|
279
|
-
reads[provenance.scope(read), name].append(read)
|
|
280
|
-
return reads
|
|
281
|
-
|
|
282
|
-
|
|
283
365
|
def _conditional_sources(context: PythonFileContext) -> set[tuple[ast.AST | None, str]]:
|
|
284
366
|
provenance = context.resource_provenance
|
|
285
367
|
pending: list[ast.AST] = list(context.nodes(ast.IfExp))
|
|
@@ -299,12 +381,13 @@ def _conditional_sources(context: PythonFileContext) -> set[tuple[ast.AST | None
|
|
|
299
381
|
def _single_keyword_read(
|
|
300
382
|
target: ast.Name,
|
|
301
383
|
provenance: ResourceProvenance,
|
|
302
|
-
reads: Mapping[tuple[ast.AST | None, str], list[ast.Name]],
|
|
303
384
|
keywords: Mapping[ast.Name, str],
|
|
304
385
|
) -> ast.Name | None:
|
|
305
386
|
scope = provenance.scope(target)
|
|
306
|
-
|
|
307
|
-
|
|
387
|
+
if provenance.bindings.get(scope, {}).get(target.id) != [target]:
|
|
388
|
+
return None
|
|
389
|
+
uses = provenance.binding_reads(target.id, target)
|
|
390
|
+
if len(uses) != 1:
|
|
308
391
|
return None
|
|
309
392
|
[use] = uses
|
|
310
393
|
if keywords.get(use) != target.id or _statement(use, provenance.parents) is None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/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
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/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.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_ast_names.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_closed_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_copy_on_write.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_dict_key_views.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/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.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_local_source.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_namespace_access.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_nominal_project.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_prose_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_route_shapes.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_runtime_bindings.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_set_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_static_json_alias.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_store_writes.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/_test_composition.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/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
|
|
File without changes
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/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.72.1 → sarj_python_lint-1.74.1}/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.72.1 → sarj_python_lint-1.74.1}/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
|
{sarj_python_lint-1.72.1 → sarj_python_lint-1.74.1}/src/sarj_python_lint/rules/no_hasattr.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|