sarj-python-lint 1.28.3__tar.gz → 1.28.4__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.28.3 → sarj_python_lint-1.28.4}/PKG-INFO +1 -1
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/pyproject.toml +1 -1
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_file_context.py +6 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_docstrings.py +90 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/redundant_class_docstring.py +1 -89
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/redundant_docstring.py +3 -90
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/.gitignore +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/LICENSE +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/README.md +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/__main__.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_source.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/benchmark.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/interpreter_argv.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_ast_index.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_fastapi.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_local_source.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_project_index.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_registry.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_set_fields.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_sql.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_test_composition.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sarj-python-lint
|
|
3
|
-
Version: 1.28.
|
|
3
|
+
Version: 1.28.4
|
|
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/
|
|
@@ -61,6 +61,12 @@ class PythonFileContext:
|
|
|
61
61
|
def has_wildcard_import(self) -> bool:
|
|
62
62
|
return any(alias.name == "*" for node in self.nodes(ast.ImportFrom) for alias in node.names)
|
|
63
63
|
|
|
64
|
+
@cached_property
|
|
65
|
+
def consumed_docstring_names(self) -> frozenset[str]:
|
|
66
|
+
from sarj_python_lint.rules._docstrings import consumed_docstring_names # ruff: ignore[import-outside-top-level] -- share runtime docstring analysis only when requested.
|
|
67
|
+
|
|
68
|
+
return consumed_docstring_names(self._valid_tree(), node_index=self.node_index)
|
|
69
|
+
|
|
64
70
|
@property
|
|
65
71
|
def parents(self) -> Mapping[ast.AST, ast.AST]:
|
|
66
72
|
return self.node_index.parents
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
@@ -5,12 +5,17 @@ from itertools import starmap
|
|
|
5
5
|
import re
|
|
6
6
|
from typing import TYPE_CHECKING, NamedTuple
|
|
7
7
|
|
|
8
|
+
from sarj_python_lint.rules._ast_index import walk as walk_ast
|
|
8
9
|
from sarj_python_lint.rules._comments import split_identifier, stem
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
if TYPE_CHECKING:
|
|
12
13
|
from collections.abc import Iterable
|
|
13
14
|
|
|
15
|
+
from sarj_python_lint.rules._ast_index import NodeIndex
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
_GETATTR_MIN_ARGS = 2
|
|
14
19
|
|
|
15
20
|
# Docstring filler that says nothing about *which* thing is being described.
|
|
16
21
|
_BASE_STOPWORDS = frozenset(
|
|
@@ -325,3 +330,88 @@ def restates(text: str, known: Iterable[str]) -> bool:
|
|
|
325
330
|
if not content:
|
|
326
331
|
return False
|
|
327
332
|
return all(stem(word) in known_stems for word in content)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def consumed_docstring_names(tree: ast.Module, *, node_index: NodeIndex | None = None) -> frozenset[str]:
|
|
336
|
+
consumed: set[str] = set()
|
|
337
|
+
aliases: dict[str, set[str]] = {}
|
|
338
|
+
for node in walk_ast(tree, index=node_index):
|
|
339
|
+
_record_docstring_use(node, consumed, aliases)
|
|
340
|
+
changed = True
|
|
341
|
+
while changed:
|
|
342
|
+
changed = False
|
|
343
|
+
for alias, originals in aliases.items():
|
|
344
|
+
if alias not in consumed:
|
|
345
|
+
continue
|
|
346
|
+
before = len(consumed)
|
|
347
|
+
consumed.update(originals)
|
|
348
|
+
changed |= len(consumed) != before
|
|
349
|
+
return frozenset(consumed)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def _terminal_name(node: ast.expr) -> str | None:
|
|
353
|
+
match node:
|
|
354
|
+
case ast.Name():
|
|
355
|
+
return node.id
|
|
356
|
+
case ast.Attribute():
|
|
357
|
+
return node.attr
|
|
358
|
+
case _:
|
|
359
|
+
return None
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _record_docstring_use(node: ast.AST, consumed: set[str], aliases: dict[str, set[str]]) -> None:
|
|
363
|
+
if isinstance(node, ast.Attribute) and node.attr == "__doc__":
|
|
364
|
+
if name := _terminal_name(node.value):
|
|
365
|
+
consumed.add(name)
|
|
366
|
+
elif isinstance(node, ast.Call) and _is_docstring_reader(node):
|
|
367
|
+
if name := _terminal_name(node.args[0]):
|
|
368
|
+
consumed.add(name)
|
|
369
|
+
elif isinstance(node, ast.Subscript):
|
|
370
|
+
if name := _subscripted_docstring_owner(node):
|
|
371
|
+
consumed.add(name)
|
|
372
|
+
else:
|
|
373
|
+
_record_docstring_alias(node, aliases)
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def _subscripted_docstring_owner(node: ast.Subscript) -> str | None:
|
|
377
|
+
if not isinstance(node.slice, ast.Constant) or node.slice.value != "__doc__":
|
|
378
|
+
return None
|
|
379
|
+
value = node.value
|
|
380
|
+
if isinstance(value, ast.Attribute) and value.attr == "__dict__":
|
|
381
|
+
return _terminal_name(value.value)
|
|
382
|
+
if isinstance(value, ast.Call) and isinstance(value.func, ast.Name) and value.func.id == "vars" and value.args:
|
|
383
|
+
return _terminal_name(value.args[0])
|
|
384
|
+
return None
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def _is_docstring_reader(node: ast.Call) -> bool:
|
|
388
|
+
if not node.args:
|
|
389
|
+
return False
|
|
390
|
+
function = node.func
|
|
391
|
+
if isinstance(function, ast.Name) and function.id == "help":
|
|
392
|
+
return True
|
|
393
|
+
if isinstance(function, ast.Attribute) and function.attr in {"getdoc", "render_doc"}:
|
|
394
|
+
return True
|
|
395
|
+
return (
|
|
396
|
+
isinstance(function, ast.Name)
|
|
397
|
+
and function.id == "getattr"
|
|
398
|
+
and len(node.args) >= _GETATTR_MIN_ARGS
|
|
399
|
+
and isinstance(node.args[1], ast.Constant)
|
|
400
|
+
and node.args[1].value == "__doc__"
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
def _record_docstring_alias(node: ast.AST, aliases: dict[str, set[str]]) -> None:
|
|
405
|
+
if isinstance(node, ast.Assign) and isinstance(node.value, (ast.Name, ast.Attribute)):
|
|
406
|
+
original = _terminal_name(node.value)
|
|
407
|
+
for target in node.targets:
|
|
408
|
+
if isinstance(target, ast.Name) and original is not None:
|
|
409
|
+
aliases.setdefault(target.id, set()).add(original)
|
|
410
|
+
elif (
|
|
411
|
+
isinstance(node, ast.AnnAssign)
|
|
412
|
+
and isinstance(node.target, ast.Name)
|
|
413
|
+
and isinstance(node.value, (ast.Name, ast.Attribute))
|
|
414
|
+
):
|
|
415
|
+
original = _terminal_name(node.value)
|
|
416
|
+
if original is not None:
|
|
417
|
+
aliases.setdefault(node.target.id, set()).add(original)
|
|
@@ -17,7 +17,6 @@ from sarj_python_lint.rule_base import (
|
|
|
17
17
|
Severity,
|
|
18
18
|
is_suppressed,
|
|
19
19
|
)
|
|
20
|
-
from sarj_python_lint.rules._ast_index import walk as walk_ast
|
|
21
20
|
from sarj_python_lint.rules._comments import is_protected, stem
|
|
22
21
|
from sarj_python_lint.rules._docstrings import (
|
|
23
22
|
VALUE_MARKER_RE,
|
|
@@ -27,11 +26,9 @@ from sarj_python_lint.rules._docstrings import (
|
|
|
27
26
|
|
|
28
27
|
if TYPE_CHECKING:
|
|
29
28
|
from sarj_python_lint._file_context import PythonFileContext
|
|
30
|
-
from sarj_python_lint.rules._ast_index import NodeIndex
|
|
31
29
|
|
|
32
30
|
|
|
33
31
|
_GRAMMATICAL_FILLER = frozenset({"a", "an", "class", "the"})
|
|
34
|
-
_GETATTR_MIN_ARGS = 2
|
|
35
32
|
_DOCSTRING_TOKEN_RE = re.compile(r"[^\W\d_]+(?:'[^\W\d_]+)?|\d+")
|
|
36
33
|
|
|
37
34
|
|
|
@@ -93,7 +90,7 @@ class RedundantClassDocstring(Rule):
|
|
|
93
90
|
if tree is None:
|
|
94
91
|
return []
|
|
95
92
|
source_lines = context.source_lines
|
|
96
|
-
consumed_docstrings =
|
|
93
|
+
consumed_docstrings = context.consumed_docstring_names
|
|
97
94
|
diags: list[Diagnostic] = []
|
|
98
95
|
for node in context.nodes(ast.ClassDef):
|
|
99
96
|
if node.name not in consumed_docstrings and self._is_ceremony(node):
|
|
@@ -128,88 +125,3 @@ class RedundantClassDocstring(Rule):
|
|
|
128
125
|
if (word := match.group(0).lower()) not in _GRAMMATICAL_FILLER
|
|
129
126
|
]
|
|
130
127
|
return bool(content) and all(stem(word) in known for word in content)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def _consumed_docstring_names(tree: ast.Module, *, node_index: NodeIndex | None = None) -> set[str]:
|
|
134
|
-
consumed: set[str] = set()
|
|
135
|
-
aliases: dict[str, set[str]] = {}
|
|
136
|
-
for node in walk_ast(tree, index=node_index):
|
|
137
|
-
_record_docstring_use(node, consumed, aliases)
|
|
138
|
-
changed = True
|
|
139
|
-
while changed:
|
|
140
|
-
changed = False
|
|
141
|
-
for alias, originals in aliases.items():
|
|
142
|
-
if alias not in consumed:
|
|
143
|
-
continue
|
|
144
|
-
before = len(consumed)
|
|
145
|
-
consumed.update(originals)
|
|
146
|
-
changed |= len(consumed) != before
|
|
147
|
-
return consumed
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def _terminal_name(node: ast.expr) -> str | None:
|
|
151
|
-
match node:
|
|
152
|
-
case ast.Name():
|
|
153
|
-
return node.id
|
|
154
|
-
case ast.Attribute():
|
|
155
|
-
return node.attr
|
|
156
|
-
case _:
|
|
157
|
-
return None
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def _record_docstring_use(node: ast.AST, consumed: set[str], aliases: dict[str, set[str]]) -> None:
|
|
161
|
-
if isinstance(node, ast.Attribute) and node.attr == "__doc__":
|
|
162
|
-
if name := _terminal_name(node.value):
|
|
163
|
-
consumed.add(name)
|
|
164
|
-
elif isinstance(node, ast.Call) and _is_docstring_reader(node):
|
|
165
|
-
if name := _terminal_name(node.args[0]):
|
|
166
|
-
consumed.add(name)
|
|
167
|
-
elif isinstance(node, ast.Subscript):
|
|
168
|
-
if name := _subscripted_docstring_owner(node):
|
|
169
|
-
consumed.add(name)
|
|
170
|
-
else:
|
|
171
|
-
_record_docstring_alias(node, aliases)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def _subscripted_docstring_owner(node: ast.Subscript) -> str | None:
|
|
175
|
-
if not isinstance(node.slice, ast.Constant) or node.slice.value != "__doc__":
|
|
176
|
-
return None
|
|
177
|
-
value = node.value
|
|
178
|
-
if isinstance(value, ast.Attribute) and value.attr == "__dict__":
|
|
179
|
-
return _terminal_name(value.value)
|
|
180
|
-
if isinstance(value, ast.Call) and isinstance(value.func, ast.Name) and value.func.id == "vars" and value.args:
|
|
181
|
-
return _terminal_name(value.args[0])
|
|
182
|
-
return None
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
def _is_docstring_reader(node: ast.Call) -> bool:
|
|
186
|
-
if not node.args:
|
|
187
|
-
return False
|
|
188
|
-
function = node.func
|
|
189
|
-
if isinstance(function, ast.Name) and function.id == "help":
|
|
190
|
-
return True
|
|
191
|
-
if isinstance(function, ast.Attribute) and function.attr in {"getdoc", "render_doc"}:
|
|
192
|
-
return True
|
|
193
|
-
return (
|
|
194
|
-
isinstance(function, ast.Name)
|
|
195
|
-
and function.id == "getattr"
|
|
196
|
-
and len(node.args) >= _GETATTR_MIN_ARGS
|
|
197
|
-
and isinstance(node.args[1], ast.Constant)
|
|
198
|
-
and node.args[1].value == "__doc__"
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def _record_docstring_alias(node: ast.AST, aliases: dict[str, set[str]]) -> None:
|
|
203
|
-
if isinstance(node, ast.Assign) and isinstance(node.value, (ast.Name, ast.Attribute)):
|
|
204
|
-
original = _terminal_name(node.value)
|
|
205
|
-
for target in node.targets:
|
|
206
|
-
if isinstance(target, ast.Name) and original is not None:
|
|
207
|
-
aliases.setdefault(target.id, set()).add(original)
|
|
208
|
-
elif (
|
|
209
|
-
isinstance(node, ast.AnnAssign)
|
|
210
|
-
and isinstance(node.target, ast.Name)
|
|
211
|
-
and isinstance(node.value, (ast.Name, ast.Attribute))
|
|
212
|
-
):
|
|
213
|
-
original = _terminal_name(node.value)
|
|
214
|
-
if original is not None:
|
|
215
|
-
aliases.setdefault(node.target.id, set()).add(original)
|
|
@@ -18,7 +18,7 @@ from sarj_python_lint.rule_base import (
|
|
|
18
18
|
Severity,
|
|
19
19
|
is_suppressed,
|
|
20
20
|
)
|
|
21
|
-
from sarj_python_lint.rules._ast_index import children
|
|
21
|
+
from sarj_python_lint.rules._ast_index import children
|
|
22
22
|
from sarj_python_lint.rules._comments import is_protected, split_identifier, stem
|
|
23
23
|
from sarj_python_lint.rules._docstrings import (
|
|
24
24
|
VALUE_MARKER_RE,
|
|
@@ -28,12 +28,10 @@ from sarj_python_lint.rules._docstrings import (
|
|
|
28
28
|
|
|
29
29
|
if TYPE_CHECKING:
|
|
30
30
|
from sarj_python_lint._file_context import PythonFileContext
|
|
31
|
-
from sarj_python_lint.rules._ast_index import NodeIndex
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
_DOCSTRING_TOKEN_RE = re.compile(r"[^\W\d_]+(?:'[^\W\d_]+)?|\d+")
|
|
35
34
|
_GRAMMATICAL_FILLER = frozenset({"a", "an", "function", "method", "the"})
|
|
36
|
-
_GETATTR_MIN_ARGS = 2
|
|
37
35
|
_MULTI_PARAMETER_MIN = 2
|
|
38
36
|
|
|
39
37
|
|
|
@@ -41,7 +39,7 @@ _MULTI_PARAMETER_MIN = 2
|
|
|
41
39
|
class _ScanContext:
|
|
42
40
|
path: Path
|
|
43
41
|
source_lines: list[str]
|
|
44
|
-
consumed_docstrings:
|
|
42
|
+
consumed_docstrings: frozenset[str]
|
|
45
43
|
diagnostics: list[Diagnostic]
|
|
46
44
|
|
|
47
45
|
|
|
@@ -105,7 +103,7 @@ class RedundantDocstring(Rule):
|
|
|
105
103
|
if tree is None:
|
|
106
104
|
return []
|
|
107
105
|
source_lines = context.source_lines
|
|
108
|
-
consumed_docstrings =
|
|
106
|
+
consumed_docstrings = context.consumed_docstring_names
|
|
109
107
|
diags: list[Diagnostic] = []
|
|
110
108
|
analysis_context = _ScanContext(path, source_lines, consumed_docstrings, diags)
|
|
111
109
|
self._walk(tree, analysis_context)
|
|
@@ -190,88 +188,3 @@ def _parameters_are_distinguished(groups: list[set[str]], content: set[str]) ->
|
|
|
190
188
|
if not distinguishing or distinguishing.isdisjoint(content):
|
|
191
189
|
return False
|
|
192
190
|
return True
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
def _consumed_docstring_names(tree: ast.Module, *, node_index: NodeIndex | None = None) -> set[str]:
|
|
196
|
-
consumed: set[str] = set()
|
|
197
|
-
aliases: dict[str, set[str]] = {}
|
|
198
|
-
for node in walk_ast(tree, index=node_index):
|
|
199
|
-
_record_docstring_use(node, consumed, aliases)
|
|
200
|
-
changed = True
|
|
201
|
-
while changed:
|
|
202
|
-
changed = False
|
|
203
|
-
for alias, originals in aliases.items():
|
|
204
|
-
if alias not in consumed:
|
|
205
|
-
continue
|
|
206
|
-
before = len(consumed)
|
|
207
|
-
consumed.update(originals)
|
|
208
|
-
changed |= len(consumed) != before
|
|
209
|
-
return consumed
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
def _terminal_name(node: ast.expr) -> str | None:
|
|
213
|
-
match node:
|
|
214
|
-
case ast.Name():
|
|
215
|
-
return node.id
|
|
216
|
-
case ast.Attribute():
|
|
217
|
-
return node.attr
|
|
218
|
-
case _:
|
|
219
|
-
return None
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
def _record_docstring_use(node: ast.AST, consumed: set[str], aliases: dict[str, set[str]]) -> None:
|
|
223
|
-
if isinstance(node, ast.Attribute) and node.attr == "__doc__":
|
|
224
|
-
if name := _terminal_name(node.value):
|
|
225
|
-
consumed.add(name)
|
|
226
|
-
elif isinstance(node, ast.Call) and _is_docstring_reader(node):
|
|
227
|
-
if name := _terminal_name(node.args[0]):
|
|
228
|
-
consumed.add(name)
|
|
229
|
-
elif isinstance(node, ast.Subscript):
|
|
230
|
-
if name := _subscripted_docstring_owner(node):
|
|
231
|
-
consumed.add(name)
|
|
232
|
-
else:
|
|
233
|
-
_record_docstring_alias(node, aliases)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def _subscripted_docstring_owner(node: ast.Subscript) -> str | None:
|
|
237
|
-
if not isinstance(node.slice, ast.Constant) or node.slice.value != "__doc__":
|
|
238
|
-
return None
|
|
239
|
-
value = node.value
|
|
240
|
-
if isinstance(value, ast.Attribute) and value.attr == "__dict__":
|
|
241
|
-
return _terminal_name(value.value)
|
|
242
|
-
if isinstance(value, ast.Call) and isinstance(value.func, ast.Name) and value.func.id == "vars" and value.args:
|
|
243
|
-
return _terminal_name(value.args[0])
|
|
244
|
-
return None
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
def _is_docstring_reader(node: ast.Call) -> bool:
|
|
248
|
-
if not node.args:
|
|
249
|
-
return False
|
|
250
|
-
function = node.func
|
|
251
|
-
if isinstance(function, ast.Name) and function.id == "help":
|
|
252
|
-
return True
|
|
253
|
-
if isinstance(function, ast.Attribute) and function.attr in {"getdoc", "render_doc"}:
|
|
254
|
-
return True
|
|
255
|
-
return (
|
|
256
|
-
isinstance(function, ast.Name)
|
|
257
|
-
and function.id == "getattr"
|
|
258
|
-
and len(node.args) >= _GETATTR_MIN_ARGS
|
|
259
|
-
and isinstance(node.args[1], ast.Constant)
|
|
260
|
-
and node.args[1].value == "__doc__"
|
|
261
|
-
)
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
def _record_docstring_alias(node: ast.AST, aliases: dict[str, set[str]]) -> None:
|
|
265
|
-
if isinstance(node, ast.Assign) and isinstance(node.value, (ast.Name, ast.Attribute)):
|
|
266
|
-
original = _terminal_name(node.value)
|
|
267
|
-
for target in node.targets:
|
|
268
|
-
if isinstance(target, ast.Name) and original is not None:
|
|
269
|
-
aliases.setdefault(target.id, set()).add(original)
|
|
270
|
-
elif (
|
|
271
|
-
isinstance(node, ast.AnnAssign)
|
|
272
|
-
and isinstance(node.target, ast.Name)
|
|
273
|
-
and isinstance(node.value, (ast.Name, ast.Attribute))
|
|
274
|
-
):
|
|
275
|
-
original = _terminal_name(node.value)
|
|
276
|
-
if original is not None:
|
|
277
|
-
aliases.setdefault(node.target.id, set()).add(original)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/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
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/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
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_closed_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_copy_on_write.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_dict_key_views.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_fixed_record.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_local_source.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_nominal_project.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_prose_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_set_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/_test_composition.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/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
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/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
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_comment_cruft.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_dunder_all.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_secret_in_log.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/no_select_star.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/over_mocked_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_class_row.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_or_pattern.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/prefer_str_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.28.3 → sarj_python_lint-1.28.4}/src/sarj_python_lint/rules/unused_mock_setup.py
RENAMED
|
File without changes
|
|
File without changes
|