sarj-python-lint 1.20.2__tar.gz → 1.21.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.20.2 → sarj_python_lint-1.21.0}/PKG-INFO +1 -1
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/pyproject.toml +1 -1
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_native_string_check.py +211 -19
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/.gitignore +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/LICENSE +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/README.md +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/__init__.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/__main__.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/_analysis_session.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/_file_context.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/_filesystem.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/_python_target.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/_ratchet_cli.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/_secret_names.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/_version.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/benchmark.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/json_boundary.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/py.typed +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/ratchet.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rule_base.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/__init__.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_annotation_semantics.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_ast_index.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_ast_position.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_comments.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_contract_annotation.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_dict_key_views.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_docstrings.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_fastapi.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_first_party.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_fixed_record.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_imports.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_local_source.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_logging.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_nominal_project.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_paths.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_project_index.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_pytest.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_registry.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_resource_provenance.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_set_fields.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_sql.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_test_composition.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_test_provenance.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/async_cleanup_registered_synchronously.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/async_mock_call_without_await_assertion.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/complex_postgres_query_requires_architecture_review.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/defect_xfail_requires_explicit_strict.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/excessive_commentary.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/fakes_in_shared_location.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/fastapi_class_router_contract.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/fastapi_explicit_openapi_contract.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/iac_source_coupled_test.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/named_record_at_boundaries.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/negative_only_http_status_assertion.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_analytical_aggregation_in_postgres_store.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_any_mapping_types.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_broad_keyword_capture.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_conftest_test_module_import.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_copied_inherited_docstring.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_database_programmability.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_delete_statement.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_dunder_all.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_excessive_cognitive_complexity.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_fastapi_on_event.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_file_level_escape_hatch_suppression.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_fixed_sleep_before_assert.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_injected_module_loader.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_invalid_argument_name_suppression.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_mocked_pydantic_value_object.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_nested_pydantic_field_validator.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_nullable_dependency_fallback.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_positional_psycopg_row_escape.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_psycopg_execution_outside_injected_owner.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_random_uuid_in_sql.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_raw_connection_in_tests.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_raw_source_text_test_oracle.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_redundant_literal_description.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_redundant_module_alias_exports.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_repeated_test_body.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_select_star.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_service_behavior_in_settings.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_shallow_container_type_guard.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_swallowed_asyncio_cancellation.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_test_method_grafting.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_unique_violation_message_match.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_unnecessary_docstring.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_unused_underscored_keyword_parameter.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_unused_value_marker.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_vague_suppression_description.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_whole_request_response_payload_in_log.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_autospec_for_callable_mock.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_collection_comprehension.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_injected_dependency_over_monkeypatch.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_library_fake.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_match_exception_dispatch.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_match_value_dispatch.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_monkeypatch_for_process_state_in_test.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_monotonic_for_elapsed_time.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_pydantic_json_value.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_pytest_fixture_injection.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_regex_fullmatch.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_required_constructor_parameters.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_set_isdisjoint.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_walrus_awaited_none_guard.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/production_derived_test_cases.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/pytest_fixture_returns_bare_tuple.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/repeated_kwarg_heavy_call_in_test.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/repeated_static_call_cases.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/repeated_test_composition.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_explicit_contract_implementation.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_explicit_psycopg_transaction.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_explicit_service_contract.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_nodecode_for_splitting_settings_field.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_precise_factory_signature.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_public_dependency_contract.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_pydantic_for_external_json.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_pydantic_for_structured_payload.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/require_pydantic_ordinal_lower_bound.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/shared_mutable_pydantic_factory.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/stepdown.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/store_get_delegates_to_bulk_read.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/subprocess_kill_without_reap.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/timestamp_order_requires_tiebreaker.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/typed_error_reasons.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/uncontrolled_randomness_in_test.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
- {sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/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.
|
|
3
|
+
Version: 1.21.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/
|
|
@@ -29,7 +29,10 @@ _PYDANTIC = frozenset({"pydantic", "pydantic.type_adapter"})
|
|
|
29
29
|
_BUILTINS = frozenset({"builtins"})
|
|
30
30
|
_PYTEST = frozenset({"pytest"})
|
|
31
31
|
_VALIDATION_ERROR = frozenset({"pydantic", "pydantic_core"})
|
|
32
|
-
|
|
32
|
+
_JSON_TYPES = frozenset({"pydantic", "pydantic.types"})
|
|
33
|
+
_ENCODERS = frozenset({"fastapi.encoders"})
|
|
34
|
+
_MODULES = _PYDANTIC | _BUILTINS | _PYTEST | _VALIDATION_ERROR | _JSON_TYPES | _ENCODERS | {"fastapi"}
|
|
35
|
+
_MAPPING_SCHEMA_ARGUMENTS = 2
|
|
33
36
|
|
|
34
37
|
|
|
35
38
|
@dataclass(frozen=True, slots=True)
|
|
@@ -44,15 +47,15 @@ class PreferNativeStringCheck(Rule):
|
|
|
44
47
|
code = "SARJ480"
|
|
45
48
|
documentation: ClassVar[RuleDocumentation | None] = RuleDocumentation(
|
|
46
49
|
default_level=Severity.WARNING,
|
|
47
|
-
summary="
|
|
48
|
-
rationale="
|
|
49
|
-
remediation="Use isinstance(value, str)
|
|
50
|
+
summary="Avoid unconstrained adapters for string assertions or already encoded JSON mappings.",
|
|
51
|
+
rationale="A plain string adapter obscures an assertion and can decode bytes. Generic JSON-dictionary validation after encoding adds a separate runtime contract, often only to satisfy an annotation; it can reject nested integer keys that a response serializer accepts and does not prove response serializability.",
|
|
52
|
+
remediation="Use isinstance(value, str) for string assertions. For annotation-only JSON adaptation, return a typed Response/JSONResponse at the serialization boundary. Keep structured input and specific schema validation. Preserve intentional coercion, recursive string-key validation or ValidationError contracts explicitly.",
|
|
50
53
|
category=RuleCategory.MAINTAINABILITY,
|
|
51
54
|
autofix=AutofixPolicy.NONE,
|
|
52
55
|
limitations=(
|
|
53
|
-
"
|
|
56
|
+
"Plain built-in str adapters are checked only inside assertions. The JSON branch checks exactly dict[str, pydantic.JsonValue] immediately wrapping FastAPI jsonable_encoder of a dictionary literal with string literal keys; dynamic values and keyword encoder options are allowed. Custom encoders must be a literal mapping with only proven built-in bytes keys, so they cannot replace the root mapping or its string keys. Unknown input shapes, opaque or shape-changing encoders, schema aliases, other containers, constrained types, unions, models, configured adapters and validation options are excluded.",
|
|
54
57
|
"Scoped import aliases and unescaped unconditional module or local adapter bindings are recognized, including independent functions reusing a name. Conditional, reassigned, indirect or class/comprehension/parameter/global/nonlocal cached bindings are excluded, as are shadowed symbols, wildcard imports and imports with visible mutation or escape.",
|
|
55
|
-
"
|
|
58
|
+
"String assertion messages and deferred expressions are excluded. The JSON branch excludes lambdas, comprehensions, function/class headers and cached encoded values; proven pytest.raises(ValidationError) contexts and try bodies catching ValidationError are preserved. Broader catches and contextlib.suppress are not inferred. This advisory does not prove equivalent behavior: intentional validation or byte-decoding contracts need a local reasoned suppression; there is no autofix.",
|
|
56
59
|
),
|
|
57
60
|
examples=(
|
|
58
61
|
RuleExample(
|
|
@@ -83,6 +86,36 @@ class PreferNativeStringCheck(Rule):
|
|
|
83
86
|
expected_count=0,
|
|
84
87
|
public=True,
|
|
85
88
|
),
|
|
89
|
+
RuleExample(
|
|
90
|
+
example_id="generic-json-after-encoding",
|
|
91
|
+
scenario="json-output",
|
|
92
|
+
title="A generic validator wraps an already encoded response mapping",
|
|
93
|
+
outcome=ExampleOutcome.MATCH,
|
|
94
|
+
files=(
|
|
95
|
+
ExampleFile.python(
|
|
96
|
+
"app/responses.py",
|
|
97
|
+
"from pydantic import TypeAdapter, JsonValue\nfrom fastapi.encoders import jsonable_encoder\ndef response_content(body):\n return TypeAdapter(dict[str, JsonValue]).validate_python(jsonable_encoder({'body': body}, custom_encoder={bytes: lambda value: value.decode('utf-8', errors='replace')}))\n",
|
|
98
|
+
),
|
|
99
|
+
),
|
|
100
|
+
focus_path=PurePosixPath("app/responses.py"),
|
|
101
|
+
expected_count=1,
|
|
102
|
+
public=True,
|
|
103
|
+
),
|
|
104
|
+
RuleExample(
|
|
105
|
+
example_id="response-serialization-boundary",
|
|
106
|
+
scenario="json-output",
|
|
107
|
+
title="The response owns encoded content without annotation-only validation",
|
|
108
|
+
outcome=ExampleOutcome.NO_MATCH,
|
|
109
|
+
files=(
|
|
110
|
+
ExampleFile.python(
|
|
111
|
+
"app/responses.py",
|
|
112
|
+
"from fastapi.encoders import jsonable_encoder\nfrom fastapi.responses import JSONResponse\ndef response(body) -> JSONResponse:\n return JSONResponse(content=jsonable_encoder({'body': body}))\n",
|
|
113
|
+
),
|
|
114
|
+
),
|
|
115
|
+
focus_path=PurePosixPath("app/responses.py"),
|
|
116
|
+
expected_count=0,
|
|
117
|
+
public=True,
|
|
118
|
+
),
|
|
86
119
|
),
|
|
87
120
|
)
|
|
88
121
|
description = documentation.summary
|
|
@@ -109,13 +142,24 @@ class PreferNativeStringCheck(Rule):
|
|
|
109
142
|
receiver = _validation_receiver(call)
|
|
110
143
|
if receiver is None:
|
|
111
144
|
continue
|
|
112
|
-
if not _inside_assertion(call, context) or _expects_validation_error(
|
|
113
|
-
call, context, provenance, imports, unsafe_imports
|
|
114
|
-
):
|
|
115
|
-
continue
|
|
116
145
|
if isinstance(receiver, ast.Name):
|
|
117
146
|
receiver = _cached_constructor(receiver, call, provenance, uncertain_names, mutated_bindings)
|
|
118
|
-
if receiver is None
|
|
147
|
+
if receiver is None:
|
|
148
|
+
continue
|
|
149
|
+
if _inside_assertion(call, context) and _plain_string_adapter(
|
|
150
|
+
receiver, context, provenance, imports, unsafe_imports
|
|
151
|
+
):
|
|
152
|
+
message = "plain str adapter in an assertion; use isinstance(value, str) with an explicit failure path, or preserve the intentional Pydantic contract explicitly"
|
|
153
|
+
elif (
|
|
154
|
+
_encoded_json_mapping(call.args[0], context, provenance, imports, unsafe_imports)
|
|
155
|
+
and _supported_json_context(call, context)
|
|
156
|
+
and _plain_json_mapping_adapter(receiver, context, provenance, imports, unsafe_imports)
|
|
157
|
+
and not _catches_validation_error(call, context, provenance, imports, unsafe_imports)
|
|
158
|
+
):
|
|
159
|
+
message = "generic JSON validation after encoding; for annotation-only adaptation, return a typed Response/JSONResponse with the encoded mapping, or preserve intentional recursive string-key/ValidationError validation explicitly"
|
|
160
|
+
else:
|
|
161
|
+
continue
|
|
162
|
+
if _expects_validation_error(call, context, provenance, imports, unsafe_imports):
|
|
119
163
|
continue
|
|
120
164
|
if is_suppressed(context.source_lines, call.lineno, self.code):
|
|
121
165
|
continue
|
|
@@ -126,7 +170,7 @@ class PreferNativeStringCheck(Rule):
|
|
|
126
170
|
col=call.col_offset + 1,
|
|
127
171
|
code=self.code,
|
|
128
172
|
severity=Severity.WARNING,
|
|
129
|
-
message=
|
|
173
|
+
message=message,
|
|
130
174
|
)
|
|
131
175
|
)
|
|
132
176
|
return sorted(findings, key=lambda finding: (finding.line, finding.col))
|
|
@@ -215,6 +259,130 @@ def _single_value(call: ast.Call, keyword: str) -> ast.expr | None:
|
|
|
215
259
|
return None
|
|
216
260
|
|
|
217
261
|
|
|
262
|
+
def _plain_json_mapping_adapter(
|
|
263
|
+
node: ast.expr,
|
|
264
|
+
context: PythonFileContext,
|
|
265
|
+
provenance: ResourceProvenance,
|
|
266
|
+
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
267
|
+
unsafe_imports: set[str],
|
|
268
|
+
) -> bool:
|
|
269
|
+
if not isinstance(node, ast.Call):
|
|
270
|
+
return False
|
|
271
|
+
function = node.func.value if isinstance(node.func, ast.Subscript) else node.func
|
|
272
|
+
schema = _single_value(node, "type")
|
|
273
|
+
if (
|
|
274
|
+
not isinstance(schema, ast.Subscript)
|
|
275
|
+
or not isinstance(schema.slice, ast.Tuple)
|
|
276
|
+
or len(schema.slice.elts) != _MAPPING_SCHEMA_ARGUMENTS
|
|
277
|
+
or not _resolves(
|
|
278
|
+
function, context, provenance, imports, unsafe_imports, sources=_PYDANTIC, symbol="TypeAdapter"
|
|
279
|
+
)
|
|
280
|
+
):
|
|
281
|
+
return False
|
|
282
|
+
key, value = schema.slice.elts
|
|
283
|
+
return (
|
|
284
|
+
_builtin_type(schema.value, context, provenance, imports, unsafe_imports, symbol="dict")
|
|
285
|
+
and _builtin_type(key, context, provenance, imports, unsafe_imports, symbol="str")
|
|
286
|
+
and _resolves(value, context, provenance, imports, unsafe_imports, sources=_JSON_TYPES, symbol="JsonValue")
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def _builtin_type(
|
|
291
|
+
node: ast.expr,
|
|
292
|
+
context: PythonFileContext,
|
|
293
|
+
provenance: ResourceProvenance,
|
|
294
|
+
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
295
|
+
unsafe_imports: set[str],
|
|
296
|
+
*,
|
|
297
|
+
symbol: str,
|
|
298
|
+
) -> bool:
|
|
299
|
+
return (
|
|
300
|
+
isinstance(node, ast.Name)
|
|
301
|
+
and node.id == symbol
|
|
302
|
+
and context.imports.builtin_is_unshadowed(symbol)
|
|
303
|
+
and _lexical_binding(symbol, node, provenance) is None
|
|
304
|
+
and "builtins" not in unsafe_imports
|
|
305
|
+
and f"builtins.{symbol}" not in unsafe_imports
|
|
306
|
+
) or _resolves(node, context, provenance, imports, unsafe_imports, sources=_BUILTINS, symbol=symbol)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _encoded_json_mapping(
|
|
310
|
+
node: ast.expr,
|
|
311
|
+
context: PythonFileContext,
|
|
312
|
+
provenance: ResourceProvenance,
|
|
313
|
+
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
314
|
+
unsafe_imports: set[str],
|
|
315
|
+
) -> bool:
|
|
316
|
+
if (
|
|
317
|
+
not isinstance(node, ast.Call)
|
|
318
|
+
or not _resolves(
|
|
319
|
+
node.func, context, provenance, imports, unsafe_imports, sources=_ENCODERS, symbol="jsonable_encoder"
|
|
320
|
+
)
|
|
321
|
+
or any(keyword.arg is None for keyword in node.keywords)
|
|
322
|
+
):
|
|
323
|
+
return False
|
|
324
|
+
custom_encoder = next((keyword.value for keyword in node.keywords if keyword.arg == "custom_encoder"), None)
|
|
325
|
+
if custom_encoder is not None and not _bytes_encoders(custom_encoder, context, provenance, imports, unsafe_imports):
|
|
326
|
+
return False
|
|
327
|
+
value = (
|
|
328
|
+
node.args[0]
|
|
329
|
+
if len(node.args) == 1 and not any(keyword.arg == "obj" for keyword in node.keywords)
|
|
330
|
+
else next((keyword.value for keyword in node.keywords if not node.args and keyword.arg == "obj"), None)
|
|
331
|
+
)
|
|
332
|
+
return isinstance(value, ast.Dict) and all(
|
|
333
|
+
isinstance(key, ast.Constant) and isinstance(key.value, str) for key in value.keys
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def _bytes_encoders(
|
|
338
|
+
node: ast.expr,
|
|
339
|
+
context: PythonFileContext,
|
|
340
|
+
provenance: ResourceProvenance,
|
|
341
|
+
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
342
|
+
unsafe_imports: set[str],
|
|
343
|
+
) -> bool:
|
|
344
|
+
return isinstance(node, ast.Dict) and all(
|
|
345
|
+
key is not None and _builtin_type(key, context, provenance, imports, unsafe_imports, symbol="bytes")
|
|
346
|
+
for key in node.keys
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def _supported_json_context(call: ast.Call, context: PythonFileContext) -> bool:
|
|
351
|
+
child: ast.AST = call
|
|
352
|
+
parent = context.parents.get(child)
|
|
353
|
+
while parent is not None:
|
|
354
|
+
if isinstance(parent, ast.Lambda | ast.ListComp | ast.SetComp | ast.DictComp | ast.GeneratorExp):
|
|
355
|
+
return False
|
|
356
|
+
if isinstance(parent, ast.FunctionDef | ast.AsyncFunctionDef | ast.ClassDef):
|
|
357
|
+
return isinstance(child, ast.stmt)
|
|
358
|
+
child = parent
|
|
359
|
+
parent = context.parents.get(child)
|
|
360
|
+
return True
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def _catches_validation_error(
|
|
364
|
+
call: ast.Call,
|
|
365
|
+
context: PythonFileContext,
|
|
366
|
+
provenance: ResourceProvenance,
|
|
367
|
+
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
368
|
+
unsafe_imports: set[str],
|
|
369
|
+
) -> bool:
|
|
370
|
+
child: ast.AST = call
|
|
371
|
+
parent = context.parents.get(child)
|
|
372
|
+
while parent is not None and not isinstance(
|
|
373
|
+
parent, ast.FunctionDef | ast.AsyncFunctionDef | ast.Lambda | ast.GeneratorExp
|
|
374
|
+
):
|
|
375
|
+
if isinstance(parent, ast.Try | ast.TryStar) and child in parent.body:
|
|
376
|
+
for handler in parent.handlers:
|
|
377
|
+
if handler.type is not None and _validation_error_type(
|
|
378
|
+
handler.type, context, provenance, imports, unsafe_imports
|
|
379
|
+
):
|
|
380
|
+
return True
|
|
381
|
+
child = parent
|
|
382
|
+
parent = context.parents.get(child)
|
|
383
|
+
return False
|
|
384
|
+
|
|
385
|
+
|
|
218
386
|
def _resolves(
|
|
219
387
|
node: ast.expr,
|
|
220
388
|
context: PythonFileContext,
|
|
@@ -256,6 +424,8 @@ def _import_key(module: str, symbol: str | None) -> str:
|
|
|
256
424
|
return f"pydantic.{symbol}"
|
|
257
425
|
if symbol == "ValidationError" and module in _VALIDATION_ERROR:
|
|
258
426
|
return f"pydantic_core.{symbol}"
|
|
427
|
+
if symbol == "JsonValue" and module in _JSON_TYPES:
|
|
428
|
+
return f"pydantic.{symbol}"
|
|
259
429
|
return f"{module}.{symbol}" if symbol is not None else module
|
|
260
430
|
|
|
261
431
|
|
|
@@ -310,6 +480,10 @@ def _unsafe_imports(
|
|
|
310
480
|
unsafe.add(key)
|
|
311
481
|
if key in _PYDANTIC:
|
|
312
482
|
unsafe.add("pydantic.TypeAdapter")
|
|
483
|
+
if key in _JSON_TYPES:
|
|
484
|
+
unsafe.add("pydantic.JsonValue")
|
|
485
|
+
if key in _ENCODERS or key == "fastapi":
|
|
486
|
+
unsafe.add("fastapi.encoders.jsonable_encoder")
|
|
313
487
|
if key in _VALIDATION_ERROR:
|
|
314
488
|
unsafe.add("pydantic_core.ValidationError")
|
|
315
489
|
if key == "pytest":
|
|
@@ -371,7 +545,7 @@ def _import_escapes(
|
|
|
371
545
|
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
372
546
|
) -> bool:
|
|
373
547
|
parent = context.parents.get(read)
|
|
374
|
-
if key
|
|
548
|
+
if key in {"pydantic.TypeAdapter", "fastapi.encoders.jsonable_encoder"}:
|
|
375
549
|
return not (
|
|
376
550
|
isinstance(parent, ast.Attribute)
|
|
377
551
|
or (isinstance(parent, ast.Subscript) and parent.value is read)
|
|
@@ -446,14 +620,22 @@ def _expects_validation_error(
|
|
|
446
620
|
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
447
621
|
unsafe_imports: set[str],
|
|
448
622
|
) -> bool:
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
623
|
+
child: ast.AST = call
|
|
624
|
+
parent = context.parents.get(child)
|
|
625
|
+
while parent is not None and not isinstance(
|
|
626
|
+
parent, ast.FunctionDef | ast.AsyncFunctionDef | ast.Lambda | ast.GeneratorExp
|
|
627
|
+
):
|
|
628
|
+
if (
|
|
629
|
+
isinstance(parent, ast.With | ast.AsyncWith)
|
|
630
|
+
and isinstance(child, ast.stmt)
|
|
631
|
+
and any(
|
|
632
|
+
_raises_validation_error(item.context_expr, context, provenance, imports, unsafe_imports)
|
|
633
|
+
for item in parent.items
|
|
634
|
+
)
|
|
454
635
|
):
|
|
455
636
|
return True
|
|
456
|
-
|
|
637
|
+
child = parent
|
|
638
|
+
parent = context.parents.get(child)
|
|
457
639
|
return False
|
|
458
640
|
|
|
459
641
|
|
|
@@ -477,6 +659,16 @@ def _raises_validation_error(
|
|
|
477
659
|
)
|
|
478
660
|
if expected is None:
|
|
479
661
|
return False
|
|
662
|
+
return _validation_error_type(expected, context, provenance, imports, unsafe_imports)
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def _validation_error_type(
|
|
666
|
+
expected: ast.expr,
|
|
667
|
+
context: PythonFileContext,
|
|
668
|
+
provenance: ResourceProvenance,
|
|
669
|
+
imports: dict[ast.Import | ast.ImportFrom, ImportIndex],
|
|
670
|
+
unsafe_imports: set[str],
|
|
671
|
+
) -> bool:
|
|
480
672
|
types = expected.elts if isinstance(expected, ast.Tuple) else (expected,)
|
|
481
673
|
return any(
|
|
482
674
|
_resolves(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_ast_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_ast_position.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_dict_key_views.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_first_party.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_fixed_record.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_local_source.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_nominal_project.py
RENAMED
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_project_index.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/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.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_set_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_test_assertions.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/_test_composition.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.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
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.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
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.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
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.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
|
|
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.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/no_secret_in_log.py
RENAMED
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/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
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/over_mocked_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_class_row.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/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.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/prefer_str_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sarj_python_lint-1.20.2 → sarj_python_lint-1.21.0}/src/sarj_python_lint/rules/unused_mock_setup.py
RENAMED
|
File without changes
|
|
File without changes
|