sarj-python-lint 1.68.0__tar.gz → 1.69.0__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.68.0 → sarj_python_lint-1.69.0}/PKG-INFO +1 -1
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/pyproject.toml +1 -1
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/__main__.py +19 -5
- sarj_python_lint-1.69.0/src/sarj_python_lint/_parallel.py +102 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_local_source.py +13 -3
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_project_index.py +38 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/.gitignore +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/LICENSE +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/README.md +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_file_context.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_source.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/benchmark.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/cast_access.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/interpreter_argv.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_ast_index.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_ast_names.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_closed_helpers.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_copy_on_write.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_data_union_discriminator.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_declared_contracts.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_docstrings.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_exports.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_fastapi.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_inert_model_annotation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_inherited_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_mapping_shape_callbacks.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_namespace_access.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_native_namespace_capability.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_pydantic_field_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_registry.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_resolved_operation_signature.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_route_shapes.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_runtime_bindings.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_set_fields.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_sql.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_static_json_alias.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_store_writes.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_test_composition.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_type_guard_symbols.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/delete_route_returns_no_content.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/duplicate_adjacent_exception_handler.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/duplicate_closed_pure_helper.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/duplicate_pytest_fixture_params.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_async_function_cache.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_before_validator_input_mutation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_blanket_suppression.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_conflicting_pydantic_alias_validation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_contradictory_type_guard.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_create_verb_in_post_path.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_defaulted_environment_setting.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_discarded_validation_result.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_dual_shape_model_field_reader.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_duplicate_field_validator_body.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_exception_text_in_500_detail.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_fixed_sleep_in_loop.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_folded_bad_request_not_found.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_hasattr.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_impossible_pydantic_field_bounds.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_input_model_mutation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_interpreter_source_arguments.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_invalid_pydantic_bypass.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_invalid_pydantic_validator_return.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_loguru_exc_info.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_loguru_printf_format.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_mutating_container_transform.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_partial_type_is.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_shallow_record_type_guard.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_slash_collection_root_under_prefix.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_unknown_pydantic_validator_field.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_unused_copy_result.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_work_verb_get_route.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_bulk_upsert.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_declarative_batch_validation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_direct_import_module.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_discriminated_model_union.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_native_string_check.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_precise_object_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_psycopg_executemany.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_pydantic_model_assertion.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_pytest_dependency_fixtures.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_typed_settings_field.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/pytest_fixture_returns_closed_resource.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/redundant_test_constructor_forwarder.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/repeated_unimplemented_test_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_exp_on_jwt_decode.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_injectable_retry_sleep.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_pydantic_for_mapping_shape.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/store_field_update_reuses_upsert.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/test_without_explicit_oracle.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/unused_test_factory_option.py +0 -0
- {sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/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.69.0
|
|
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/
|
|
@@ -96,7 +96,7 @@ def _canonical_rule_ids(rule_ids: list[str]) -> list[str]:
|
|
|
96
96
|
return list(dict.fromkeys(rid if rid in REGISTRY else aliases.get(rid, rid) for rid in rule_ids))
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def _check(rule_ids: list[str], paths: list[Path]) -> list[Diagnostic]:
|
|
99
|
+
def _check(rule_ids: list[str], paths: list[Path], *, jobs: int = 1) -> list[Diagnostic]:
|
|
100
100
|
rule_ids = _canonical_rule_ids(rule_ids)
|
|
101
101
|
unknown = [rid for rid in rule_ids if rid not in REGISTRY]
|
|
102
102
|
if unknown:
|
|
@@ -116,6 +116,12 @@ def _check(rule_ids: list[str], paths: list[Path]) -> list[Diagnostic]:
|
|
|
116
116
|
session.project = indexes
|
|
117
117
|
for rule in project_rules:
|
|
118
118
|
rule.prepare(indexes)
|
|
119
|
+
if jobs > 1 and len(loaded) > 1:
|
|
120
|
+
from sarj_python_lint._parallel import check_parallel # ruff: ignore[import-outside-top-level] -- serial API users do not need multiprocessing.
|
|
121
|
+
|
|
122
|
+
parallel = check_parallel([type(rule) for rule in rules], loaded, session.project, jobs=jobs)
|
|
123
|
+
if parallel is not None:
|
|
124
|
+
return parallel
|
|
119
125
|
diags: list[Diagnostic] = []
|
|
120
126
|
for p, source in loaded.items():
|
|
121
127
|
diags.extend(check_source(rules, p, source, session=session))
|
|
@@ -144,8 +150,12 @@ def analyze(
|
|
|
144
150
|
*,
|
|
145
151
|
baseline: Path | None = None,
|
|
146
152
|
root: Path | None = None,
|
|
153
|
+
jobs: int = 1,
|
|
147
154
|
) -> list[Diagnostic]:
|
|
148
|
-
|
|
155
|
+
if jobs < 1:
|
|
156
|
+
msg = "jobs must be at least 1"
|
|
157
|
+
raise ValueError(msg)
|
|
158
|
+
diagnostics = _check(rule_ids, paths, jobs=jobs)
|
|
149
159
|
return diagnostics if baseline is None else _apply_baseline(diagnostics, _read_baseline(baseline), root=root)
|
|
150
160
|
|
|
151
161
|
|
|
@@ -481,9 +491,11 @@ def _apply_baseline(
|
|
|
481
491
|
return out
|
|
482
492
|
|
|
483
493
|
|
|
484
|
-
def _run_check(
|
|
494
|
+
def _run_check(
|
|
495
|
+
rule: list[str], files: list[Path], baseline: Path | None, update_baseline: Path | None, *, jobs: int = 1
|
|
496
|
+
) -> int:
|
|
485
497
|
try:
|
|
486
|
-
diags = analyze(rule, files)
|
|
498
|
+
diags = analyze(rule, files, jobs=jobs)
|
|
487
499
|
except (OSError, ValueError, SyntaxError) as exc:
|
|
488
500
|
sys.stderr.write(f"error: {exc}\n")
|
|
489
501
|
return 2
|
|
@@ -554,14 +566,16 @@ def _check_command(
|
|
|
554
566
|
context: typer.Context,
|
|
555
567
|
files: Annotated[list[Path], typer.Argument()],
|
|
556
568
|
rule: Annotated[list[str], typer.Option("--rule", help="Rule ID (repeat for multiple).")],
|
|
569
|
+
*,
|
|
557
570
|
baseline: Annotated[
|
|
558
571
|
Path | None, typer.Option(help="Per-file shrink-only baseline JSON: {path: {CODE: count}}.")
|
|
559
572
|
] = None,
|
|
560
573
|
update_baseline: Annotated[
|
|
561
574
|
Path | None, typer.Option(help="Write current per-file diagnostic counts to JSON and exit 0.")
|
|
562
575
|
] = None,
|
|
576
|
+
jobs: Annotated[int, typer.Option(min=1, help="Analysis worker budget (up to 2); default is serial.")] = 1,
|
|
563
577
|
) -> None:
|
|
564
|
-
context.ensure_object(_Result).code = _run_check(rule, files, baseline, update_baseline)
|
|
578
|
+
context.ensure_object(_Result).code = _run_check(rule, files, baseline, update_baseline, jobs=jobs)
|
|
565
579
|
|
|
566
580
|
|
|
567
581
|
def main(argv: list[str] | None = None) -> int:
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from concurrent.futures import ProcessPoolExecutor
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
import multiprocessing
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
from sarj_python_lint._analysis_session import AnalysisSession
|
|
10
|
+
from sarj_python_lint.rule_base import Diagnostic, ProjectRule, Rule
|
|
11
|
+
from sarj_python_lint.rules._local_source import LOCAL_SOURCE_CACHE_LIMIT
|
|
12
|
+
from sarj_python_lint.rules._paths import clear_path_caches
|
|
13
|
+
from sarj_python_lint.rules._project_index import ProjectIndexSet
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from sarj_python_lint.rules._project_index import ProjectSourceSnapshot
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
type _ResolutionKey = tuple[Path, str | None, int]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class _WorkerState:
|
|
25
|
+
rules: list[Rule]
|
|
26
|
+
session: AnalysisSession
|
|
27
|
+
resolutions: frozenset[_ResolutionKey] = frozenset()
|
|
28
|
+
modules: frozenset[Path] = frozenset()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True, slots=True)
|
|
32
|
+
class _FileResult:
|
|
33
|
+
diagnostics: list[Diagnostic]
|
|
34
|
+
resolutions: frozenset[_ResolutionKey]
|
|
35
|
+
modules: frozenset[Path]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
_state: _WorkerState | None = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _initialize(rule_types: list[type[Rule]], snapshot: ProjectSourceSnapshot | None) -> None:
|
|
42
|
+
global _state # ruff: ignore[global-statement] -- each spawned process owns one initialized session.
|
|
43
|
+
rules = [rule_type() for rule_type in rule_types]
|
|
44
|
+
session = AnalysisSession()
|
|
45
|
+
for rule in rules:
|
|
46
|
+
rule.prepare_session(session)
|
|
47
|
+
clear_path_caches()
|
|
48
|
+
project = ProjectIndexSet.from_source_snapshot(snapshot) if snapshot is not None else None
|
|
49
|
+
session.project = project
|
|
50
|
+
for rule in rules:
|
|
51
|
+
if isinstance(rule, ProjectRule) and project is not None:
|
|
52
|
+
rule.prepare(project)
|
|
53
|
+
_state = _WorkerState(rules, session)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _check_file(item: tuple[Path, str]) -> _FileResult:
|
|
57
|
+
from sarj_python_lint.__main__ import check_source # ruff: ignore[import-outside-top-level] -- keep spawn targets in an importable module.
|
|
58
|
+
|
|
59
|
+
if _state is None:
|
|
60
|
+
msg = "Python analysis worker was not initialized"
|
|
61
|
+
raise RuntimeError(msg)
|
|
62
|
+
path, source = item
|
|
63
|
+
diagnostics = check_source(_state.rules, path, source, session=_state.session)
|
|
64
|
+
keys = _state.session.local_source.cache_keys()
|
|
65
|
+
result = _FileResult(diagnostics, keys.resolutions - _state.resolutions, keys.modules - _state.modules)
|
|
66
|
+
_state.resolutions, _state.modules = keys.resolutions, keys.modules
|
|
67
|
+
return result
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def check_parallel(
|
|
71
|
+
rule_types: list[type[Rule]],
|
|
72
|
+
loaded: dict[Path, str],
|
|
73
|
+
project: ProjectIndexSet | None,
|
|
74
|
+
*,
|
|
75
|
+
jobs: int,
|
|
76
|
+
) -> list[Diagnostic] | None:
|
|
77
|
+
# The untouched parent rules/session remain the serial fallback. Workers
|
|
78
|
+
# receive the same complete project snapshot and selected source strings.
|
|
79
|
+
workers = min(jobs, 2, len(loaded))
|
|
80
|
+
pool = ProcessPoolExecutor(
|
|
81
|
+
max_workers=workers,
|
|
82
|
+
mp_context=multiprocessing.get_context("spawn"),
|
|
83
|
+
initializer=_initialize,
|
|
84
|
+
initargs=(rule_types, project.source_snapshot() if project is not None else None),
|
|
85
|
+
)
|
|
86
|
+
diagnostics: list[Diagnostic] = []
|
|
87
|
+
resolutions: set[_ResolutionKey] = set()
|
|
88
|
+
modules: set[Path] = set()
|
|
89
|
+
try:
|
|
90
|
+
for result in pool.map(_check_file, loaded.items(), chunksize=1, buffersize=workers):
|
|
91
|
+
resolutions.update(result.resolutions)
|
|
92
|
+
modules.update(result.modules)
|
|
93
|
+
# A worker cannot hit either order-dependent limit when the whole
|
|
94
|
+
# union stays strictly below it. At the boundary, discard all output.
|
|
95
|
+
if len(resolutions) >= LOCAL_SOURCE_CACHE_LIMIT or len(modules) >= LOCAL_SOURCE_CACHE_LIMIT:
|
|
96
|
+
return None
|
|
97
|
+
diagnostics.extend(result.diagnostics)
|
|
98
|
+
return diagnostics
|
|
99
|
+
finally:
|
|
100
|
+
# Bound queued work and reap before fallback/error return. Running file
|
|
101
|
+
# checks finish normally; group cancellation belongs to the supervisor.
|
|
102
|
+
pool.shutdown(wait=True, cancel_futures=True)
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_local_source.py
RENAMED
|
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
|
|
15
15
|
|
|
16
16
|
_MAX_ANCESTORS = 24
|
|
17
17
|
_MAX_MODULE_BYTES = 256_000
|
|
18
|
-
|
|
18
|
+
LOCAL_SOURCE_CACHE_LIMIT = 512
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
@dataclass(frozen=True, slots=True)
|
|
@@ -26,6 +26,12 @@ class LocalModule:
|
|
|
26
26
|
runtime_imports: ImportIndex
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
@dataclass(frozen=True, slots=True)
|
|
30
|
+
class LocalSourceKeys:
|
|
31
|
+
resolutions: frozenset[tuple[Path, str | None, int]]
|
|
32
|
+
modules: frozenset[Path]
|
|
33
|
+
|
|
34
|
+
|
|
29
35
|
@final
|
|
30
36
|
class LocalSourceFacts:
|
|
31
37
|
def __init__(self) -> None:
|
|
@@ -40,7 +46,7 @@ class LocalSourceFacts:
|
|
|
40
46
|
key = (current, module, level)
|
|
41
47
|
if key in self._resolutions:
|
|
42
48
|
return self._resolutions[key]
|
|
43
|
-
if len(self._resolutions) >=
|
|
49
|
+
if len(self._resolutions) >= LOCAL_SOURCE_CACHE_LIMIT:
|
|
44
50
|
return None
|
|
45
51
|
result = _resolve_module(current, module, level, facts=facts)
|
|
46
52
|
self._resolutions[key] = result
|
|
@@ -49,12 +55,16 @@ class LocalSourceFacts:
|
|
|
49
55
|
def read_module(self, path: Path) -> LocalModule | None:
|
|
50
56
|
if path in self._modules:
|
|
51
57
|
return self._modules[path]
|
|
52
|
-
if len(self._modules) >=
|
|
58
|
+
if len(self._modules) >= LOCAL_SOURCE_CACHE_LIMIT:
|
|
53
59
|
return None
|
|
54
60
|
module = _read_module(path)
|
|
55
61
|
self._modules[path] = module
|
|
56
62
|
return module
|
|
57
63
|
|
|
64
|
+
def cache_keys(self) -> LocalSourceKeys:
|
|
65
|
+
# Failed lookups consume the same semantic budgets as successful ones.
|
|
66
|
+
return LocalSourceKeys(frozenset(self._resolutions), frozenset(self._modules))
|
|
67
|
+
|
|
58
68
|
|
|
59
69
|
def _resolve_module(current: Path, module: str | None, level: int, *, facts: FirstPartyFacts) -> Path | None:
|
|
60
70
|
if ".." in current.parts or level > _MAX_ANCESTORS:
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
@@ -154,6 +154,20 @@ class LoadedSource:
|
|
|
154
154
|
source: str
|
|
155
155
|
|
|
156
156
|
|
|
157
|
+
@dataclass(frozen=True, slots=True)
|
|
158
|
+
class _IndexedSource:
|
|
159
|
+
key: Path
|
|
160
|
+
path: Path
|
|
161
|
+
module: str | None
|
|
162
|
+
source: str
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@dataclass(frozen=True, slots=True)
|
|
166
|
+
class ProjectSourceSnapshot:
|
|
167
|
+
roots: tuple[Path, ...]
|
|
168
|
+
units: tuple[_IndexedSource, ...]
|
|
169
|
+
|
|
170
|
+
|
|
157
171
|
@dataclass(frozen=True, slots=True)
|
|
158
172
|
class _ClassValueUse:
|
|
159
173
|
reference: ast.Name | ast.Attribute
|
|
@@ -196,6 +210,30 @@ class ProjectIndexSet:
|
|
|
196
210
|
self._classes = MappingProxyType(classes)
|
|
197
211
|
self._nominals = MappingProxyType({key: frozenset(value) for key, value in nominals.items()})
|
|
198
212
|
|
|
213
|
+
def source_snapshot(self) -> ProjectSourceSnapshot:
|
|
214
|
+
# Rebuild memoized facts without rescanning roots or changing the
|
|
215
|
+
# module identities/order of the complete prepared source graph.
|
|
216
|
+
return ProjectSourceSnapshot(
|
|
217
|
+
self._roots,
|
|
218
|
+
tuple(_IndexedSource(key, unit.path, unit.module, unit.source) for key, unit in self._units.items()),
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
@classmethod
|
|
222
|
+
def from_source_snapshot(cls, snapshot: ProjectSourceSnapshot) -> Self:
|
|
223
|
+
units: dict[Path, SourceUnit] = {}
|
|
224
|
+
for source in snapshot.units:
|
|
225
|
+
tree: ast.Module | None = None
|
|
226
|
+
with suppress(SyntaxError):
|
|
227
|
+
tree = ast.parse(source.source, filename=str(source.path))
|
|
228
|
+
units[source.key] = SourceUnit(
|
|
229
|
+
path=source.path,
|
|
230
|
+
module=source.module,
|
|
231
|
+
source=source.source,
|
|
232
|
+
tree=tree,
|
|
233
|
+
imports=MappingProxyType(_imports(source.module, tree, is_package=source.path.name == "__init__.py")),
|
|
234
|
+
)
|
|
235
|
+
return cls(units, snapshot.roots)
|
|
236
|
+
|
|
199
237
|
@classmethod
|
|
200
238
|
def build(
|
|
201
239
|
cls,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/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
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/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.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_ast_names.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_closed_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_copy_on_write.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_dict_key_views.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_fixed_record.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_namespace_access.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_nominal_project.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_prose_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_route_shapes.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_runtime_bindings.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_set_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_static_json_alias.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_store_writes.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/_test_composition.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/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.68.0 → sarj_python_lint-1.69.0}/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.68.0 → sarj_python_lint-1.69.0}/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.68.0 → sarj_python_lint-1.69.0}/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.68.0 → sarj_python_lint-1.69.0}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.68.0 → sarj_python_lint-1.69.0}/src/sarj_python_lint/rules/no_loguru_exc_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|