From be6e00ef6e5efea68a8a1a0093611b26142b753d Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" <69878+youknowone@users.noreply.github.com> Date: Thu, 11 May 2023 16:47:17 +0900 Subject: [PATCH] Re-integrate RustPython parser repository (#4359) Co-authored-by: Micha Reiser --- Cargo.lock | 271 ++-------- Cargo.toml | 9 +- crates/ruff/src/autofix/actions.rs | 40 +- crates/ruff/src/checkers/ast/mod.rs | 466 ++++++++--------- crates/ruff/src/checkers/imports.rs | 13 +- crates/ruff/src/doc_lines.rs | 8 +- crates/ruff/src/docstrings/extraction.rs | 8 +- crates/ruff/src/importer.rs | 15 +- crates/ruff/src/logging.rs | 2 +- crates/ruff/src/rules/flake8_2020/rules.rs | 49 +- .../src/rules/flake8_annotations/fixes.rs | 2 +- .../src/rules/flake8_annotations/helpers.rs | 10 +- .../src/rules/flake8_annotations/rules.rs | 6 +- .../ruff/src/rules/flake8_bandit/helpers.rs | 8 +- .../rules/bad_file_permissions.rs | 10 +- .../rules/flake8_bandit/rules/exec_used.rs | 4 +- .../rules/hardcoded_password_string.rs | 12 +- .../rules/hardcoded_sql_expression.rs | 14 +- .../rules/hashlib_insecure_hash_functions.rs | 6 +- .../rules/jinja2_autoescape_false.rs | 12 +- .../rules/request_with_no_cert_validation.rs | 6 +- .../rules/request_without_timeout.rs | 6 +- .../flake8_bandit/rules/shell_injection.rs | 8 +- .../rules/snmp_insecure_version.rs | 6 +- .../rules/suspicious_function_call.rs | 4 +- .../flake8_bandit/rules/unsafe_yaml_load.rs | 6 +- .../src/rules/flake8_blind_except/rules.rs | 18 +- .../src/rules/flake8_boolean_trap/rules.rs | 16 +- .../rules/abstract_base_class.rs | 14 +- .../flake8_bugbear/rules/assert_false.rs | 31 +- .../rules/assert_raises_exception.rs | 7 +- .../rules/assignment_to_os_environ.rs | 6 +- .../rules/cached_instance_method.rs | 6 +- .../rules/cannot_raise_literal.rs | 2 +- .../rules/duplicate_exceptions.rs | 15 +- .../rules/except_with_empty_tuple.rs | 7 +- .../except_with_non_exception_classes.rs | 17 +- .../rules/f_string_docstring.rs | 6 +- .../rules/function_call_argument_default.rs | 12 +- .../rules/function_uses_loop_variable.rs | 52 +- .../rules/getattr_with_constant.rs | 17 +- .../rules/jump_statement_in_finally.rs | 33 +- .../rules/loop_variable_overrides_iterator.rs | 14 +- .../rules/mutable_argument_default.rs | 16 +- .../rules/raise_without_from_inside_except.rs | 4 +- .../redundant_tuple_in_exception_handler.rs | 6 +- .../rules/reuse_of_groupby_generator.rs | 37 +- .../rules/setattr_with_constant.rs | 28 +- .../star_arg_unpacking_after_keyword_arg.rs | 2 +- .../rules/strip_with_multi_characters.rs | 8 +- .../rules/unary_prefix_increment.rs | 4 +- .../rules/unintentional_type_annotation.rs | 10 +- .../rules/unreliable_callable_check.rs | 8 +- .../rules/unused_loop_control_variable.rs | 4 +- .../rules/useless_comparison.rs | 2 +- .../rules/useless_expression.rs | 12 +- .../rules/zip_without_explicit_strict.rs | 4 +- .../ruff/src/rules/flake8_builtins/rules.rs | 4 +- .../src/rules/flake8_comprehensions/fixes.rs | 8 +- .../flake8_comprehensions/rules/helpers.rs | 4 +- .../rules/unnecessary_call_around_sorted.rs | 4 +- .../rules/unnecessary_comprehension.rs | 14 +- .../unnecessary_comprehension_any_all.rs | 8 +- .../unnecessary_double_cast_or_process.rs | 4 +- .../rules/unnecessary_generator_dict.rs | 6 +- .../rules/unnecessary_generator_list.rs | 2 +- .../rules/unnecessary_generator_set.rs | 2 +- .../rules/unnecessary_list_call.rs | 2 +- .../unnecessary_list_comprehension_dict.rs | 6 +- .../unnecessary_list_comprehension_set.rs | 2 +- .../rules/unnecessary_literal_dict.rs | 13 +- .../rules/unnecessary_literal_set.rs | 4 +- .../unnecessary_literal_within_dict_call.rs | 4 +- .../unnecessary_literal_within_list_call.rs | 4 +- .../unnecessary_literal_within_tuple_call.rs | 4 +- .../rules/unnecessary_map.rs | 16 +- .../rules/unnecessary_subscript_reversal.rs | 14 +- .../ruff/src/rules/flake8_datetimez/rules.rs | 11 +- .../rules/all_with_model_form.rs | 10 +- .../rules/exclude_with_model_form.rs | 8 +- .../rules/locals_in_render_function.rs | 4 +- .../rules/model_without_dunder_str.rs | 13 +- .../rules/non_leading_receiver_decorator.rs | 9 +- .../rules/nullable_model_string_field.rs | 8 +- .../rules/unordered_body_content_in_model.rs | 12 +- crates/ruff/src/rules/flake8_errmsg/rules.rs | 28 +- crates/ruff/src/rules/flake8_gettext/rules.rs | 20 +- .../rules/flake8_implicit_str_concat/rules.rs | 16 +- .../src/rules/flake8_logging_format/rules.rs | 33 +- crates/ruff/src/rules/flake8_pie/rules.rs | 74 ++- .../rules/duplicate_union_member.rs | 8 +- .../flake8_pyi/rules/non_empty_stub_body.rs | 6 +- .../flake8_pyi/rules/prefix_type_params.rs | 6 +- .../rules/flake8_pyi/rules/simple_defaults.rs | 94 ++-- .../flake8_pyi/rules/type_alias_naming.rs | 6 +- .../flake8_pyi/rules/unrecognized_platform.rs | 6 +- .../flake8_pytest_style/rules/assertion.rs | 35 +- .../flake8_pytest_style/rules/fixture.rs | 21 +- .../flake8_pytest_style/rules/helpers.rs | 18 +- .../flake8_pytest_style/rules/imports.rs | 2 +- .../rules/flake8_pytest_style/rules/marks.rs | 9 +- .../flake8_pytest_style/rules/parametrize.rs | 68 +-- .../rules/flake8_pytest_style/rules/patch.rs | 6 +- .../rules/flake8_pytest_style/rules/raises.rs | 23 +- .../rules/unittest_assert.rs | 42 +- .../unnecessary_paren_on_raise_exception.rs | 6 +- .../ruff/src/rules/flake8_return/helpers.rs | 6 +- crates/ruff/src/rules/flake8_return/rules.rs | 50 +- .../ruff/src/rules/flake8_return/visitor.rs | 47 +- .../rules/private_member_access.rs | 13 +- .../flake8_simplify/rules/ast_bool_op.rs | 75 +-- .../rules/flake8_simplify/rules/ast_expr.rs | 30 +- .../src/rules/flake8_simplify/rules/ast_if.rs | 120 ++--- .../rules/flake8_simplify/rules/ast_ifexp.rs | 28 +- .../flake8_simplify/rules/ast_unary_op.rs | 22 +- .../rules/flake8_simplify/rules/ast_with.rs | 6 +- .../flake8_simplify/rules/key_in_dict.rs | 8 +- .../rules/open_file_with_context_handler.rs | 22 +- .../rules/reimplemented_builtin.rs | 60 +-- .../rules/return_in_try_except_finally.rs | 7 +- .../rules/suppressible_exception.rs | 30 +- .../flake8_simplify/rules/yoda_conditions.rs | 14 +- .../rules/flake8_tidy_imports/banned_api.rs | 6 +- .../flake8_tidy_imports/relative_imports.rs | 14 +- .../src/rules/flake8_type_checking/helpers.rs | 10 +- .../rules/typing_only_runtime_import.rs | 7 +- .../rules/flake8_unused_arguments/helpers.rs | 22 +- crates/ruff/src/rules/flynt/helpers.rs | 34 +- .../flynt/rules/static_join_to_fstring.rs | 17 +- crates/ruff/src/rules/isort/annotate.rs | 10 +- crates/ruff/src/rules/isort/categorize.rs | 2 +- crates/ruff/src/rules/isort/comments.rs | 2 +- crates/ruff/src/rules/isort/helpers.rs | 2 +- crates/ruff/src/rules/isort/mod.rs | 2 +- .../rules/isort/rules/add_required_imports.rs | 26 +- crates/ruff/src/rules/isort/sorting.rs | 4 +- crates/ruff/src/rules/isort/track.rs | 43 +- crates/ruff/src/rules/isort/types.rs | 2 +- crates/ruff/src/rules/mccabe/rules.rs | 32 +- crates/ruff/src/rules/pandas_vet/fixes.rs | 8 +- crates/ruff/src/rules/pandas_vet/helpers.rs | 18 +- .../pandas_vet/rules/assignment_to_df.rs | 4 +- .../src/rules/pandas_vet/rules/check_attr.rs | 6 +- .../src/rules/pandas_vet/rules/check_call.rs | 6 +- .../pandas_vet/rules/inplace_argument.rs | 8 +- .../src/rules/pandas_vet/rules/pd_merge.rs | 6 +- crates/ruff/src/rules/pep8_naming/helpers.rs | 14 +- .../rules/error_suffix_on_exception_name.rs | 4 +- ...id_first_argument_name_for_class_method.rs | 2 +- .../invalid_first_argument_name_for_method.rs | 2 +- crates/ruff/src/rules/pycodestyle/helpers.rs | 4 +- .../rules/pycodestyle/rules/bare_except.rs | 4 +- .../src/rules/pycodestyle/rules/errors.rs | 4 +- .../pycodestyle/rules/lambda_assignment.rs | 46 +- .../pycodestyle/rules/literal_comparisons.rs | 18 +- .../src/rules/pycodestyle/rules/not_tests.rs | 7 +- .../pycodestyle/rules/type_comparison.rs | 16 +- .../rules/pydocstyle/rules/no_signature.rs | 4 +- .../src/rules/pydocstyle/rules/sections.rs | 16 +- crates/ruff/src/rules/pyflakes/fixes.rs | 3 +- .../src/rules/pyflakes/rules/assert_tuple.rs | 4 +- .../pyflakes/rules/break_outside_loop.rs | 12 +- .../pyflakes/rules/continue_outside_loop.rs | 12 +- .../pyflakes/rules/default_except_not_last.rs | 5 +- .../rules/f_string_missing_placeholders.rs | 4 +- .../ruff/src/rules/pyflakes/rules/if_tuple.rs | 4 +- .../ruff/src/rules/pyflakes/rules/imports.rs | 2 +- .../pyflakes/rules/invalid_print_syntax.rs | 4 +- .../pyflakes/rules/raise_not_implemented.rs | 8 +- .../src/rules/pyflakes/rules/repeated_keys.rs | 8 +- .../pyflakes/rules/starred_expressions.rs | 2 +- .../ruff/src/rules/pyflakes/rules/strings.rs | 50 +- .../rules/pyflakes/rules/unused_variable.rs | 22 +- .../pyflakes/rules/yield_outside_function.rs | 6 +- .../pygrep_hooks/rules/invalid_mock_access.rs | 10 +- .../src/rules/pygrep_hooks/rules/no_eval.rs | 4 +- .../pylint/rules/assert_on_string_literal.rs | 10 +- .../rules/pylint/rules/bad_str_strip_call.rs | 12 +- .../pylint/rules/bad_string_format_type.rs | 46 +- .../rules/pylint/rules/binary_op_exception.rs | 7 +- .../rules/pylint/rules/collapsible_else_if.rs | 2 +- .../pylint/rules/compare_to_empty_string.rs | 8 +- .../pylint/rules/comparison_of_constant.rs | 12 +- .../rules/pylint/rules/continue_in_finally.rs | 21 +- .../src/rules/pylint/rules/import_self.rs | 4 +- .../pylint/rules/invalid_envvar_default.rs | 21 +- .../pylint/rules/invalid_envvar_value.rs | 19 +- crates/ruff/src/rules/pylint/rules/logging.rs | 10 +- .../pylint/rules/magic_value_comparison.rs | 10 +- .../rules/pylint/rules/manual_import_from.rs | 16 +- .../src/rules/pylint/rules/nested_min_max.rs | 16 +- .../pylint/rules/property_with_parameters.rs | 4 +- .../rules/pylint/rules/redefined_loop_name.rs | 56 +- .../pylint/rules/repeated_isinstance_calls.rs | 10 +- .../src/rules/pylint/rules/return_in_init.rs | 8 +- .../src/rules/pylint/rules/sys_exit_alias.rs | 4 +- .../rules/pylint/rules/too_many_branches.rs | 27 +- .../rules/pylint/rules/too_many_statements.rs | 34 +- .../rules/unnecessary_direct_lambda_call.rs | 2 +- .../pylint/rules/useless_else_on_loop.rs | 34 +- .../src/rules/pylint/rules/useless_return.rs | 12 +- ...convert_named_tuple_functional_to_class.rs | 36 +- .../convert_typed_dict_functional_to_class.rs | 32 +- .../rules/deprecated_c_element_tree.rs | 16 +- .../pyupgrade/rules/deprecated_import.rs | 8 +- .../pyupgrade/rules/deprecated_mock_import.rs | 16 +- .../rules/deprecated_unittest_alias.rs | 6 +- .../src/rules/pyupgrade/rules/f_strings.rs | 12 +- .../rules/lru_cache_with_maxsize_none.rs | 10 +- .../rules/lru_cache_without_parameters.rs | 6 +- .../rules/pyupgrade/rules/native_literals.rs | 12 +- .../rules/pyupgrade/rules/os_error_alias.rs | 22 +- .../pyupgrade/rules/outdated_version_block.rs | 20 +- .../rules/printf_string_formatting.rs | 25 +- .../pyupgrade/rules/redundant_open_modes.rs | 18 +- .../rules/super_call_with_parameters.rs | 26 +- .../pyupgrade/rules/type_of_primitive.rs | 4 +- .../rules/unnecessary_builtin_import.rs | 4 +- .../rules/unnecessary_encode_utf8.rs | 18 +- .../rules/unnecessary_future_import.rs | 8 +- .../rules/unpacked_list_comprehension.rs | 78 +-- .../pyupgrade/rules/use_pep604_annotation.rs | 29 +- .../pyupgrade/rules/use_pep604_isinstance.rs | 15 +- .../pyupgrade/rules/useless_metaclass_type.rs | 6 +- .../rules/useless_object_inheritance.rs | 4 +- .../pyupgrade/rules/yield_in_for_loop.rs | 36 +- .../rules/ruff/rules/asyncio_dangling_task.rs | 4 +- .../rules/collection_literal_concatenation.rs | 28 +- .../mutable_defaults_in_dataclass_fields.rs | 28 +- .../rules/ruff/rules/pairwise_over_zipped.rs | 26 +- crates/ruff/src/rules/tryceratops/helpers.rs | 4 +- .../rules/error_instead_of_exception.rs | 7 +- .../tryceratops/rules/raise_vanilla_args.rs | 10 +- .../tryceratops/rules/raise_vanilla_class.rs | 14 +- .../tryceratops/rules/raise_within_try.rs | 4 +- .../tryceratops/rules/reraise_no_cause.rs | 4 +- .../tryceratops/rules/try_consider_else.rs | 4 +- .../rules/type_check_without_type_error.rs | 30 +- .../tryceratops/rules/verbose_log_message.rs | 18 +- .../rules/tryceratops/rules/verbose_raise.rs | 22 +- crates/ruff_python_ast/Cargo.toml | 3 +- crates/ruff_python_ast/src/all.rs | 42 +- crates/ruff_python_ast/src/call_path.rs | 10 +- crates/ruff_python_ast/src/cast.rs | 11 +- crates/ruff_python_ast/src/comparable.rs | 215 ++++---- crates/ruff_python_ast/src/helpers.rs | 488 +++++++++--------- crates/ruff_python_ast/src/imports.rs | 4 +- crates/ruff_python_ast/src/relocate.rs | 62 +-- .../src/source_code/generator.rs | 256 ++++----- .../src/source_code/stylist.rs | 8 +- .../ruff_python_ast/src/statement_visitor.rs | 32 +- crates/ruff_python_ast/src/typing.rs | 2 +- crates/ruff_python_ast/src/visitor.rs | 152 +++--- crates/ruff_python_ast/src/whitespace.rs | 4 +- crates/ruff_python_formatter/Cargo.toml | 1 - .../ruff_python_formatter/src/cst/helpers.rs | 6 +- crates/ruff_python_formatter/src/cst/mod.rs | 430 ++++++++------- .../src/format/comments.rs | 18 +- .../ruff_python_formatter/src/format/stmt.rs | 2 +- .../src/format/strings.rs | 2 +- .../src/analyze/branch_detection.rs | 19 +- .../src/analyze/logging.rs | 4 +- .../src/analyze/typing.rs | 23 +- .../src/analyze/visibility.rs | 15 +- crates/ruff_python_semantic/src/binding.rs | 2 +- crates/ruff_rustpython/Cargo.toml | 2 - crates/ruff_rustpython/src/lib.rs | 6 +- crates/ruff_rustpython/src/vendor/bytes.rs | 68 --- crates/ruff_rustpython/src/vendor/mod.rs | 2 - crates/ruff_rustpython/src/vendor/str.rs | 182 ------- 270 files changed, 3061 insertions(+), 3361 deletions(-) delete mode 100644 crates/ruff_rustpython/src/vendor/bytes.rs delete mode 100644 crates/ruff_rustpython/src/vendor/mod.rs delete mode 100644 crates/ruff_rustpython/src/vendor/str.rs diff --git a/Cargo.lock b/Cargo.lock index 98183d8a3a..27fbf696fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -144,15 +144,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" -[[package]] -name = "ascii-canvas" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" -dependencies = [ - "term", -] - [[package]] name = "assert_cmd" version = "2.0.11" @@ -200,21 +191,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - [[package]] name = "bitflags" version = "1.3.2" @@ -223,9 +199,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c70beb79cbb5ce9c4f8e20849978f34225931f665bb49efa6982875a4d5facb3" +checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813" [[package]] name = "bstr" @@ -700,16 +676,6 @@ dependencies = [ "dirs-sys 0.4.0", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.7" @@ -732,17 +698,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "doc-comment" version = "0.3.3" @@ -767,15 +722,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" -[[package]] -name = "ena" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" -dependencies = [ - "log", -] - [[package]] name = "encode_unicode" version = "0.3.6" @@ -833,12 +779,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "flake8-to-ruff" version = "0.0.265" @@ -1168,37 +1108,11 @@ dependencies = [ "libc", ] -[[package]] -name = "lalrpop" -version = "0.19.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34313ec00c2eb5c3c87ca6732ea02dcf3af99c3ff7a8fb622ffb99c9d860a87" -dependencies = [ - "ascii-canvas", - "bit-set", - "diff", - "ena", - "is-terminal", - "itertools", - "lalrpop-util", - "petgraph", - "pico-args", - "regex", - "regex-syntax 0.6.29", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", -] - [[package]] name = "lalrpop-util" -version = "0.19.9" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c1f7869c94d214466c5fd432dfed12c379fd87786768d36455892d46b18edd" -dependencies = [ - "regex", -] +checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" [[package]] name = "lazy_static" @@ -1388,12 +1302,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308d96db8debc727c3fd9744aac51751243420e46edf401010908da7f8d5e57c" -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - [[package]] name = "nextest-workspace-hack" version = "0.1.0" @@ -1525,29 +1433,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "windows-sys 0.45.0", -] - [[package]] name = "paste" version = "1.0.12" @@ -1624,23 +1509,13 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" -[[package]] -name = "petgraph" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" -dependencies = [ - "fixedbitset", - "indexmap", -] - [[package]] name = "phf" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" dependencies = [ - "phf_shared 0.11.1", + "phf_shared", ] [[package]] @@ -1650,7 +1525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" dependencies = [ "phf_generator", - "phf_shared 0.11.1", + "phf_shared", ] [[package]] @@ -1659,19 +1534,10 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" dependencies = [ - "phf_shared 0.11.1", + "phf_shared", "rand", ] -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - [[package]] name = "phf_shared" version = "0.11.1" @@ -1681,12 +1547,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pico-args" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468" - [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1738,12 +1598,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "predicates" version = "3.0.3" @@ -1944,7 +1798,7 @@ checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick 1.0.1", "memchr", - "regex-syntax 0.7.1", + "regex-syntax", ] [[package]] @@ -1953,12 +1807,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.7.1" @@ -2008,7 +1856,7 @@ version = "0.0.265" dependencies = [ "annotate-snippets 0.9.1", "anyhow", - "bitflags 2.1.0", + "bitflags 2.2.1", "chrono", "clap 4.2.4", "colored", @@ -2101,7 +1949,7 @@ dependencies = [ "assert_cmd", "atty", "bincode", - "bitflags 2.1.0", + "bitflags 2.2.1", "cachedir", "chrono", "clap 4.2.4", @@ -2200,7 +2048,7 @@ name = "ruff_python_ast" version = "0.0.0" dependencies = [ "anyhow", - "bitflags 2.1.0", + "bitflags 2.2.1", "is-macro", "itertools", "log", @@ -2209,10 +2057,9 @@ dependencies = [ "num-traits", "once_cell", "regex", - "ruff_rustpython", "ruff_text_size", "rustc-hash", - "rustpython-common", + "rustpython-literal 0.2.0 (git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666)", "rustpython-parser", "serde", "smallvec", @@ -2234,7 +2081,6 @@ dependencies = [ "ruff_testing_macros", "ruff_text_size", "rustc-hash", - "rustpython-common", "rustpython-parser", "similar", "test-case", @@ -2244,7 +2090,7 @@ dependencies = [ name = "ruff_python_semantic" version = "0.0.0" dependencies = [ - "bitflags 2.1.0", + "bitflags 2.2.1", "is-macro", "nohash-hasher", "ruff_python_ast", @@ -2268,8 +2114,6 @@ name = "ruff_rustpython" version = "0.0.0" dependencies = [ "anyhow", - "once_cell", - "rustpython-common", "rustpython-parser", ] @@ -2286,7 +2130,7 @@ dependencies = [ [[package]] name = "ruff_text_size" version = "0.0.0" -source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" +source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666" dependencies = [ "schemars", "serde", @@ -2357,75 +2201,92 @@ dependencies = [ [[package]] name = "rustpython-ast" version = "0.2.0" -source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" +source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666" dependencies = [ "num-bigint", - "ruff_text_size", + "rustpython-parser-core", ] [[package]] name = "rustpython-common" version = "0.2.0" -source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" +source = "git+https://github.com/RustPython/RustPython.git?rev=f3e4d3409253660bd4fa7f3d24d3db747e7dca61#f3e4d3409253660bd4fa7f3d24d3db747e7dca61" dependencies = [ "ascii", - "bitflags 1.3.2", + "bitflags 2.2.1", "bstr 0.2.17", "cfg-if", - "getrandom", - "hexf-parse", "itertools", - "lexical-parse-float", "libc", "lock_api", "num-bigint", + "num-complex", "num-traits", "once_cell", "radium", "rand", + "rustpython-literal 0.2.0 (git+https://github.com/youknowone/RustPython-parser.git?rev=5b2af304a2baa53598e594097824165d4ac7a119)", "siphasher", - "unic-ucd-category", "volatile", "widestring", ] [[package]] -name = "rustpython-compiler-core" +name = "rustpython-literal" version = "0.2.0" -source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" +source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666" dependencies = [ - "bitflags 1.3.2", - "itertools", - "lz4_flex", - "num-bigint", - "num-complex", - "ruff_text_size", + "hexf-parse", + "lexical-parse-float", + "num-traits", + "unic-ucd-category", +] + +[[package]] +name = "rustpython-literal" +version = "0.2.0" +source = "git+https://github.com/youknowone/RustPython-parser.git?rev=5b2af304a2baa53598e594097824165d4ac7a119#5b2af304a2baa53598e594097824165d4ac7a119" +dependencies = [ + "hexf-parse", + "lexical-parse-float", + "num-traits", + "unic-ucd-category", ] [[package]] name = "rustpython-parser" version = "0.2.0" -source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" +source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666" dependencies = [ "anyhow", "itertools", - "lalrpop", "lalrpop-util", "log", "num-bigint", "num-traits", "phf", "phf_codegen", - "ruff_text_size", "rustc-hash", "rustpython-ast", - "rustpython-compiler-core", + "rustpython-parser-core", "tiny-keccak", "unic-emoji-char", "unic-ucd-ident", "unicode_names2", ] +[[package]] +name = "rustpython-parser-core" +version = "0.2.0" +source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666" +dependencies = [ + "itertools", + "lz4_flex", + "num-bigint", + "num-complex", + "ruff_text_size", +] + [[package]] name = "rustversion" version = "1.0.12" @@ -2613,19 +2474,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", -] - [[package]] name = "strsim" version = "0.10.0" @@ -2698,17 +2546,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "term" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] - [[package]] name = "termcolor" version = "1.2.0" @@ -3061,12 +2898,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "unicode_names2" version = "0.6.0" diff --git a/Cargo.toml b/Cargo.toml index cc5b1275c7..1e5c8ef846 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ authors = ["Charlie Marsh "] [workspace.dependencies] anyhow = { version = "1.0.69" } -bitflags = { version = "2.1.0" } +bitflags = { version = "2.2.1" } chrono = { version = "0.4.23", default-features = false, features = ["clock"] } clap = { version = "4.1.8", features = ["derive"] } colored = { version = "2.0.0" } @@ -30,10 +30,11 @@ path-absolutize = { version = "3.0.14" } proc-macro2 = { version = "1.0.51" } quote = { version = "1.0.23" } regex = { version = "1.7.1" } -ruff_text_size = { git = "https://github.com/charliermarsh/RustPython.git", rev = "c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" } +ruff_text_size = { git = "https://github.com/RustPython/Parser.git", rev = "2af98056629fbe75ccc0d90c4ee05dfeb403d666" } rustc-hash = { version = "1.1.0" } -rustpython-common = { git = "https://github.com/charliermarsh/RustPython.git", rev = "c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" } -rustpython-parser = { git = "https://github.com/charliermarsh/RustPython.git", rev = "c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" } +rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "f3e4d3409253660bd4fa7f3d24d3db747e7dca61" } +rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "2af98056629fbe75ccc0d90c4ee05dfeb403d666" } +rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "2af98056629fbe75ccc0d90c4ee05dfeb403d666" , default-features = false} schemars = { version = "0.8.12" } serde = { version = "1.0.152", features = ["derive"] } serde_json = { version = "1.0.93", features = ["preserve_order"] } diff --git a/crates/ruff/src/autofix/actions.rs b/crates/ruff/src/autofix/actions.rs index 8b26783edf..84bfa86e39 100644 --- a/crates/ruff/src/autofix/actions.rs +++ b/crates/ruff/src/autofix/actions.rs @@ -5,7 +5,7 @@ use libcst_native::{ Codegen, CodegenState, ImportNames, ParenthesizableWhitespace, SmallStatement, Statement, }; use ruff_text_size::{TextLen, TextRange, TextSize}; -use rustpython_parser::ast::{ExcepthandlerKind, Expr, Keyword, Stmt, StmtKind}; +use rustpython_parser::ast::{self, ExcepthandlerKind, Expr, Keyword, Stmt, StmtKind}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::Edit; @@ -28,21 +28,21 @@ fn has_single_child(body: &[Stmt], deleted: &[&Stmt]) -> bool { /// Determine if a child is the only statement in its body. fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result { match &parent.node { - StmtKind::FunctionDef { body, .. } - | StmtKind::AsyncFunctionDef { body, .. } - | StmtKind::ClassDef { body, .. } - | StmtKind::With { body, .. } - | StmtKind::AsyncWith { body, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { body, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) + | StmtKind::ClassDef(ast::StmtClassDef { body, .. }) + | StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { if body.iter().contains(child) { Ok(has_single_child(body, deleted)) } else { bail!("Unable to find child in parent body") } } - StmtKind::For { body, orelse, .. } - | StmtKind::AsyncFor { body, orelse, .. } - | StmtKind::While { body, orelse, .. } - | StmtKind::If { body, orelse, .. } => { + StmtKind::For(ast::StmtFor { body, orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. }) + | StmtKind::While(ast::StmtWhile { body, orelse, .. }) + | StmtKind::If(ast::StmtIf { body, orelse, .. }) => { if body.iter().contains(child) { Ok(has_single_child(body, deleted)) } else if orelse.iter().contains(child) { @@ -51,18 +51,18 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result bail!("Unable to find child in parent body") } } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { if body.iter().contains(child) { Ok(has_single_child(body, deleted)) } else if orelse.iter().contains(child) { @@ -70,7 +70,9 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result } else if finalbody.iter().contains(child) { Ok(has_single_child(finalbody, deleted)) } else if let Some(body) = handlers.iter().find_map(|handler| match &handler.node { - ExcepthandlerKind::ExceptHandler { body, .. } => { + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + body, .. + }) => { if body.iter().contains(child) { Some(body) } else { @@ -83,7 +85,7 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result bail!("Unable to find child in parent body") } } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { if let Some(body) = cases.iter().find_map(|case| { if case.body.iter().contains(child) { Some(&case.body) @@ -350,7 +352,7 @@ pub fn remove_argument( if n_arguments == 1 { // Case 1: there is only one argument. let mut count: usize = 0; - for (tok, range) in lexer::lex_located(contents, Mode::Module, call_at).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, call_at).flatten() { if matches!(tok, Tok::Lpar) { if count == 0 { fix_start = Some(if remove_parentheses { @@ -382,7 +384,7 @@ pub fn remove_argument( { // Case 2: argument or keyword is _not_ the last node. let mut seen_comma = false; - for (tok, range) in lexer::lex_located(contents, Mode::Module, call_at).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, call_at).flatten() { if seen_comma { if matches!(tok, Tok::NonLogicalNewline) { // Also delete any non-logical newlines after the comma. @@ -405,7 +407,7 @@ pub fn remove_argument( } else { // Case 3: argument or keyword is the last node, so we have to find the last // comma in the stmt. - for (tok, range) in lexer::lex_located(contents, Mode::Module, call_at).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, call_at).flatten() { if range.start() == expr_range.start() { fix_end = Some(expr_range.end()); break; diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index 2909c19b11..632d03aa9d 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -6,8 +6,9 @@ use ruff_text_size::{TextRange, TextSize}; use rustc_hash::{FxHashMap, FxHashSet}; use rustpython_common::cformat::{CFormatError, CFormatErrorType}; use rustpython_parser::ast::{ - Arg, Arguments, Comprehension, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprContext, - ExprKind, KeywordData, Located, Operator, Pattern, PatternKind, Stmt, StmtKind, Suite, Unaryop, + self, Arg, Arguments, Attributed, Comprehension, Constant, Excepthandler, ExcepthandlerKind, + Expr, ExprContext, ExprKind, KeywordData, Operator, Pattern, PatternKind, Stmt, StmtKind, + Suite, Unaryop, }; use ruff_diagnostics::{Diagnostic, Fix}; @@ -176,7 +177,7 @@ where // Track whether we've seen docstrings, non-imports, etc. match &stmt.node { - StmtKind::ImportFrom { module, .. } => { + StmtKind::ImportFrom(ast::StmtImportFrom { module, .. }) => { // Allow __future__ imports until we see a non-__future__ import. if self.ctx.futures_allowed { if let Some(module) = module { @@ -186,7 +187,7 @@ where } } } - StmtKind::Import { .. } => { + StmtKind::Import(_) => { self.ctx.futures_allowed = false; } _ => { @@ -201,10 +202,7 @@ where } // Track each top-level import, to guide import insertions. - if matches!( - &stmt.node, - StmtKind::Import { .. } | StmtKind::ImportFrom { .. } - ) { + if matches!(&stmt.node, StmtKind::Import(_) | StmtKind::ImportFrom(_)) { if self.ctx.at_top_level() { self.importer.visit_import(stmt); } @@ -212,7 +210,7 @@ where // Pre-visit. match &stmt.node { - StmtKind::Global { names } => { + StmtKind::Global(ast::StmtGlobal { names }) => { let ranges: Vec = helpers::find_names(stmt, self.locator).collect(); if !self.ctx.scope_id.is_global() { // Add the binding to the current scope. @@ -242,7 +240,7 @@ where })); } } - StmtKind::Nonlocal { names } => { + StmtKind::Nonlocal(ast::StmtNonlocal { names }) => { let ranges: Vec = helpers::find_names(stmt, self.locator).collect(); if !self.ctx.scope_id.is_global() { let context = self.ctx.execution_context(); @@ -317,22 +315,22 @@ where } } } - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, decorator_list, returns, args, body, .. - } - | StmtKind::AsyncFunctionDef { + }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, decorator_list, returns, args, body, .. - } => { + }) => { if self .settings .rules @@ -690,7 +688,7 @@ where }, ); } - StmtKind::Return { .. } => { + StmtKind::Return(_) => { if self.settings.rules.enabled(Rule::ReturnOutsideFunction) { pyflakes::rules::return_outside_function(self, stmt); } @@ -698,13 +696,13 @@ where pylint::rules::return_in_init(self, stmt); } } - StmtKind::ClassDef { + StmtKind::ClassDef(ast::StmtClassDef { name, bases, keywords, decorator_list, body, - } => { + }) => { if self .settings .rules @@ -859,7 +857,7 @@ where self.visit_expr(expr); } } - StmtKind::Import { names } => { + StmtKind::Import(ast::StmtImport { names }) => { if self.settings.rules.enabled(Rule::MultipleImportsOnOneLine) { pycodestyle::rules::multiple_imports_on_one_line(self, stmt, names); } @@ -889,7 +887,7 @@ where } for alias in names { - if alias.node.name == "__future__" { + if &alias.node.name == "__future__" { let name = alias.node.asname.as_ref().unwrap_or(&alias.node.name); self.add_binding( name, @@ -1120,11 +1118,13 @@ where } } } - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { names, module, level, - } => { + }) => { + let module = module.as_deref(); + let level = level.map(|level| level.to_u32()); if self .settings .rules @@ -1146,7 +1146,7 @@ where if self.settings.rules.enabled(Rule::UnnecessaryFutureImport) && self.settings.target_version >= PythonVersion::Py37 { - if let Some("__future__") = module.as_deref() { + if let Some("__future__") = module { pyupgrade::rules::unnecessary_future_import(self, stmt, names); } } @@ -1157,24 +1157,18 @@ where pyupgrade::rules::deprecated_c_element_tree(self, stmt); } if self.settings.rules.enabled(Rule::DeprecatedImport) { - pyupgrade::rules::deprecated_import( - self, - stmt, - names, - module.as_ref().map(String::as_str), - *level, - ); + pyupgrade::rules::deprecated_import(self, stmt, names, module, level); } if self.settings.rules.enabled(Rule::UnnecessaryBuiltinImport) { - if let Some(module) = module.as_deref() { + if let Some(module) = module { pyupgrade::rules::unnecessary_builtin_import(self, stmt, module, names); } } if self.settings.rules.enabled(Rule::BannedApi) { if let Some(module) = helpers::resolve_imported_module_path( - *level, - module.as_deref(), + level, + module, self.module_path.as_deref(), ) { flake8_tidy_imports::banned_api::name_or_parent_is_banned( @@ -1182,7 +1176,7 @@ where ); for alias in names { - if alias.node.name == "*" { + if &alias.node.name == "*" { continue; } flake8_tidy_imports::banned_api::name_is_banned( @@ -1200,14 +1194,14 @@ where .enabled(Rule::PytestIncorrectPytestImport) { if let Some(diagnostic) = - flake8_pytest_style::rules::import_from(stmt, module.as_deref(), *level) + flake8_pytest_style::rules::import_from(stmt, module, level) { self.diagnostics.push(diagnostic); } } for alias in names { - if let Some("__future__") = module.as_deref() { + if let Some("__future__") = module { let name = alias.node.asname.as_ref().unwrap_or(&alias.node.name); self.add_binding( name, @@ -1224,7 +1218,7 @@ where }, ); - if alias.node.name == "annotations" { + if &alias.node.name == "annotations" { self.ctx.annotations_future_enabled = true; } @@ -1240,11 +1234,10 @@ where stmt.range(), )); } - } else if alias.node.name == "*" { - self.ctx.scope_mut().add_star_import(StarImportation { - module: module.as_ref().map(String::as_str), - level: *level, - }); + } else if &alias.node.name == "*" { + self.ctx + .scope_mut() + .add_star_import(StarImportation { level, module }); if self .settings @@ -1255,10 +1248,7 @@ where if !matches!(scope.kind, ScopeKind::Module) { self.diagnostics.push(Diagnostic::new( pyflakes::rules::UndefinedLocalWithNestedImportStarUsage { - name: helpers::format_import_from( - *level, - module.as_deref(), - ), + name: helpers::format_import_from(level, module), }, stmt.range(), )); @@ -1272,7 +1262,7 @@ where { self.diagnostics.push(Diagnostic::new( pyflakes::rules::UndefinedLocalWithImportStar { - name: helpers::format_import_from(*level, module.as_deref()), + name: helpers::format_import_from(level, module), }, stmt.range(), )); @@ -1294,11 +1284,8 @@ where // be "foo.bar". Given `from foo import bar as baz`, `name` would be "baz" // and `full_name` would be "foo.bar". let name = alias.node.asname.as_ref().unwrap_or(&alias.node.name); - let full_name = helpers::format_import_from_member( - *level, - module.as_deref(), - &alias.node.name, - ); + let full_name = + helpers::format_import_from_member(level, module, &alias.node.name); self.add_binding( name, Binding { @@ -1326,8 +1313,8 @@ where flake8_tidy_imports::relative_imports::banned_relative_import( self, stmt, - *level, - module.as_deref(), + level, + module, self.module_path.as_deref(), &self.settings.flake8_tidy_imports.ban_relative_imports, ) @@ -1338,21 +1325,16 @@ where // flake8-debugger if self.settings.rules.enabled(Rule::Debugger) { - if let Some(diagnostic) = flake8_debugger::rules::debugger_import( - stmt, - module.as_deref(), - &alias.node.name, - ) { + if let Some(diagnostic) = + flake8_debugger::rules::debugger_import(stmt, module, &alias.node.name) + { self.diagnostics.push(diagnostic); } } if self.settings.rules.enabled(Rule::UnconventionalImportAlias) { - let full_name = helpers::format_import_from_member( - *level, - module.as_deref(), - &alias.node.name, - ); + let full_name = + helpers::format_import_from_member(level, module, &alias.node.name); if let Some(diagnostic) = flake8_import_conventions::rules::conventional_import_alias( stmt, @@ -1367,11 +1349,8 @@ where if self.settings.rules.enabled(Rule::BannedImportAlias) { if let Some(asname) = &alias.node.asname { - let full_name = helpers::format_import_from_member( - *level, - module.as_deref(), - &alias.node.name, - ); + let full_name = + helpers::format_import_from_member(level, module, &alias.node.name); if let Some(diagnostic) = flake8_import_conventions::rules::banned_import_alias( stmt, @@ -1482,8 +1461,8 @@ where if self.settings.rules.enabled(Rule::ImportSelf) { if let Some(diagnostic) = pylint::rules::import_from_self( - *level, - module.as_deref(), + level, + module, names, self.module_path.as_deref(), ) { @@ -1494,14 +1473,14 @@ where if self.settings.rules.enabled(Rule::BannedImportFrom) { if let Some(diagnostic) = flake8_import_conventions::rules::banned_import_from( stmt, - &helpers::format_import_from(*level, module.as_deref()), + &helpers::format_import_from(level, module), &self.settings.flake8_import_conventions.banned_from, ) { self.diagnostics.push(diagnostic); } } } - StmtKind::Raise { exc, .. } => { + StmtKind::Raise(ast::StmtRaise { exc, .. }) => { if self.settings.rules.enabled(Rule::RaiseNotImplemented) { if let Some(expr) = exc { pyflakes::rules::raise_not_implemented(self, expr); @@ -1546,16 +1525,16 @@ where } } } - StmtKind::AugAssign { target, .. } => { + StmtKind::AugAssign(ast::StmtAugAssign { target, .. }) => { self.handle_node_load(target); if self.settings.rules.enabled(Rule::GlobalStatement) { - if let ExprKind::Name { id, .. } = &target.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { pylint::rules::global_statement(self, id); } } } - StmtKind::If { test, body, orelse } => { + StmtKind::If(ast::StmtIf { test, body, orelse }) => { if self.settings.rules.enabled(Rule::IfTuple) { pyflakes::rules::if_tuple(self, stmt, test); } @@ -1630,7 +1609,7 @@ where } } } - StmtKind::Assert { test, msg } => { + StmtKind::Assert(ast::StmtAssert { test, msg }) => { if !self.ctx.in_type_checking_block { if self.settings.rules.enabled(Rule::Assert) { self.diagnostics @@ -1661,7 +1640,7 @@ where pygrep_hooks::rules::non_existent_mock_method(self, test); } } - StmtKind::With { items, body, .. } => { + StmtKind::With(ast::StmtWith { items, body, .. }) => { if self.settings.rules.enabled(Rule::AssertRaisesException) { flake8_bugbear::rules::assert_raises_exception(self, stmt, items); } @@ -1684,7 +1663,7 @@ where pylint::rules::redefined_loop_name(self, &Node::Stmt(stmt)); } } - StmtKind::While { body, orelse, .. } => { + StmtKind::While(ast::StmtWhile { body, orelse, .. }) => { if self.settings.rules.enabled(Rule::FunctionUsesLoopVariable) { flake8_bugbear::rules::function_uses_loop_variable(self, &Node::Stmt(stmt)); } @@ -1692,20 +1671,20 @@ where pylint::rules::useless_else_on_loop(self, stmt, body, orelse); } } - StmtKind::For { + StmtKind::For(ast::StmtFor { target, body, iter, orelse, .. - } - | StmtKind::AsyncFor { + }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { target, body, iter, orelse, .. - } => { + }) => { if self.settings.rules.enabled(Rule::UnusedLoopControlVariable) { self.deferred.for_loops.push(self.ctx.snapshot()); } @@ -1728,7 +1707,7 @@ where if self.settings.rules.enabled(Rule::RedefinedLoopName) { pylint::rules::redefined_loop_name(self, &Node::Stmt(stmt)); } - if matches!(stmt.node, StmtKind::For { .. }) { + if matches!(stmt.node, StmtKind::For(_)) { if self.settings.rules.enabled(Rule::ReimplementedBuiltin) { flake8_simplify::rules::convert_for_loop_to_any_all( self, @@ -1741,20 +1720,18 @@ where } } } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - .. - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - .. - } => { + }) => { if self.settings.rules.enabled(Rule::DefaultExceptNotLast) { if let Some(diagnostic) = pyflakes::rules::default_except_not_last(handlers, self.locator) @@ -1809,7 +1786,7 @@ where tryceratops::rules::error_instead_of_exception(self, handlers); } } - StmtKind::Assign { targets, value, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { if self.settings.rules.enabled(Rule::LambdaAssignment) { if let [target] = &targets[..] { pycodestyle::rules::lambda_assignment(self, target, value, None, stmt); @@ -1830,7 +1807,7 @@ where if self.settings.rules.enabled(Rule::GlobalStatement) { for target in targets.iter() { - if let ExprKind::Name { id, .. } = &target.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { pylint::rules::global_statement(self, id); } } @@ -1885,12 +1862,12 @@ where } } } - StmtKind::AnnAssign { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, value, annotation, .. - } => { + }) => { if self.settings.rules.enabled(Rule::LambdaAssignment) { if let Some(value) = value { pycodestyle::rules::lambda_assignment( @@ -1935,16 +1912,16 @@ where } } } - StmtKind::Delete { targets } => { + StmtKind::Delete(ast::StmtDelete { targets }) => { if self.settings.rules.enabled(Rule::GlobalStatement) { for target in targets.iter() { - if let ExprKind::Name { id, .. } = &target.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { pylint::rules::global_statement(self, id); } } } } - StmtKind::Expr { value, .. } => { + StmtKind::Expr(ast::StmtExpr { value }) => { if self.settings.rules.enabled(Rule::UselessComparison) { flake8_bugbear::rules::useless_comparison(self, value); } @@ -1969,20 +1946,20 @@ where let prev_in_exception_handler = self.ctx.in_exception_handler; let prev_visible_scope = self.ctx.visible_scope; match &stmt.node { - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { body, name, args, decorator_list, .. - } - | StmtKind::AsyncFunctionDef { + }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, name, args, decorator_list, .. - } => { + }) => { if self.settings.rules.enabled(Rule::FStringDocstring) { flake8_bugbear::rules::f_string_docstring(self, body); } @@ -2029,7 +2006,7 @@ where body, args, decorator_list, - async_: matches!(stmt.node, StmtKind::AsyncFunctionDef { .. }), + async_: matches!(stmt.node, StmtKind::AsyncFunctionDef(_)), globals, })); @@ -2037,14 +2014,13 @@ where .functions .push((self.ctx.snapshot(), self.ctx.visible_scope)); } - StmtKind::ClassDef { + StmtKind::ClassDef(ast::StmtClassDef { body, name, bases, keywords, decorator_list, - .. - } => { + }) => { if self.settings.rules.enabled(Rule::FStringDocstring) { flake8_bugbear::rules::f_string_docstring(self, body); } @@ -2093,18 +2069,18 @@ where self.visit_body(body); } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { let mut handled_exceptions = Exceptions::empty(); for type_ in extract_handled_exceptions(handlers) { if let Some(call_path) = self.ctx.resolve_call_path(type_) { @@ -2140,12 +2116,12 @@ where self.visit_body(orelse); self.visit_body(finalbody); } - StmtKind::AnnAssign { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, annotation, value, .. - } => { + }) => { // If we're in a class or module scope, then the annotation needs to be // available at runtime. // See: https://docs.python.org/3/reference/simple_stmts.html#annotated-assignment-statements @@ -2188,18 +2164,18 @@ where } self.visit_expr(target); } - StmtKind::Assert { test, msg } => { + StmtKind::Assert(ast::StmtAssert { test, msg }) => { visit_boolean_test!(self, test); if let Some(expr) = msg { self.visit_expr(expr); } } - StmtKind::While { test, body, orelse } => { + StmtKind::While(ast::StmtWhile { test, body, orelse }) => { visit_boolean_test!(self, test); self.visit_body(body); self.visit_body(orelse); } - StmtKind::If { test, body, orelse } => { + StmtKind::If(ast::StmtIf { test, body, orelse }) => { visit_boolean_test!(self, test); if flake8_type_checking::helpers::is_type_checking_block(&self.ctx, test) { @@ -2223,10 +2199,10 @@ where // Post-visit. match &stmt.node { - StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) => { self.ctx.pop_scope(); } - StmtKind::ClassDef { name, .. } => { + StmtKind::ClassDef(ast::StmtClassDef { name, .. }) => { self.ctx.pop_scope(); self.add_binding( name, @@ -2262,10 +2238,10 @@ where && self.ctx.in_type_definition && self.ctx.annotations_future_enabled { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &expr.node + }) = &expr.node { self.deferred.string_type_definitions.push(( expr.range(), @@ -2290,18 +2266,18 @@ where // subexpression (e.g., `a` in `f(a)`), then we're no longer in a boolean test. if !matches!( expr.node, - ExprKind::BoolOp { .. } - | ExprKind::UnaryOp { + ExprKind::BoolOp(_) + | ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::Not, .. - } + }) ) { self.ctx.in_boolean_test = false; } // Pre-visit. match &expr.node { - ExprKind::Subscript { value, slice, .. } => { + ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => { // Ex) Optional[...], Union[...] if !self.settings.pyupgrade.keep_runtime_typing && self.settings.rules.enabled(Rule::NonPEP604Annotation) @@ -2334,7 +2310,8 @@ where flake8_simplify::rules::use_capital_environment_variables(self, expr); } } - ExprKind::Tuple { elts, ctx } | ExprKind::List { elts, ctx } => { + ExprKind::Tuple(ast::ExprTuple { elts, ctx }) + | ExprKind::List(ast::ExprList { elts, ctx }) => { if matches!(ctx, ExprContext::Store) { let check_too_many_expressions = self .settings @@ -2354,7 +2331,7 @@ where } } } - ExprKind::Name { id, ctx } => { + ExprKind::Name(ast::ExprName { id, ctx }) => { match ctx { ExprContext::Load => { if self.settings.rules.enabled(Rule::TypingTextStrAlias) { @@ -2406,7 +2383,7 @@ where pylint::rules::load_before_global_declaration(self, id, expr); } } - ExprKind::Attribute { attr, value, .. } => { + ExprKind::Attribute(ast::ExprAttribute { attr, value, .. }) => { // Ex) typing.List[...] if !self.settings.pyupgrade.keep_runtime_typing && self.settings.rules.enabled(Rule::NonPEP585Annotation) @@ -2443,11 +2420,11 @@ where } pandas_vet::rules::check_attr(self, attr, value, expr); } - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { + }) => { if self.settings.rules.any_enabled(&[ // pyflakes Rule::StringDotFormatInvalidFormat, @@ -2461,11 +2438,13 @@ where // flynt Rule::StaticJoinToFString, ]) { - if let ExprKind::Attribute { value, attr, .. } = &func.node { - if let ExprKind::Constant { + if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node + { + let attr = attr.as_str(); + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &value.node + }) = &value.node { if attr == "join" { // "...".join(...) call @@ -2877,7 +2856,7 @@ where self, args, func, ); } - if let ExprKind::Name { id, ctx } = &func.node { + if let ExprKind::Name(ast::ExprName { id, ctx }) = &func.node { if id == "locals" && matches!(ctx, ExprContext::Load) { let scope = self.ctx.scope_mut(); scope.uses_locals = true; @@ -3152,7 +3131,7 @@ where flake8_django::rules::locals_in_render_function(self, func, args, keywords); } } - ExprKind::Dict { keys, values } => { + ExprKind::Dict(ast::ExprDict { keys, values }) => { if self.settings.rules.any_enabled(&[ Rule::MultiValueRepeatedKeyLiteral, Rule::MultiValueRepeatedKeyVariable, @@ -3164,7 +3143,7 @@ where flake8_pie::rules::unnecessary_spread(self, keys, values); } } - ExprKind::Yield { .. } => { + ExprKind::Yield(_) => { if self.settings.rules.enabled(Rule::YieldOutsideFunction) { pyflakes::rules::yield_outside_function(self, expr); } @@ -3172,7 +3151,7 @@ where pylint::rules::yield_in_init(self, expr); } } - ExprKind::YieldFrom { .. } => { + ExprKind::YieldFrom(_) => { if self.settings.rules.enabled(Rule::YieldOutsideFunction) { pyflakes::rules::yield_outside_function(self, expr); } @@ -3180,7 +3159,7 @@ where pylint::rules::yield_in_init(self, expr); } } - ExprKind::Await { .. } => { + ExprKind::Await(_) => { if self.settings.rules.enabled(Rule::YieldOutsideFunction) { pyflakes::rules::yield_outside_function(self, expr); } @@ -3188,7 +3167,7 @@ where pylint::rules::await_outside_async(self, expr); } } - ExprKind::JoinedStr { values } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { if self .settings .rules @@ -3200,24 +3179,24 @@ where flake8_bandit::rules::hardcoded_sql_expression(self, expr); } } - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::RShift, .. - } => { + }) => { if self.settings.rules.enabled(Rule::InvalidPrintSyntax) { pyflakes::rules::invalid_print_syntax(self, left); } } - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::Mod, right, - } => { - if let ExprKind::Constant { + }) => { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &left.node + }) = &left.node { if self.settings.rules.any_enabled(&[ Rule::PercentFormatInvalidFormat, @@ -3342,9 +3321,9 @@ where } } } - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { op: Operator::Add, .. - } => { + }) => { if self .settings .rules @@ -3365,20 +3344,20 @@ where flake8_bandit::rules::hardcoded_sql_expression(self, expr); } } - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { op: Operator::BitOr, .. - } => { + }) => { if self.is_stub { if self.settings.rules.enabled(Rule::DuplicateUnionMember) && self.ctx.in_type_definition && self.ctx.expr_parent().map_or(true, |parent| { !matches!( parent.node, - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { op: Operator::BitOr, .. - } + }) ) }) { @@ -3386,7 +3365,7 @@ where } } } - ExprKind::UnaryOp { op, operand } => { + ExprKind::UnaryOp(ast::ExprUnaryOp { op, operand }) => { let check_not_in = self.settings.rules.enabled(Rule::NotInTest); let check_not_is = self.settings.rules.enabled(Rule::NotIsTest); if check_not_in || check_not_is { @@ -3414,11 +3393,11 @@ where flake8_simplify::rules::double_negation(self, expr, op, operand); } } - ExprKind::Compare { + ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } => { + }) => { let check_none_comparisons = self.settings.rules.enabled(Rule::NoneComparison); let check_true_false_comparisons = self.settings.rules.enabled(Rule::TrueFalseComparison); @@ -3512,10 +3491,10 @@ where } } } - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), kind, - } => { + }) => { if self.ctx.in_type_definition && !self.ctx.in_literal && !self.ctx.in_f_string { self.deferred.string_type_definitions.push(( expr.range(), @@ -3547,7 +3526,7 @@ where pyupgrade::rules::unicode_kind_prefix(self, expr, kind.as_deref()); } } - ExprKind::Lambda { args, body, .. } => { + ExprKind::Lambda(ast::ExprLambda { args, body }) => { if self.settings.rules.enabled(Rule::ReimplementedListBuiltin) { flake8_pie::rules::reimplemented_list_builtin(self, expr); } @@ -3562,7 +3541,7 @@ where self.ctx .push_scope(ScopeKind::Lambda(Lambda { args, body })); } - ExprKind::IfExp { test, body, orelse } => { + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { if self.settings.rules.enabled(Rule::IfExprWithTrueFalse) { flake8_simplify::rules::explicit_true_false_in_ifexpr( self, expr, test, body, orelse, @@ -3577,7 +3556,8 @@ where flake8_simplify::rules::twisted_arms_in_ifexpr(self, expr, test, body, orelse); } } - ExprKind::ListComp { elt, generators } | ExprKind::SetComp { elt, generators } => { + ExprKind::ListComp(ast::ExprListComp { elt, generators }) + | ExprKind::SetComp(ast::ExprSetComp { elt, generators }) => { if self.settings.rules.enabled(Rule::UnnecessaryComprehension) { flake8_comprehensions::rules::unnecessary_list_set_comprehension( self, expr, elt, generators, @@ -3588,11 +3568,11 @@ where } self.ctx.push_scope(ScopeKind::Generator); } - ExprKind::DictComp { + ExprKind::DictComp(ast::ExprDictComp { key, value, generators, - } => { + }) => { if self.settings.rules.enabled(Rule::UnnecessaryComprehension) { flake8_comprehensions::rules::unnecessary_dict_comprehension( self, expr, key, value, generators, @@ -3603,13 +3583,13 @@ where } self.ctx.push_scope(ScopeKind::Generator); } - ExprKind::GeneratorExp { .. } => { + ExprKind::GeneratorExp(_) => { if self.settings.rules.enabled(Rule::FunctionUsesLoopVariable) { flake8_bugbear::rules::function_uses_loop_variable(self, &Node::Expr(expr)); } self.ctx.push_scope(ScopeKind::Generator); } - ExprKind::BoolOp { op, values } => { + ExprKind::BoolOp(ast::ExprBoolOp { op, values }) => { if self.settings.rules.enabled(Rule::RepeatedIsinstanceCalls) { pylint::rules::repeated_isinstance_calls(self, expr, op, values); } @@ -3640,19 +3620,19 @@ where // Recurse. match &expr.node { - ExprKind::Lambda { .. } => { + ExprKind::Lambda(_) => { self.deferred.lambdas.push((expr, self.ctx.snapshot())); } - ExprKind::IfExp { test, body, orelse } => { + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { visit_boolean_test!(self, test); self.visit_expr(body); self.visit_expr(orelse); } - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { + }) => { let callable = self.ctx.resolve_call_path(func).and_then(|call_path| { if self.ctx.match_typing_call_path(&call_path, "cast") { Some(Callable::Cast) @@ -3729,11 +3709,12 @@ where // Ex) NamedTuple("a", [("a", int)]) if args.len() > 1 { match &args[1].node { - ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { for elt in elts { match &elt.node { - ExprKind::List { elts, .. } - | ExprKind::Tuple { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { if elts.len() == 2 { visit_non_type_definition!(self, &elts[0]); visit_type_definition!(self, &elts[1]); @@ -3758,7 +3739,7 @@ where // Ex) TypedDict("a", {"a": int}) if args.len() > 1 { - if let ExprKind::Dict { keys, values } = &args[1].node { + if let ExprKind::Dict(ast::ExprDict { keys, values }) = &args[1].node { for key in keys.iter().flatten() { visit_non_type_definition!(self, key); } @@ -3815,7 +3796,7 @@ where } } } - ExprKind::Subscript { value, slice, ctx } => { + ExprKind::Subscript(ast::ExprSubscript { value, slice, ctx }) => { // Only allow annotations in `ExprContext::Load`. If we have, e.g., // `obj["foo"]["bar"]`, we need to avoid treating the `obj["foo"]` // portion as an annotation, despite having `ExprContext::Load`. Thus, we track @@ -3845,7 +3826,9 @@ where // First argument is a type (including forward references); the // rest are arbitrary Python objects. self.visit_expr(value); - if let ExprKind::Tuple { elts, ctx } = &slice.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, ctx }) = + &slice.node + { if let Some(expr) = elts.first() { self.visit_expr(expr); for expr in elts.iter().skip(1) { @@ -3867,7 +3850,7 @@ where } self.ctx.in_subscript = prev_in_subscript; } - ExprKind::JoinedStr { .. } => { + ExprKind::JoinedStr(_) => { let prev_in_f_string = self.ctx.in_f_string; self.ctx.in_f_string = true; visitor::walk_expr(self, expr); @@ -3878,11 +3861,11 @@ where // Post-visit. match &expr.node { - ExprKind::Lambda { .. } - | ExprKind::GeneratorExp { .. } - | ExprKind::ListComp { .. } - | ExprKind::DictComp { .. } - | ExprKind::SetComp { .. } => { + ExprKind::Lambda(_) + | ExprKind::GeneratorExp(_) + | ExprKind::ListComp(_) + | ExprKind::DictComp(_) + | ExprKind::SetComp(_) => { self.ctx.pop_scope(); } _ => {} @@ -3912,9 +3895,12 @@ where fn visit_excepthandler(&mut self, excepthandler: &'b Excepthandler) { match &excepthandler.node { - ExcepthandlerKind::ExceptHandler { - type_, name, body, .. - } => { + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + type_, + name, + body, + }) => { + let name = name.as_deref(); if self.settings.rules.enabled(Rule::BareExcept) { if let Some(diagnostic) = pycodestyle::rules::bare_except( type_.as_deref(), @@ -3933,19 +3919,14 @@ where flake8_bugbear::rules::raise_without_from_inside_except(self, body); } if self.settings.rules.enabled(Rule::BlindExcept) { - flake8_blind_except::rules::blind_except( - self, - type_.as_deref(), - name.as_deref(), - body, - ); + flake8_blind_except::rules::blind_except(self, type_.as_deref(), name, body); } if self.settings.rules.enabled(Rule::TryExceptPass) { flake8_bandit::rules::try_except_pass( self, excepthandler, type_.as_deref(), - name.as_deref(), + name, body, self.settings.flake8_bandit.check_typed_exception, ); @@ -3955,7 +3936,7 @@ where self, excepthandler, type_.as_deref(), - name.as_deref(), + name, body, self.settings.flake8_bandit.check_typed_exception, ); @@ -3994,28 +3975,28 @@ where let name_range = helpers::excepthandler_name_range(excepthandler, self.locator).unwrap(); - if self.ctx.scope().defines(name.as_str()) { + if self.ctx.scope().defines(name) { self.handle_node_store( name, - &Expr::with_range( - ExprKind::Name { - id: name.to_string(), - ctx: ExprContext::Store, - }, + &Expr::new( name_range, + ExprKind::Name(ast::ExprName { + id: name.into(), + ctx: ExprContext::Store, + }), ), ); } - let definition = self.ctx.scope().get(name.as_str()).copied(); + let definition = self.ctx.scope().get(name).copied(); self.handle_node_store( name, - &Expr::with_range( - ExprKind::Name { - id: name.to_string(), - ctx: ExprContext::Store, - }, + &Expr::new( name_range, + ExprKind::Name(ast::ExprName { + id: name.into(), + ctx: ExprContext::Store, + }), ), ); @@ -4023,14 +4004,12 @@ where if let Some(index) = { let scope = self.ctx.scope_mut(); - &scope.remove(name.as_str()) + &scope.remove(name) } { if !self.ctx.bindings[*index].used() { if self.settings.rules.enabled(Rule::UnusedVariable) { let mut diagnostic = Diagnostic::new( - pyflakes::rules::UnusedVariable { - name: name.to_string(), - }, + pyflakes::rules::UnusedVariable { name: name.into() }, name_range, ); if self.patch(Rule::UnusedVariable) { @@ -4060,7 +4039,7 @@ where fn visit_format_spec(&mut self, format_spec: &'b Expr) { match &format_spec.node { - ExprKind::JoinedStr { values } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { for value in values { self.visit_expr(value); } @@ -4154,13 +4133,13 @@ where } fn visit_pattern(&mut self, pattern: &'b Pattern) { - if let PatternKind::MatchAs { + if let PatternKind::MatchAs(ast::PatternMatchAs { name: Some(name), .. - } - | PatternKind::MatchStar { name: Some(name) } - | PatternKind::MatchMapping { + }) + | PatternKind::MatchStar(ast::PatternMatchStar { name: Some(name) }) + | PatternKind::MatchMapping(ast::PatternMatchMapping { rest: Some(name), .. - } = &pattern.node + }) = &pattern.node { self.add_binding( name, @@ -4276,7 +4255,7 @@ impl<'a> Checker<'a> { ); if let Some(parent) = binding.source { let parent = self.ctx.stmts[parent]; - if matches!(parent.node, StmtKind::ImportFrom { .. }) + if matches!(parent.node, StmtKind::ImportFrom(_)) && parent.range().contains_range(binding.range) { diagnostic.set_parent(parent.start()); @@ -4376,9 +4355,10 @@ impl<'a> Checker<'a> { } fn handle_node_load(&mut self, expr: &Expr) { - let ExprKind::Name { id, .. } = &expr.node else { + let ExprKind::Name(ast::ExprName { id, .. } )= &expr.node else { return; }; + let id = id.as_str(); let mut first_iter = true; let mut in_generator = false; @@ -4393,7 +4373,7 @@ impl<'a> Checker<'a> { } } - if let Some(index) = scope.get(id.as_str()) { + if let Some(index) = scope.get(id) { // Mark the binding as used. let context = self.ctx.execution_context(); self.ctx.bindings[*index].mark_used(self.ctx.scope_id, expr.range(), context); @@ -4514,7 +4494,9 @@ impl<'a> Checker<'a> { } self.diagnostics.push(Diagnostic::new( - pyflakes::rules::UndefinedName { name: id.clone() }, + pyflakes::rules::UndefinedName { + name: id.to_string(), + }, expr.range(), )); } @@ -4571,7 +4553,10 @@ impl<'a> Checker<'a> { } } - if matches!(parent.node, StmtKind::AnnAssign { value: None, .. }) { + if matches!( + parent.node, + StmtKind::AnnAssign(ast::StmtAnnAssign { value: None, .. }) + ) { self.add_binding( id, Binding { @@ -4588,10 +4573,7 @@ impl<'a> Checker<'a> { return; } - if matches!( - parent.node, - StmtKind::For { .. } | StmtKind::AsyncFor { .. } - ) { + if matches!(parent.node, StmtKind::For(_) | StmtKind::AsyncFor(_)) { self.add_binding( id, Binding { @@ -4631,12 +4613,12 @@ impl<'a> Checker<'a> { && scope.kind.is_module() && matches!( parent.node, - StmtKind::Assign { .. } | StmtKind::AugAssign { .. } | StmtKind::AnnAssign { .. } + StmtKind::Assign(_) | StmtKind::AugAssign(_) | StmtKind::AnnAssign(_) ) { if match &parent.node { - StmtKind::Assign { targets, .. } => { - if let Some(ExprKind::Name { id, .. }) = + StmtKind::Assign(ast::StmtAssign { targets, .. }) => { + if let Some(ExprKind::Name(ast::ExprName { id, .. })) = targets.first().map(|target| &target.node) { id == "__all__" @@ -4644,15 +4626,15 @@ impl<'a> Checker<'a> { false } } - StmtKind::AugAssign { target, .. } => { - if let ExprKind::Name { id, .. } = &target.node { + StmtKind::AugAssign(ast::StmtAugAssign { target, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { id == "__all__" } else { false } } - StmtKind::AnnAssign { target, .. } => { - if let ExprKind::Name { id, .. } = &target.node { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { id == "__all__" } else { false @@ -4665,7 +4647,7 @@ impl<'a> Checker<'a> { extract_all_names(parent, |name| self.ctx.is_builtin(name)); // Grab the existing bound __all__ values. - if let StmtKind::AugAssign { .. } = &parent.node { + if let StmtKind::AugAssign(_) = &parent.node { if let Some(index) = scope.get("__all__") { if let BindingKind::Export(Export { names: existing }) = &self.ctx.bindings[*index].kind @@ -4712,7 +4694,7 @@ impl<'a> Checker<'a> { if self .ctx .expr_ancestors() - .any(|expr| matches!(expr.node, ExprKind::NamedExpr { .. })) + .any(|expr| matches!(expr.node, ExprKind::NamedExpr(_))) { self.add_binding( id, @@ -4746,7 +4728,7 @@ impl<'a> Checker<'a> { } fn handle_node_delete(&mut self, expr: &'a Expr) { - let ExprKind::Name { id, .. } = &expr.node else { + let ExprKind::Name(ast::ExprName { id, .. } )= &expr.node else { return; }; if helpers::on_conditional_branch(&mut self.ctx.parents()) { @@ -4855,8 +4837,10 @@ impl<'a> Checker<'a> { self.ctx.visible_scope = visibility; match &self.ctx.stmt().node { - StmtKind::FunctionDef { body, args, .. } - | StmtKind::AsyncFunctionDef { body, args, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { body, args, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { + body, args, .. + }) => { self.visit_arguments(args); self.visit_body(body); } @@ -4876,7 +4860,7 @@ impl<'a> Checker<'a> { for (expr, snapshot) in lambdas { self.ctx.restore(snapshot); - if let ExprKind::Lambda { args, body } = &expr.node { + if let ExprKind::Lambda(ast::ExprLambda { args, body }) = &expr.node { self.visit_arguments(args); self.visit_expr(body); } else { @@ -4933,8 +4917,9 @@ impl<'a> Checker<'a> { for snapshot in for_loops { self.ctx.restore(snapshot); - if let StmtKind::For { target, body, .. } - | StmtKind::AsyncFor { target, body, .. } = &self.ctx.stmt().node + if let StmtKind::For(ast::StmtFor { target, body, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { target, body, .. }) = + &self.ctx.stmt().node { if self.settings.rules.enabled(Rule::UnusedLoopControlVariable) { flake8_bugbear::rules::unused_loop_control_variable(self, target, body); @@ -5089,7 +5074,7 @@ impl<'a> Checker<'a> { if binding.kind.is_global() { if let Some(source) = binding.source { let stmt = &self.ctx.stmts[source]; - if matches!(stmt.node, StmtKind::Global { .. }) { + if matches!(stmt.node, StmtKind::Global(_)) { diagnostics.push(Diagnostic::new( pylint::rules::GlobalVariableNotAssigned { name: (*name).to_string(), @@ -5153,7 +5138,7 @@ impl<'a> Checker<'a> { ); if let Some(source) = rebound.source { let parent = &self.ctx.stmts[source]; - if matches!(parent.node, StmtKind::ImportFrom { .. }) + if matches!(parent.node, StmtKind::ImportFrom(_)) && parent.range().contains_range(rebound.range) { diagnostic.set_parent(parent.start()); @@ -5237,7 +5222,7 @@ impl<'a> Checker<'a> { let exceptions = binding.exceptions; let diagnostic_offset = binding.range.start(); let child = &self.ctx.stmts[child_id]; - let parent_offset = if matches!(child.node, StmtKind::ImportFrom { .. }) { + let parent_offset = if matches!(child.node, StmtKind::ImportFrom(_)) { Some(child.start()) } else { None @@ -5313,7 +5298,7 @@ impl<'a> Checker<'a> { }, *range, ); - if matches!(child.node, StmtKind::ImportFrom { .. }) { + if matches!(child.node, StmtKind::ImportFrom(_)) { diagnostic.set_parent(child.start()); } @@ -5347,7 +5332,7 @@ impl<'a> Checker<'a> { }, *range, ); - if matches!(child.node, StmtKind::ImportFrom { .. }) { + if matches!(child.node, StmtKind::ImportFrom(_)) { diagnostic.set_parent(child.start()); } diagnostics.push(diagnostic); @@ -5605,7 +5590,12 @@ impl<'a> Checker<'a> { } } - fn check_builtin_shadowing(&mut self, name: &str, located: &Located, is_attribute: bool) { + fn check_builtin_shadowing( + &mut self, + name: &str, + located: &Attributed, + is_attribute: bool, + ) { if is_attribute && matches!(self.ctx.scope().kind, ScopeKind::Class(_)) { if self.settings.rules.enabled(Rule::BuiltinAttributeShadowing) { if let Some(diagnostic) = flake8_builtins::rules::builtin_shadowing( diff --git a/crates/ruff/src/checkers/imports.rs b/crates/ruff/src/checkers/imports.rs index a74bfee724..d8338dd040 100644 --- a/crates/ruff/src/checkers/imports.rs +++ b/crates/ruff/src/checkers/imports.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::path::Path; -use rustpython_parser::ast::{StmtKind, Suite}; +use rustpython_parser::ast::{self, StmtKind, Suite}; use ruff_diagnostics::Diagnostic; use ruff_python_ast::helpers::to_module_path; @@ -29,20 +29,21 @@ fn extract_import_map(path: &Path, package: Option<&Path>, blocks: &[&Block]) -> let mut module_imports = Vec::with_capacity(num_imports); for stmt in blocks.iter().flat_map(|block| &block.imports) { match &stmt.node { - StmtKind::Import { names } => { + StmtKind::Import(ast::StmtImport { names }) => { module_imports.extend( names .iter() - .map(|name| ModuleImport::new(name.node.name.clone(), stmt.range())), + .map(|name| ModuleImport::new(name.node.name.to_string(), stmt.range())), ); } - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } => { - let level = level.unwrap_or(0); + }) => { + let level = level.map_or(0, |level| level.to_usize()); let module = if let Some(module) = module { + let module: &String = module.as_ref(); if level == 0 { Cow::Borrowed(module) } else { diff --git a/crates/ruff/src/doc_lines.rs b/crates/ruff/src/doc_lines.rs index a170f184ed..e564f11df8 100644 --- a/crates/ruff/src/doc_lines.rs +++ b/crates/ruff/src/doc_lines.rs @@ -4,7 +4,7 @@ use std::iter::FusedIterator; use ruff_text_size::{TextRange, TextSize}; -use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind, Suite}; +use rustpython_parser::ast::{self, Constant, ExprKind, Stmt, StmtKind, Suite}; use rustpython_parser::lexer::LexResult; use rustpython_parser::Tok; @@ -76,11 +76,11 @@ struct StringLinesVisitor<'a> { impl StatementVisitor<'_> for StringLinesVisitor<'_> { fn visit_stmt(&mut self, stmt: &Stmt) { - if let StmtKind::Expr { value } = &stmt.node { - if let ExprKind::Constant { + if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..), .. - } = &value.node + }) = &value.node { for line in UniversalNewlineIterator::with_offset( self.locator.slice(value.range()), diff --git a/crates/ruff/src/docstrings/extraction.rs b/crates/ruff/src/docstrings/extraction.rs index 7fbe79a2d1..e9434cb5cb 100644 --- a/crates/ruff/src/docstrings/extraction.rs +++ b/crates/ruff/src/docstrings/extraction.rs @@ -1,6 +1,6 @@ //! Extract docstrings from an AST. -use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind}; use ruff_python_semantic::analyze::visibility; @@ -10,16 +10,16 @@ use crate::docstrings::definition::{Definition, DefinitionKind, Documentable}; pub fn docstring_from(suite: &[Stmt]) -> Option<&Expr> { let stmt = suite.first()?; // Require the docstring to be a standalone expression. - let StmtKind::Expr { value } = &stmt.node else { + let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node else { return None; }; // Only match strings. if !matches!( &value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - } + }) ) { return None; } diff --git a/crates/ruff/src/importer.rs b/crates/ruff/src/importer.rs index eb87bd749e..b02c3c7b9f 100644 --- a/crates/ruff/src/importer.rs +++ b/crates/ruff/src/importer.rs @@ -3,7 +3,7 @@ use anyhow::Result; use libcst_native::{Codegen, CodegenState, ImportAlias, Name, NameOrAttribute}; use ruff_text_size::TextSize; -use rustpython_parser::ast::{Stmt, StmtKind, Suite}; +use rustpython_parser::ast::{self, Stmt, StmtKind, Suite}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::Edit; @@ -79,13 +79,13 @@ impl<'a> Importer<'a> { if stmt.start() >= at { break; } - if let StmtKind::ImportFrom { + if let StmtKind::ImportFrom(ast::StmtImportFrom { module: name, level, .. - } = &stmt.node + }) = &stmt.node { - if level.map_or(true, |level| level == 0) + if level.map_or(true, |level| level.to_u32() == 0) && name.as_ref().map_or(false, |name| name == module) { import_from = Some(*stmt); @@ -178,7 +178,8 @@ fn match_docstring_end(body: &[Stmt]) -> Option { /// along with a trailing newline suffix. fn end_of_statement_insertion(stmt: &Stmt, locator: &Locator, stylist: &Stylist) -> Insertion { let location = stmt.end(); - let mut tokens = lexer::lex_located(locator.after(location), Mode::Module, location).flatten(); + let mut tokens = + lexer::lex_starts_at(locator.after(location), Mode::Module, location).flatten(); if let Some((Tok::Semi, range)) = tokens.next() { // If the first token after the docstring is a semicolon, insert after the semicolon as an // inline statement; @@ -211,7 +212,7 @@ fn top_of_file_insertion(body: &[Stmt], locator: &Locator, stylist: &Stylist) -> let mut location = if let Some(location) = match_docstring_end(body) { // If the first token after the docstring is a semicolon, insert after the semicolon as an // inline statement; - let first_token = lexer::lex_located(locator.after(location), Mode::Module, location) + let first_token = lexer::lex_starts_at(locator.after(location), Mode::Module, location) .flatten() .next(); if let Some((Tok::Semi, range)) = first_token { @@ -226,7 +227,7 @@ fn top_of_file_insertion(body: &[Stmt], locator: &Locator, stylist: &Stylist) -> // Skip over any comments and empty lines. for (tok, range) in - lexer::lex_located(locator.after(location), Mode::Module, location).flatten() + lexer::lex_starts_at(locator.after(location), Mode::Module, location).flatten() { if matches!(tok, Tok::Comment(..) | Tok::Newline) { location = locator.full_line_end(range.end()); diff --git a/crates/ruff/src/logging.rs b/crates/ruff/src/logging.rs index 7ed9974042..458f27c582 100644 --- a/crates/ruff/src/logging.rs +++ b/crates/ruff/src/logging.rs @@ -145,7 +145,7 @@ impl<'a> DisplayParseError<'a> { impl Display for DisplayParseError<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let source_location = self.source_code.source_location(self.error.location); + let source_location = self.source_code.source_location(self.error.offset); write!( f, diff --git a/crates/ruff/src/rules/flake8_2020/rules.rs b/crates/ruff/src/rules/flake8_2020/rules.rs index a4d7bd3898..6c7cca5b9a 100644 --- a/crates/ruff/src/rules/flake8_2020/rules.rs +++ b/crates/ruff/src/rules/flake8_2020/rules.rs @@ -1,5 +1,5 @@ use num_bigint::BigInt; -use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind, Located}; +use rustpython_parser::ast::{self, Attributed, Cmpop, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -124,16 +124,15 @@ fn is_sys(checker: &Checker, expr: &Expr, target: &str) -> bool { pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) { if is_sys(checker, value, "version") { match &slice.node { - ExprKind::Slice { + ExprKind::Slice(ast::ExprSlice { lower: None, upper: Some(upper), step: None, - .. - } => { - if let ExprKind::Constant { + }) => { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(i), .. - } = &upper.node + }) = &upper.node { if *i == BigInt::from(1) && checker.settings.rules.enabled(Rule::SysVersionSlice1) @@ -151,10 +150,10 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) { } } - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(i), .. - } => { + }) => { if *i == BigInt::from(2) && checker.settings.rules.enabled(Rule::SysVersion2) { checker .diagnostics @@ -175,21 +174,23 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) { /// YTT103, YTT201, YTT203, YTT204, YTT302 pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &[Expr]) { match &left.node { - ExprKind::Subscript { value, slice, .. } if is_sys(checker, value, "version_info") => { - if let ExprKind::Constant { + ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) + if is_sys(checker, value, "version_info") => + { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(i), .. - } = &slice.node + }) = &slice.node { if *i == BigInt::from(0) { if let ( [Cmpop::Eq | Cmpop::NotEq], - [Located { + [Attributed { node: - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(n), .. - }, + }), .. }], ) = (ops, comparators) @@ -205,12 +206,12 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: & } else if *i == BigInt::from(1) { if let ( [Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE], - [Located { + [Attributed { node: - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(_), .. - }, + }), .. }], ) = (ops, comparators) @@ -225,17 +226,17 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: & } } - ExprKind::Attribute { value, attr, .. } + ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) if is_sys(checker, value, "version_info") && attr == "minor" => { if let ( [Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE], - [Located { + [Attributed { node: - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(_), .. - }, + }), .. }], ) = (ops, comparators) @@ -258,12 +259,12 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: & if is_sys(checker, left, "version") { if let ( [Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE], - [Located { + [Attributed { node: - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(s), .. - }, + }), .. }], ) = (ops, comparators) diff --git a/crates/ruff/src/rules/flake8_annotations/fixes.rs b/crates/ruff/src/rules/flake8_annotations/fixes.rs index 5a6fea6f4f..305368ca1f 100644 --- a/crates/ruff/src/rules/flake8_annotations/fixes.rs +++ b/crates/ruff/src/rules/flake8_annotations/fixes.rs @@ -13,7 +13,7 @@ pub fn add_return_annotation(locator: &Locator, stmt: &Stmt, annotation: &str) - let mut seen_lpar = false; let mut seen_rpar = false; let mut count: usize = 0; - for (tok, range) in lexer::lex_located(contents, Mode::Module, stmt.start()).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, stmt.start()).flatten() { if seen_lpar && seen_rpar { if matches!(tok, Tok::Colon) { return Ok(Edit::insertion(format!(" -> {annotation}"), range.start())); diff --git a/crates/ruff/src/rules/flake8_annotations/helpers.rs b/crates/ruff/src/rules/flake8_annotations/helpers.rs index 8702c6f957..5db8369193 100644 --- a/crates/ruff/src/rules/flake8_annotations/helpers.rs +++ b/crates/ruff/src/rules/flake8_annotations/helpers.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Arguments, Expr, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Arguments, Expr, Stmt, StmtKind}; use ruff_python_ast::cast; use ruff_python_semantic::analyze::visibility; @@ -8,20 +8,20 @@ use crate::docstrings::definition::{Definition, DefinitionKind}; pub(super) fn match_function_def(stmt: &Stmt) -> (&str, &Arguments, Option<&Expr>, &Vec) { match &stmt.node { - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, args, returns, body, .. - } - | StmtKind::AsyncFunctionDef { + }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, args, returns, body, .. - } => (name, args, returns.as_ref().map(|expr| &**expr), body), + }) => (name, args, returns.as_ref().map(|expr| &**expr), body), _ => panic!("Found non-FunctionDef in match_name"), } } diff --git a/crates/ruff/src/rules/flake8_annotations/rules.rs b/crates/ruff/src/rules/flake8_annotations/rules.rs index 5b9dcbbce5..d737d3136f 100644 --- a/crates/ruff/src/rules/flake8_annotations/rules.rs +++ b/crates/ruff/src/rules/flake8_annotations/rules.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -420,10 +420,10 @@ fn is_none_returning(body: &[Stmt]) -> bool { for expr in visitor.returns.into_iter().flatten() { if !matches!( expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } + }) ) { return false; } diff --git a/crates/ruff/src/rules/flake8_bandit/helpers.rs b/crates/ruff/src/rules/flake8_bandit/helpers.rs index e578cb8430..d27842d7cd 100644 --- a/crates/ruff/src/rules/flake8_bandit/helpers.rs +++ b/crates/ruff/src/rules/flake8_bandit/helpers.rs @@ -1,6 +1,6 @@ use once_cell::sync::Lazy; use regex::Regex; -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use crate::checkers::ast::Checker; @@ -10,10 +10,10 @@ static PASSWORD_CANDIDATE_REGEX: Lazy = Lazy::new(|| { pub fn string_literal(expr: &Expr) -> Option<&str> { match &expr.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } => Some(string), + }) => Some(string), _ => None, } } @@ -24,7 +24,7 @@ pub fn matches_password_name(string: &str) -> bool { pub fn is_untyped_exception(type_: Option<&Expr>, checker: &Checker) -> bool { type_.map_or(true, |type_| { - if let ExprKind::Tuple { elts, .. } = &type_.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &type_.node { elts.iter().any(|type_| { checker .ctx diff --git a/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs b/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs index ccf07c8c6c..a1087cac81 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/bad_file_permissions.rs @@ -1,7 +1,7 @@ use num_traits::ToPrimitive; use once_cell::sync::Lazy; use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Operator}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Operator}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -70,14 +70,14 @@ static PYSTAT_MAPPING: Lazy> = Lazy::new(|| { fn get_int_value(expr: &Expr) -> Option { match &expr.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(value), .. - } => value.to_u16(), - ExprKind::Attribute { .. } => { + }) => value.to_u16(), + ExprKind::Attribute(_) => { compose_call_path(expr).and_then(|path| PYSTAT_MAPPING.get(path.as_str()).copied()) } - ExprKind::BinOp { left, op, right } => { + ExprKind::BinOp(ast::ExprBinOp { left, op, right }) => { if let (Some(left_value), Some(right_value)) = (get_int_value(left), get_int_value(right)) { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/exec_used.rs b/crates/ruff/src/rules/flake8_bandit/rules/exec_used.rs index d54dee0850..d6fa50753e 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/exec_used.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/exec_used.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -15,7 +15,7 @@ impl Violation for ExecBuiltin { /// S102 pub fn exec_used(expr: &Expr, func: &Expr) -> Option { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { return None; }; if id != "exec" { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_password_string.rs b/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_password_string.rs index 1a947807d1..9008123bdd 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_password_string.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_password_string.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -24,17 +24,17 @@ impl Violation for HardcodedPasswordString { fn password_target(target: &Expr) -> Option<&str> { let target_name = match &target.node { // variable = "s3cr3t" - ExprKind::Name { id, .. } => id, + ExprKind::Name(ast::ExprName { id, .. }) => id.as_str(), // d["password"] = "s3cr3t" - ExprKind::Subscript { slice, .. } => match &slice.node { - ExprKind::Constant { + ExprKind::Subscript(ast::ExprSubscript { slice, .. }) => match &slice.node { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } => string, + }) => string, _ => return None, }, // obj.password = "s3cr3t" - ExprKind::Attribute { attr, .. } => attr, + ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => attr, _ => return None, }; diff --git a/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs b/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs index ee10134b0a..6143453a45 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/hardcoded_sql_expression.rs @@ -1,6 +1,6 @@ use once_cell::sync::Lazy; use regex::Regex; -use rustpython_parser::ast::{Expr, ExprKind, Operator}; +use rustpython_parser::ast::{self, Expr, ExprKind, Operator}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -56,10 +56,10 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio match &expr.node { // "select * from table where val = " + "str" + ... // "select * from table where val = %s" % ... - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { op: Operator::Add | Operator::Mod, .. - } => { + }) => { let Some(parent) = checker.ctx.expr_parent() else { if any_over_expr(expr, &has_string_literal) { return Some(unparse_expr(expr, checker.stylist)); @@ -67,7 +67,7 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio return None; }; // Only evaluate the full BinOp, not the nested components. - let ExprKind::BinOp { .. } = &parent.node else { + let ExprKind::BinOp(_ )= &parent.node else { if any_over_expr(expr, &has_string_literal) { return Some(unparse_expr(expr, checker.stylist)); } @@ -75,8 +75,8 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio }; None } - ExprKind::Call { func, .. } => { - let ExprKind::Attribute{ attr, value, .. } = &func.node else { + ExprKind::Call(ast::ExprCall { func, .. }) => { + let ExprKind::Attribute(ast::ExprAttribute { attr, value, .. }) = &func.node else { return None; }; // "select * from table where val = {}".format(...) @@ -86,7 +86,7 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio None } // f"select * from table where val = {val}" - ExprKind::JoinedStr { .. } => Some(unparse_expr(expr, checker.stylist)), + ExprKind::JoinedStr(_) => Some(unparse_expr(expr, checker.stylist)), _ => None, } } diff --git a/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs b/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs index 5fa74bb710..ee060886e0 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/hashlib_insecure_hash_functions.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -27,10 +27,10 @@ fn is_used_for_security(call_args: &SimpleCallArgs) -> bool { match call_args.keyword_argument("usedforsecurity") { Some(expr) => !matches!( &expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(false), .. - } + }) ), _ => true, } diff --git a/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs b/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs index 9c3b73d6f7..9c1b2ca661 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/jinja2_autoescape_false.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -47,13 +47,13 @@ pub fn jinja2_autoescape_false( if let Some(autoescape_arg) = call_args.keyword_argument("autoescape") { match &autoescape_arg.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(true), .. - } => (), - ExprKind::Call { func, .. } => { - if let ExprKind::Name { id, .. } = &func.node { - if id.as_str() != "select_autoescape" { + }) => (), + ExprKind::Call(ast::ExprCall { func, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { + if id != "select_autoescape" { checker.diagnostics.push(Diagnostic::new( Jinja2AutoescapeFalse { value: true }, autoescape_arg.range(), diff --git a/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs b/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs index 358efa8917..6ed0cf8bdd 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/request_with_no_cert_validation.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -56,10 +56,10 @@ pub fn request_with_no_cert_validation( }) { let call_args = SimpleCallArgs::new(args, keywords); if let Some(verify_arg) = call_args.keyword_argument("verify") { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(false), .. - } = &verify_arg.node + }) = &verify_arg.node { checker.diagnostics.push(Diagnostic::new( RequestWithNoCertValidation { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs b/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs index 0ac9bf93b4..9071d17d10 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/request_without_timeout.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -45,10 +45,10 @@ pub fn request_without_timeout( let call_args = SimpleCallArgs::new(args, keywords); if let Some(timeout_arg) = call_args.keyword_argument("timeout") { if let Some(timeout) = match &timeout_arg.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: value @ Constant::None, .. - } => Some(unparse_constant(value, checker.stylist)), + }) => Some(unparse_constant(value, checker.stylist)), _ => None, } { checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs b/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs index dec37b05ff..b035597ceb 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/shell_injection.rs @@ -2,7 +2,7 @@ use once_cell::sync::Lazy; use regex::Regex; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -159,17 +159,17 @@ fn find_shell_keyword<'a>(ctx: &Context, keywords: &'a [Keyword]) -> Option bool { matches!( arg.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - } + }) ) } /// Return the [`Expr`] as a string literal, if it's a string or a list of strings. fn try_string_literal(expr: &Expr) -> Option<&str> { match &expr.node { - ExprKind::List { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) => { if elts.is_empty() { None } else { diff --git a/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs b/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs index 1a32c9620b..237ccb9de6 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/snmp_insecure_version.rs @@ -1,5 +1,5 @@ use num_traits::{One, Zero}; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -33,10 +33,10 @@ pub fn snmp_insecure_version( { let call_args = SimpleCallArgs::new(args, keywords); if let Some(mp_model_arg) = call_args.keyword_argument("mpModel") { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(value), .. - } = &mp_model_arg.node + }) = &mp_model_arg.node { if value.is_zero() || value.is_one() { checker diff --git a/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs b/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs index 2921c9569b..15d5c753d2 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/suspicious_function_call.rs @@ -1,7 +1,7 @@ //! Check for calls to suspicious functions, or calls into suspicious modules. //! //! See: -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -466,7 +466,7 @@ const SUSPICIOUS_MODULES: &[SuspiciousModule] = &[ /// S001 pub fn suspicious_function_call(checker: &mut Checker, expr: &Expr) { - let ExprKind::Call { func, .. } = &expr.node else { + let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node else { return; }; diff --git a/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs b/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs index cd05f639b6..45e378a40b 100644 --- a/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs +++ b/crates/ruff/src/rules/flake8_bandit/rules/unsafe_yaml_load.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -48,8 +48,8 @@ pub fn unsafe_yaml_load(checker: &mut Checker, func: &Expr, args: &[Expr], keywo }) { let loader = match &loader_arg.node { - ExprKind::Attribute { attr, .. } => Some(attr.to_string()), - ExprKind::Name { id, .. } => Some(id.to_string()), + ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => Some(attr.to_string()), + ExprKind::Name(ast::ExprName { id, .. }) => Some(id.to_string()), _ => None, }; checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_blind_except/rules.rs b/crates/ruff/src/rules/flake8_blind_except/rules.rs index 3c1d8de757..6cb460e81d 100644 --- a/crates/ruff/src/rules/flake8_blind_except/rules.rs +++ b/crates/ruff/src/rules/flake8_blind_except/rules.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -30,17 +30,17 @@ pub fn blind_except( let Some(type_) = type_ else { return; }; - let ExprKind::Name { id, .. } = &type_.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &type_.node else { return; }; for exception in ["BaseException", "Exception"] { if id == exception && checker.ctx.is_builtin(exception) { // If the exception is re-raised, don't flag an error. if body.iter().any(|stmt| { - if let StmtKind::Raise { exc, .. } = &stmt.node { + if let StmtKind::Raise(ast::StmtRaise { exc, .. }) = &stmt.node { if let Some(exc) = exc { - if let ExprKind::Name { id, .. } = &exc.node { - name.map_or(false, |name| name == id) + if let ExprKind::Name(ast::ExprName { id, .. }) = &exc.node { + name.map_or(false, |name| id == name) } else { false } @@ -56,10 +56,12 @@ pub fn blind_except( // If the exception is logged, don't flag an error. if body.iter().any(|stmt| { - if let StmtKind::Expr { value } = &stmt.node { - if let ExprKind::Call { func, keywords, .. } = &value.node { + if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node { + if let ExprKind::Call(ast::ExprCall { func, keywords, .. }) = &value.node { if logging::is_logger_candidate(&checker.ctx, func) { - if let ExprKind::Attribute { attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node + { + let attr = attr.as_str(); if attr == "exception" { return true; } diff --git a/crates/ruff/src/rules/flake8_boolean_trap/rules.rs b/crates/ruff/src/rules/flake8_boolean_trap/rules.rs index f09ece952f..b5bb4e7fa8 100644 --- a/crates/ruff/src/rules/flake8_boolean_trap/rules.rs +++ b/crates/ruff/src/rules/flake8_boolean_trap/rules.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Arguments, Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Arguments, Constant, Expr, ExprKind}; use ruff_diagnostics::Violation; use ruff_diagnostics::{Diagnostic, DiagnosticKind}; @@ -67,11 +67,11 @@ const FUNC_DEF_NAME_ALLOWLIST: &[&str] = &["__setitem__"]; /// `true`, the function name must be explicitly allowed, and the argument must /// be either the first or second argument in the call. fn allow_boolean_trap(func: &Expr) -> bool { - if let ExprKind::Attribute { attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node { return FUNC_CALL_NAME_ALLOWLIST.contains(&attr.as_ref()); } - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { return FUNC_CALL_NAME_ALLOWLIST.contains(&id.as_ref()); } @@ -81,10 +81,10 @@ fn allow_boolean_trap(func: &Expr) -> bool { const fn is_boolean_arg(arg: &Expr) -> bool { matches!( &arg.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(_), .. - } + }) ) } @@ -120,11 +120,11 @@ pub fn check_positional_boolean_in_def( // check for both bool (python class) and 'bool' (string annotation) let hint = match &expr.node { - ExprKind::Name { id, .. } => id == "bool", - ExprKind::Constant { + ExprKind::Name(ast::ExprName { id, .. }) => id == "bool", + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } => value == "bool", + }) => value == "bool", _ => false, }; if !hint { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs b/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs index 30ef468ad4..c87feaeeca 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -57,8 +57,8 @@ fn is_abc_class(context: &Context, bases: &[Expr], keywords: &[Keyword]) -> bool fn is_empty_body(body: &[Stmt]) -> bool { body.iter().all(|stmt| match &stmt.node { StmtKind::Pass => true, - StmtKind::Expr { value } => match &value.node { - ExprKind::Constant { value, .. } => { + StmtKind::Expr(ast::StmtExpr { value }) => match &value.node { + ExprKind::Constant(ast::ExprConstant { value, .. }) => { matches!(value, Constant::Str(..) | Constant::Ellipsis) } _ => false, @@ -88,23 +88,23 @@ pub fn abstract_base_class( for stmt in body { // https://github.com/PyCQA/flake8-bugbear/issues/293 // Ignore abc's that declares a class attribute that must be set - if let StmtKind::AnnAssign { .. } | StmtKind::Assign { .. } = &stmt.node { + if let StmtKind::AnnAssign(_) | StmtKind::Assign(_) = &stmt.node { has_abstract_method = true; continue; } let ( - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { decorator_list, body, name: method_name, .. - } | StmtKind::AsyncFunctionDef { + }) | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { decorator_list, body, name: method_name, .. - } + }) ) = &stmt.node else { continue; }; diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs b/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs index bdf4d9404d..2cfc086886 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/assert_false.rs @@ -1,5 +1,5 @@ -use ruff_text_size::TextSize; -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; +use ruff_text_size::TextRange; +use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -24,20 +24,17 @@ impl AlwaysAutofixableViolation for AssertFalse { fn assertion_error(msg: Option<&Expr>) -> Stmt { Stmt::new( - TextSize::default(), - TextSize::default(), - StmtKind::Raise { + TextRange::default(), + StmtKind::Raise(ast::StmtRaise { exc: Some(Box::new(Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::Call { + TextRange::default(), + ExprKind::Call(ast::ExprCall { func: Box::new(Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::Name { - id: "AssertionError".to_string(), + TextRange::default(), + ExprKind::Name(ast::ExprName { + id: "AssertionError".into(), ctx: ExprContext::Load, - }, + }), )), args: if let Some(msg) = msg { vec![msg.clone()] @@ -45,19 +42,19 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt { vec![] }, keywords: vec![], - }, + }), ))), cause: None, - }, + }), ) } /// B011 pub fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: Option<&Expr>) { - let ExprKind::Constant { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(false), .. - } = &test.node else { + } )= &test.node else { return; }; diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs b/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs index 74ecfb14ad..0ed86ae144 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/assert_raises_exception.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ExprKind, Stmt, Withitem}; +use rustpython_parser::ast::{self, ExprKind, Stmt, Withitem}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -55,7 +55,7 @@ pub fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[With return; }; let item_context = &item.context_expr; - let ExprKind::Call { func, args, keywords } = &item_context.node else { + let ExprKind::Call(ast::ExprCall { func, args, keywords }) = &item_context.node else { return; }; if args.len() != 1 { @@ -74,7 +74,8 @@ pub fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[With } let kind = { - if matches!(&func.node, ExprKind::Attribute { attr, .. } if attr == "assertRaises") { + if matches!(&func.node, ExprKind::Attribute(ast::ExprAttribute { attr, .. }) if attr == "assertRaises") + { AssertionKind::AssertRaises } else if checker .ctx diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs b/crates/ruff/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs index c5aea9ca3d..480da29df7 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/assignment_to_os_environ.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -20,13 +20,13 @@ pub fn assignment_to_os_environ(checker: &mut Checker, targets: &[Expr]) { return; } let target = &targets[0]; - let ExprKind::Attribute { value, attr, .. } = &target.node else { + let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &target.node else { return; }; if attr != "environ" { return; } - let ExprKind::Name { id, .. } = &value.node else { + let ExprKind::Name(ast::ExprName { id, .. } )= &value.node else { return; }; if id != "os" { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs b/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs index 12cca25355..0b56a9806f 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/cached_instance_method.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -36,7 +36,7 @@ pub fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) { for decorator in decorator_list { // TODO(charlie): This should take into account `classmethod-decorators` and // `staticmethod-decorators`. - if let ExprKind::Name { id, .. } = &decorator.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &decorator.node { if id == "classmethod" || id == "staticmethod" { return; } @@ -46,7 +46,7 @@ pub fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) { if is_cache_func( checker, match &decorator.node { - ExprKind::Call { func, .. } => func, + ExprKind::Call(ast::ExprCall { func, .. }) => func, _ => decorator, }, ) { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/cannot_raise_literal.rs b/crates/ruff/src/rules/flake8_bugbear/rules/cannot_raise_literal.rs index 9709649cb0..913cb2131b 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/cannot_raise_literal.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/cannot_raise_literal.rs @@ -17,7 +17,7 @@ impl Violation for CannotRaiseLiteral { /// B016 pub fn cannot_raise_literal(checker: &mut Checker, expr: &Expr) { - let ExprKind::Constant { .. } = &expr.node else { + let ExprKind::Constant ( _) = &expr.node else { return; }; checker diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs b/crates/ruff/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs index 017ecd4f10..30e17a86e8 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/duplicate_exceptions.rs @@ -1,7 +1,7 @@ use itertools::Itertools; -use ruff_text_size::TextSize; +use ruff_text_size::TextRange; use rustc_hash::{FxHashMap, FxHashSet}; -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; @@ -50,9 +50,8 @@ impl AlwaysAutofixableViolation for DuplicateHandlerException { fn type_pattern(elts: Vec<&Expr>) -> Expr { Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::Tuple { + TextRange::default(), + ast::ExprTuple { elts: elts.into_iter().cloned().collect(), ctx: ExprContext::Load, }, @@ -117,11 +116,11 @@ pub fn duplicate_exceptions(checker: &mut Checker, handlers: &[Excepthandler]) { let mut seen: FxHashSet = FxHashSet::default(); let mut duplicates: FxHashMap> = FxHashMap::default(); for handler in handlers { - let ExcepthandlerKind::ExceptHandler { type_: Some(type_), .. } = &handler.node else { + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_: Some(type_), .. }) = &handler.node else { continue; }; match &type_.node { - ExprKind::Attribute { .. } | ExprKind::Name { .. } => { + ExprKind::Attribute(_) | ExprKind::Name(_) => { if let Some(call_path) = call_path::collect_call_path(type_) { if seen.contains(&call_path) { duplicates.entry(call_path).or_default().push(type_); @@ -130,7 +129,7 @@ pub fn duplicate_exceptions(checker: &mut Checker, handlers: &[Excepthandler]) { } } } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { for (name, expr) in duplicate_handler_exceptions(checker, type_, elts) { if seen.contains(&name) { duplicates.entry(name).or_default().push(expr); diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/except_with_empty_tuple.rs b/crates/ruff/src/rules/flake8_bugbear/rules/except_with_empty_tuple.rs index cf183851ec..300fa5e8d0 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/except_with_empty_tuple.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/except_with_empty_tuple.rs @@ -1,5 +1,5 @@ use rustpython_parser::ast::Excepthandler; -use rustpython_parser::ast::{ExcepthandlerKind, ExprKind}; +use rustpython_parser::ast::{self, ExcepthandlerKind, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -18,11 +18,12 @@ impl Violation for ExceptWithEmptyTuple { /// B029 pub fn except_with_empty_tuple(checker: &mut Checker, excepthandler: &Excepthandler) { - let ExcepthandlerKind::ExceptHandler { type_, .. } = &excepthandler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = + &excepthandler.node; let Some(type_) = type_ else { return; }; - let ExprKind::Tuple { elts, .. } = &type_.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &type_.node else { return; }; if elts.is_empty() { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/except_with_non_exception_classes.rs b/crates/ruff/src/rules/flake8_bugbear/rules/except_with_non_exception_classes.rs index dbdce82222..8c4f5b700e 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/except_with_non_exception_classes.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/except_with_non_exception_classes.rs @@ -1,6 +1,6 @@ use std::collections::VecDeque; -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -21,15 +21,16 @@ impl Violation for ExceptWithNonExceptionClasses { /// This should leave any unstarred iterables alone (subsequently raising a /// warning for B029). fn flatten_starred_iterables(expr: &Expr) -> Vec<&Expr> { - let ExprKind::Tuple { elts, .. } = &expr.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, .. } )= &expr.node else { return vec![expr]; }; let mut flattened_exprs: Vec<&Expr> = Vec::with_capacity(elts.len()); let mut exprs_to_process: VecDeque<&Expr> = elts.iter().collect(); while let Some(expr) = exprs_to_process.pop_front() { match &expr.node { - ExprKind::Starred { value, .. } => match &value.node { - ExprKind::Tuple { elts, .. } | ExprKind::List { elts, .. } => { + ExprKind::Starred(ast::ExprStarred { value, .. }) => match &value.node { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) + | ExprKind::List(ast::ExprList { elts, .. }) => { exprs_to_process.append(&mut elts.iter().collect()); } _ => flattened_exprs.push(value), @@ -42,17 +43,15 @@ fn flatten_starred_iterables(expr: &Expr) -> Vec<&Expr> { /// B030 pub fn except_with_non_exception_classes(checker: &mut Checker, excepthandler: &Excepthandler) { - let ExcepthandlerKind::ExceptHandler { type_, .. } = &excepthandler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = + &excepthandler.node; let Some(type_) = type_ else { return; }; for expr in flatten_starred_iterables(type_) { if !matches!( &expr.node, - ExprKind::Subscript { .. } - | ExprKind::Attribute { .. } - | ExprKind::Name { .. } - | ExprKind::Call { .. }, + ExprKind::Subscript(_) | ExprKind::Attribute(_) | ExprKind::Name(_) | ExprKind::Call(_), ) { checker .diagnostics diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs b/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs index ab2582ded0..4d6c762cc0 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/f_string_docstring.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -23,10 +23,10 @@ pub fn f_string_docstring(checker: &mut Checker, body: &[Stmt]) { let Some(stmt) = body.first() else { return; }; - let StmtKind::Expr { value } = &stmt.node else { + let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node else { return; }; - let ExprKind::JoinedStr { .. } = value.node else { + let ExprKind::JoinedStr ( _) = value.node else { return; }; checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs b/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs index bdc1a1b43d..0c74658d7a 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/function_call_argument_default.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Arguments, Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Arguments, Constant, Expr, ExprKind}; use ruff_diagnostics::Violation; use ruff_diagnostics::{Diagnostic, DiagnosticKind}; @@ -84,7 +84,7 @@ where { fn visit_expr(&mut self, expr: &'b Expr) { match &expr.node { - ExprKind::Call { func, args, .. } => { + ExprKind::Call(ast::ExprCall { func, args, .. }) => { if !is_mutable_func(self.checker, func) && !is_immutable_func(&self.checker.ctx, func, &self.extend_immutable_calls) && !is_nan_or_infinity(func, args) @@ -99,14 +99,14 @@ where } visitor::walk_expr(self, expr); } - ExprKind::Lambda { .. } => {} + ExprKind::Lambda(_) => {} _ => visitor::walk_expr(self, expr), } } } fn is_nan_or_infinity(expr: &Expr, args: &[Expr]) -> bool { - let ExprKind::Name { id, .. } = &expr.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node else { return false; }; if id != "float" { @@ -115,10 +115,10 @@ fn is_nan_or_infinity(expr: &Expr, args: &[Expr]) -> bool { let Some(arg) = args.first() else { return false; }; - let ExprKind::Constant { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &arg.node else { + } )= &arg.node else { return false; }; let lowercased = value.to_lowercase(); diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs b/crates/ruff/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs index d42127500f..ea84e9b3f3 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/function_uses_loop_variable.rs @@ -1,6 +1,6 @@ use ruff_text_size::TextRange; use rustc_hash::FxHashSet; -use rustpython_parser::ast::{Comprehension, Expr, ExprContext, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Comprehension, Expr, ExprContext, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -36,7 +36,7 @@ struct LoadedNamesVisitor<'a> { impl<'a> Visitor<'a> for LoadedNamesVisitor<'a> { fn visit_expr(&mut self, expr: &'a Expr) { match &expr.node { - ExprKind::Name { id, ctx } => match ctx { + ExprKind::Name(ast::ExprName { id, ctx }) => match ctx { ExprContext::Load => self.loaded.push((id, expr, expr.range())), ExprContext::Store => self.stored.push((id, expr, expr.range())), ExprContext::Del => {} @@ -57,8 +57,8 @@ struct SuspiciousVariablesVisitor<'a> { impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { fn visit_stmt(&mut self, stmt: &'a Stmt) { match &stmt.node { - StmtKind::FunctionDef { args, body, .. } - | StmtKind::AsyncFunctionDef { args, body, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { args, body, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { args, body, .. }) => { // Collect all loaded variable names. let mut visitor = LoadedNamesVisitor::default(); visitor.visit_body(body); @@ -76,9 +76,9 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { ); return; } - StmtKind::Return { value: Some(value) } => { + StmtKind::Return(ast::StmtReturn { value: Some(value) }) => { // Mark `return lambda: x` as safe. - if matches!(value.node, ExprKind::Lambda { .. }) { + if matches!(value.node, ExprKind::Lambda(_)) { self.safe_functions.push(value); } } @@ -89,26 +89,27 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { fn visit_expr(&mut self, expr: &'a Expr) { match &expr.node { - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { - if let ExprKind::Name { id, .. } = &func.node { + }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { + let id = id.as_str(); if id == "filter" || id == "reduce" || id == "map" { for arg in args { - if matches!(arg.node, ExprKind::Lambda { .. }) { + if matches!(arg.node, ExprKind::Lambda(_)) { self.safe_functions.push(arg); } } } } - if let ExprKind::Attribute { value, attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node { if attr == "reduce" { - if let ExprKind::Name { id, .. } = &value.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { if id == "functools" { for arg in args { - if matches!(arg.node, ExprKind::Lambda { .. }) { + if matches!(arg.node, ExprKind::Lambda(_)) { self.safe_functions.push(arg); } } @@ -118,13 +119,13 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> { } for keyword in keywords { if keyword.node.arg.as_ref().map_or(false, |arg| arg == "key") - && matches!(keyword.node.value.node, ExprKind::Lambda { .. }) + && matches!(keyword.node.value.node, ExprKind::Lambda(_)) { self.safe_functions.push(&keyword.node.value); } } } - ExprKind::Lambda { args, body } => { + ExprKind::Lambda(ast::ExprLambda { args, body }) => { if !self.safe_functions.contains(&expr) { // Collect all loaded variable names. let mut visitor = LoadedNamesVisitor::default(); @@ -160,13 +161,14 @@ struct NamesFromAssignmentsVisitor<'a> { impl<'a> Visitor<'a> for NamesFromAssignmentsVisitor<'a> { fn visit_expr(&mut self, expr: &'a Expr) { match &expr.node { - ExprKind::Name { id, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => { self.names.insert(id.as_str()); } - ExprKind::Starred { value, .. } => { + ExprKind::Starred(ast::ExprStarred { value, .. }) => { self.visit_expr(value); } - ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { for expr in elts { self.visit_expr(expr); } @@ -186,24 +188,24 @@ impl<'a> Visitor<'a> for AssignedNamesVisitor<'a> { fn visit_stmt(&mut self, stmt: &'a Stmt) { if matches!( &stmt.node, - StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. } + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) ) { // Don't recurse. return; } match &stmt.node { - StmtKind::Assign { targets, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, .. }) => { let mut visitor = NamesFromAssignmentsVisitor::default(); for expr in targets { visitor.visit_expr(expr); } self.names.extend(visitor.names); } - StmtKind::AugAssign { target, .. } - | StmtKind::AnnAssign { target, .. } - | StmtKind::For { target, .. } - | StmtKind::AsyncFor { target, .. } => { + StmtKind::AugAssign(ast::StmtAugAssign { target, .. }) + | StmtKind::AnnAssign(ast::StmtAnnAssign { target, .. }) + | StmtKind::For(ast::StmtFor { target, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { target, .. }) => { let mut visitor = NamesFromAssignmentsVisitor::default(); visitor.visit_expr(target); self.names.extend(visitor.names); @@ -215,7 +217,7 @@ impl<'a> Visitor<'a> for AssignedNamesVisitor<'a> { } fn visit_expr(&mut self, expr: &'a Expr) { - if matches!(&expr.node, ExprKind::Lambda { .. }) { + if matches!(&expr.node, ExprKind::Lambda(_)) { // Don't recurse. return; } diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/getattr_with_constant.rs b/crates/ruff/src/rules/flake8_bugbear/rules/getattr_with_constant.rs index a2666a9328..70841c4d05 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/getattr_with_constant.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/getattr_with_constant.rs @@ -1,5 +1,5 @@ -use ruff_text_size::TextSize; -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind}; +use ruff_text_size::TextRange; +use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -27,11 +27,10 @@ impl AlwaysAutofixableViolation for GetAttrWithConstant { } fn attribute(value: &Expr, attr: &str) -> Expr { Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::Attribute { + TextRange::default(), + ast::ExprAttribute { value: Box::new(value.clone()), - attr: attr.to_string(), + attr: attr.into(), ctx: ExprContext::Load, }, ) @@ -39,7 +38,7 @@ fn attribute(value: &Expr, attr: &str) -> Expr { /// B009 pub fn getattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. } )= &func.node else { return; }; if id != "getattr" { @@ -48,10 +47,10 @@ pub fn getattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar let [obj, arg] = args else { return; }; - let ExprKind::Constant { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &arg.node else { + } )= &arg.node else { return; }; if !is_identifier(value) { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/jump_statement_in_finally.rs b/crates/ruff/src/rules/flake8_bugbear/rules/jump_statement_in_finally.rs index cd9e644154..6773361b2e 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/jump_statement_in_finally.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/jump_statement_in_finally.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Stmt, StmtKind}; +use rustpython_parser::ast::{self, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -24,33 +24,34 @@ fn walk_stmt(checker: &mut Checker, body: &[Stmt], f: fn(&Stmt) -> bool) { checker.diagnostics.push(Diagnostic::new( JumpStatementInFinally { name: match &stmt.node { - StmtKind::Break { .. } => "break".to_string(), - StmtKind::Continue { .. } => "continue".to_string(), - StmtKind::Return { .. } => "return".to_string(), + StmtKind::Break => "break", + StmtKind::Continue => "continue", + StmtKind::Return(_) => "return", _ => unreachable!( "Expected StmtKind::Break | StmtKind::Continue | StmtKind::Return" ), - }, + } + .to_owned(), }, stmt.range(), )); } match &stmt.node { - StmtKind::While { body, .. } - | StmtKind::For { body, .. } - | StmtKind::AsyncFor { body, .. } => { + StmtKind::While(ast::StmtWhile { body, .. }) + | StmtKind::For(ast::StmtFor { body, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { body, .. }) => { walk_stmt(checker, body, |stmt| { - matches!(stmt.node, StmtKind::Return { .. }) + matches!(stmt.node, StmtKind::Return(_)) }); } - StmtKind::If { body, .. } - | StmtKind::Try { body, .. } - | StmtKind::TryStar { body, .. } - | StmtKind::With { body, .. } - | StmtKind::AsyncWith { body, .. } => { + StmtKind::If(ast::StmtIf { body, .. }) + | StmtKind::Try(ast::StmtTry { body, .. }) + | StmtKind::TryStar(ast::StmtTryStar { body, .. }) + | StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { walk_stmt(checker, body, f); } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { for case in cases { walk_stmt(checker, &case.body, f); } @@ -65,7 +66,7 @@ pub fn jump_statement_in_finally(checker: &mut Checker, finalbody: &[Stmt]) { walk_stmt(checker, finalbody, |stmt| { matches!( stmt.node, - StmtKind::Break | StmtKind::Continue | StmtKind::Return { .. } + StmtKind::Break | StmtKind::Continue | StmtKind::Return(_) ) }); } diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/loop_variable_overrides_iterator.rs b/crates/ruff/src/rules/flake8_bugbear/rules/loop_variable_overrides_iterator.rs index 0ad811e05c..de3808343b 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/loop_variable_overrides_iterator.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/loop_variable_overrides_iterator.rs @@ -1,5 +1,5 @@ use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -32,18 +32,18 @@ where { fn visit_expr(&mut self, expr: &'b Expr) { match &expr.node { - ExprKind::Name { id, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => { self.names.insert(id, expr); } - ExprKind::ListComp { generators, .. } - | ExprKind::DictComp { generators, .. } - | ExprKind::SetComp { generators, .. } - | ExprKind::GeneratorExp { generators, .. } => { + ExprKind::ListComp(ast::ExprListComp { generators, .. }) + | ExprKind::DictComp(ast::ExprDictComp { generators, .. }) + | ExprKind::SetComp(ast::ExprSetComp { generators, .. }) + | ExprKind::GeneratorExp(ast::ExprGeneratorExp { generators, .. }) => { for comp in generators { self.visit_expr(&comp.iter); } } - ExprKind::Lambda { args, body } => { + ExprKind::Lambda(ast::ExprLambda { args, body }) => { visitor::walk_expr(self, body); for arg in &args.args { self.names.remove(arg.node.arg.as_str()); diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs b/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs index 600468c804..da604308f7 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/mutable_argument_default.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Arguments, Expr, ExprKind}; +use rustpython_parser::ast::{self, Arguments, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -38,13 +38,13 @@ pub fn is_mutable_func(checker: &Checker, func: &Expr) -> bool { fn is_mutable_expr(checker: &Checker, expr: &Expr) -> bool { match &expr.node { - ExprKind::List { .. } - | ExprKind::Dict { .. } - | ExprKind::Set { .. } - | ExprKind::ListComp { .. } - | ExprKind::DictComp { .. } - | ExprKind::SetComp { .. } => true, - ExprKind::Call { func, .. } => is_mutable_func(checker, func), + ExprKind::List(_) + | ExprKind::Dict(_) + | ExprKind::Set(_) + | ExprKind::ListComp(_) + | ExprKind::DictComp(_) + | ExprKind::SetComp(_) => true, + ExprKind::Call(ast::ExprCall { func, .. }) => is_mutable_func(checker, func), _ => false, } } diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs b/crates/ruff/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs index 4f90f46b86..cbf6e7c53f 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/raise_without_from_inside_except.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ExprKind, Stmt}; +use rustpython_parser::ast::{self, ExprKind, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -33,7 +33,7 @@ pub fn raise_without_from_inside_except(checker: &mut Checker, body: &[Stmt]) { if cause.is_none() { if let Some(exc) = exc { match &exc.node { - ExprKind::Name { id, .. } if is_lower(id) => {} + ExprKind::Name(ast::ExprName { id, .. }) if is_lower(id) => {} _ => { checker .diagnostics diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs b/crates/ruff/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs index cefae124e7..a4455d4f4e 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/redundant_tuple_in_exception_handler.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, ExprKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -31,10 +31,10 @@ impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler { /// B013 pub fn redundant_tuple_in_exception_handler(checker: &mut Checker, handlers: &[Excepthandler]) { for handler in handlers { - let ExcepthandlerKind::ExceptHandler { type_: Some(type_), .. } = &handler.node else { + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_: Some(type_), .. }) = &handler.node else { continue; }; - let ExprKind::Tuple { elts, .. } = &type_.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &type_.node else { continue; }; let [elt] = &elts[..] else { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs b/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs index c6622737d5..dc36fb1be1 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/reuse_of_groupby_generator.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Comprehension, Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Comprehension, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -84,7 +84,7 @@ impl<'a> GroupNameFinder<'a> { } fn name_matches(&self, expr: &Expr) -> bool { - if let ExprKind::Name { id, .. } = &expr.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node { id == self.group_name } else { false @@ -113,9 +113,9 @@ where return; } match &stmt.node { - StmtKind::For { + StmtKind::For(ast::StmtFor { target, iter, body, .. - } => { + }) => { if self.name_matches(target) { self.overridden = true; } else { @@ -138,15 +138,15 @@ where self.nested = false; } } - StmtKind::While { body, .. } => { + StmtKind::While(ast::StmtWhile { body, .. }) => { self.nested = true; visitor::walk_body(self, body); self.nested = false; } - StmtKind::If { test, body, orelse } => { + StmtKind::If(ast::StmtIf { test, body, orelse }) => { // Determine whether we're on an `if` arm (as opposed to an `elif`). let is_if_arm = !self.parent_ifs.iter().any(|parent| { - if let StmtKind::If { orelse, .. } = &parent.node { + if let StmtKind::If(ast::StmtIf { orelse, .. }) = &parent.node { orelse.len() == 1 && &orelse[0] == stmt } else { false @@ -166,7 +166,7 @@ where let has_else = orelse .first() - .map_or(false, |expr| !matches!(expr.node, StmtKind::If { .. })); + .map_or(false, |expr| !matches!(expr.node, StmtKind::If(_))); self.parent_ifs.push(stmt); if has_else { @@ -193,7 +193,7 @@ where } } } - StmtKind::Match { subject, cases } => { + StmtKind::Match(ast::StmtMatch { subject, cases }) => { self.counter_stack.push(Vec::with_capacity(cases.len())); self.visit_expr(subject); for match_case in cases { @@ -207,14 +207,14 @@ where self.increment_usage_count(max_count); } } - StmtKind::Assign { targets, value, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { if targets.iter().any(|target| self.name_matches(target)) { self.overridden = true; } else { self.visit_expr(value); } } - StmtKind::AnnAssign { target, value, .. } => { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, value, .. }) => { if self.name_matches(target) { self.overridden = true; } else if let Some(expr) = value { @@ -241,7 +241,7 @@ where } fn visit_expr(&mut self, expr: &'a Expr) { - if let ExprKind::NamedExpr { target, .. } = &expr.node { + if let ExprKind::NamedExpr(ast::ExprNamedExpr { target, .. }) = &expr.node { if self.name_matches(target) { self.overridden = true; } @@ -251,7 +251,8 @@ where } match &expr.node { - ExprKind::ListComp { elt, generators } | ExprKind::SetComp { elt, generators } => { + ExprKind::ListComp(ast::ExprListComp { elt, generators }) + | ExprKind::SetComp(ast::ExprSetComp { elt, generators }) => { for comprehension in generators { self.visit_comprehension(comprehension); } @@ -261,11 +262,11 @@ where self.nested = false; } } - ExprKind::DictComp { + ExprKind::DictComp(ast::ExprDictComp { key, value, generators, - } => { + }) => { for comprehension in generators { self.visit_comprehension(comprehension); } @@ -307,10 +308,10 @@ pub fn reuse_of_groupby_generator( body: &[Stmt], iter: &Expr, ) { - let ExprKind::Call { func, .. } = &iter.node else { + let ExprKind::Call(ast::ExprCall { func, .. }) = &iter.node else { return; }; - let ExprKind::Tuple { elts, .. } = &target.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &target.node else { // Ignore any `groupby()` invocation that isn't unpacked return; }; @@ -318,7 +319,7 @@ pub fn reuse_of_groupby_generator( return; } // We have an invocation of groupby which is a simple unpacking - let ExprKind::Name { id: group_name, .. } = &elts[1].node else { + let ExprKind::Name(ast::ExprName { id: group_name, .. }) = &elts[1].node else { return; }; // Check if the function call is `itertools.groupby` diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs b/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs index 57efc0d8c0..3427dda7ad 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/setattr_with_constant.rs @@ -1,5 +1,5 @@ -use ruff_text_size::TextSize; -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; +use ruff_text_size::TextRange; +use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -29,28 +29,26 @@ impl AlwaysAutofixableViolation for SetAttrWithConstant { fn assignment(obj: &Expr, name: &str, value: &Expr, stylist: &Stylist) -> String { let stmt = Stmt::new( - TextSize::default(), - TextSize::default(), - StmtKind::Assign { + TextRange::default(), + StmtKind::Assign(ast::StmtAssign { targets: vec![Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::Attribute { + TextRange::default(), + ExprKind::Attribute(ast::ExprAttribute { value: Box::new(obj.clone()), - attr: name.to_string(), + attr: name.into(), ctx: ExprContext::Store, - }, + }), )], value: Box::new(value.clone()), type_comment: None, - }, + }), ); unparse_stmt(&stmt, stylist) } /// B010 pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { return; }; if id != "setattr" { @@ -59,10 +57,10 @@ pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar let [obj, name, value] = args else { return; }; - let ExprKind::Constant { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(name), .. - } = &name.node else { + } )= &name.node else { return; }; if !is_identifier(name) { @@ -74,7 +72,7 @@ pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar // We can only replace a `setattr` call (which is an `Expr`) with an assignment // (which is a `Stmt`) if the `Expr` is already being used as a `Stmt` // (i.e., it's directly within an `StmtKind::Expr`). - if let StmtKind::Expr { value: child } = &checker.ctx.stmt().node { + if let StmtKind::Expr(ast::StmtExpr { value: child }) = &checker.ctx.stmt().node { if expr == child.as_ref() { let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range()); diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/star_arg_unpacking_after_keyword_arg.rs b/crates/ruff/src/rules/flake8_bugbear/rules/star_arg_unpacking_after_keyword_arg.rs index e4cc0733b7..1db8bc0c43 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/star_arg_unpacking_after_keyword_arg.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/star_arg_unpacking_after_keyword_arg.rs @@ -34,7 +34,7 @@ pub fn star_arg_unpacking_after_keyword_arg( return; }; for arg in args { - let ExprKind::Starred { .. } = arg.node else { + let ExprKind::Starred (_) = arg.node else { continue; }; if arg.start() <= keyword.start() { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs b/crates/ruff/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs index 551ca2eea2..fa0874c3e7 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/strip_with_multi_characters.rs @@ -1,5 +1,5 @@ use itertools::Itertools; -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -18,7 +18,7 @@ impl Violation for StripWithMultiCharacters { /// B005 pub fn strip_with_multi_characters(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) { - let ExprKind::Attribute { attr, .. } = &func.node else { + let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node else { return; }; if !matches!(attr.as_str(), "strip" | "lstrip" | "rstrip") { @@ -28,10 +28,10 @@ pub fn strip_with_multi_characters(checker: &mut Checker, expr: &Expr, func: &Ex return; } - let ExprKind::Constant { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &args[0].node else { + } )= &args[0].node else { return; }; diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/unary_prefix_increment.rs b/crates/ruff/src/rules/flake8_bugbear/rules/unary_prefix_increment.rs index 066b7cf677..121e4ba772 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/unary_prefix_increment.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/unary_prefix_increment.rs @@ -17,7 +17,7 @@ //! n += 1 //! ``` -use rustpython_parser::ast::{Expr, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Expr, ExprKind, Unaryop}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -39,7 +39,7 @@ pub fn unary_prefix_increment(checker: &mut Checker, expr: &Expr, op: &Unaryop, if !matches!(op, Unaryop::UAdd) { return; } - let ExprKind::UnaryOp { op, .. } = &operand.node else { + let ExprKind::UnaryOp(ast::ExprUnaryOp { op, .. })= &operand.node else { return; }; if !matches!(op, Unaryop::UAdd) { diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs b/crates/ruff/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs index d8b5b8793c..dfe246c6ae 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/unintentional_type_annotation.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -44,15 +44,15 @@ pub fn unintentional_type_annotation( return; } match &target.node { - ExprKind::Subscript { value, .. } => { - if matches!(&value.node, ExprKind::Name { .. }) { + ExprKind::Subscript(ast::ExprSubscript { value, .. }) => { + if matches!(&value.node, ExprKind::Name(_)) { checker .diagnostics .push(Diagnostic::new(UnintentionalTypeAnnotation, stmt.range())); } } - ExprKind::Attribute { value, .. } => { - if let ExprKind::Name { id, .. } = &value.node { + ExprKind::Attribute(ast::ExprAttribute { value, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { if id != "self" { checker .diagnostics diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs b/crates/ruff/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs index 570b2f1a5a..2350e6d59e 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/unreliable_callable_check.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -20,7 +20,7 @@ impl Violation for UnreliableCallableCheck { /// B004 pub fn unreliable_callable_check(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { return; }; if id != "getattr" && id != "hasattr" { @@ -29,10 +29,10 @@ pub fn unreliable_callable_check(checker: &mut Checker, expr: &Expr, func: &Expr if args.len() < 2 { return; }; - let ExprKind::Constant { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(s), .. - } = &args[1].node else + }) = &args[1].node else { return; }; diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs b/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs index aca4ad2762..ac49e41a15 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs @@ -19,7 +19,7 @@ //! ``` use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt}; use serde::{Deserialize, Serialize}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; @@ -93,7 +93,7 @@ where 'b: 'a, { fn visit_expr(&mut self, expr: &'a Expr) { - if let ExprKind::Name { id, .. } = &expr.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node { self.names.insert(id, expr); } visitor::walk_expr(self, expr); diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/useless_comparison.rs b/crates/ruff/src/rules/flake8_bugbear/rules/useless_comparison.rs index 4d4dc2fe63..ea6b564125 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/useless_comparison.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/useless_comparison.rs @@ -20,7 +20,7 @@ impl Violation for UselessComparison { /// B015 pub fn useless_comparison(checker: &mut Checker, expr: &Expr) { - if matches!(expr.node, ExprKind::Compare { .. }) { + if matches!(expr.node, ExprKind::Compare(_)) { checker .diagnostics .push(Diagnostic::new(UselessComparison, expr.range())); diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs b/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs index 3ff2acaec7..f982abb9fa 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/useless_expression.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -36,18 +36,18 @@ impl Violation for UselessExpression { /// B018 pub fn useless_expression(checker: &mut Checker, value: &Expr) { // Ignore comparisons, as they're handled by `useless_comparison`. - if matches!(value.node, ExprKind::Compare { .. }) { + if matches!(value.node, ExprKind::Compare(_)) { return; } // Ignore strings, to avoid false positives with docstrings. if matches!( value.node, - ExprKind::JoinedStr { .. } - | ExprKind::Constant { + ExprKind::JoinedStr(_) + | ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..) | Constant::Ellipsis, .. - } + }) ) { return; } @@ -56,7 +56,7 @@ pub fn useless_expression(checker: &mut Checker, value: &Expr) { if contains_effect(value, |id| checker.ctx.is_builtin(id)) { // Flag attributes as useless expressions, even if they're attached to calls or other // expressions. - if matches!(value.node, ExprKind::Attribute { .. }) { + if matches!(value.node, ExprKind::Attribute(_)) { checker.diagnostics.push(Diagnostic::new( UselessExpression { kind: Kind::Attribute, diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs b/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs index ec3c3db340..4f2cab283c 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/zip_without_explicit_strict.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use crate::checkers::ast::Checker; use ruff_diagnostics::{Diagnostic, Violation}; @@ -21,7 +21,7 @@ pub fn zip_without_explicit_strict( func: &Expr, kwargs: &[Keyword], ) { - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { if id == "zip" && checker.ctx.is_builtin("zip") && !kwargs.iter().any(|keyword| { diff --git a/crates/ruff/src/rules/flake8_builtins/rules.rs b/crates/ruff/src/rules/flake8_builtins/rules.rs index 07e5dcd653..eddaff482e 100644 --- a/crates/ruff/src/rules/flake8_builtins/rules.rs +++ b/crates/ruff/src/rules/flake8_builtins/rules.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::Located; +use rustpython_parser::ast::Attributed; use ruff_diagnostics::Violation; use ruff_diagnostics::{Diagnostic, DiagnosticKind}; @@ -170,7 +170,7 @@ impl Violation for BuiltinAttributeShadowing { /// Check builtin name shadowing. pub fn builtin_shadowing( name: &str, - located: &Located, + located: &Attributed, node_type: ShadowingType, ignorelist: &[String], ) -> Option { diff --git a/crates/ruff/src/rules/flake8_comprehensions/fixes.rs b/crates/ruff/src/rules/flake8_comprehensions/fixes.rs index 335174f327..955c38edd4 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/fixes.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/fixes.rs @@ -116,7 +116,7 @@ pub fn fix_unnecessary_generator_set( // If the expression is embedded in an f-string, surround it with spaces to avoid // syntax errors. if let Some(parent_element) = parent { - if let &rustpython_parser::ast::ExprKind::FormattedValue { .. } = &parent_element.node { + if let &rustpython_parser::ast::ExprKind::FormattedValue(_) = &parent_element.node { content = format!(" {content} "); } } @@ -186,7 +186,7 @@ pub fn fix_unnecessary_generator_dict( // If the expression is embedded in an f-string, surround it with spaces to avoid // syntax errors. if let Some(parent_element) = parent { - if let &rustpython_parser::ast::ExprKind::FormattedValue { .. } = &parent_element.node { + if let &rustpython_parser::ast::ExprKind::FormattedValue(_) = &parent_element.node { content = format!(" {content} "); } } @@ -1101,9 +1101,7 @@ pub fn fix_unnecessary_map( // syntax errors. if kind == "set" || kind == "dict" { if let Some(parent_element) = parent { - if let &rustpython_parser::ast::ExprKind::FormattedValue { .. } = - &parent_element.node - { + if let &rustpython_parser::ast::ExprKind::FormattedValue(_) = &parent_element.node { content = format!(" {content} "); } } diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/helpers.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/helpers.rs index 0e5244e04e..c5f55e7cf2 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/helpers.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/helpers.rs @@ -1,7 +1,7 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; pub fn expr_name(func: &Expr) -> Option<&str> { - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { Some(id) } else { None diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs index 604e5e2f5e..85b1afa245 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_call_around_sorted.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use crate::checkers::ast::Checker; use crate::registry::AsRule; @@ -65,7 +65,7 @@ pub fn unnecessary_call_around_sorted( let Some(arg) = args.first() else { return; }; - let ExprKind::Call { func, .. } = &arg.node else { + let ExprKind::Call(ast::ExprCall { func, .. }) = &arg.node else { return; }; let Some(inner) = helpers::expr_name(func) else { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs index 5b0a60a349..212292fe14 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Comprehension, Expr, ExprKind}; +use rustpython_parser::ast::{self, Comprehension, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic}; use ruff_macros::{derive_message_formats, violation}; @@ -51,9 +51,9 @@ impl AlwaysAutofixableViolation for UnnecessaryComprehension { /// Add diagnostic for C416 based on the expression node id. fn add_diagnostic(checker: &mut Checker, expr: &Expr) { let id = match &expr.node { - ExprKind::ListComp { .. } => "list", - ExprKind::SetComp { .. } => "set", - ExprKind::DictComp { .. } => "dict", + ExprKind::ListComp(_) => "list", + ExprKind::SetComp(_) => "set", + ExprKind::DictComp(_) => "dict", _ => return, }; if !checker.ctx.is_builtin(id) { @@ -86,7 +86,7 @@ pub fn unnecessary_dict_comprehension( return; } let generator = &generators[0]; - if !(generator.ifs.is_empty() && generator.is_async == 0) { + if !generator.ifs.is_empty() || generator.is_async { return; } let Some(key_id) = helpers::expr_name(key) else { @@ -95,7 +95,7 @@ pub fn unnecessary_dict_comprehension( let Some(value_id) = helpers::expr_name(value) else { return; }; - let ExprKind::Tuple { elts, .. } = &generator.target.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &generator.target.node else { return; }; if elts.len() != 2 { @@ -127,7 +127,7 @@ pub fn unnecessary_list_set_comprehension( return; } let generator = &generators[0]; - if !(generator.ifs.is_empty() && generator.is_async == 0) { + if !generator.ifs.is_empty() || generator.is_async { return; } let Some(elt_id) = helpers::expr_name(elt) else { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs index 9074c53c86..c6276285e7 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_comprehension_any_all.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use ruff_diagnostics::Violation; use ruff_diagnostics::{AutofixKind, Diagnostic}; @@ -66,11 +66,11 @@ pub fn unnecessary_comprehension_any_all( if !keywords.is_empty() { return; } - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. } )= &func.node else { return; }; if (matches!(id.as_str(), "all" | "any")) && args.len() == 1 { - let (ExprKind::ListComp { elt, .. } | ExprKind::SetComp { elt, .. }) = &args[0].node else { + let (ExprKind::ListComp(ast::ExprListComp { elt, .. } )| ExprKind::SetComp(ast::ExprSetComp { elt, .. })) = &args[0].node else { return; }; if is_async_generator(elt) { @@ -92,5 +92,5 @@ pub fn unnecessary_comprehension_any_all( /// Return `true` if the `Expr` contains an `await` expression. fn is_async_generator(expr: &Expr) -> bool { - any_over_expr(expr, &|expr| matches!(expr.node, ExprKind::Await { .. })) + any_over_expr(expr, &|expr| matches!(expr.node, ExprKind::Await(_))) } diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs index 91f045cf94..e9a4e510bd 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_double_cast_or_process.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic}; use ruff_macros::{derive_message_formats, violation}; @@ -84,7 +84,7 @@ pub fn unnecessary_double_cast_or_process( let Some(arg) = args.first() else { return; }; - let ExprKind::Call { func, ..} = &arg.node else { + let ExprKind::Call(ast::ExprCall { func, ..} )= &arg.node else { return; }; let Some(inner) = helpers::expr_name(func) else { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs index 5362123858..a2b686512c 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_dict.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic}; use ruff_macros::{derive_message_formats, violation}; @@ -53,9 +53,9 @@ pub fn unnecessary_generator_dict( let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else { return; }; - if let ExprKind::GeneratorExp { elt, .. } = argument { + if let ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, .. }) = argument { match &elt.node { - ExprKind::Tuple { elts, .. } if elts.len() == 2 => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) if elts.len() == 2 => { let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorDict, expr.range()); if checker.patch(diagnostic.kind.rule()) { #[allow(deprecated)] diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs index 21410a2fd0..e5031155bb 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_list.rs @@ -55,7 +55,7 @@ pub fn unnecessary_generator_list( if !checker.ctx.is_builtin("list") { return; } - if let ExprKind::GeneratorExp { .. } = argument { + if let ExprKind::GeneratorExp(_) = argument { let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorList, expr.range()); if checker.patch(diagnostic.kind.rule()) { #[allow(deprecated)] diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs index b368778fc4..a6391bf068 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs @@ -56,7 +56,7 @@ pub fn unnecessary_generator_set( if !checker.ctx.is_builtin("set") { return; } - if let ExprKind::GeneratorExp { .. } = argument { + if let ExprKind::GeneratorExp(_) = argument { let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorSet, expr.range()); if checker.patch(diagnostic.kind.rule()) { #[allow(deprecated)] diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs index ef978a8c10..7aeb89c851 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_call.rs @@ -45,7 +45,7 @@ pub fn unnecessary_list_call(checker: &mut Checker, expr: &Expr, func: &Expr, ar if !checker.ctx.is_builtin("list") { return; } - if !matches!(argument, ExprKind::ListComp { .. }) { + if !matches!(argument, ExprKind::ListComp(_)) { return; } let mut diagnostic = Diagnostic::new(UnnecessaryListCall, expr.range()); diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs index 9a350298e6..f96c466086 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_dict.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use crate::checkers::ast::Checker; use crate::registry::AsRule; @@ -52,10 +52,10 @@ pub fn unnecessary_list_comprehension_dict( if !checker.ctx.is_builtin("dict") { return; } - let ExprKind::ListComp { elt, .. } = &argument else { + let ExprKind::ListComp(ast::ExprListComp { elt, .. }) = &argument else { return; }; - let ExprKind::Tuple { elts, .. } = &elt.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &elt.node else { return; }; if elts.len() != 2 { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs index 89489406fd..da41599912 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_list_comprehension_set.rs @@ -53,7 +53,7 @@ pub fn unnecessary_list_comprehension_set( if !checker.ctx.is_builtin("set") { return; } - if let ExprKind::ListComp { .. } = &argument { + if let ExprKind::ListComp(_) = &argument { let mut diagnostic = Diagnostic::new(UnnecessaryListComprehensionSet, expr.range()); if checker.patch(diagnostic.kind.rule()) { #[allow(deprecated)] diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs index 4809b64b7c..3d382b90d0 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_dict.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use crate::checkers::ast::Checker; use crate::registry::AsRule; @@ -60,15 +60,14 @@ pub fn unnecessary_literal_dict( return; } let (kind, elts) = match argument { - ExprKind::Tuple { elts, .. } => ("tuple", elts), - ExprKind::List { elts, .. } => ("list", elts), + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => ("tuple", elts), + ExprKind::List(ast::ExprList { elts, .. }) => ("list", elts), _ => return, }; // Accept `dict((1, 2), ...))` `dict([(1, 2), ...])`. - if !elts - .iter() - .all(|elt| matches!(&elt.node, ExprKind::Tuple { elts, .. } if elts.len() == 2)) - { + if !elts.iter().all( + |elt| matches!(&elt.node, ExprKind::Tuple(ast::ExprTuple { elts, .. } )if elts.len() == 2), + ) { return; } let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs index 20900243fb..1cd490451a 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_set.rs @@ -61,8 +61,8 @@ pub fn unnecessary_literal_set( return; } let kind = match argument { - ExprKind::List { .. } => "list", - ExprKind::Tuple { .. } => "tuple", + ExprKind::List(_) => "list", + ExprKind::Tuple(_) => "tuple", _ => return, }; let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs index 3548f8fc9f..b7b2f9bb91 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_dict_call.rs @@ -79,8 +79,8 @@ pub fn unnecessary_literal_within_dict_call( return; } let argument_kind = match argument { - ExprKind::DictComp { .. } => DictKind::Comprehension, - ExprKind::Dict { .. } => DictKind::Literal, + ExprKind::DictComp(_) => DictKind::Comprehension, + ExprKind::Dict(_) => DictKind::Literal, _ => return, }; let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs index ff6cc7c923..3ec88ff9c6 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_list_call.rs @@ -82,8 +82,8 @@ pub fn unnecessary_literal_within_list_call( return; } let argument_kind = match argument { - ExprKind::Tuple { .. } => "tuple", - ExprKind::List { .. } => "list", + ExprKind::Tuple(_) => "tuple", + ExprKind::List(_) => "list", _ => return, }; let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs index 48c6a6a075..a7b4aa7dc6 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_literal_within_tuple_call.rs @@ -83,8 +83,8 @@ pub fn unnecessary_literal_within_tuple_call( return; } let argument_kind = match argument { - ExprKind::Tuple { .. } => "tuple", - ExprKind::List { .. } => "list", + ExprKind::Tuple(_) => "tuple", + ExprKind::List(_) => "list", _ => return, }; let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs index e184c44d3e..f1536047d4 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_map.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::Diagnostic; use ruff_diagnostics::{AutofixKind, Violation}; @@ -94,7 +94,7 @@ pub fn unnecessary_map( // Exclude the parent if already matched by other arms if let Some(parent) = parent { - if let ExprKind::Call { func: f, .. } = &parent.node { + if let ExprKind::Call(ast::ExprCall { func: f, .. }) = &parent.node { if let Some(id_parent) = helpers::expr_name(f) { if id_parent == "dict" || id_parent == "set" || id_parent == "list" { return; @@ -103,7 +103,7 @@ pub fn unnecessary_map( }; }; - if args.len() == 2 && matches!(&args[0].node, ExprKind::Lambda { .. }) { + if args.len() == 2 && matches!(&args[0].node, ExprKind::Lambda(_)) { let mut diagnostic = create_diagnostic("generator", expr.range()); if checker.patch(diagnostic.kind.rule()) { #[allow(deprecated)] @@ -126,14 +126,14 @@ pub fn unnecessary_map( } if let Some(arg) = args.first() { - if let ExprKind::Call { func, args, .. } = &arg.node { + if let ExprKind::Call(ast::ExprCall { func, args, .. }) = &arg.node { if args.len() != 2 { return; } let Some(argument) = helpers::first_argument_with_matching_function("map", func, args) else { return; }; - if let ExprKind::Lambda { .. } = argument { + if let ExprKind::Lambda(_) = argument { let mut diagnostic = create_diagnostic(id, expr.range()); if checker.patch(diagnostic.kind.rule()) { #[allow(deprecated)] @@ -158,12 +158,12 @@ pub fn unnecessary_map( } if args.len() == 1 { - if let ExprKind::Call { func, args, .. } = &args[0].node { + if let ExprKind::Call(ast::ExprCall { func, args, .. }) = &args[0].node { let Some(argument) = helpers::first_argument_with_matching_function("map", func, args) else { return; }; - if let ExprKind::Lambda { body, .. } = &argument { - if matches!(&body.node, ExprKind::Tuple { elts, .. } | ExprKind::List { elts, .. } if elts.len() == 2) + if let ExprKind::Lambda(ast::ExprLambda { body, .. }) = &argument { + if matches!(&body.node, ExprKind::Tuple(ast::ExprTuple { elts, .. }) | ExprKind::List(ast::ExprList { elts, .. } )if elts.len() == 2) { let mut diagnostic = create_diagnostic(id, expr.range()); if checker.patch(diagnostic.kind.rule()) { diff --git a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs index fca60a1d54..62ea19c828 100644 --- a/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs +++ b/crates/ruff/src/rules/flake8_comprehensions/rules/unnecessary_subscript_reversal.rs @@ -1,5 +1,5 @@ use num_bigint::BigInt; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Unaryop}; use crate::checkers::ast::Checker; use ruff_diagnostics::{Diagnostic, Violation}; @@ -60,10 +60,10 @@ pub fn unnecessary_subscript_reversal( if !checker.ctx.is_builtin(id) { return; } - let ExprKind::Subscript { slice, .. } = &first_arg.node else { + let ExprKind::Subscript(ast::ExprSubscript { slice, .. }) = &first_arg.node else { return; }; - let ExprKind::Slice { lower, upper, step } = &slice.node else { + let ExprKind::Slice(ast::ExprSlice { lower, upper, step }) = &slice.node else { return; }; if lower.is_some() || upper.is_some() { @@ -72,16 +72,16 @@ pub fn unnecessary_subscript_reversal( let Some(step) = step.as_ref() else { return; }; - let ExprKind::UnaryOp { + let ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::USub, operand, - } = &step.node else { + }) = &step.node else { return; }; - let ExprKind::Constant { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(val), .. - } = &operand.node else { + }) = &operand.node else { return; }; if *val != BigInt::from(1) { diff --git a/crates/ruff/src/rules/flake8_datetimez/rules.rs b/crates/ruff/src/rules/flake8_datetimez/rules.rs index ec38cd7a84..83c3cd36a4 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -317,10 +317,10 @@ pub fn call_datetime_strptime_without_zone( } // Does the `strptime` call contain a format string with a timezone specifier? - if let Some(ExprKind::Constant { + if let Some(ExprKind::Constant(ast::ExprConstant { value: Constant::Str(format), kind: None, - }) = args.get(1).as_ref().map(|arg| &arg.node) + })) = args.get(1).as_ref().map(|arg| &arg.node) { if format.contains("%z") { return; @@ -335,8 +335,9 @@ pub fn call_datetime_strptime_without_zone( return; }; - if let ExprKind::Call { keywords, .. } = &grandparent.node { - if let ExprKind::Attribute { attr, .. } = &parent.node { + if let ExprKind::Call(ast::ExprCall { keywords, .. }) = &grandparent.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &parent.node { + let attr = attr.as_str(); // Ex) `datetime.strptime(...).astimezone()` if attr == "astimezone" { return; diff --git a/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs b/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs index 8fbff6667a..7a861a268f 100644 --- a/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs +++ b/crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -52,24 +52,24 @@ pub fn all_with_model_form(checker: &Checker, bases: &[Expr], body: &[Stmt]) -> return None; } for element in body.iter() { - let StmtKind::ClassDef { name, body, .. } = &element.node else { + let StmtKind::ClassDef(ast::StmtClassDef { name, body, .. }) = &element.node else { continue; }; if name != "Meta" { continue; } for element in body.iter() { - let StmtKind::Assign { targets, value, .. } = &element.node else { + let StmtKind::Assign(ast::StmtAssign { targets, value, .. }) = &element.node else { continue; }; for target in targets.iter() { - let ExprKind::Name { id, .. } = &target.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &target.node else { continue; }; if id != "fields" { continue; } - let ExprKind::Constant { value, .. } = &value.node else { + let ExprKind::Constant(ast::ExprConstant { value, .. }) = &value.node else { continue; }; match &value { diff --git a/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs b/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs index b2d5054b5f..f5d1e87b29 100644 --- a/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs +++ b/crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -54,18 +54,18 @@ pub fn exclude_with_model_form( return None; } for element in body.iter() { - let StmtKind::ClassDef { name, body, .. } = &element.node else { + let StmtKind::ClassDef(ast::StmtClassDef { name, body, .. }) = &element.node else { continue; }; if name != "Meta" { continue; } for element in body.iter() { - let StmtKind::Assign { targets, .. } = &element.node else { + let StmtKind::Assign(ast::StmtAssign { targets, .. }) = &element.node else { continue; }; for target in targets.iter() { - let ExprKind::Name { id, .. } = &target.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &target.node else { continue; }; if id == "exclude" { diff --git a/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs b/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs index d2e012bc5f..9c488d60ff 100644 --- a/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs +++ b/crates/ruff/src/rules/flake8_django/rules/locals_in_render_function.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -86,7 +86,7 @@ pub fn locals_in_render_function( } fn is_locals_call(checker: &Checker, expr: &Expr) -> bool { - let ExprKind::Call { func, .. } = &expr.node else { + let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node else { return false }; checker diff --git a/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs b/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs index 6a321ef50a..3d5f66770a 100644 --- a/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs +++ b/crates/ruff/src/rules/flake8_django/rules/model_without_dunder_str.rs @@ -1,5 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, StmtKind}; -use rustpython_parser::ast::{ExprKind, Stmt}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -70,7 +69,7 @@ pub fn model_without_dunder_str( fn has_dunder_method(body: &[Stmt]) -> bool { body.iter().any(|val| match &val.node { - StmtKind::FunctionDef { name, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, .. }) => { if name == "__str__" { return true; } @@ -95,24 +94,24 @@ fn checker_applies(checker: &Checker, bases: &[Expr], body: &[Stmt]) -> bool { /// Check if class is abstract, in terms of Django model inheritance. fn is_model_abstract(body: &[Stmt]) -> bool { for element in body.iter() { - let StmtKind::ClassDef {name, body, ..} = &element.node else { + let StmtKind::ClassDef(ast::StmtClassDef {name, body, ..}) = &element.node else { continue }; if name != "Meta" { continue; } for element in body.iter() { - let StmtKind::Assign {targets, value, ..} = &element.node else { + let StmtKind::Assign(ast::StmtAssign {targets, value, ..}) = &element.node else { continue; }; for target in targets.iter() { - let ExprKind::Name {id , ..} = &target.node else { + let ExprKind::Name(ast::ExprName {id , ..}) = &target.node else { continue; }; if id != "abstract" { continue; } - let ExprKind::Constant{value: Constant::Bool(true), ..} = &value.node else { + let ExprKind::Constant(ast::ExprConstant{value: Constant::Bool(true), ..}) = &value.node else { continue; }; return true; diff --git a/crates/ruff/src/rules/flake8_django/rules/non_leading_receiver_decorator.rs b/crates/ruff/src/rules/flake8_django/rules/non_leading_receiver_decorator.rs index 189a5ccabc..714e55357c 100644 --- a/crates/ruff/src/rules/flake8_django/rules/non_leading_receiver_decorator.rs +++ b/crates/ruff/src/rules/flake8_django/rules/non_leading_receiver_decorator.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -59,9 +59,10 @@ where let mut seen_receiver = false; for (i, decorator) in decorator_list.iter().enumerate() { let is_receiver = match &decorator.node { - ExprKind::Call { func, .. } => resolve_call_path(func).map_or(false, |call_path| { - call_path.as_slice() == ["django", "dispatch", "receiver"] - }), + ExprKind::Call(ast::ExprCall { func, .. }) => resolve_call_path(func) + .map_or(false, |call_path| { + call_path.as_slice() == ["django", "dispatch", "receiver"] + }), _ => false, }; if i > 0 && is_receiver && !seen_receiver { diff --git a/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs b/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs index e5b0f8408c..bddddd9776 100644 --- a/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs +++ b/crates/ruff/src/rules/flake8_django/rules/nullable_model_string_field.rs @@ -1,5 +1,5 @@ use rustpython_parser::ast::Constant::Bool; -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -64,7 +64,7 @@ const NOT_NULL_TRUE_FIELDS: [&str; 6] = [ pub fn nullable_model_string_field(checker: &Checker, body: &[Stmt]) -> Vec { let mut errors = Vec::new(); for statement in body.iter() { - let StmtKind::Assign {value, ..} = &statement.node else { + let StmtKind::Assign(ast::StmtAssign {value, ..}) = &statement.node else { continue }; if let Some(field_name) = is_nullable_field(checker, value) { @@ -80,7 +80,7 @@ pub fn nullable_model_string_field(checker: &Checker, body: &[Stmt]) -> Vec(checker: &'a Checker, value: &'a Expr) -> Option<&'a str> { - let ExprKind::Call {func, keywords, ..} = &value.node else { + let ExprKind::Call(ast::ExprCall {func, keywords, ..}) = &value.node else { return None; }; @@ -96,7 +96,7 @@ fn is_nullable_field<'a>(checker: &'a Checker, value: &'a Expr) -> Option<&'a st let mut blank_key = false; let mut unique_key = false; for keyword in keywords.iter() { - let ExprKind::Constant {value: Bool(true), ..} = &keyword.node.value.node else { + let ExprKind::Constant(ast::ExprConstant {value: Bool(true), ..}) = &keyword.node.value.node else { continue }; let Some(argument) = &keyword.node.arg else { diff --git a/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs b/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs index ecdd4354b3..135879c0af 100644 --- a/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs +++ b/crates/ruff/src/rules/flake8_django/rules/unordered_body_content_in_model.rs @@ -1,6 +1,6 @@ use std::fmt; -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -101,8 +101,8 @@ impl fmt::Display for ContentType { fn get_element_type(checker: &Checker, element: &StmtKind) -> Option { match element { - StmtKind::Assign { targets, value, .. } => { - if let ExprKind::Call { func, .. } = &value.node { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node { if helpers::is_model_field(&checker.ctx, func) { return Some(ContentType::FieldDeclaration); } @@ -110,7 +110,7 @@ fn get_element_type(checker: &Checker, element: &StmtKind) -> Option Option { + StmtKind::ClassDef(ast::StmtClassDef { name, .. }) => { if name == "Meta" { Some(ContentType::MetaClass) } else { None } } - StmtKind::FunctionDef { name, .. } => match name.as_str() { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, .. }) => match name.as_str() { "__str__" => Some(ContentType::StrMethod), "save" => Some(ContentType::SaveMethod), "get_absolute_url" => Some(ContentType::GetAbsoluteUrlMethod), diff --git a/crates/ruff/src/rules/flake8_errmsg/rules.rs b/crates/ruff/src/rules/flake8_errmsg/rules.rs index 453b5aa4ac..ea4a517dc6 100644 --- a/crates/ruff/src/rules/flake8_errmsg/rules.rs +++ b/crates/ruff/src/rules/flake8_errmsg/rules.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -184,14 +184,14 @@ impl Violation for DotFormatInException { /// 2. Replace the exception argument with the variable name. fn generate_fix(stylist: &Stylist, stmt: &Stmt, exc_arg: &Expr, indentation: &str) -> Fix { let assignment = unparse_stmt( - &create_stmt(StmtKind::Assign { - targets: vec![create_expr(ExprKind::Name { - id: String::from("msg"), + &create_stmt(StmtKind::Assign(ast::StmtAssign { + targets: vec![create_expr(ExprKind::Name(ast::ExprName { + id: "msg".into(), ctx: ExprContext::Store, - })], + }))], value: Box::new(exc_arg.clone()), type_comment: None, - }), + })), stylist, ); #[allow(deprecated)] @@ -214,14 +214,14 @@ fn generate_fix(stylist: &Stylist, stmt: &Stmt, exc_arg: &Expr, indentation: &st /// EM101, EM102, EM103 pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) { - if let ExprKind::Call { args, .. } = &exc.node { + if let ExprKind::Call(ast::ExprCall { args, .. }) = &exc.node { if let Some(first) = args.first() { match &first.node { // Check for string literals - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } => { + }) => { if checker.settings.rules.enabled(Rule::RawStringInException) { if string.len() > checker.settings.flake8_errmsg.max_string_length { let indentation = whitespace::indentation(checker.locator, stmt) @@ -249,7 +249,7 @@ pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) { } } // Check for f-strings - ExprKind::JoinedStr { .. } => { + ExprKind::JoinedStr(_) => { if checker.settings.rules.enabled(Rule::FStringInException) { let indentation = whitespace::indentation(checker.locator, stmt).and_then( |indentation| { @@ -275,10 +275,12 @@ pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) { } } // Check for .format() calls - ExprKind::Call { func, .. } => { + ExprKind::Call(ast::ExprCall { func, .. }) => { if checker.settings.rules.enabled(Rule::DotFormatInException) { - if let ExprKind::Attribute { value, attr, .. } = &func.node { - if attr == "format" && matches!(value.node, ExprKind::Constant { .. }) { + if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = + &func.node + { + if attr == "format" && matches!(value.node, ExprKind::Constant(_)) { let indentation = whitespace::indentation(checker.locator, stmt) .and_then(|indentation| { if checker.ctx.find_binding("msg").is_none() { diff --git a/crates/ruff/src/rules/flake8_gettext/rules.rs b/crates/ruff/src/rules/flake8_gettext/rules.rs index 36f9cfca09..d292bba3d2 100644 --- a/crates/ruff/src/rules/flake8_gettext/rules.rs +++ b/crates/ruff/src/rules/flake8_gettext/rules.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Operator}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Operator}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -34,8 +34,8 @@ impl Violation for PrintfInGetTextFuncCall { /// Returns true if the [`Expr`] is an internationalization function call. pub fn is_gettext_func_call(func: &Expr, functions_names: &[String]) -> bool { - if let ExprKind::Name { id, .. } = &func.node { - functions_names.contains(id) + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { + functions_names.contains(id.as_ref()) } else { false } @@ -44,7 +44,7 @@ pub fn is_gettext_func_call(func: &Expr, functions_names: &[String]) -> bool { /// INT001 pub fn f_string_in_gettext_func_call(args: &[Expr]) -> Option { if let Some(first) = args.first() { - if matches!(first.node, ExprKind::JoinedStr { .. }) { + if matches!(first.node, ExprKind::JoinedStr(_)) { return Some(Diagnostic::new(FStringInGetTextFuncCall {}, first.range())); } } @@ -54,8 +54,8 @@ pub fn f_string_in_gettext_func_call(args: &[Expr]) -> Option { /// INT002 pub fn format_in_gettext_func_call(args: &[Expr]) -> Option { if let Some(first) = args.first() { - if let ExprKind::Call { func, .. } = &first.node { - if let ExprKind::Attribute { attr, .. } = &func.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &first.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node { if attr == "format" { return Some(Diagnostic::new(FormatInGetTextFuncCall {}, first.range())); } @@ -68,16 +68,16 @@ pub fn format_in_gettext_func_call(args: &[Expr]) -> Option { /// INT003 pub fn printf_in_gettext_func_call(args: &[Expr]) -> Option { if let Some(first) = args.first() { - if let ExprKind::BinOp { + if let ExprKind::BinOp(ast::ExprBinOp { op: Operator::Mod { .. }, left, .. - } = &first.node + }) = &first.node { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - } = left.node + }) = left.node { return Some(Diagnostic::new(PrintfInGetTextFuncCall {}, first.range())); } diff --git a/crates/ruff/src/rules/flake8_implicit_str_concat/rules.rs b/crates/ruff/src/rules/flake8_implicit_str_concat/rules.rs index 6ce93c3121..feb8889c81 100644 --- a/crates/ruff/src/rules/flake8_implicit_str_concat/rules.rs +++ b/crates/ruff/src/rules/flake8_implicit_str_concat/rules.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use ruff_text_size::TextRange; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Operator}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Operator}; use rustpython_parser::lexer::LexResult; use rustpython_parser::Tok; @@ -149,22 +149,22 @@ pub fn implicit(tokens: &[LexResult], settings: &Settings, locator: &Locator) -> /// ISC003 pub fn explicit(expr: &Expr) -> Option { - if let ExprKind::BinOp { left, op, right } = &expr.node { + if let ExprKind::BinOp(ast::ExprBinOp { left, op, right }) = &expr.node { if matches!(op, Operator::Add) { if matches!( left.node, - ExprKind::JoinedStr { .. } - | ExprKind::Constant { + ExprKind::JoinedStr(_) + | ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..) | Constant::Bytes(..), .. - } + }) ) && matches!( right.node, - ExprKind::JoinedStr { .. } - | ExprKind::Constant { + ExprKind::JoinedStr(_) + | ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..) | Constant::Bytes(..), .. - } + }) ) { return Some(Diagnostic::new(ExplicitStringConcatenation, expr.range())); } diff --git a/crates/ruff/src/rules/flake8_logging_format/rules.rs b/crates/ruff/src/rules/flake8_logging_format/rules.rs index ff43fd4ef6..056c04494b 100644 --- a/crates/ruff/src/rules/flake8_logging_format/rules.rs +++ b/crates/ruff/src/rules/flake8_logging_format/rules.rs @@ -1,6 +1,5 @@ use ruff_text_size::{TextRange, TextSize}; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Operator}; -use std::ops::Add; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Operator}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; use ruff_python_ast::helpers::{find_keyword, SimpleCallArgs}; @@ -43,7 +42,7 @@ const RESERVED_ATTRS: &[&str; 22] = &[ fn check_msg(checker: &mut Checker, msg: &Expr) { match &msg.node { // Check for string concatenation and percent format. - ExprKind::BinOp { op, .. } => match op { + ExprKind::BinOp(ast::ExprBinOp { op, .. }) => match op { Operator::Add => { if checker.settings.rules.enabled(Rule::LoggingStringConcat) { checker @@ -61,7 +60,7 @@ fn check_msg(checker: &mut Checker, msg: &Expr) { _ => {} }, // Check for f-strings. - ExprKind::JoinedStr { .. } => { + ExprKind::JoinedStr(_) => { if checker.settings.rules.enabled(Rule::LoggingFString) { checker .diagnostics @@ -69,10 +68,10 @@ fn check_msg(checker: &mut Checker, msg: &Expr) { } } // Check for .format() calls. - ExprKind::Call { func, .. } => { + ExprKind::Call(ast::ExprCall { func, .. }) => { if checker.settings.rules.enabled(Rule::LoggingStringFormat) { - if let ExprKind::Attribute { value, attr, .. } = &func.node { - if attr == "format" && matches!(value.node, ExprKind::Constant { .. }) { + if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node { + if attr == "format" && matches!(value.node, ExprKind::Constant(_)) { checker .diagnostics .push(Diagnostic::new(LoggingStringFormat, msg.range())); @@ -87,13 +86,13 @@ fn check_msg(checker: &mut Checker, msg: &Expr) { /// Check contents of the `extra` argument to logging calls. fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) { match &extra.node.value.node { - ExprKind::Dict { keys, .. } => { + ExprKind::Dict(ast::ExprDict { keys, .. }) => { for key in keys { if let Some(key) = &key { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } = &key.node + }) = &key.node { if RESERVED_ATTRS.contains(&string.as_str()) { checker.diagnostics.push(Diagnostic::new( @@ -105,7 +104,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) { } } } - ExprKind::Call { func, keywords, .. } => { + ExprKind::Call(ast::ExprCall { func, keywords, .. }) => { if checker .ctx .resolve_call_path(func) @@ -151,10 +150,10 @@ pub fn logging_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: return; } - if let ExprKind::Attribute { value, attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node { if let Some(logging_call_type) = LoggingCallType::from_attribute(attr.as_str()) { let call_args = SimpleCallArgs::new(args, keywords); - let level_call_range = TextRange::new(value.end().add(TextSize::from(1)), func.end()); + let level_call_range = TextRange::new(value.end() + TextSize::from(1), func.end()); // G001 - G004 let msg_pos = usize::from(matches!(logging_call_type, LoggingCallType::LogCall)); @@ -202,11 +201,13 @@ pub fn logging_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: // return. if !(matches!( exc_info.node.value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(true), .. - } - ) || if let ExprKind::Call { func, .. } = &exc_info.node.value.node { + }) + ) || if let ExprKind::Call(ast::ExprCall { func, .. }) = + &exc_info.node.value.node + { checker .ctx .resolve_call_path(func) diff --git a/crates/ruff/src/rules/flake8_pie/rules.rs b/crates/ruff/src/rules/flake8_pie/rules.rs index f3bd1b4036..8fdff8e9c5 100644 --- a/crates/ruff/src/rules/flake8_pie/rules.rs +++ b/crates/ruff/src/rules/flake8_pie/rules.rs @@ -5,7 +5,7 @@ use itertools::Either::{Left, Right}; use log::error; use rustc_hash::FxHashSet; use rustpython_parser::ast::{ - Boolop, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind, + self, Boolop, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind, }; use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; @@ -301,15 +301,15 @@ pub fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) { // redundant. Consider removing all `pass` statements instead. let docstring_stmt = &body[0]; let pass_stmt = &body[1]; - let StmtKind::Expr { value } = &docstring_stmt.node else { + let StmtKind::Expr(ast::StmtExpr { value } )= &docstring_stmt.node else { return; }; if matches!( value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..), .. - } + }) ) { if matches!(pass_stmt.node, StmtKind::Pass) { let mut diagnostic = Diagnostic::new(UnnecessaryPass, pass_stmt.range()); @@ -351,18 +351,18 @@ pub fn duplicate_class_field_definition<'a, 'b>( for stmt in body { // Extract the property name from the assignment statement. let target = match &stmt.node { - StmtKind::Assign { targets, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, .. }) => { if targets.len() != 1 { continue; } - if let ExprKind::Name { id, .. } = &targets[0].node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &targets[0].node { id } else { continue; } } - StmtKind::AnnAssign { target, .. } => { - if let ExprKind::Name { id, .. } = &target.node { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { id } else { continue; @@ -407,7 +407,7 @@ pub fn non_unique_enums<'a, 'b>(checker: &mut Checker<'a>, parent: &'b Stmt, bod where 'b: 'a, { - let StmtKind::ClassDef { bases, .. } = &parent.node else { + let StmtKind::ClassDef(ast::StmtClassDef { bases, .. }) = &parent.node else { return; }; @@ -422,11 +422,11 @@ where let mut seen_targets: FxHashSet = FxHashSet::default(); for stmt in body { - let StmtKind::Assign { value, .. } = &stmt.node else { + let StmtKind::Assign(ast::StmtAssign { value, .. }) = &stmt.node else { continue; }; - if let ExprKind::Call { func, .. } = &value.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node { if checker .ctx .resolve_call_path(func) @@ -454,7 +454,7 @@ pub fn unnecessary_spread(checker: &mut Checker, keys: &[Option], values: if let (None, value) = item { // We only care about when the key is None which indicates a spread `**` // inside a dict. - if let ExprKind::Dict { .. } = value.node { + if let ExprKind::Dict(_) = value.node { let diagnostic = Diagnostic::new(UnnecessarySpread, value.range()); checker.diagnostics.push(diagnostic); } @@ -464,10 +464,10 @@ pub fn unnecessary_spread(checker: &mut Checker, keys: &[Option], values: /// Return `true` if a key is a valid keyword argument name. fn is_valid_kwarg_name(key: &Expr) -> bool { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &key.node + }) = &key.node { is_identifier(value) } else { @@ -480,7 +480,7 @@ pub fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[Key for kw in kwargs { // keyword is a spread operator (indicated by None) if kw.node.arg.is_none() { - if let ExprKind::Dict { keys, .. } = &kw.node.value.node { + if let ExprKind::Dict(ast::ExprDict { keys, .. }) = &kw.node.value.node { // ensure foo(**{"bar-bar": 1}) doesn't error if keys.iter().all(|expr| expr.as_ref().map_or(false, is_valid_kwarg_name)) || // handle case of foo(**{**bar}) @@ -496,18 +496,17 @@ pub fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[Key /// PIE810 pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { - let ExprKind::BoolOp { op: Boolop::Or, values } = &expr.node else { + let ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values }) = &expr.node else { return; }; let mut duplicates = BTreeMap::new(); for (index, call) in values.iter().enumerate() { - let ExprKind::Call { + let ExprKind::Call(ast::ExprCall { func, args, keywords, - .. - } = &call.node else { + }) = &call.node else { continue }; @@ -515,15 +514,14 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { continue; } - let ExprKind::Attribute { value, attr, .. } = &func.node else { + let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. } )= &func.node else { continue }; - if attr != "startswith" && attr != "endswith" { continue; } - let ExprKind::Name { id: arg_name, .. } = &value.node else { + let ExprKind::Name(ast::ExprName { id: arg_name, .. } )= &value.node else { continue }; @@ -547,7 +545,7 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { .iter() .map(|index| &values[*index]) .map(|expr| { - let ExprKind::Call { func: _, args, keywords: _} = &expr.node else { + let ExprKind::Call(ast::ExprCall { func: _, args, keywords: _}) = &expr.node else { unreachable!("{}", format!("Indices should only contain `{attr_name}` calls")) }; args.get(0) @@ -555,20 +553,20 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { }) .collect(); - let call = create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Attribute { - value: Box::new(create_expr(ExprKind::Name { - id: arg_name.to_string(), + let call = create_expr(ExprKind::Call(ast::ExprCall { + func: Box::new(create_expr(ExprKind::Attribute(ast::ExprAttribute { + value: Box::new(create_expr(ExprKind::Name(ast::ExprName { + id: arg_name.into(), ctx: ExprContext::Load, - })), - attr: attr_name.to_string(), + }))), + attr: attr_name.into(), ctx: ExprContext::Load, - })), - args: vec![create_expr(ExprKind::Tuple { + }))), + args: vec![create_expr(ExprKind::Tuple(ast::ExprTuple { elts: words .iter() .flat_map(|value| { - if let ExprKind::Tuple { elts, .. } = &value.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &value.node { Left(elts.iter()) } else { Right(iter::once(*value)) @@ -577,13 +575,13 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { .map(Clone::clone) .collect(), ctx: ExprContext::Load, - })], + }))], keywords: vec![], - }); + })); // Generate the combined `BoolOp`. let mut call = Some(call); - let bool_op = create_expr(ExprKind::BoolOp { + let bool_op = create_expr(ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values: values .iter() @@ -596,7 +594,7 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { } }) .collect(), - }); + })); #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr(&bool_op, checker.stylist), @@ -610,7 +608,7 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) { /// PIE807 pub fn reimplemented_list_builtin(checker: &mut Checker, expr: &Expr) { - let ExprKind::Lambda { args, body } = &expr.node else { + let ExprKind::Lambda(ast::ExprLambda { args, body }) = &expr.node else { panic!("Expected ExprKind::Lambda"); }; if args.args.is_empty() @@ -619,7 +617,7 @@ pub fn reimplemented_list_builtin(checker: &mut Checker, expr: &Expr) { && args.vararg.is_none() && args.kwarg.is_none() { - if let ExprKind::List { elts, .. } = &body.node { + if let ExprKind::List(ast::ExprList { elts, .. }) = &body.node { if elts.is_empty() { let mut diagnostic = Diagnostic::new(ReimplementedListBuiltin, expr.range()); if checker.patch(diagnostic.kind.rule()) { diff --git a/crates/ruff/src/rules/flake8_pyi/rules/duplicate_union_member.rs b/crates/ruff/src/rules/flake8_pyi/rules/duplicate_union_member.rs index 6c081b5a3e..cae6193e0f 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/duplicate_union_member.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/duplicate_union_member.rs @@ -1,5 +1,5 @@ use rustc_hash::FxHashSet; -use rustpython_parser::ast::{Expr, ExprKind, Operator}; +use rustpython_parser::ast::{self, Expr, ExprKind, Operator}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -45,11 +45,11 @@ fn traverse_union<'a>( // // So we have to traverse both branches in order (left, then right), to report duplicates // in the order they appear in the source code. - if let ExprKind::BinOp { + if let ExprKind::BinOp(ast::ExprBinOp { op: Operator::BitOr, left, right, - } = &expr.node + }) = &expr.node { // Traverse left subtree, then the right subtree, propagating the previous node. traverse_union(seen_nodes, checker, left, Some(expr)); @@ -72,7 +72,7 @@ fn traverse_union<'a>( let parent = parent.expect("Parent node must exist"); // SAFETY: Parent node must have been a `BinOp` in order for us to have traversed it. - let ExprKind::BinOp { left, right, .. } = &parent.node else { + let ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) = &parent.node else { panic!("Parent node must be a BinOp"); }; diff --git a/crates/ruff/src/rules/flake8_pyi/rules/non_empty_stub_body.rs b/crates/ruff/src/rules/flake8_pyi/rules/non_empty_stub_body.rs index 5467df5780..de669f4736 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/non_empty_stub_body.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/non_empty_stub_body.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -20,8 +20,8 @@ pub fn non_empty_stub_body(checker: &mut Checker, body: &[Stmt]) { if body.len() != 1 { return; } - if let StmtKind::Expr { value } = &body[0].node { - if let ExprKind::Constant { value, .. } = &value.node { + if let StmtKind::Expr(ast::StmtExpr { value }) = &body[0].node { + if let ExprKind::Constant(ast::ExprConstant { value, .. }) = &value.node { if matches!(value, Constant::Ellipsis | Constant::Str(_)) { return; } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs b/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs index fd19847a2f..5d8b73e46a 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/prefix_type_params.rs @@ -1,6 +1,6 @@ use std::fmt; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -63,13 +63,13 @@ pub fn prefix_type_params(checker: &mut Checker, value: &Expr, targets: &[Expr]) if targets.len() != 1 { return; } - if let ExprKind::Name { id, .. } = &targets[0].node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &targets[0].node { if id.starts_with('_') { return; } }; - if let ExprKind::Call { func, .. } = &value.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node { let Some(kind) = checker.ctx.resolve_call_path(func).and_then(|call_path| { if checker.ctx.match_typing_call_path(&call_path, "ParamSpec") { Some(VarKind::ParamSpec) diff --git a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs index dbfb00434d..c9077add37 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/simple_defaults.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Arguments, Constant, Expr, ExprKind, Operator, Unaryop}; +use rustpython_parser::ast::{self, Arguments, Constant, Expr, ExprKind, Operator, Unaryop}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -80,14 +80,16 @@ fn is_valid_default_value_with_annotation( allow_container: bool, ) -> bool { match &default.node { - ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } | ExprKind::Set { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) + | ExprKind::Set(ast::ExprSet { elts }) => { return allow_container && elts.len() <= 10 && elts .iter() .all(|e| is_valid_default_value_with_annotation(e, checker, false)); } - ExprKind::Dict { keys, values, .. } => { + ExprKind::Dict(ast::ExprDict { keys, values }) => { return allow_container && keys.len() <= 10 && keys.iter().zip(values).all(|(k, v)| { @@ -96,60 +98,60 @@ fn is_valid_default_value_with_annotation( }) && is_valid_default_value_with_annotation(v, checker, false) }); } - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Ellipsis | Constant::None, .. - } => { + }) => { return true; } - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..), .. - } => return checker.locator.slice(default.range()).len() <= 50, - ExprKind::Constant { + }) => return checker.locator.slice(default.range()).len() <= 50, + ExprKind::Constant(ast::ExprConstant { value: Constant::Bytes(..), .. - } => return checker.locator.slice(default.range()).len() <= 50, + }) => return checker.locator.slice(default.range()).len() <= 50, // Ex) `123`, `True`, `False`, `3.14` - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(..) | Constant::Bool(..) | Constant::Float(..), .. - } => { + }) => { return checker.locator.slice(default.range()).len() <= 10; } // Ex) `2j` - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Complex { real, .. }, .. - } => { + }) => { if *real == 0.0 { return checker.locator.slice(default.range()).len() <= 10; } } - ExprKind::UnaryOp { + ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::USub, operand, - } => { + }) => { // Ex) `-1`, `-3.14` - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(..) | Constant::Float(..), .. - } = &operand.node + }) = &operand.node { return checker.locator.slice(operand.range()).len() <= 10; } // Ex) `-2j` - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Complex { real, .. }, .. - } = &operand.node + }) = &operand.node { if *real == 0.0 { return checker.locator.slice(operand.range()).len() <= 10; } } // Ex) `-math.inf`, `-math.pi`, etc. - if let ExprKind::Attribute { .. } = &operand.node { + if let ExprKind::Attribute(_) = &operand.node { if checker .ctx .resolve_call_path(operand) @@ -164,34 +166,34 @@ fn is_valid_default_value_with_annotation( } } } - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::Add | Operator::Sub, right, - } => { + }) => { // Ex) `1 + 2j`, `1 - 2j`, `-1 - 2j`, `-1 + 2j` - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Complex { .. }, .. - } = right.node + }) = right.node { // Ex) `1 + 2j`, `1 - 2j` - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(..) | Constant::Float(..), .. - } = &left.node + }) = &left.node { return checker.locator.slice(left.range()).len() <= 10; - } else if let ExprKind::UnaryOp { + } else if let ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::USub, operand, - } = &left.node + }) = &left.node { // Ex) `-1 + 2j`, `-1 - 2j` - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(..) | Constant::Float(..), .. - } = &operand.node + }) = &operand.node { return checker.locator.slice(operand.range()).len() <= 10; } @@ -199,7 +201,7 @@ fn is_valid_default_value_with_annotation( } } // Ex) `math.inf`, `sys.stdin`, etc. - ExprKind::Attribute { .. } => { + ExprKind::Attribute(_) => { if checker .ctx .resolve_call_path(default) @@ -221,18 +223,18 @@ fn is_valid_default_value_with_annotation( /// Returns `true` if an [`Expr`] appears to be a valid PEP 604 union. (e.g. `int | None`) fn is_valid_pep_604_union(annotation: &Expr) -> bool { match &annotation.node { - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::BitOr, right, - } => is_valid_pep_604_union(left) && is_valid_pep_604_union(right), - ExprKind::Name { .. } - | ExprKind::Subscript { .. } - | ExprKind::Attribute { .. } - | ExprKind::Constant { + }) => is_valid_pep_604_union(left) && is_valid_pep_604_union(right), + ExprKind::Name(_) + | ExprKind::Subscript(_) + | ExprKind::Attribute(_) + | ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } => true, + }) => true, _ => false, } } @@ -241,21 +243,21 @@ fn is_valid_pep_604_union(annotation: &Expr) -> bool { fn is_valid_default_value_without_annotation(default: &Expr) -> bool { matches!( &default.node, - ExprKind::Call { .. } - | ExprKind::Name { .. } - | ExprKind::Attribute { .. } - | ExprKind::Subscript { .. } - | ExprKind::Constant { + ExprKind::Call(_) + | ExprKind::Name(_) + | ExprKind::Attribute(_) + | ExprKind::Subscript(_) + | ExprKind::Constant(ast::ExprConstant { value: Constant::Ellipsis | Constant::None, .. - } + }) ) || is_valid_pep_604_union(default) } /// Returns `true` if an [`Expr`] appears to be `TypeVar`, `TypeVarTuple`, `NewType`, or `ParamSpec` /// call. fn is_type_var_like_call(context: &Context, expr: &Expr) -> bool { - let ExprKind::Call { func, .. } = &expr.node else { + let ExprKind::Call(ast::ExprCall { func, .. } )= &expr.node else { return false; }; context.resolve_call_path(func).map_or(false, |call_path| { @@ -272,7 +274,7 @@ fn is_type_var_like_call(context: &Context, expr: &Expr) -> bool { /// Returns `true` if this is a "special" assignment which must have a value (e.g., an assignment to /// `__all__`). fn is_special_assignment(context: &Context, target: &Expr) -> bool { - if let ExprKind::Name { id, .. } = &target.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { match id.as_str() { "__all__" => context.scope().kind.is_module(), "__match_args__" | "__slots__" => context.scope().kind.is_class(), diff --git a/crates/ruff/src/rules/flake8_pyi/rules/type_alias_naming.rs b/crates/ruff/src/rules/flake8_pyi/rules/type_alias_naming.rs index a177689d78..e5dece1db9 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/type_alias_naming.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/type_alias_naming.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -60,7 +60,7 @@ fn is_t_suffixed_type_alias(name: &str) -> bool { /// PYI042 pub fn snake_case_type_alias(checker: &mut Checker, target: &Expr) { - if let ExprKind::Name { id, .. } = target.node() { + if let ExprKind::Name(ast::ExprName { id, .. }) = target.node() { if !is_snake_case_type_alias(id) { return; } @@ -76,7 +76,7 @@ pub fn snake_case_type_alias(checker: &mut Checker, target: &Expr) { /// PYI043 pub fn t_suffixed_type_alias(checker: &mut Checker, target: &Expr) { - if let ExprKind::Name { id, .. } = target.node() { + if let ExprKind::Name(ast::ExprName { id, .. }) = target.node() { if !is_t_suffixed_type_alias(id) { return; } diff --git a/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs index ff62fe6df1..272b5aaa67 100644 --- a/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs +++ b/crates/ruff/src/rules/flake8_pyi/rules/unrecognized_platform.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -126,10 +126,10 @@ pub fn unrecognized_platform( } match &right.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } => { + }) => { // Other values are possible but we don't need them right now. // This protects against typos. if !["linux", "win32", "cygwin", "darwin"].contains(&value.as_str()) diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs index 0865725789..29425a1364 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/assertion.rs @@ -6,7 +6,8 @@ use libcst_native::{ SmallStatement, Statement, Suite, TrailingWhitespace, UnaryOp, UnaryOperation, }; use rustpython_parser::ast::{ - Boolop, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Keyword, Stmt, StmtKind, Unaryop, + self, Boolop, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Keyword, Stmt, StmtKind, + Unaryop, }; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; @@ -135,7 +136,7 @@ where { fn visit_stmt(&mut self, stmt: &'a Stmt) { match &stmt.node { - StmtKind::Assert { .. } => { + StmtKind::Assert(_) => { self.current_assert = Some(stmt); visitor::walk_stmt(self, stmt); self.current_assert = None; @@ -146,9 +147,9 @@ where fn visit_expr(&mut self, expr: &'a Expr) { match &expr.node { - ExprKind::Name { id, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => { if let Some(current_assert) = self.current_assert { - if id.as_str() == self.exception_name { + if id == self.exception_name { self.errors.push(Diagnostic::new( PytestAssertInExcept { name: id.to_string(), @@ -181,11 +182,11 @@ pub fn unittest_assertion( keywords: &[Keyword], ) -> Option { match &func.node { - ExprKind::Attribute { attr, .. } => { + ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => { if let Ok(unittest_assert) = UnittestAssert::try_from(attr.as_str()) { // We're converting an expression to a statement, so avoid applying the fix if // the assertion is part of a larger expression. - let fixable = matches!(checker.ctx.stmt().node, StmtKind::Expr { .. }) + let fixable = matches!(checker.ctx.stmt().node, StmtKind::Expr(_)) && checker.ctx.expr_parent().is_none() && !checker.ctx.scope().kind.is_lambda() && !has_comments_in(expr.range(), checker.locator); @@ -227,7 +228,11 @@ pub fn assert_in_exception_handler(handlers: &[Excepthandler]) -> Vec { + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + name, + body, + .. + }) => { if let Some(name) = name { check_assert_in_except(name, body) } else { @@ -255,28 +260,28 @@ enum CompositionKind { /// `not a and not b` by De Morgan's laws. fn is_composite_condition(test: &Expr) -> CompositionKind { match &test.node { - ExprKind::BoolOp { + ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::And, .. - } => { + }) => { return CompositionKind::Simple; } - ExprKind::UnaryOp { + ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::Not, operand, - } => { - if let ExprKind::BoolOp { + }) => { + if let ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values, - } = &operand.node + }) = &operand.node { // Only split cases without mixed `and` and `or`. return if values.iter().all(|expr| { !matches!( expr.node, - ExprKind::BoolOp { + ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::And, .. - } + }) ) }) { CompositionKind::Simple diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs index b2036afb57..d80a7b2223 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/fixture.rs @@ -1,6 +1,6 @@ use anyhow::Result; use ruff_text_size::{TextLen, TextRange, TextSize}; -use rustpython_parser::ast::{Arguments, Expr, ExprKind, Keyword, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Arguments, Expr, ExprKind, Keyword, Stmt, StmtKind}; use std::fmt; use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; @@ -208,28 +208,28 @@ where { fn visit_stmt(&mut self, stmt: &'b Stmt) { match &stmt.node { - StmtKind::Return { value, .. } => { + StmtKind::Return(ast::StmtReturn { value }) => { if value.is_some() { self.has_return_with_value = true; } } - StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. } => {} + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) => {} _ => visitor::walk_stmt(self, stmt), } } fn visit_expr(&mut self, expr: &'b Expr) { match &expr.node { - ExprKind::YieldFrom { .. } => { + ExprKind::YieldFrom(_) => { self.has_yield_from = true; } - ExprKind::Yield { value, .. } => { + ExprKind::Yield(ast::ExprYield { value }) => { self.yield_statements.push(expr); if value.is_some() { self.has_return_with_value = true; } } - ExprKind::Call { func, .. } => { + ExprKind::Call(ast::ExprCall { func, .. }) => { if collect_call_path(func).map_or(false, |call_path| { call_path.as_slice() == ["request", "addfinalizer"] }) { @@ -278,12 +278,11 @@ pub fn fix_extraneous_scope_function( /// PT001, PT002, PT003 fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &Expr) { match &decorator.node { - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - .. - } => { + }) => { if checker .settings .rules @@ -415,8 +414,8 @@ fn check_fixture_returns(checker: &mut Checker, stmt: &Stmt, name: &str, body: & .enabled(Rule::PytestUselessYieldFixture) { if let Some(stmt) = body.last() { - if let StmtKind::Expr { value, .. } = &stmt.node { - if let ExprKind::Yield { .. } = value.node { + if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node { + if let ExprKind::Yield(_) = value.node { if visitor.yield_statements.len() == 1 { let mut diagnostic = Diagnostic::new( PytestUselessYieldFixture { diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs index 74d0c90506..308cc0b4f4 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/helpers.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_python_ast::call_path::{collect_call_path, CallPath}; use ruff_python_ast::helpers::map_callable; @@ -48,10 +48,10 @@ pub(super) fn is_pytest_parametrize(context: &Context, decorator: &Expr) -> bool } pub(super) fn keyword_is_literal(kw: &Keyword, literal: &str) -> bool { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } = &kw.node.value.node + }) = &kw.node.value.node { string == literal } else { @@ -61,15 +61,17 @@ pub(super) fn keyword_is_literal(kw: &Keyword, literal: &str) -> bool { pub(super) fn is_empty_or_null_string(expr: &Expr) -> bool { match &expr.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } => string.is_empty(), - ExprKind::Constant { + }) => string.is_empty(), + ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } => true, - ExprKind::JoinedStr { values } => values.iter().all(is_empty_or_null_string), + }) => true, + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { + values.iter().all(is_empty_or_null_string) + } _ => false, } } diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/imports.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/imports.rs index 50154ed0e3..df2601e0fa 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/imports.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/imports.rs @@ -36,7 +36,7 @@ pub fn import(import_from: &Stmt, name: &str, asname: Option<&str>) -> Option, - level: Option, + level: Option, ) -> Option { // If level is not zero or module is none, return if let Some(level) = level { diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/marks.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/marks.rs index 92da8d41d8..0cf8987889 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/marks.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/marks.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextSize; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -74,12 +74,11 @@ fn pytest_mark_parentheses( fn check_mark_parentheses(checker: &mut Checker, decorator: &Expr, call_path: &CallPath) { match &decorator.node { - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - .. - } => { + }) => { if !checker.settings.flake8_pytest_style.mark_parentheses && args.is_empty() && keywords.is_empty() @@ -106,7 +105,7 @@ fn check_useless_usefixtures(checker: &mut Checker, decorator: &Expr, call_path: let mut has_parameters = false; - if let ExprKind::Call { args, keywords, .. } = &decorator.node { + if let ExprKind::Call(ast::ExprCall { args, keywords, .. }) = &decorator.node { if !args.is_empty() || !keywords.is_empty() { has_parameters = true; } diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs index c462722f1f..dc6cb5b251 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/parametrize.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; @@ -50,10 +50,10 @@ fn elts_to_csv(elts: &[Expr], checker: &Checker) -> Option { let all_literals = elts.iter().all(|e| { matches!( e.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - } + }) ) }); @@ -62,12 +62,12 @@ fn elts_to_csv(elts: &[Expr], checker: &Checker) -> Option { } Some(unparse_expr( - &create_expr(ExprKind::Constant { + &create_expr(ExprKind::Constant(ast::ExprConstant { value: Constant::Str(elts.iter().fold(String::new(), |mut acc, elt| { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(ref s), .. - } = elt.node + }) = elt.node { if !acc.is_empty() { acc.push(','); @@ -77,7 +77,7 @@ fn elts_to_csv(elts: &[Expr], checker: &Checker) -> Option { acc })), kind: None, - }), + })), checker.stylist, )) } @@ -101,7 +101,7 @@ fn get_parametrize_name_range(checker: &Checker, decorator: &Expr, expr: &Expr) // The parenthesis are not part of the AST, so we need to tokenize the // decorator to find them. - for (tok, range) in lexer::lex_located( + for (tok, range) in lexer::lex_starts_at( checker.locator.slice(decorator.range()), Mode::Module, decorator.start(), @@ -133,10 +133,10 @@ fn check_names(checker: &mut Checker, decorator: &Expr, expr: &Expr) { let names_type = checker.settings.flake8_pytest_style.parametrize_names_type; match &expr.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } => { + }) => { let names = split_names(string); if names.len() > 1 { match names_type { @@ -154,18 +154,20 @@ fn check_names(checker: &mut Checker, decorator: &Expr, expr: &Expr) { format!( "({})", unparse_expr( - &create_expr(ExprKind::Tuple { + &create_expr(ExprKind::Tuple(ast::ExprTuple { elts: names .iter() .map(|&name| { - create_expr(ExprKind::Constant { - value: Constant::Str(name.to_string()), - kind: None, - }) + create_expr(ExprKind::Constant( + ast::ExprConstant { + value: Constant::Str(name.to_string()), + kind: None, + }, + )) }) .collect(), ctx: ExprContext::Load, - }), + })), checker.stylist, ) ), @@ -186,18 +188,18 @@ fn check_names(checker: &mut Checker, decorator: &Expr, expr: &Expr) { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::List { + &create_expr(ExprKind::List(ast::ExprList { elts: names .iter() .map(|&name| { - create_expr(ExprKind::Constant { + create_expr(ExprKind::Constant(ast::ExprConstant { value: Constant::Str(name.to_string()), kind: None, - }) + })) }) .collect(), ctx: ExprContext::Load, - }), + })), checker.stylist, ), name_range, @@ -209,7 +211,7 @@ fn check_names(checker: &mut Checker, decorator: &Expr, expr: &Expr) { } } } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { if elts.len() == 1 { if let Some(first) = elts.first() { handle_single_name(checker, expr, first); @@ -228,10 +230,10 @@ fn check_names(checker: &mut Checker, decorator: &Expr, expr: &Expr) { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::List { + &create_expr(ExprKind::List(ast::ExprList { elts: elts.clone(), ctx: ExprContext::Load, - }), + })), checker.stylist, ), expr.range(), @@ -260,7 +262,7 @@ fn check_names(checker: &mut Checker, decorator: &Expr, expr: &Expr) { } }; } - ExprKind::List { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) => { if elts.len() == 1 { if let Some(first) = elts.first() { handle_single_name(checker, expr, first); @@ -281,10 +283,10 @@ fn check_names(checker: &mut Checker, decorator: &Expr, expr: &Expr) { format!( "({})", unparse_expr( - &create_expr(ExprKind::Tuple { + &create_expr(ExprKind::Tuple(ast::ExprTuple { elts: elts.clone(), ctx: ExprContext::Load, - }), + })), checker.stylist, ) ), @@ -327,10 +329,10 @@ fn check_values(checker: &mut Checker, names: &Expr, values: &Expr) { .flake8_pytest_style .parametrize_values_row_type; - let is_multi_named = if let ExprKind::Constant { + let is_multi_named = if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. - } = &names.node + }) = &names.node { split_names(string).len() > 1 } else { @@ -338,7 +340,7 @@ fn check_values(checker: &mut Checker, names: &Expr, values: &Expr) { }; match &values.node { - ExprKind::List { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) => { if values_type != types::ParametrizeValuesType::List { checker.diagnostics.push(Diagnostic::new( PytestParametrizeValuesWrongType { @@ -352,7 +354,7 @@ fn check_values(checker: &mut Checker, names: &Expr, values: &Expr) { handle_value_rows(checker, elts, values_type, values_row_type); } } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { if values_type != types::ParametrizeValuesType::Tuple { checker.diagnostics.push(Diagnostic::new( PytestParametrizeValuesWrongType { @@ -396,7 +398,7 @@ fn handle_value_rows( ) { for elt in elts { match &elt.node { - ExprKind::Tuple { .. } => { + ExprKind::Tuple(_) => { if values_row_type != types::ParametrizeValuesRowType::Tuple { checker.diagnostics.push(Diagnostic::new( PytestParametrizeValuesWrongType { @@ -407,7 +409,7 @@ fn handle_value_rows( )); } } - ExprKind::List { .. } => { + ExprKind::List(_) => { if values_row_type != types::ParametrizeValuesRowType::List { checker.diagnostics.push(Diagnostic::new( PytestParametrizeValuesWrongType { @@ -426,7 +428,7 @@ fn handle_value_rows( pub fn parametrize(checker: &mut Checker, decorators: &[Expr]) { for decorator in decorators { if is_pytest_parametrize(&checker.ctx, decorator) { - if let ExprKind::Call { args, .. } = &decorator.node { + if let ExprKind::Call(ast::ExprCall { args, .. }) = &decorator.node { if checker .settings .rules diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/patch.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/patch.rs index 4363a8fb80..2cdb60c7ec 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/patch.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/patch.rs @@ -1,5 +1,5 @@ use rustc_hash::FxHashSet; -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -51,7 +51,7 @@ where { fn visit_expr(&mut self, expr: &'b Expr) { match &expr.node { - ExprKind::Name { id, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => { if self.names.contains(&id.as_str()) { self.uses_args = true; } @@ -73,7 +73,7 @@ fn check_patch_call( } if let Some(new_arg) = simple_args.argument("new", new_arg_number) { - if let ExprKind::Lambda { args, body } = &new_arg.node { + if let ExprKind::Lambda(ast::ExprLambda { args, body }) = &new_arg.node { // Walk the lambda body. let mut visitor = LambdaBodyVisitor { names: collect_arg_names(args), diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs index 97d691f618..948c116a99 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/raises.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Keyword, Stmt, StmtKind, Withitem}; +use rustpython_parser::ast::{self, Expr, ExprKind, Identifier, Keyword, Stmt, StmtKind, Withitem}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -82,7 +82,7 @@ pub fn raises_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: if checker.settings.rules.enabled(Rule::PytestRaisesTooBroad) { let match_keyword = keywords .iter() - .find(|kw| kw.node.arg == Some("match".to_string())); + .find(|kw| kw.node.arg == Some(Identifier::new("match"))); if let Some(exception) = args.first() { if let Some(match_keyword) = match_keyword { @@ -101,7 +101,7 @@ pub fn complex_raises(checker: &mut Checker, stmt: &Stmt, items: &[Withitem], bo let mut is_too_complex = false; let raises_called = items.iter().any(|item| match &item.context_expr.node { - ExprKind::Call { func, .. } => is_pytest_raises(checker, func), + ExprKind::Call(ast::ExprCall { func, .. }) => is_pytest_raises(checker, func), _ => false, }); @@ -111,18 +111,19 @@ pub fn complex_raises(checker: &mut Checker, stmt: &Stmt, items: &[Withitem], bo is_too_complex = true; } else if let Some(first_stmt) = body.first() { match &first_stmt.node { - StmtKind::With { body, .. } | StmtKind::AsyncWith { body, .. } => { + StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { if is_non_trivial_with_body(body) { is_too_complex = true; } } - StmtKind::If { .. } - | StmtKind::For { .. } - | StmtKind::Match { .. } - | StmtKind::AsyncFor { .. } - | StmtKind::While { .. } - | StmtKind::Try { .. } - | StmtKind::TryStar { .. } => { + StmtKind::If(_) + | StmtKind::For(_) + | StmtKind::Match(_) + | StmtKind::AsyncFor(_) + | StmtKind::While(_) + | StmtKind::Try(_) + | StmtKind::TryStar(_) => { is_too_complex = true; } _ => {} diff --git a/crates/ruff/src/rules/flake8_pytest_style/rules/unittest_assert.rs b/crates/ruff/src/rules/flake8_pytest_style/rules/unittest_assert.rs index 9ce60532c7..2eefd373ea 100644 --- a/crates/ruff/src/rules/flake8_pytest_style/rules/unittest_assert.rs +++ b/crates/ruff/src/rules/flake8_pytest_style/rules/unittest_assert.rs @@ -3,7 +3,7 @@ use std::hash::BuildHasherDefault; use anyhow::{anyhow, bail, Result}; use rustc_hash::FxHashMap; use rustpython_parser::ast::{ - Cmpop, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind, Unaryop, + self, Cmpop, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind, Unaryop, }; use ruff_python_ast::helpers::{create_expr, create_stmt}; @@ -145,18 +145,18 @@ impl TryFrom<&str> for UnittestAssert { } fn assert(expr: &Expr, msg: Option<&Expr>) -> Stmt { - create_stmt(StmtKind::Assert { + create_stmt(StmtKind::Assert(ast::StmtAssert { test: Box::new(expr.clone()), msg: msg.map(|msg| Box::new(msg.clone())), - }) + })) } fn compare(left: &Expr, cmpop: Cmpop, right: &Expr) -> Expr { - create_expr(ExprKind::Compare { + create_expr(ExprKind::Compare(ast::ExprCompare { left: Box::new(left.clone()), ops: vec![cmpop], comparators: vec![right.clone()], - }) + })) } impl UnittestAssert { @@ -209,7 +209,7 @@ impl UnittestAssert { // If we have variable-length arguments, abort. if args .iter() - .any(|arg| matches!(arg.node, ExprKind::Starred { .. })) + .any(|arg| matches!(arg.node, ExprKind::Starred(_))) || keywords.iter().any(|kw| kw.node.arg.is_none()) { bail!("Variable-length arguments are not supported"); @@ -245,7 +245,7 @@ impl UnittestAssert { .node .arg .as_ref() - .map_or(false, |kwarg_name| kwarg_name == arg_name) + .map_or(false, |kwarg_name| &kwarg_name == arg_name) { Some(&keyword.node.value) } else { @@ -268,10 +268,10 @@ impl UnittestAssert { .ok_or_else(|| anyhow!("Missing argument `expr`"))?; let msg = args.get("msg").copied(); Ok(if matches!(self, UnittestAssert::False) { - let unary_expr = create_expr(ExprKind::UnaryOp { + let unary_expr = create_expr(ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::Not, operand: Box::new(create_expr(expr.node.clone())), - }); + })); assert(&unary_expr, msg) } else { assert(expr, msg) @@ -337,10 +337,10 @@ impl UnittestAssert { let expr = compare( expr, cmpop, - &create_expr(ExprKind::Constant { + &create_expr(ExprKind::Constant(ast::ExprConstant { value: Constant::None, kind: None, - }), + })), ); Ok(assert(&expr, msg)) } @@ -352,9 +352,9 @@ impl UnittestAssert { .get("cls") .ok_or_else(|| anyhow!("Missing argument `cls`"))?; let msg = args.get("msg").copied(); - let isinstance = create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Name { - id: "isinstance".to_string(), + let isinstance = create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprName { + id: "isinstance".into(), ctx: ExprContext::Load, })), args: vec![(**obj).clone(), (**cls).clone()], @@ -363,7 +363,7 @@ impl UnittestAssert { if matches!(self, UnittestAssert::IsInstance) { Ok(assert(&isinstance, msg)) } else { - let expr = create_expr(ExprKind::UnaryOp { + let expr = create_expr(ast::ExprUnaryOp { op: Unaryop::Not, operand: Box::new(isinstance), }); @@ -381,13 +381,13 @@ impl UnittestAssert { .get("regex") .ok_or_else(|| anyhow!("Missing argument `regex`"))?; let msg = args.get("msg").copied(); - let re_search = create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Attribute { - value: Box::new(create_expr(ExprKind::Name { - id: "re".to_string(), + let re_search = create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprAttribute { + value: Box::new(create_expr(ast::ExprName { + id: "re".into(), ctx: ExprContext::Load, })), - attr: "search".to_string(), + attr: "search".into(), ctx: ExprContext::Load, })), args: vec![(**regex).clone(), (**text).clone()], @@ -397,7 +397,7 @@ impl UnittestAssert { Ok(assert(&re_search, msg)) } else { Ok(assert( - &create_expr(ExprKind::UnaryOp { + &create_expr(ast::ExprUnaryOp { op: Unaryop::Not, operand: Box::new(re_search), }), diff --git a/crates/ruff/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs b/crates/ruff/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs index f7be163548..e9bdc69b5b 100644 --- a/crates/ruff/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs +++ b/crates/ruff/src/rules/flake8_raise/rules/unnecessary_paren_on_raise_exception.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -23,11 +23,11 @@ impl AlwaysAutofixableViolation for UnnecessaryParenOnRaiseException { /// RSE102 pub fn unnecessary_paren_on_raise_exception(checker: &mut Checker, expr: &Expr) { - if let ExprKind::Call { + if let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &expr.node + }) = &expr.node { if args.is_empty() && keywords.is_empty() { let range = match_parens(func.end(), checker.locator) diff --git a/crates/ruff/src/rules/flake8_return/helpers.rs b/crates/ruff/src/rules/flake8_return/helpers.rs index 5352fe9587..6f26804b53 100644 --- a/crates/ruff/src/rules/flake8_return/helpers.rs +++ b/crates/ruff/src/rules/flake8_return/helpers.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextSize; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt}; use ruff_python_ast::newlines::StrExt; use ruff_python_ast::source_code::Locator; @@ -11,10 +11,10 @@ pub fn result_exists(returns: &[(&Stmt, Option<&Expr>)]) -> bool { expr.map(|expr| { !matches!( expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } + }) ) }) .unwrap_or(false) diff --git a/crates/ruff/src/rules/flake8_return/rules.rs b/crates/ruff/src/rules/flake8_return/rules.rs index f9bd06734e..b6fa8fa26a 100644 --- a/crates/ruff/src/rules/flake8_return/rules.rs +++ b/crates/ruff/src/rules/flake8_return/rules.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use ruff_text_size::{TextRange, TextSize}; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; @@ -332,10 +332,10 @@ fn unnecessary_return_none(checker: &mut Checker, stack: &Stack) { }; if !matches!( expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } + }) ) { continue; } @@ -403,7 +403,7 @@ fn is_noreturn_func(context: &Context, func: &Expr) -> bool { /// RET503 fn implicit_return(checker: &mut Checker, stmt: &Stmt) { match &stmt.node { - StmtKind::If { body, orelse, .. } => { + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { if let Some(last_stmt) = body.last() { implicit_return(checker, last_stmt); } @@ -427,25 +427,25 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) { checker.diagnostics.push(diagnostic); } } - StmtKind::Assert { test, .. } + StmtKind::Assert(ast::StmtAssert { test, .. }) if matches!( test.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(false), .. - } + }) ) => {} - StmtKind::While { test, .. } + StmtKind::While(ast::StmtWhile { test, .. }) if matches!( test.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(true), .. - } + }) ) => {} - StmtKind::For { orelse, .. } - | StmtKind::AsyncFor { orelse, .. } - | StmtKind::While { orelse, .. } => { + StmtKind::For(ast::StmtFor { orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { orelse, .. }) + | StmtKind::While(ast::StmtWhile { orelse, .. }) => { if let Some(last_stmt) = orelse.last() { implicit_return(checker, last_stmt); } else { @@ -466,26 +466,24 @@ fn implicit_return(checker: &mut Checker, stmt: &Stmt) { checker.diagnostics.push(diagnostic); } } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { for case in cases { if let Some(last_stmt) = case.body.last() { implicit_return(checker, last_stmt); } } } - StmtKind::With { body, .. } | StmtKind::AsyncWith { body, .. } => { + StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { if let Some(last_stmt) = body.last() { implicit_return(checker, last_stmt); } } - StmtKind::Return { .. } - | StmtKind::Raise { .. } - | StmtKind::Try { .. } - | StmtKind::TryStar { .. } => {} - StmtKind::Expr { value, .. } + StmtKind::Return(_) | StmtKind::Raise(_) | StmtKind::Try(_) | StmtKind::TryStar(_) => {} + StmtKind::Expr(ast::StmtExpr { value }) if matches!( &value.node, - ExprKind::Call { func, .. } + ExprKind::Call(ast::ExprCall { func, .. }) if is_noreturn_func(&checker.ctx, func) ) => {} _ => { @@ -595,7 +593,7 @@ fn has_refs_or_assigns_within_try_or_loop(id: &str, stack: &Stack) -> bool { /// RET504 fn unnecessary_assign(checker: &mut Checker, stack: &Stack, expr: &Expr) { - if let ExprKind::Name { id, .. } = &expr.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node { if !stack.assignments.contains_key(id.as_str()) { return; } @@ -626,11 +624,11 @@ fn unnecessary_assign(checker: &mut Checker, stack: &Stack, expr: &Expr) { /// RET505, RET506, RET507, RET508 fn superfluous_else_node(checker: &mut Checker, stmt: &Stmt, branch: Branch) -> bool { - let StmtKind::If { body, .. } = &stmt.node else { + let StmtKind::If(ast::StmtIf { body, .. }) = &stmt.node else { return false; }; for child in body { - if matches!(child.node, StmtKind::Return { .. }) { + if matches!(child.node, StmtKind::Return(_)) { let diagnostic = Diagnostic::new( SuperfluousElseReturn { branch }, elif_else_range(stmt, checker.locator).unwrap_or_else(|| stmt.range()), @@ -650,7 +648,7 @@ fn superfluous_else_node(checker: &mut Checker, stmt: &Stmt, branch: Branch) -> } return true; } - if matches!(child.node, StmtKind::Raise { .. }) { + if matches!(child.node, StmtKind::Raise(_)) { let diagnostic = Diagnostic::new( SuperfluousElseRaise { branch }, elif_else_range(stmt, checker.locator).unwrap_or_else(|| stmt.range()), @@ -697,7 +695,7 @@ pub fn function(checker: &mut Checker, body: &[Stmt], returns: Option<&Expr>) { }; // Skip functions that consist of a single return statement. - if body.len() == 1 && matches!(last_stmt.node, StmtKind::Return { .. }) { + if body.len() == 1 && matches!(last_stmt.node, StmtKind::Return(_)) { return; } diff --git a/crates/ruff/src/rules/flake8_return/visitor.rs b/crates/ruff/src/rules/flake8_return/visitor.rs index a1b0d018e9..d14ae293cc 100644 --- a/crates/ruff/src/rules/flake8_return/visitor.rs +++ b/crates/ruff/src/rules/flake8_return/visitor.rs @@ -1,6 +1,6 @@ use ruff_text_size::{TextRange, TextSize}; use rustc_hash::{FxHashMap, FxHashSet}; -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Identifier, Stmt, StmtKind}; use ruff_python_ast::visitor; use ruff_python_ast::visitor::Visitor; @@ -27,13 +27,13 @@ pub struct ReturnVisitor<'a> { impl<'a> ReturnVisitor<'a> { fn visit_assign_target(&mut self, expr: &'a Expr) { match &expr.node { - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { for elt in elts { self.visit_assign_target(elt); } return; } - ExprKind::Name { id, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => { self.stack .assignments .entry(id) @@ -41,7 +41,7 @@ impl<'a> ReturnVisitor<'a> { .push(expr.start()); return; } - ExprKind::Attribute { .. } => { + ExprKind::Attribute(_) => { // Attribute assignments are often side-effects (e.g., `self.property = value`), // so we conservatively treat them as references to every known // variable. @@ -62,23 +62,24 @@ impl<'a> ReturnVisitor<'a> { impl<'a> Visitor<'a> for ReturnVisitor<'a> { fn visit_stmt(&mut self, stmt: &'a Stmt) { match &stmt.node { - StmtKind::Global { names } | StmtKind::Nonlocal { names } => { + StmtKind::Global(ast::StmtGlobal { names }) + | StmtKind::Nonlocal(ast::StmtNonlocal { names }) => { self.stack .non_locals - .extend(names.iter().map(String::as_str)); + .extend(names.iter().map(Identifier::as_str)); } - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { decorator_list, args, returns, .. - } - | StmtKind::AsyncFunctionDef { + }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { decorator_list, args, returns, .. - } => { + }) => { // Don't recurse into the body, but visit the decorators, etc. for expr in decorator_list { visitor::walk_expr(self, expr); @@ -88,7 +89,7 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { } visitor::walk_arguments(self, args); } - StmtKind::Return { value } => { + StmtKind::Return(ast::StmtReturn { value }) => { self.stack .returns .push((stmt, value.as_ref().map(|expr| &**expr))); @@ -97,9 +98,9 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { visitor::walk_stmt(self, stmt); self.parents.pop(); } - StmtKind::If { orelse, .. } => { + StmtKind::If(ast::StmtIf { orelse, .. }) => { let is_elif_arm = self.parents.iter().any(|parent| { - if let StmtKind::If { orelse, .. } = &parent.node { + if let StmtKind::If(ast::StmtIf { orelse, .. }) = &parent.node { orelse.len() == 1 && &orelse[0] == stmt } else { false @@ -108,7 +109,7 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { if !is_elif_arm { let has_elif = orelse.len() == 1 - && matches!(orelse.first().unwrap().node, StmtKind::If { .. }); + && matches!(orelse.first().unwrap().node, StmtKind::If(_)); let has_else = !orelse.is_empty(); if has_elif { @@ -124,8 +125,8 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { visitor::walk_stmt(self, stmt); self.parents.pop(); } - StmtKind::Assign { targets, value, .. } => { - if let ExprKind::Name { id, .. } = &value.node { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { self.stack .references .entry(id) @@ -137,8 +138,8 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { if let Some(target) = targets.first() { // Skip unpacking assignments, like `x, y = my_object`. - if matches!(target.node, ExprKind::Tuple { .. }) - && !matches!(value.node, ExprKind::Tuple { .. }) + if matches!(target.node, ExprKind::Tuple(_)) + && !matches!(value.node, ExprKind::Tuple(_)) { return; } @@ -146,14 +147,14 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { self.visit_assign_target(target); } } - StmtKind::For { .. } | StmtKind::AsyncFor { .. } | StmtKind::While { .. } => { + StmtKind::For(_) | StmtKind::AsyncFor(_) | StmtKind::While(_) => { self.stack.loops.push(stmt.range()); self.parents.push(stmt); visitor::walk_stmt(self, stmt); self.parents.pop(); } - StmtKind::Try { .. } | StmtKind::TryStar { .. } => { + StmtKind::Try(_) | StmtKind::TryStar(_) => { self.stack.tries.push(stmt.range()); self.parents.push(stmt); @@ -170,7 +171,7 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { fn visit_expr(&mut self, expr: &'a Expr) { match &expr.node { - ExprKind::Call { .. } => { + ExprKind::Call(_) => { // Arbitrary function calls can have side effects, so we conservatively treat // every function call as a reference to every known variable. for name in self.stack.assignments.keys() { @@ -181,14 +182,14 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { .push(expr.start()); } } - ExprKind::Name { id, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => { self.stack .references .entry(id) .or_insert_with(Vec::new) .push(expr.start()); } - ExprKind::YieldFrom { .. } | ExprKind::Yield { .. } => { + ExprKind::YieldFrom(_) | ExprKind::Yield(_) => { self.stack.yields.push(expr); } _ => visitor::walk_expr(self, expr), diff --git a/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs b/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs index 680293e5b1..f97ac69711 100644 --- a/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs +++ b/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -62,15 +62,20 @@ impl Violation for PrivateMemberAccess { /// SLF001 pub fn private_member_access(checker: &mut Checker, expr: &Expr) { - if let ExprKind::Attribute { value, attr, .. } = &expr.node { + if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &expr.node { if (attr.starts_with("__") && !attr.ends_with("__")) || (attr.starts_with('_') && !attr.starts_with("__")) { - if checker.settings.flake8_self.ignore_names.contains(attr) { + if checker + .settings + .flake8_self + .ignore_names + .contains(attr.as_ref()) + { return; } - if let ExprKind::Call { func, .. } = &value.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node { // Ignore `super()` calls. if let Some(call_path) = collect_call_path(func) { if call_path.as_slice() == ["super"] { diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs index 6d0a585f9a..5141ab41e2 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_bool_op.rs @@ -5,7 +5,7 @@ use itertools::Either::{Left, Right}; use itertools::Itertools; use ruff_text_size::TextRange; use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Boolop, Cmpop, Expr, ExprContext, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Boolop, Cmpop, Expr, ExprContext, ExprKind, Unaryop}; use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -239,7 +239,11 @@ impl AlwaysAutofixableViolation for ExprAndFalse { /// Return `true` if two `Expr` instances are equivalent names. fn is_same_expr<'a>(a: &'a Expr, b: &'a Expr) -> Option<&'a str> { - if let (ExprKind::Name { id: a, .. }, ExprKind::Name { id: b, .. }) = (&a.node, &b.node) { + if let ( + ExprKind::Name(ast::ExprName { id: a, .. }), + ExprKind::Name(ast::ExprName { id: b, .. }), + ) = (&a.node, &b.node) + { if a == b { return Some(a); } @@ -249,7 +253,7 @@ fn is_same_expr<'a>(a: &'a Expr, b: &'a Expr) -> Option<&'a str> { /// SIM101 pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { - let ExprKind::BoolOp { op: Boolop::Or, values } = &expr.node else { + let ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values } )= &expr.node else { return; }; @@ -258,7 +262,7 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { let mut duplicates: FxHashMap> = FxHashMap::default(); for (index, call) in values.iter().enumerate() { // Verify that this is an `isinstance` call. - let ExprKind::Call { func, args, keywords } = &call.node else { + let ExprKind::Call(ast::ExprCall { func, args, keywords }) = &call.node else { continue; }; if args.len() != 2 { @@ -267,7 +271,7 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { if !keywords.is_empty() { continue; } - let ExprKind::Name { id: func_name, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id: func_name, .. }) = &func.node else { continue; }; if func_name != "isinstance" { @@ -290,15 +294,16 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { if indices.len() > 1 { // Grab the target used in each duplicate `isinstance` call (e.g., `obj` in // `isinstance(obj, int)`). - let target = if let ExprKind::Call { args, .. } = &values[indices[0]].node { - args.get(0).expect("`isinstance` should have two arguments") - } else { - unreachable!("Indices should only contain `isinstance` calls") - }; + let target = + if let ExprKind::Call(ast::ExprCall { args, .. }) = &values[indices[0]].node { + args.get(0).expect("`isinstance` should have two arguments") + } else { + unreachable!("Indices should only contain `isinstance` calls") + }; let fixable = !contains_effect(target, |id| checker.ctx.is_builtin(id)); let mut diagnostic = Diagnostic::new( DuplicateIsinstanceCall { - name: if let ExprKind::Name { id, .. } = &target.node { + name: if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { Some(id.to_string()) } else { None @@ -313,7 +318,7 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { .iter() .map(|index| &values[*index]) .map(|expr| { - let ExprKind::Call { args, ..} = &expr.node else { + let ExprKind::Call(ast::ExprCall { args, ..}) = &expr.node else { unreachable!("Indices should only contain `isinstance` calls") }; args.get(1).expect("`isinstance` should have two arguments") @@ -321,19 +326,21 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { .collect(); // Generate a single `isinstance` call. - let call = create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Name { - id: "isinstance".to_string(), + let call = create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprName { + id: "isinstance".into(), ctx: ExprContext::Load, })), args: vec![ target.clone(), - create_expr(ExprKind::Tuple { + create_expr(ast::ExprTuple { // Flatten all the types used across the `isinstance` calls. elts: types .iter() .flat_map(|value| { - if let ExprKind::Tuple { elts, .. } = &value.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = + &value.node + { Left(elts.iter()) } else { Right(iter::once(*value)) @@ -348,7 +355,7 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { }); // Generate the combined `BoolOp`. - let bool_op = create_expr(ExprKind::BoolOp { + let bool_op = create_expr(ast::ExprBoolOp { op: Boolop::Or, values: iter::once(call) .chain( @@ -375,7 +382,7 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) { } fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> { - let ExprKind::Compare { left, ops, comparators } = &expr.node else { + let ExprKind::Compare(ast::ExprCompare { left, ops, comparators } )= &expr.node else { return None; }; if ops.len() != 1 || comparators.len() != 1 { @@ -384,11 +391,11 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> { if !matches!(&ops[0], Cmpop::Eq) { return None; } - let ExprKind::Name { id, .. } = &left.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &left.node else { return None; }; let comparator = &comparators[0]; - if !matches!(&comparator.node, ExprKind::Name { .. }) { + if !matches!(&comparator.node, ExprKind::Name(_)) { return None; } Some((id, comparator)) @@ -396,7 +403,7 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> { /// SIM109 pub fn compare_with_tuple(checker: &mut Checker, expr: &Expr) { - let ExprKind::BoolOp { op: Boolop::Or, values } = &expr.node else { + let ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values }) = &expr.node else { return; }; @@ -433,13 +440,13 @@ pub fn compare_with_tuple(checker: &mut Checker, expr: &Expr) { } // Create a `x in (a, b)` expression. - let in_expr = create_expr(ExprKind::Compare { - left: Box::new(create_expr(ExprKind::Name { - id: id.to_string(), + let in_expr = create_expr(ast::ExprCompare { + left: Box::new(create_expr(ast::ExprName { + id: id.into(), ctx: ExprContext::Load, })), ops: vec![Cmpop::In], - comparators: vec![create_expr(ExprKind::Tuple { + comparators: vec![create_expr(ast::ExprTuple { elts: comparators.into_iter().map(Clone::clone).collect(), ctx: ExprContext::Load, })], @@ -461,7 +468,7 @@ pub fn compare_with_tuple(checker: &mut Checker, expr: &Expr) { in_expr } else { // Wrap in a `x in (a, b) or ...` boolean operation. - create_expr(ExprKind::BoolOp { + create_expr(ast::ExprBoolOp { op: Boolop::Or, values: iter::once(in_expr).chain(unmatched).collect(), }) @@ -478,7 +485,7 @@ pub fn compare_with_tuple(checker: &mut Checker, expr: &Expr) { /// SIM220 pub fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) { - let ExprKind::BoolOp { op: Boolop::And, values, } = &expr.node else { + let ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::And, values, }) = &expr.node else { return; }; if values.len() < 2 { @@ -489,10 +496,10 @@ pub fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) { let mut negated_expr = vec![]; let mut non_negated_expr = vec![]; for expr in values { - if let ExprKind::UnaryOp { + if let ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::Not, operand, - } = &expr.node + }) = &expr.node { negated_expr.push(operand); } else { @@ -532,7 +539,7 @@ pub fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) { /// SIM221 pub fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) { - let ExprKind::BoolOp { op: Boolop::Or, values, } = &expr.node else { + let ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values, }) = &expr.node else { return; }; if values.len() < 2 { @@ -543,10 +550,10 @@ pub fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) { let mut negated_expr = vec![]; let mut non_negated_expr = vec![]; for expr in values { - if let ExprKind::UnaryOp { + if let ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::Not, operand, - } = &expr.node + }) = &expr.node { negated_expr.push(operand); } else { @@ -611,7 +618,7 @@ fn is_short_circuit( context: &Context, stylist: &Stylist, ) -> Option<(Edit, ContentAround)> { - let ExprKind::BoolOp { op, values, } = &expr.node else { + let ExprKind::BoolOp(ast::ExprBoolOp { op, values, }) = &expr.node else { return None; }; if op != expected_op { diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs index 7823293a97..dabe1170e9 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_expr.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -71,19 +71,19 @@ impl AlwaysAutofixableViolation for DictGetWithNoneDefault { /// SIM112 pub fn use_capital_environment_variables(checker: &mut Checker, expr: &Expr) { // Ex) `os.environ['foo']` - if let ExprKind::Subscript { .. } = &expr.node { + if let ExprKind::Subscript(_) = &expr.node { check_os_environ_subscript(checker, expr); return; } // Ex) `os.environ.get('foo')`, `os.getenv('foo')` - let ExprKind::Call { func, args, .. } = &expr.node else { + let ExprKind::Call(ast::ExprCall { func, args, .. }) = &expr.node else { return; }; let Some(arg) = args.get(0) else { return; }; - let ExprKind::Constant { value: Constant::Str(env_var), .. } = &arg.node else { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(env_var), .. }) = &arg.node else { return; }; if !checker @@ -112,19 +112,19 @@ pub fn use_capital_environment_variables(checker: &mut Checker, expr: &Expr) { } fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { - let ExprKind::Subscript { value, slice, .. } = &expr.node else { + let ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) = &expr.node else { return; }; - let ExprKind::Attribute { value: attr_value, attr, .. } = &value.node else { + let ExprKind::Attribute(ast::ExprAttribute { value: attr_value, attr, .. }) = &value.node else { return; }; - let ExprKind::Name { id, .. } = &attr_value.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &attr_value.node else { return; }; if id != "os" || attr != "environ" { return; } - let ExprKind::Constant { value: Constant::Str(env_var), kind } = &slice.node else { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(env_var), kind }) = &slice.node else { return; }; let capital_env_var = env_var.to_ascii_uppercase(); @@ -140,7 +140,7 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { slice.range(), ); if checker.patch(diagnostic.kind.rule()) { - let new_env_var = create_expr(ExprKind::Constant { + let new_env_var = create_expr(ast::ExprConstant { value: capital_env_var.into(), kind: kind.clone(), }); @@ -155,16 +155,16 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) { /// SIM910 pub fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) { - let ExprKind::Call { func, args, keywords } = &expr.node else { + let ExprKind::Call(ast::ExprCall { func, args, keywords }) = &expr.node else { return; }; if !keywords.is_empty() { return; } - let ExprKind::Attribute { value, attr, .. } = &func.node else { + let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. } )= &func.node else { return; }; - if !matches!(value.node, ExprKind::Dict { .. }) { + if !matches!(value.node, ExprKind::Dict(_)) { return; } if attr != "get" { @@ -173,7 +173,7 @@ pub fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) { let Some(key) = args.get(0) else { return; }; - if !matches!(key.node, ExprKind::Constant { .. } | ExprKind::Name { .. }) { + if !matches!(key.node, ExprKind::Constant(_) | ExprKind::Name(_)) { return; } let Some(default) = args.get(1) else { @@ -181,10 +181,10 @@ pub fn dict_get_with_none_default(checker: &mut Checker, expr: &Expr) { }; if !matches!( default.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } + }) ) { return; }; diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs index a4734048f1..b453e1e064 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_if.rs @@ -1,7 +1,7 @@ use log::error; use ruff_text_size::TextRange; use rustc_hash::FxHashSet; -use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind}; use unicode_width::UnicodeWidthStr; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; @@ -173,17 +173,17 @@ impl Violation for IfElseBlockInsteadOfDictGet { } fn is_main_check(expr: &Expr) -> bool { - if let ExprKind::Compare { + if let ExprKind::Compare(ast::ExprCompare { left, comparators, .. - } = &expr.node + }) = &expr.node { - if let ExprKind::Name { id, .. } = &left.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &left.node { if id == "__name__" { if comparators.len() == 1 { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &comparators[0].node + }) = &comparators[0].node { if value == "__main__" { return true; @@ -208,7 +208,7 @@ fn is_main_check(expr: &Expr) -> bool { /// ... /// ``` fn find_last_nested_if(body: &[Stmt]) -> Option<(&Expr, &Stmt)> { - let [Stmt { node: StmtKind::If { test, body: inner_body, orelse }, ..}] = body else { return None }; + let [Stmt { node: StmtKind::If(ast::StmtIf { test, body: inner_body, orelse }), ..}] = body else { return None }; if !orelse.is_empty() { return None; } @@ -231,7 +231,7 @@ pub fn nested_if_statements( ) { // If the parent could contain a nested if-statement, abort. if let Some(parent) = parent { - if let StmtKind::If { body, orelse, .. } = &parent.node { + if let StmtKind::If(ast::StmtIf { body, orelse, .. }) = &parent.node { if orelse.is_empty() && body.len() == 1 { return; } @@ -251,10 +251,10 @@ pub fn nested_if_statements( // Allow `if True:` and `if False:` statements. if matches!( test.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(..), .. - } + }) ) { return; } @@ -323,10 +323,10 @@ fn is_one_line_return_bool(stmts: &[Stmt]) -> Option { if stmts.len() != 1 { return None; } - let StmtKind::Return { value } = &stmts[0].node else { + let StmtKind::Return(ast::StmtReturn { value }) = &stmts[0].node else { return None; }; - let Some(ExprKind::Constant { value, .. }) = value.as_ref().map(|value| &value.node) else { + let Some(ExprKind::Constant(ast::ExprConstant { value, .. })) = value.as_ref().map(|value| &value.node) else { return None; }; let Constant::Bool(value) = value else { @@ -337,7 +337,7 @@ fn is_one_line_return_bool(stmts: &[Stmt]) -> Option { /// SIM103 pub fn needless_bool(checker: &mut Checker, stmt: &Stmt) { - let StmtKind::If { test, body, orelse } = &stmt.node else { + let StmtKind::If(ast::StmtIf { test, body, orelse }) = &stmt.node else { return; }; let (Some(if_return), Some(else_return)) = (is_one_line_return_bool(body), is_one_line_return_bool(orelse)) else { @@ -354,16 +354,16 @@ pub fn needless_bool(checker: &mut Checker, stmt: &Stmt) { let fixable = matches!(if_return, Bool::True) && matches!(else_return, Bool::False) && !has_comments(stmt, checker.locator) - && (matches!(test.node, ExprKind::Compare { .. }) || checker.ctx.is_builtin("bool")); + && (matches!(test.node, ExprKind::Compare(_)) || checker.ctx.is_builtin("bool")); let mut diagnostic = Diagnostic::new(NeedlessBool { condition }, stmt.range()); if fixable && checker.patch(diagnostic.kind.rule()) { - if matches!(test.node, ExprKind::Compare { .. }) { + if matches!(test.node, ExprKind::Compare(_)) { // If the condition is a comparison, we can replace it with the condition. #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_stmt( - &create_stmt(StmtKind::Return { + &create_stmt(ast::StmtReturn { value: Some(test.clone()), }), checker.stylist, @@ -376,10 +376,10 @@ pub fn needless_bool(checker: &mut Checker, stmt: &Stmt) { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_stmt( - &create_stmt(StmtKind::Return { - value: Some(Box::new(create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Name { - id: "bool".to_string(), + &create_stmt(ast::StmtReturn { + value: Some(Box::new(create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprName { + id: "bool".into(), ctx: ExprContext::Load, })), args: vec![(**test).clone()], @@ -396,9 +396,9 @@ pub fn needless_bool(checker: &mut Checker, stmt: &Stmt) { } fn ternary(target_var: &Expr, body_value: &Expr, test: &Expr, orelse_value: &Expr) -> Stmt { - create_stmt(StmtKind::Assign { + create_stmt(ast::StmtAssign { targets: vec![target_var.clone()], - value: Box::new(create_expr(ExprKind::IfExp { + value: Box::new(create_expr(ast::ExprIfExp { test: Box::new(test.clone()), body: Box::new(body_value.clone()), orelse: Box::new(orelse_value.clone()), @@ -417,25 +417,25 @@ fn contains_call_path(ctx: &Context, expr: &Expr, target: &[&str]) -> bool { /// SIM108 pub fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: Option<&Stmt>) { - let StmtKind::If { test, body, orelse } = &stmt.node else { + let StmtKind::If(ast::StmtIf { test, body, orelse } )= &stmt.node else { return; }; if body.len() != 1 || orelse.len() != 1 { return; } - let StmtKind::Assign { targets: body_targets, value: body_value, .. } = &body[0].node else { + let StmtKind::Assign(ast::StmtAssign { targets: body_targets, value: body_value, .. } )= &body[0].node else { return; }; - let StmtKind::Assign { targets: orelse_targets, value: orelse_value, .. } = &orelse[0].node else { + let StmtKind::Assign(ast::StmtAssign { targets: orelse_targets, value: orelse_value, .. } )= &orelse[0].node else { return; }; if body_targets.len() != 1 || orelse_targets.len() != 1 { return; } - let ExprKind::Name { id: body_id, .. } = &body_targets[0].node else { + let ExprKind::Name(ast::ExprName { id: body_id, .. } )= &body_targets[0].node else { return; }; - let ExprKind::Name { id: orelse_id, .. } = &orelse_targets[0].node else { + let ExprKind::Name(ast::ExprName { id: orelse_id, .. } )= &orelse_targets[0].node else { return; }; if body_id != orelse_id { @@ -455,10 +455,10 @@ pub fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: Option<& // It's part of a bigger if-elif block: // https://github.com/MartinThoma/flake8-simplify/issues/115 - if let Some(StmtKind::If { + if let Some(StmtKind::If(ast::StmtIf { orelse: parent_orelse, .. - }) = parent.map(|parent| &parent.node) + })) = parent.map(|parent| &parent.node) { if parent_orelse.len() == 1 && stmt == &parent_orelse[0] { // TODO(charlie): These two cases have the same AST: @@ -487,13 +487,13 @@ pub fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: Option<& // TODO(charlie): Fix precedence handling for yields in generator. if matches!( body_value.node, - ExprKind::Yield { .. } | ExprKind::YieldFrom { .. } | ExprKind::Await { .. } + ExprKind::Yield(_) | ExprKind::YieldFrom(_) | ExprKind::Await(_) ) { return; } if matches!( orelse_value.node, - ExprKind::Yield { .. } | ExprKind::YieldFrom { .. } | ExprKind::Await { .. } + ExprKind::Yield(_) | ExprKind::YieldFrom(_) | ExprKind::Await(_) ) { return; } @@ -539,7 +539,7 @@ fn get_if_body_pairs<'a>( if orelse.len() != 1 { break; } - let StmtKind::If { test, body, orelse: orelse_orelse, .. } = &orelse[0].node else { + let StmtKind::If(ast::StmtIf { test, body, orelse: orelse_orelse }) = &orelse[0].node else { break; }; pairs.push((test, body)); @@ -550,16 +550,16 @@ fn get_if_body_pairs<'a>( /// SIM114 pub fn if_with_same_arms(checker: &mut Checker, stmt: &Stmt, parent: Option<&Stmt>) { - let StmtKind::If { test, body, orelse } = &stmt.node else { + let StmtKind::If(ast::StmtIf { test, body, orelse }) = &stmt.node else { return; }; // It's part of a bigger if-elif block: // https://github.com/MartinThoma/flake8-simplify/issues/115 - if let Some(StmtKind::If { + if let Some(StmtKind::If(ast::StmtIf { orelse: parent_orelse, .. - }) = parent.map(|parent| &parent.node) + })) = parent.map(|parent| &parent.node) { if parent_orelse.len() == 1 && stmt == &parent_orelse[0] { // TODO(charlie): These two cases have the same AST: @@ -614,14 +614,14 @@ pub fn manual_dict_lookup( // * Each if-statement's body must consist of a single `return`. // * Each if-statement's orelse must be either another if-statement or empty. // * The final if-statement's orelse must be empty, or a single `return`. - let ExprKind::Compare { + let ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } = &test.node else { + })= &test.node else { return; }; - let ExprKind::Name { id: target, .. } = &left.node else { + let ExprKind::Name(ast::ExprName { id: target, .. }) = &left.node else { return; }; if body.len() != 1 { @@ -636,10 +636,10 @@ pub fn manual_dict_lookup( if comparators.len() != 1 { return; } - let ExprKind::Constant { value: constant, .. } = &comparators[0].node else { + let ExprKind::Constant(ast::ExprConstant { value: constant, .. }) = &comparators[0].node else { return; }; - let StmtKind::Return { value, .. } = &body[0].node else { + let StmtKind::Return(ast::StmtReturn { value }) = &body[0].node else { return; }; if value.as_ref().map_or(false, |value| { @@ -650,10 +650,10 @@ pub fn manual_dict_lookup( // It's part of a bigger if-elif block: // https://github.com/MartinThoma/flake8-simplify/issues/115 - if let Some(StmtKind::If { + if let Some(StmtKind::If(ast::StmtIf { orelse: parent_orelse, .. - }) = parent.map(|parent| &parent.node) + })) = parent.map(|parent| &parent.node) { if parent_orelse.len() == 1 && stmt == &parent_orelse[0] { // TODO(charlie): These two cases have the same AST: @@ -683,7 +683,7 @@ pub fn manual_dict_lookup( let mut child: Option<&Stmt> = orelse.get(0); while let Some(current) = child.take() { - let StmtKind::If { test, body, orelse } = ¤t.node else { + let StmtKind::If(ast::StmtIf { test, body, orelse }) = ¤t.node else { return; }; if body.len() != 1 { @@ -692,14 +692,14 @@ pub fn manual_dict_lookup( if orelse.len() > 1 { return; } - let ExprKind::Compare { + let ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } = &test.node else { + } )= &test.node else { return; }; - let ExprKind::Name { id, .. } = &left.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &left.node else { return; }; if !(id == target && ops.len() == 1 && ops[0] == Cmpop::Eq) { @@ -708,10 +708,10 @@ pub fn manual_dict_lookup( if comparators.len() != 1 { return; } - let ExprKind::Constant { value: constant, .. } = &comparators[0].node else { + let ExprKind::Constant(ast::ExprConstant { value: constant, .. } )= &comparators[0].node else { return; }; - let StmtKind::Return { value, .. } = &body[0].node else { + let StmtKind::Return(ast::StmtReturn { value } )= &body[0].node else { return; }; if value.as_ref().map_or(false, |value| { @@ -723,10 +723,10 @@ pub fn manual_dict_lookup( constants.insert(constant.into()); if let Some(orelse) = orelse.first() { match &orelse.node { - StmtKind::If { .. } => { + StmtKind::If(_) => { child = Some(orelse); } - StmtKind::Return { .. } => { + StmtKind::Return(_) => { child = None; } _ => return, @@ -758,19 +758,19 @@ pub fn use_dict_get_with_default( if body.len() != 1 || orelse.len() != 1 { return; } - let StmtKind::Assign { targets: body_var, value: body_value, ..} = &body[0].node else { + let StmtKind::Assign(ast::StmtAssign { targets: body_var, value: body_value, ..}) = &body[0].node else { return; }; if body_var.len() != 1 { return; }; - let StmtKind::Assign { targets: orelse_var, value: orelse_value, .. } = &orelse[0].node else { + let StmtKind::Assign(ast::StmtAssign { targets: orelse_var, value: orelse_value, .. }) = &orelse[0].node else { return; }; if orelse_var.len() != 1 { return; }; - let ExprKind::Compare { left: test_key, ops , comparators: test_dict } = &test.node else { + let ExprKind::Compare(ast::ExprCompare { left: test_key, ops , comparators: test_dict }) = &test.node else { return; }; if test_dict.len() != 1 { @@ -784,7 +784,7 @@ pub fn use_dict_get_with_default( } }; let test_dict = &test_dict[0]; - let ExprKind::Subscript { value: expected_subscript, slice: expected_slice, .. } = &expected_value.node else { + let ExprKind::Subscript(ast::ExprSubscript { value: expected_subscript, slice: expected_slice, .. } ) = &expected_value.node else { return; }; @@ -804,10 +804,10 @@ pub fn use_dict_get_with_default( // It's part of a bigger if-elif block: // https://github.com/MartinThoma/flake8-simplify/issues/115 - if let Some(StmtKind::If { + if let Some(StmtKind::If(ast::StmtIf { orelse: parent_orelse, .. - }) = parent.map(|parent| &parent.node) + })) = parent.map(|parent| &parent.node) { if parent_orelse.len() == 1 && stmt == &parent_orelse[0] { // TODO(charlie): These two cases have the same AST: @@ -833,12 +833,12 @@ pub fn use_dict_get_with_default( } let contents = unparse_stmt( - &create_stmt(StmtKind::Assign { + &create_stmt(ast::StmtAssign { targets: vec![create_expr(expected_var.node.clone())], - value: Box::new(create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Attribute { + value: Box::new(create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprAttribute { value: expected_subscript.clone(), - attr: "get".to_string(), + attr: "get".into(), ctx: ExprContext::Load, })), args: vec![ diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs index d49878e59a..f076701f5b 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_ifexp.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind, Unaryop}; use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -81,13 +81,13 @@ pub fn explicit_true_false_in_ifexpr( body: &Expr, orelse: &Expr, ) { - let ExprKind::Constant { value, .. } = &body.node else { + let ExprKind::Constant(ast::ExprConstant { value, .. } )= &body.node else { return; }; if !matches!(value, Constant::Bool(true)) { return; } - let ExprKind::Constant { value, .. } = &orelse.node else { + let ExprKind::Constant(ast::ExprConstant { value, .. } )= &orelse.node else { return; }; if !matches!(value, Constant::Bool(false)) { @@ -101,7 +101,7 @@ pub fn explicit_true_false_in_ifexpr( expr.range(), ); if checker.patch(diagnostic.kind.rule()) { - if matches!(test.node, ExprKind::Compare { .. }) { + if matches!(test.node, ExprKind::Compare(_)) { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr(&test.clone(), checker.stylist), @@ -111,9 +111,9 @@ pub fn explicit_true_false_in_ifexpr( #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Name { - id: "bool".to_string(), + &create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprName { + id: "bool".into(), ctx: ExprContext::Load, })), args: vec![test.clone()], @@ -136,13 +136,13 @@ pub fn explicit_false_true_in_ifexpr( body: &Expr, orelse: &Expr, ) { - let ExprKind::Constant { value, .. } = &body.node else { + let ExprKind::Constant(ast::ExprConstant { value, .. }) = &body.node else { return; }; if !matches!(value, Constant::Bool(false)) { return; } - let ExprKind::Constant { value, .. } = &orelse.node else { + let ExprKind::Constant(ast::ExprConstant { value, .. }) = &orelse.node else { return; }; if !matches!(value, Constant::Bool(true)) { @@ -159,7 +159,7 @@ pub fn explicit_false_true_in_ifexpr( #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::UnaryOp { + &create_expr(ast::ExprUnaryOp { op: Unaryop::Not, operand: Box::new(create_expr(test.node.clone())), }), @@ -179,7 +179,7 @@ pub fn twisted_arms_in_ifexpr( body: &Expr, orelse: &Expr, ) { - let ExprKind::UnaryOp { op, operand: test_operand } = &test.node else { + let ExprKind::UnaryOp(ast::ExprUnaryOp { op, operand: test_operand } )= &test.node else { return; }; if !matches!(op, Unaryop::Not) { @@ -187,10 +187,10 @@ pub fn twisted_arms_in_ifexpr( } // Check if the test operand and else branch use the same variable. - let ExprKind::Name { id: test_id, .. } = &test_operand.node else { + let ExprKind::Name(ast::ExprName { id: test_id, .. } )= &test_operand.node else { return; }; - let ExprKind::Name {id: orelse_id, ..} = &orelse.node else { + let ExprKind::Name(ast::ExprName {id: orelse_id, ..}) = &orelse.node else { return; }; if !test_id.eq(orelse_id) { @@ -208,7 +208,7 @@ pub fn twisted_arms_in_ifexpr( #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::IfExp { + &create_expr(ast::ExprIfExp { test: Box::new(create_expr(orelse.node.clone())), body: Box::new(create_expr(orelse.node.clone())), orelse: Box::new(create_expr(body.node.clone())), diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs index 103e6d28ed..8bbabcca09 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_unary_op.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Cmpop, Expr, ExprContext, ExprKind, Stmt, StmtKind, Unaryop}; +use rustpython_parser::ast::{self, Cmpop, Expr, ExprContext, ExprKind, Stmt, StmtKind, Unaryop}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -65,13 +65,13 @@ impl AlwaysAutofixableViolation for DoubleNegation { const DUNDER_METHODS: &[&str] = &["__eq__", "__ne__", "__lt__", "__le__", "__gt__", "__ge__"]; fn is_exception_check(stmt: &Stmt) -> bool { - let StmtKind::If {test: _, body, orelse: _} = &stmt.node else { + let StmtKind::If(ast::StmtIf {test: _, body, orelse: _ })= &stmt.node else { return false; }; if body.len() != 1 { return false; } - if matches!(body[0].node, StmtKind::Raise { .. }) { + if matches!(body[0].node, StmtKind::Raise(_)) { return true; } false @@ -82,7 +82,7 @@ pub fn negation_with_equal_op(checker: &mut Checker, expr: &Expr, op: &Unaryop, if !matches!(op, Unaryop::Not) { return; } - let ExprKind::Compare{ left, ops, comparators} = &operand.node else { + let ExprKind::Compare(ast::ExprCompare { left, ops, comparators}) = &operand.node else { return; }; if !matches!(&ops[..], [Cmpop::Eq]) { @@ -110,7 +110,7 @@ pub fn negation_with_equal_op(checker: &mut Checker, expr: &Expr, op: &Unaryop, #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::Compare { + &create_expr(ast::ExprCompare { left: left.clone(), ops: vec![Cmpop::NotEq], comparators: comparators.clone(), @@ -133,7 +133,7 @@ pub fn negation_with_not_equal_op( if !matches!(op, Unaryop::Not) { return; } - let ExprKind::Compare{ left, ops, comparators} = &operand.node else { + let ExprKind::Compare(ast::ExprCompare { left, ops, comparators}) = &operand.node else { return; }; if !matches!(&ops[..], [Cmpop::NotEq]) { @@ -161,7 +161,7 @@ pub fn negation_with_not_equal_op( #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::Compare { + &create_expr(ast::ExprCompare { left: left.clone(), ops: vec![Cmpop::Eq], comparators: comparators.clone(), @@ -179,7 +179,7 @@ pub fn double_negation(checker: &mut Checker, expr: &Expr, op: &Unaryop, operand if !matches!(op, Unaryop::Not) { return; } - let ExprKind::UnaryOp { op: operand_op, operand } = &operand.node else { + let ExprKind::UnaryOp(ast::ExprUnaryOp { op: operand_op, operand }) = &operand.node else { return; }; if !matches!(operand_op, Unaryop::Not) { @@ -203,9 +203,9 @@ pub fn double_negation(checker: &mut Checker, expr: &Expr, op: &Unaryop, operand #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr( - &create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Name { - id: "bool".to_string(), + &create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprName { + id: "bool".into(), ctx: ExprContext::Load, })), args: vec![*operand.clone()], diff --git a/crates/ruff/src/rules/flake8_simplify/rules/ast_with.rs b/crates/ruff/src/rules/flake8_simplify/rules/ast_with.rs index 2b09e476fb..9c787c10cf 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/ast_with.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/ast_with.rs @@ -1,6 +1,6 @@ use log::error; use ruff_text_size::TextRange; -use rustpython_parser::ast::{Located, Stmt, StmtKind, Withitem}; +use rustpython_parser::ast::{self, Attributed, Stmt, StmtKind, Withitem}; use unicode_width::UnicodeWidthStr; use ruff_diagnostics::{AutofixKind, Violation}; @@ -61,7 +61,7 @@ impl Violation for MultipleWithStatements { } fn find_last_with(body: &[Stmt]) -> Option<(&Vec, &Vec)> { - let [Located { node: StmtKind::With { items, body, .. }, ..}] = body else { return None }; + let [Attributed { node: StmtKind::With(ast::StmtWith { items, body, .. }), ..}] = body else { return None }; find_last_with(body).or(Some((items, body))) } @@ -73,7 +73,7 @@ pub fn multiple_with_statements( with_parent: Option<&Stmt>, ) { if let Some(parent) = with_parent { - if let StmtKind::With { body, .. } = &parent.node { + if let StmtKind::With(ast::StmtWith { body, .. }) = &parent.node { if body.len() == 1 { return; } diff --git a/crates/ruff/src/rules/flake8_simplify/rules/key_in_dict.rs b/crates/ruff/src/rules/flake8_simplify/rules/key_in_dict.rs index f8a9fed6d1..18abf6e9bf 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/key_in_dict.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/key_in_dict.rs @@ -2,7 +2,7 @@ use anyhow::Result; use libcst_native::{Codegen, CodegenState}; use log::error; use ruff_text_size::TextRange; -use rustpython_parser::ast::{Cmpop, Expr, ExprKind}; +use rustpython_parser::ast::{self, Cmpop, Expr, ExprKind}; use ruff_diagnostics::Edit; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; @@ -54,18 +54,18 @@ fn get_value_content_for_key_in_dict( /// SIM118 fn key_in_dict(checker: &mut Checker, left: &Expr, right: &Expr, range: TextRange) { - let ExprKind::Call { + let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &right.node else { + }) = &right.node else { return; }; if !(args.is_empty() && keywords.is_empty()) { return; } - let ExprKind::Attribute { attr, .. } = &func.node else { + let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node else { return; }; if attr != "keys" { diff --git a/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs b/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs index d33d046008..381699217a 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/open_file_with_context_handler.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -45,22 +45,22 @@ fn match_async_exit_stack(checker: &Checker) -> bool { let Some(expr) = checker.ctx.expr_grandparent() else { return false; }; - let ExprKind::Await { value } = &expr.node else { + let ExprKind::Await(ast::ExprAwait { value }) = &expr.node else { return false; }; - let ExprKind::Call { func, .. } = &value.node else { + let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node else { return false; }; - let ExprKind::Attribute { attr, .. } = &func.node else { + let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node else { return false; }; if attr != "enter_async_context" { return false; } for parent in checker.ctx.parents() { - if let StmtKind::With { items, .. } = &parent.node { + if let StmtKind::With(ast::StmtWith { items, .. }) = &parent.node { for item in items { - if let ExprKind::Call { func, .. } = &item.context_expr.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &item.context_expr.node { if checker .ctx .resolve_call_path(func) @@ -83,19 +83,19 @@ fn match_exit_stack(checker: &Checker) -> bool { let Some(expr) = checker.ctx.expr_parent() else { return false; }; - let ExprKind::Call { func, .. } = &expr.node else { + let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node else { return false; }; - let ExprKind::Attribute { attr, .. } = &func.node else { + let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node else { return false; }; if attr != "enter_context" { return false; } for parent in checker.ctx.parents() { - if let StmtKind::With { items, .. } = &parent.node { + if let StmtKind::With(ast::StmtWith { items, .. }) = &parent.node { for item in items { - if let ExprKind::Call { func, .. } = &item.context_expr.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &item.context_expr.node { if checker .ctx .resolve_call_path(func) @@ -121,7 +121,7 @@ pub fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) { { if checker.ctx.is_builtin("open") { // Ex) `with open("foo.txt") as f: ...` - if matches!(checker.ctx.stmt().node, StmtKind::With { .. }) { + if matches!(checker.ctx.stmt().node, StmtKind::With(_)) { return; } diff --git a/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs b/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs index 7d3f8582fc..543c2ba31c 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/reimplemented_builtin.rs @@ -1,6 +1,6 @@ use ruff_text_size::{TextRange, TextSize}; use rustpython_parser::ast::{ - Cmpop, Comprehension, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind, Unaryop, + self, Cmpop, Comprehension, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind, Unaryop, }; use unicode_width::UnicodeWidthStr; @@ -43,13 +43,13 @@ struct Loop<'a> { /// Extract the returned boolean values a `StmtKind::For` with an `else` body. fn return_values_for_else(stmt: &Stmt) -> Option { - let StmtKind::For { + let StmtKind::For(ast::StmtFor { body, target, iter, orelse, .. - } = &stmt.node else { + }) = &stmt.node else { return None; }; @@ -61,11 +61,11 @@ fn return_values_for_else(stmt: &Stmt) -> Option { if orelse.len() != 1 { return None; } - let StmtKind::If { + let StmtKind::If(ast::StmtIf { body: nested_body, test: nested_test, orelse: nested_orelse, - } = &body[0].node else { + }) = &body[0].node else { return None; }; if nested_body.len() != 1 { @@ -74,24 +74,24 @@ fn return_values_for_else(stmt: &Stmt) -> Option { if !nested_orelse.is_empty() { return None; } - let StmtKind::Return { value } = &nested_body[0].node else { + let StmtKind::Return(ast::StmtReturn { value }) = &nested_body[0].node else { return None; }; let Some(value) = value else { return None; }; - let ExprKind::Constant { value: Constant::Bool(value), .. } = &value.node else { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(value), .. }) = &value.node else { return None; }; // The `else` block has to contain a single `return True` or `return False`. - let StmtKind::Return { value: next_value } = &orelse[0].node else { + let StmtKind::Return(ast::StmtReturn { value: next_value }) = &orelse[0].node else { return None; }; let Some(next_value) = next_value else { return None; }; - let ExprKind::Constant { value: Constant::Bool(next_value), .. } = &next_value.node else { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(next_value), .. }) = &next_value.node else { return None; }; @@ -108,13 +108,13 @@ fn return_values_for_else(stmt: &Stmt) -> Option { /// Extract the returned boolean values from subsequent `StmtKind::For` and /// `StmtKind::Return` statements, or `None`. fn return_values_for_siblings<'a>(stmt: &'a Stmt, sibling: &'a Stmt) -> Option> { - let StmtKind::For { + let StmtKind::For(ast::StmtFor { body, target, iter, orelse, .. - } = &stmt.node else { + }) = &stmt.node else { return None; }; @@ -126,11 +126,11 @@ fn return_values_for_siblings<'a>(stmt: &'a Stmt, sibling: &'a Stmt) -> Option(stmt: &'a Stmt, sibling: &'a Stmt) -> Option(stmt: &'a Stmt, sibling: &'a Stmt) -> Option String { unparse_stmt( - &create_stmt(StmtKind::Return { - value: Some(Box::new(create_expr(ExprKind::Call { - func: Box::new(create_expr(ExprKind::Name { - id: id.to_string(), + &create_stmt(ast::StmtReturn { + value: Some(Box::new(create_expr(ast::ExprCall { + func: Box::new(create_expr(ast::ExprName { + id: id.into(), ctx: ExprContext::Load, })), - args: vec![create_expr(ExprKind::GeneratorExp { + args: vec![create_expr(ast::ExprGeneratorExp { elt: Box::new(test.clone()), generators: vec![Comprehension { target: target.clone(), iter: iter.clone(), ifs: vec![], - is_async: 0, + is_async: false, }], })], keywords: vec![], @@ -244,17 +244,17 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling: if checker.settings.rules.enabled(Rule::ReimplementedBuiltin) { // Invert the condition. let test = { - if let ExprKind::UnaryOp { + if let ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::Not, operand, - } = &loop_info.test.node + }) = &loop_info.test.node { *operand.clone() - } else if let ExprKind::Compare { + } else if let ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } = &loop_info.test.node + }) = &loop_info.test.node { if ops.len() == 1 && comparators.len() == 1 { let op = match &ops[0] { @@ -269,19 +269,19 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling: Cmpop::In => Cmpop::NotIn, Cmpop::NotIn => Cmpop::In, }; - create_expr(ExprKind::Compare { + create_expr(ast::ExprCompare { left: left.clone(), ops: vec![op], comparators: vec![comparators[0].clone()], }) } else { - create_expr(ExprKind::UnaryOp { + create_expr(ast::ExprUnaryOp { op: Unaryop::Not, operand: Box::new(loop_info.test.clone()), }) } } else { - create_expr(ExprKind::UnaryOp { + create_expr(ast::ExprUnaryOp { op: Unaryop::Not, operand: Box::new(loop_info.test.clone()), }) diff --git a/crates/ruff/src/rules/flake8_simplify/rules/return_in_try_except_finally.rs b/crates/ruff/src/rules/flake8_simplify/rules/return_in_try_except_finally.rs index b473a071c8..2e99808541 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/return_in_try_except_finally.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/return_in_try_except_finally.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -52,7 +52,7 @@ impl Violation for ReturnInTryExceptFinally { fn find_return(stmts: &[Stmt]) -> Option<&Stmt> { stmts .iter() - .find(|stmt| matches!(stmt.node, StmtKind::Return { .. })) + .find(|stmt| matches!(stmt.node, StmtKind::Return(_))) } /// SIM107 @@ -64,7 +64,8 @@ pub fn return_in_try_except_finally( ) { let try_has_return = find_return(body).is_some(); let except_has_return = handlers.iter().any(|handler| { - let ExcepthandlerKind::ExceptHandler { body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = + &handler.node; find_return(body).is_some() }); diff --git a/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs b/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs index e6ec3bdf56..eadfea4914 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/suppressible_exception.rs @@ -1,6 +1,6 @@ use ruff_text_size::{TextLen, TextRange}; use rustpython_parser::ast::{ - Constant, Excepthandler, ExcepthandlerKind, ExprKind, Located, Stmt, StmtKind, + self, Attributed, Constant, Excepthandler, ExcepthandlerKind, ExprKind, Stmt, StmtKind, }; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; @@ -45,15 +45,15 @@ pub fn suppressible_exception( ) { if !matches!( try_body, - [Located { - node: StmtKind::Delete { .. } - | StmtKind::Assign { .. } - | StmtKind::AugAssign { .. } - | StmtKind::AnnAssign { .. } - | StmtKind::Assert { .. } - | StmtKind::Import { .. } - | StmtKind::ImportFrom { .. } - | StmtKind::Expr { .. } + [Attributed { + node: StmtKind::Delete(_) + | StmtKind::Assign(_) + | StmtKind::AugAssign(_) + | StmtKind::AnnAssign(_) + | StmtKind::Assert(_) + | StmtKind::Import(_) + | StmtKind::ImportFrom(_) + | StmtKind::Expr(_) | StmtKind::Pass, .. }] @@ -64,17 +64,15 @@ pub fn suppressible_exception( return; } let handler = &handlers[0]; - let ExcepthandlerKind::ExceptHandler { body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = + &handler.node; if body.len() == 1 { let node = &body[0].node; if matches!(node, StmtKind::Pass) || (matches!( node, - StmtKind::Expr { - value, - .. - } - if matches!(**value, Located { node: ExprKind::Constant { value: Constant::Ellipsis, .. }, ..}) + StmtKind::Expr(ast::StmtExpr { value }) + if matches!(**value, Attributed { node: ExprKind::Constant(ast::ExprConstant { value: Constant::Ellipsis, .. }), ..}) )) { let handler_names: Vec = helpers::extract_handled_exceptions(handlers) diff --git a/crates/ruff/src/rules/flake8_simplify/rules/yoda_conditions.rs b/crates/ruff/src/rules/flake8_simplify/rules/yoda_conditions.rs index 4ad87463f6..46dea18877 100644 --- a/crates/ruff/src/rules/flake8_simplify/rules/yoda_conditions.rs +++ b/crates/ruff/src/rules/flake8_simplify/rules/yoda_conditions.rs @@ -1,6 +1,6 @@ use anyhow::Result; use libcst_native::{Codegen, CodegenState, CompOp}; -use rustpython_parser::ast::{Cmpop, Expr, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Cmpop, Expr, ExprKind, Unaryop}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -40,14 +40,14 @@ impl Violation for YodaConditions { /// Return `true` if an [`Expr`] is a constant or a constant-like name. fn is_constant_like(expr: &Expr) -> bool { match &expr.node { - ExprKind::Attribute { attr, .. } => str::is_upper(attr), - ExprKind::Constant { .. } => true, - ExprKind::Tuple { elts, .. } => elts.iter().all(is_constant_like), - ExprKind::Name { id, .. } => str::is_upper(id), - ExprKind::UnaryOp { + ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => str::is_upper(attr), + ExprKind::Constant(_) => true, + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().all(is_constant_like), + ExprKind::Name(ast::ExprName { id, .. }) => str::is_upper(id), + ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::UAdd | Unaryop::USub | Unaryop::Invert, operand, - } => matches!(operand.node, ExprKind::Constant { .. }), + }) => matches!(operand.node, ExprKind::Constant(_)), _ => false, } } diff --git a/crates/ruff/src/rules/flake8_tidy_imports/banned_api.rs b/crates/ruff/src/rules/flake8_tidy_imports/banned_api.rs index 3e64d155cb..1739f04acc 100644 --- a/crates/ruff/src/rules/flake8_tidy_imports/banned_api.rs +++ b/crates/ruff/src/rules/flake8_tidy_imports/banned_api.rs @@ -1,5 +1,5 @@ use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Expr, Located}; +use rustpython_parser::ast::{Attributed, Expr}; use serde::{Deserialize, Serialize}; use crate::checkers::ast::Checker; @@ -49,7 +49,7 @@ impl Violation for BannedApi { } /// TID251 -pub fn name_is_banned(checker: &mut Checker, name: String, located: &Located) { +pub fn name_is_banned(checker: &mut Checker, name: String, located: &Attributed) { let banned_api = &checker.settings.flake8_tidy_imports.banned_api; if let Some(ban) = banned_api.get(&name) { checker.diagnostics.push(Diagnostic::new( @@ -63,7 +63,7 @@ pub fn name_is_banned(checker: &mut Checker, name: String, located: &Located< } /// TID251 -pub fn name_or_parent_is_banned(checker: &mut Checker, name: &str, located: &Located) { +pub fn name_or_parent_is_banned(checker: &mut Checker, name: &str, located: &Attributed) { let banned_api = &checker.settings.flake8_tidy_imports.banned_api; let mut name = name; loop { diff --git a/crates/ruff/src/rules/flake8_tidy_imports/relative_imports.rs b/crates/ruff/src/rules/flake8_tidy_imports/relative_imports.rs index 7ef710538c..27ac761de4 100644 --- a/crates/ruff/src/rules/flake8_tidy_imports/relative_imports.rs +++ b/crates/ruff/src/rules/flake8_tidy_imports/relative_imports.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Stmt, StmtKind}; +use rustpython_parser::ast::{self, Int, Stmt, StmtKind}; use serde::{Deserialize, Serialize}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; @@ -86,7 +86,7 @@ impl Violation for RelativeImports { fn fix_banned_relative_import( stmt: &Stmt, - level: Option, + level: Option, module: Option<&str>, module_path: Option<&[String]>, stylist: &Stylist, @@ -102,14 +102,14 @@ fn fix_banned_relative_import( return None; } - let StmtKind::ImportFrom { names, .. } = &stmt.node else { + let StmtKind::ImportFrom(ast::StmtImportFrom { names, .. }) = &stmt.node else { panic!("Expected StmtKind::ImportFrom"); }; let content = unparse_stmt( - &create_stmt(StmtKind::ImportFrom { - module: Some(module_path.to_string()), + &create_stmt(ast::StmtImportFrom { + module: Some(module_path.to_string().into()), names: names.clone(), - level: Some(0), + level: Some(Int::new(0)), }), stylist, ); @@ -124,7 +124,7 @@ fn fix_banned_relative_import( pub fn banned_relative_import( checker: &Checker, stmt: &Stmt, - level: Option, + level: Option, module: Option<&str>, module_path: Option<&[String]>, strictness: &Strictness, diff --git a/crates/ruff/src/rules/flake8_type_checking/helpers.rs b/crates/ruff/src/rules/flake8_type_checking/helpers.rs index 86e851e7d9..2d1f2b1580 100644 --- a/crates/ruff/src/rules/flake8_type_checking/helpers.rs +++ b/crates/ruff/src/rules/flake8_type_checking/helpers.rs @@ -1,5 +1,5 @@ use num_traits::Zero; -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_python_ast::call_path::from_qualified_name; use ruff_python_ast::helpers::map_callable; @@ -12,19 +12,19 @@ pub fn is_type_checking_block(context: &Context, test: &Expr) -> bool { // Ex) `if False:` if matches!( test.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(false), .. - } + }) ) { return true; } // Ex) `if 0:` - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(value), .. - } = &test.node + }) = &test.node { if value.is_zero() { return true; diff --git a/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs b/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs index 0d0e31ceb2..82bb28f204 100644 --- a/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs +++ b/crates/ruff/src/rules/flake8_type_checking/rules/typing_only_runtime_import.rs @@ -283,7 +283,12 @@ pub fn typing_only_runtime_import( // Extract the module base and level from the full name. // Ex) `foo.bar.baz` -> `foo`, `0` // Ex) `.foo.bar.baz` -> `foo`, `1` - let level = full_name.chars().take_while(|c| *c == '.').count(); + let level = full_name + .chars() + .take_while(|c| *c == '.') + .count() + .try_into() + .unwrap(); // Categorize the import. match categorize( diff --git a/crates/ruff/src/rules/flake8_unused_arguments/helpers.rs b/crates/ruff/src/rules/flake8_unused_arguments/helpers.rs index 9b76c2eccd..7f487f3522 100644 --- a/crates/ruff/src/rules/flake8_unused_arguments/helpers.rs +++ b/crates/ruff/src/rules/flake8_unused_arguments/helpers.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, ExprKind, Stmt, StmtKind}; use ruff_python_ast::helpers::is_docstring_stmt; @@ -7,27 +7,25 @@ use ruff_python_ast::helpers::is_docstring_stmt; fn is_empty_stmt(stmt: &Stmt) -> bool { match &stmt.node { StmtKind::Pass => return true, - StmtKind::Expr { value } => { + StmtKind::Expr(ast::StmtExpr { value }) => { return matches!( value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Ellipsis, .. - } + }) ) } - StmtKind::Raise { exc, cause } => { + StmtKind::Raise(ast::StmtRaise { exc, cause }) => { if cause.is_none() { if let Some(exc) = exc { match &exc.node { - ExprKind::Name { id, .. } => { - return id.as_str() == "NotImplementedError" - || id.as_str() == "NotImplemented"; + ExprKind::Name(ast::ExprName { id, .. }) => { + return id == "NotImplementedError" || id == "NotImplemented"; } - ExprKind::Call { func, .. } => { - if let ExprKind::Name { id, .. } = &func.node { - return id.as_str() == "NotImplementedError" - || id.as_str() == "NotImplemented"; + ExprKind::Call(ast::ExprCall { func, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { + return id == "NotImplementedError" || id == "NotImplemented"; } } _ => {} diff --git a/crates/ruff/src/rules/flynt/helpers.rs b/crates/ruff/src/rules/flynt/helpers.rs index 849e62cdea..1420d4f2ee 100644 --- a/crates/ruff/src/rules/flynt/helpers.rs +++ b/crates/ruff/src/rules/flynt/helpers.rs @@ -1,19 +1,19 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Int}; use ruff_python_ast::helpers::create_expr; /// Wrap an expression in a `FormattedValue` with no special formatting. fn to_formatted_value_expr(inner: &Expr) -> Expr { - create_expr(ExprKind::FormattedValue { + create_expr(ast::ExprFormattedValue { value: Box::new(inner.clone()), - conversion: 0, + conversion: Int::new(0), format_spec: None, }) } /// Convert a string to a constant string expression. pub(crate) fn to_constant_string(s: &str) -> Expr { - create_expr(ExprKind::Constant { + create_expr(ast::ExprConstant { value: Constant::Str(s.to_owned()), kind: None, }) @@ -23,11 +23,11 @@ pub(crate) fn to_constant_string(s: &str) -> Expr { /// (i.e. one that can be safely converted to a formatted value). fn is_simple_call(expr: &Expr) -> bool { match &expr.node { - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => args.is_empty() && keywords.is_empty() && is_simple_callee(func), + }) => args.is_empty() && keywords.is_empty() && is_simple_callee(func), _ => false, } } @@ -36,8 +36,8 @@ fn is_simple_call(expr: &Expr) -> bool { /// attribute accesses). fn is_simple_callee(func: &Expr) -> bool { match &func.node { - ExprKind::Name { .. } => true, - ExprKind::Attribute { value, .. } => is_simple_callee(value), + ExprKind::Name(_) => true, + ExprKind::Attribute(ast::ExprAttribute { value, .. }) => is_simple_callee(value), _ => false, } } @@ -46,21 +46,21 @@ fn is_simple_callee(func: &Expr) -> bool { pub(crate) fn to_fstring_elem(expr: &Expr) -> Option { match &expr.node { // These are directly handled by `unparse_fstring_elem`: - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - } - | ExprKind::JoinedStr { .. } - | ExprKind::FormattedValue { .. } => Some(expr.clone()), + }) + | ExprKind::JoinedStr(_) + | ExprKind::FormattedValue(_) => Some(expr.clone()), // These should be pretty safe to wrap in a formatted value. - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(_) | Constant::Float(_) | Constant::Bool(_) | Constant::Complex { .. }, .. - } - | ExprKind::Name { .. } - | ExprKind::Attribute { .. } => Some(to_formatted_value_expr(expr)), - ExprKind::Call { .. } if is_simple_call(expr) => Some(to_formatted_value_expr(expr)), + }) + | ExprKind::Name(_) + | ExprKind::Attribute(_) => Some(to_formatted_value_expr(expr)), + ExprKind::Call(_) if is_simple_call(expr) => Some(to_formatted_value_expr(expr)), _ => None, } } diff --git a/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs b/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs index add76ad1dc..85e8b4a657 100644 --- a/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs +++ b/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -27,8 +27,7 @@ impl AlwaysAutofixableViolation for StaticJoinToFString { } fn is_static_length(elts: &[Expr]) -> bool { - elts.iter() - .all(|e| !matches!(e.node, ExprKind::Starred { .. })) + elts.iter().all(|e| !matches!(e.node, ExprKind::Starred(_))) } fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { @@ -36,7 +35,7 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { let mut first = true; for expr in joinees { - if matches!(expr.node, ExprKind::JoinedStr { .. }) { + if matches!(expr.node, ExprKind::JoinedStr(_)) { // Oops, already an f-string. We don't know how to handle those // gracefully right now. return None; @@ -47,17 +46,17 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { fstring_elems.push(helpers::to_fstring_elem(expr)?); } - Some(create_expr(ExprKind::JoinedStr { + Some(create_expr(ast::ExprJoinedStr { values: fstring_elems, })) } pub fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) { - let ExprKind::Call { + let ExprKind::Call(ast::ExprCall { args, keywords, .. - } = &expr.node else { + })= &expr.node else { return; }; @@ -69,8 +68,8 @@ pub fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) // Get the elements to join; skip (e.g.) generators, sets, etc. let joinees = match &args[0].node { - ExprKind::List { elts, .. } if is_static_length(elts) => elts, - ExprKind::Tuple { elts, .. } if is_static_length(elts) => elts, + ExprKind::List(ast::ExprList { elts, .. }) if is_static_length(elts) => elts, + ExprKind::Tuple(ast::ExprTuple { elts, .. }) if is_static_length(elts) => elts, _ => return, }; diff --git a/crates/ruff/src/rules/isort/annotate.rs b/crates/ruff/src/rules/isort/annotate.rs index a2d0866f13..1cfa1d1a2e 100644 --- a/crates/ruff/src/rules/isort/annotate.rs +++ b/crates/ruff/src/rules/isort/annotate.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Stmt, StmtKind}; +use rustpython_parser::ast::{self, Stmt, StmtKind}; use ruff_python_ast::source_code::Locator; @@ -20,7 +20,7 @@ pub fn annotate_imports<'a>( .iter() .map(|import| { match &import.node { - StmtKind::Import { names } => { + StmtKind::Import(ast::StmtImport { names }) => { // Find comments above. let mut atop = vec![]; while let Some(comment) = @@ -51,11 +51,11 @@ pub fn annotate_imports<'a>( inline, } } - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } => { + }) => { // Find comments above. let mut atop = vec![]; while let Some(comment) = @@ -116,7 +116,7 @@ pub fn annotate_imports<'a>( AnnotatedImport::ImportFrom { module: module.as_deref(), names: aliases, - level: *level, + level: level.map(|level| level.to_u32()), trailing_comma: if split_on_trailing_comma { trailing_comma(import, locator) } else { diff --git a/crates/ruff/src/rules/isort/categorize.rs b/crates/ruff/src/rules/isort/categorize.rs index 090186fd66..4009baed60 100644 --- a/crates/ruff/src/rules/isort/categorize.rs +++ b/crates/ruff/src/rules/isort/categorize.rs @@ -65,7 +65,7 @@ enum Reason<'a> { #[allow(clippy::too_many_arguments)] pub fn categorize<'a>( module_name: &str, - level: Option, + level: Option, src: &[PathBuf], package: Option<&Path>, known_modules: &'a KnownModules, diff --git a/crates/ruff/src/rules/isort/comments.rs b/crates/ruff/src/rules/isort/comments.rs index 3bc02d2f42..af1040a4e4 100644 --- a/crates/ruff/src/rules/isort/comments.rs +++ b/crates/ruff/src/rules/isort/comments.rs @@ -28,7 +28,7 @@ impl Comment<'_> { /// Collect all comments in an import block. pub fn collect_comments<'a>(range: TextRange, locator: &'a Locator) -> Vec> { let contents = locator.slice(range); - lexer::lex_located(contents, Mode::Module, range.start()) + lexer::lex_starts_at(contents, Mode::Module, range.start()) .flatten() .filter_map(|(tok, range)| { if let Tok::Comment(value) = tok { diff --git a/crates/ruff/src/rules/isort/helpers.rs b/crates/ruff/src/rules/isort/helpers.rs index ef25643a00..1bc40e4bf3 100644 --- a/crates/ruff/src/rules/isort/helpers.rs +++ b/crates/ruff/src/rules/isort/helpers.rs @@ -12,7 +12,7 @@ pub fn trailing_comma(stmt: &Stmt, locator: &Locator) -> TrailingComma { let contents = locator.slice(stmt.range()); let mut count: usize = 0; let mut trailing_comma = TrailingComma::Absent; - for (tok, _) in lexer::lex_located(contents, Mode::Module, stmt.start()).flatten() { + for (tok, _) in lexer::lex_starts_at(contents, Mode::Module, stmt.start()).flatten() { if matches!(tok, Tok::Lpar) { count += 1; } diff --git a/crates/ruff/src/rules/isort/mod.rs b/crates/ruff/src/rules/isort/mod.rs index 5fa1c2ce12..ad72fdbc2b 100644 --- a/crates/ruff/src/rules/isort/mod.rs +++ b/crates/ruff/src/rules/isort/mod.rs @@ -52,7 +52,7 @@ pub enum AnnotatedImport<'a> { ImportFrom { module: Option<&'a str>, names: Vec>, - level: Option, + level: Option, atop: Vec>, inline: Vec>, trailing_comma: TrailingComma, diff --git a/crates/ruff/src/rules/isort/rules/add_required_imports.rs b/crates/ruff/src/rules/isort/rules/add_required_imports.rs index 56fa2e473b..8cd65dccc1 100644 --- a/crates/ruff/src/rules/isort/rules/add_required_imports.rs +++ b/crates/ruff/src/rules/isort/rules/add_required_imports.rs @@ -1,7 +1,7 @@ use log::error; use ruff_text_size::{TextRange, TextSize}; use rustpython_parser as parser; -use rustpython_parser::ast::{StmtKind, Suite}; +use rustpython_parser::ast::{self, StmtKind, Suite}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -56,28 +56,28 @@ impl AlwaysAutofixableViolation for MissingRequiredImport { fn contains(block: &Block, required_import: &AnyImport) -> bool { block.imports.iter().any(|import| match required_import { AnyImport::Import(required_import) => { - let StmtKind::Import { + let StmtKind::Import(ast::StmtImport { names, - } = &import.node else { + }) = &import.node else { return false; }; names.iter().any(|alias| { - alias.node.name == required_import.name.name + &alias.node.name == required_import.name.name && alias.node.asname.as_deref() == required_import.name.as_name }) } AnyImport::ImportFrom(required_import) => { - let StmtKind::ImportFrom { + let StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } = &import.node else { + }) = &import.node else { return false; }; module.as_deref() == required_import.module - && *level == required_import.level + && level.map(|level| level.to_u32()) == required_import.level && names.iter().any(|alias| { - alias.node.name == required_import.name.name + &alias.node.name == required_import.name.name && alias.node.asname.as_deref() == required_import.name.as_name }) } @@ -155,21 +155,21 @@ pub fn add_required_imports( } let stmt = &body[0]; match &stmt.node { - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } => names + }) => names .iter() .filter_map(|name| { add_required_import( &AnyImport::ImportFrom(ImportFrom { - module: module.as_ref().map(String::as_str), + module: module.as_deref(), name: Alias { name: name.node.name.as_str(), as_name: name.node.asname.as_deref(), }, - level: *level, + level: level.map(|level| level.to_u32()), }), blocks, python_ast, @@ -180,7 +180,7 @@ pub fn add_required_imports( ) }) .collect(), - StmtKind::Import { names } => names + StmtKind::Import(ast::StmtImport { names }) => names .iter() .filter_map(|name| { add_required_import( diff --git a/crates/ruff/src/rules/isort/sorting.rs b/crates/ruff/src/rules/isort/sorting.rs index 7d68a0602b..7686d6eb14 100644 --- a/crates/ruff/src/rules/isort/sorting.rs +++ b/crates/ruff/src/rules/isort/sorting.rs @@ -95,8 +95,8 @@ pub fn cmp_members( /// Compare two relative import levels. pub fn cmp_levels( - level1: Option, - level2: Option, + level1: Option, + level2: Option, relative_imports_order: RelativeImportsOrder, ) -> Ordering { match (level1, level2) { diff --git a/crates/ruff/src/rules/isort/track.rs b/crates/ruff/src/rules/isort/track.rs index 6b04a85cf4..b0b33249df 100644 --- a/crates/ruff/src/rules/isort/track.rs +++ b/crates/ruff/src/rules/isort/track.rs @@ -1,5 +1,5 @@ use ruff_text_size::{TextRange, TextSize}; -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, MatchCase, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, MatchCase, Stmt, StmtKind}; use ruff_python_ast::source_code::Locator; use ruff_python_ast::statement_visitor::StatementVisitor; @@ -72,14 +72,14 @@ impl<'a> ImportTracker<'a> { // sibling (i.e., as if the comment is the next statement, as // opposed to the class or function). match &stmt.node { - StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) => { if helpers::has_comment_break(stmt, self.locator) { Trailer::Sibling } else { Trailer::FunctionDef } } - StmtKind::ClassDef { .. } => { + StmtKind::ClassDef(_) => { if helpers::has_comment_break(stmt, self.locator) { Trailer::Sibling } else { @@ -134,11 +134,7 @@ where } // Track imports. - if matches!( - stmt.node, - StmtKind::Import { .. } | StmtKind::ImportFrom { .. } - ) && !is_excluded - { + if matches!(stmt.node, StmtKind::Import(_) | StmtKind::ImportFrom(_)) && !is_excluded { self.track_import(stmt); } else { self.finalize(self.trailer_for(stmt)); @@ -148,25 +144,25 @@ where let prev_nested = self.nested; self.nested = true; match &stmt.node { - StmtKind::FunctionDef { body, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { body, .. }) => { for stmt in body { self.visit_stmt(stmt); } self.finalize(None); } - StmtKind::AsyncFunctionDef { body, .. } => { + StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) => { for stmt in body { self.visit_stmt(stmt); } self.finalize(None); } - StmtKind::ClassDef { body, .. } => { + StmtKind::ClassDef(ast::StmtClassDef { body, .. }) => { for stmt in body { self.visit_stmt(stmt); } self.finalize(None); } - StmtKind::For { body, orelse, .. } => { + StmtKind::For(ast::StmtFor { body, orelse, .. }) => { for stmt in body { self.visit_stmt(stmt); } @@ -177,7 +173,7 @@ where } self.finalize(None); } - StmtKind::AsyncFor { body, orelse, .. } => { + StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. }) => { for stmt in body { self.visit_stmt(stmt); } @@ -188,7 +184,7 @@ where } self.finalize(None); } - StmtKind::While { body, orelse, .. } => { + StmtKind::While(ast::StmtWhile { body, orelse, .. }) => { for stmt in body { self.visit_stmt(stmt); } @@ -199,7 +195,7 @@ where } self.finalize(None); } - StmtKind::If { body, orelse, .. } => { + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { for stmt in body { self.visit_stmt(stmt); } @@ -210,35 +206,35 @@ where } self.finalize(None); } - StmtKind::With { body, .. } => { + StmtKind::With(ast::StmtWith { body, .. }) => { for stmt in body { self.visit_stmt(stmt); } self.finalize(None); } - StmtKind::AsyncWith { body, .. } => { + StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { for stmt in body { self.visit_stmt(stmt); } self.finalize(None); } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { for match_case in cases { self.visit_match_case(match_case); } } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { for excepthandler in handlers { self.visit_excepthandler(excepthandler); } @@ -267,7 +263,8 @@ where let prev_nested = self.nested; self.nested = true; - let ExcepthandlerKind::ExceptHandler { body, .. } = &excepthandler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = + &excepthandler.node; for stmt in body { self.visit_stmt(stmt); } diff --git a/crates/ruff/src/rules/isort/types.rs b/crates/ruff/src/rules/isort/types.rs index 2eb5c7e82a..de23e5a2d0 100644 --- a/crates/ruff/src/rules/isort/types.rs +++ b/crates/ruff/src/rules/isort/types.rs @@ -14,7 +14,7 @@ pub enum TrailingComma { #[derive(Debug, Hash, Ord, PartialOrd, Eq, PartialEq, Clone)] pub struct ImportFromData<'a> { pub module: Option<&'a str>, - pub level: Option, + pub level: Option, } #[derive(Debug, Hash, Ord, PartialOrd, Eq, PartialEq)] diff --git a/crates/ruff/src/rules/mccabe/rules.rs b/crates/ruff/src/rules/mccabe/rules.rs index 7c0f0e6bb2..c20d8a548e 100644 --- a/crates/ruff/src/rules/mccabe/rules.rs +++ b/crates/ruff/src/rules/mccabe/rules.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ExcepthandlerKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, ExcepthandlerKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -69,42 +69,44 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize { let mut complexity = 0; for stmt in stmts { match &stmt.node { - StmtKind::If { body, orelse, .. } => { + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { complexity += 1; complexity += get_complexity_number(body); complexity += get_complexity_number(orelse); } - StmtKind::For { body, orelse, .. } | StmtKind::AsyncFor { body, orelse, .. } => { + StmtKind::For(ast::StmtFor { body, orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. }) => { complexity += 1; complexity += get_complexity_number(body); complexity += get_complexity_number(orelse); } - StmtKind::With { body, .. } | StmtKind::AsyncWith { body, .. } => { + StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { complexity += get_complexity_number(body); } - StmtKind::While { body, orelse, .. } => { + StmtKind::While(ast::StmtWhile { body, orelse, .. }) => { complexity += 1; complexity += get_complexity_number(body); complexity += get_complexity_number(orelse); } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { complexity += 1; for case in cases { complexity += get_complexity_number(&case.body); } } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { complexity += get_complexity_number(body); if !orelse.is_empty() { complexity += 1; @@ -113,15 +115,19 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize { complexity += get_complexity_number(finalbody); for handler in handlers { complexity += 1; - let ExcepthandlerKind::ExceptHandler { body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + body, + .. + }) = &handler.node; complexity += get_complexity_number(body); } } - StmtKind::FunctionDef { body, .. } | StmtKind::AsyncFunctionDef { body, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { body, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) => { complexity += 1; complexity += get_complexity_number(body); } - StmtKind::ClassDef { body, .. } => { + StmtKind::ClassDef(ast::StmtClassDef { body, .. }) => { complexity += get_complexity_number(body); } _ => {} diff --git a/crates/ruff/src/rules/pandas_vet/fixes.rs b/crates/ruff/src/rules/pandas_vet/fixes.rs index e6b5c6e40b..76a43b3b78 100644 --- a/crates/ruff/src/rules/pandas_vet/fixes.rs +++ b/crates/ruff/src/rules/pandas_vet/fixes.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Edit, Fix}; use ruff_python_ast::source_code::Locator; @@ -7,9 +7,9 @@ use ruff_python_ast::source_code::Locator; use crate::autofix::actions::remove_argument; fn match_name(expr: &Expr) -> Option<&str> { - if let ExprKind::Call { func, .. } = &expr.node { - if let ExprKind::Attribute { value, .. } = &func.node { - if let ExprKind::Name { id, .. } = &value.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node { + if let ExprKind::Attribute(ast::ExprAttribute { value, .. }) = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { return Some(id); } } diff --git a/crates/ruff/src/rules/pandas_vet/helpers.rs b/crates/ruff/src/rules/pandas_vet/helpers.rs index d9e72ce72b..99be263318 100644 --- a/crates/ruff/src/rules/pandas_vet/helpers.rs +++ b/crates/ruff/src/rules/pandas_vet/helpers.rs @@ -5,14 +5,14 @@ use rustpython_parser::ast::{Expr, ExprKind}; pub const fn is_dataframe_candidate(expr: &Expr) -> bool { !matches!( expr.node, - ExprKind::Constant { .. } - | ExprKind::Tuple { .. } - | ExprKind::List { .. } - | ExprKind::Set { .. } - | ExprKind::Dict { .. } - | ExprKind::SetComp { .. } - | ExprKind::ListComp { .. } - | ExprKind::DictComp { .. } - | ExprKind::GeneratorExp { .. } + ExprKind::Constant(_) + | ExprKind::Tuple(_) + | ExprKind::List(_) + | ExprKind::Set(_) + | ExprKind::Dict(_) + | ExprKind::SetComp(_) + | ExprKind::ListComp(_) + | ExprKind::DictComp(_) + | ExprKind::GeneratorExp(_) ) } diff --git a/crates/ruff/src/rules/pandas_vet/rules/assignment_to_df.rs b/crates/ruff/src/rules/pandas_vet/rules/assignment_to_df.rs index 3aca25eb52..3a0d4a69d7 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/assignment_to_df.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/assignment_to_df.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -19,7 +19,7 @@ pub fn assignment_to_df(targets: &[Expr]) -> Option { return None; } let target = &targets[0]; - let ExprKind::Name { id, .. } = &target.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &target.node else { return None; }; if id != "df" { diff --git a/crates/ruff/src/rules/pandas_vet/rules/check_attr.rs b/crates/ruff/src/rules/pandas_vet/rules/check_attr.rs index 22636ea6f6..efdaab6115 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/check_attr.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/check_attr.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::Violation; use ruff_diagnostics::{Diagnostic, DiagnosticKind}; @@ -61,7 +61,7 @@ pub fn check_attr(checker: &mut Checker, attr: &str, value: &Expr, attr_expr: &E // Avoid flagging on function calls (e.g., `df.values()`). if let Some(parent) = checker.ctx.expr_parent() { - if matches!(parent.node, ExprKind::Call { .. }) { + if matches!(parent.node, ExprKind::Call(_)) { return; } } @@ -72,7 +72,7 @@ pub fn check_attr(checker: &mut Checker, attr: &str, value: &Expr, attr_expr: &E // If the target is a named variable, avoid triggering on // irrelevant bindings (like imports). - if let ExprKind::Name { id, .. } = &value.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { if checker.ctx.find_binding(id).map_or(true, |binding| { matches!( binding.kind, diff --git a/crates/ruff/src/rules/pandas_vet/rules/check_call.rs b/crates/ruff/src/rules/pandas_vet/rules/check_call.rs index 494e33909e..5abd56432d 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/check_call.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/check_call.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::Violation; use ruff_diagnostics::{Diagnostic, DiagnosticKind}; @@ -63,7 +63,7 @@ impl Violation for PandasUseOfDotStack { pub fn check_call(checker: &mut Checker, func: &Expr) { let rules = &checker.settings.rules; - let ExprKind::Attribute { value, attr, .. } = &func.node else {return}; + let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. } )= &func.node else {return}; let violation: DiagnosticKind = match attr.as_str() { "isnull" if rules.enabled(Rule::PandasUseOfDotIsNull) => PandasUseOfDotIsNull.into(), "notnull" if rules.enabled(Rule::PandasUseOfDotNotNull) => PandasUseOfDotNotNull.into(), @@ -83,7 +83,7 @@ pub fn check_call(checker: &mut Checker, func: &Expr) { // If the target is a named variable, avoid triggering on // irrelevant bindings (like non-Pandas imports). - if let ExprKind::Name { id, .. } = &value.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { if checker.ctx.find_binding(id).map_or(true, |binding| { if let BindingKind::Importation(Importation { full_name: module, .. diff --git a/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs b/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs index 2896f5ef89..c91a2e21f2 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/inplace_argument.rs @@ -1,5 +1,5 @@ use ruff_python_semantic::binding::{BindingKind, Importation}; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, StmtKind}; use ruff_diagnostics::{AutofixKind, Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -82,10 +82,10 @@ pub fn inplace_argument( }; if arg == "inplace" { let is_true_literal = match &keyword.node.value.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(boolean), .. - } => *boolean, + }) => *boolean, _ => false, }; if is_true_literal { @@ -99,7 +99,7 @@ pub fn inplace_argument( // but we don't currently restore expression stacks when parsing deferred nodes, // and so the parent is lost. let fixable = !seen_star - && matches!(checker.ctx.stmt().node, StmtKind::Expr { .. }) + && matches!(checker.ctx.stmt().node, StmtKind::Expr(_)) && checker.ctx.expr_parent().is_none() && !checker.ctx.scope().kind.is_lambda(); let mut diagnostic = Diagnostic::new(PandasUseOfInplaceArgument, keyword.range()); diff --git a/crates/ruff/src/rules/pandas_vet/rules/pd_merge.rs b/crates/ruff/src/rules/pandas_vet/rules/pd_merge.rs index acd6cee0a6..1d1491cb14 100644 --- a/crates/ruff/src/rules/pandas_vet/rules/pd_merge.rs +++ b/crates/ruff/src/rules/pandas_vet/rules/pd_merge.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -18,8 +18,8 @@ impl Violation for PandasUseOfPdMerge { /// PD015 pub fn use_of_pd_merge(func: &Expr) -> Option { - if let ExprKind::Attribute { attr, value, .. } = &func.node { - if let ExprKind::Name { id, .. } = &value.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, value, .. }) = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { if id == "pd" && attr == "merge" { return Some(Diagnostic::new(PandasUseOfPdMerge, func.range())); } diff --git a/crates/ruff/src/rules/pep8_naming/helpers.rs b/crates/ruff/src/rules/pep8_naming/helpers.rs index 7345c645b3..1bed2d3014 100644 --- a/crates/ruff/src/rules/pep8_naming/helpers.rs +++ b/crates/ruff/src/rules/pep8_naming/helpers.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use ruff_python_semantic::context::Context; -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_python_stdlib::str::{is_lower, is_upper}; @@ -23,10 +23,10 @@ pub(crate) fn is_acronym(name: &str, asname: &str) -> bool { } pub(crate) fn is_named_tuple_assignment(context: &Context, stmt: &Stmt) -> bool { - let StmtKind::Assign { value, .. } = &stmt.node else { + let StmtKind::Assign(ast::StmtAssign { value, .. }) = &stmt.node else { return false; }; - let ExprKind::Call {func, ..} = &value.node else { + let ExprKind::Call(ast::ExprCall {func, ..}) = &value.node else { return false; }; context.resolve_call_path(func).map_or(false, |call_path| { @@ -38,10 +38,10 @@ pub(crate) fn is_named_tuple_assignment(context: &Context, stmt: &Stmt) -> bool } pub(crate) fn is_typed_dict_assignment(context: &Context, stmt: &Stmt) -> bool { - let StmtKind::Assign { value, .. } = &stmt.node else { + let StmtKind::Assign(ast::StmtAssign { value, .. }) = &stmt.node else { return false; }; - let ExprKind::Call {func, ..} = &value.node else { + let ExprKind::Call(ast::ExprCall {func, ..}) = &value.node else { return false; }; context.resolve_call_path(func).map_or(false, |call_path| { @@ -50,10 +50,10 @@ pub(crate) fn is_typed_dict_assignment(context: &Context, stmt: &Stmt) -> bool { } pub(crate) fn is_type_var_assignment(context: &Context, stmt: &Stmt) -> bool { - let StmtKind::Assign { value, .. } = &stmt.node else { + let StmtKind::Assign(ast::StmtAssign { value, .. }) = &stmt.node else { return false; }; - let ExprKind::Call {func, ..} = &value.node else { + let ExprKind::Call(ast::ExprCall {func, ..}) = &value.node else { return false; }; context.resolve_call_path(func).map_or(false, |call_path| { diff --git a/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs b/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs index 02576e634e..9f753261b4 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/error_suffix_on_exception_name.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -49,7 +49,7 @@ pub fn error_suffix_on_exception_name( locator: &Locator, ) -> Option { if !bases.iter().any(|base| { - if let ExprKind::Name { id, .. } = &base.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &base.node { id == "Exception" || id.ends_with("Error") } else { false diff --git a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs index 76296104a1..cd78a698ff 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_class_method.rs @@ -76,7 +76,7 @@ pub fn invalid_first_argument_name_for_class_method( return None; } if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) { - if arg.node.arg != "cls" { + if &arg.node.arg != "cls" { if checker .settings .pep8_naming diff --git a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs index 148b565712..faf1f4625c 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/invalid_first_argument_name_for_method.rs @@ -73,7 +73,7 @@ pub fn invalid_first_argument_name_for_method( return None; } let arg = args.posonlyargs.first().or_else(|| args.args.first())?; - if arg.node.arg == "self" { + if &arg.node.arg == "self" { return None; } if checker diff --git a/crates/ruff/src/rules/pycodestyle/helpers.rs b/crates/ruff/src/rules/pycodestyle/helpers.rs index 70be4dcfe0..26e43c75ba 100644 --- a/crates/ruff/src/rules/pycodestyle/helpers.rs +++ b/crates/ruff/src/rules/pycodestyle/helpers.rs @@ -2,7 +2,7 @@ use ruff_python_ast::helpers::{create_expr, unparse_expr}; use ruff_python_ast::newlines::Line; use ruff_python_ast::source_code::Stylist; use ruff_text_size::{TextLen, TextRange}; -use rustpython_parser::ast::{Cmpop, Expr, ExprKind}; +use rustpython_parser::ast::{self, Cmpop, Expr}; use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; pub fn is_ambiguous_name(name: &str) -> bool { @@ -11,7 +11,7 @@ pub fn is_ambiguous_name(name: &str) -> bool { pub fn compare(left: &Expr, ops: &[Cmpop], comparators: &[Expr], stylist: &Stylist) -> String { unparse_expr( - &create_expr(ExprKind::Compare { + &create_expr(ast::ExprCompare { left: Box::new(left.clone()), ops: ops.to_vec(), comparators: comparators.to_vec(), diff --git a/crates/ruff/src/rules/pycodestyle/rules/bare_except.rs b/crates/ruff/src/rules/pycodestyle/rules/bare_except.rs index d9ea3adf03..c472df1d1b 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/bare_except.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/bare_except.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, Expr, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Excepthandler, Expr, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -54,7 +54,7 @@ pub fn bare_except( if type_.is_none() && !body .iter() - .any(|stmt| matches!(stmt.node, StmtKind::Raise { exc: None, .. })) + .any(|stmt| matches!(stmt.node, StmtKind::Raise(ast::StmtRaise { exc: None, .. }))) { Some(Diagnostic::new(BareExcept, except_range(handler, locator))) } else { diff --git a/crates/ruff/src/rules/pycodestyle/rules/errors.rs b/crates/ruff/src/rules/pycodestyle/rules/errors.rs index 365ab8a4ad..f3427e0c9e 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/errors.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/errors.rs @@ -39,7 +39,7 @@ pub fn syntax_error( parse_error: &ParseError, locator: &Locator, ) { - let rest = locator.after(parse_error.location); + let rest = locator.after(parse_error.offset); // Try to create a non-empty range so that the diagnostic can print a caret at the // right position. This requires that we retrieve the next character, if any, and take its length @@ -53,6 +53,6 @@ pub fn syntax_error( SyntaxError { message: format!("{}", DisplayParseErrorType::new(&parse_error.error)), }, - TextRange::at(parse_error.location, len), + TextRange::at(parse_error.offset, len), )); } diff --git a/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs b/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs index 3d3484b82f..5521a35b89 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/lambda_assignment.rs @@ -6,8 +6,8 @@ use ruff_python_ast::source_code::Stylist; use ruff_python_ast::whitespace::leading_space; use ruff_python_semantic::context::Context; use ruff_python_semantic::scope::ScopeKind; -use ruff_text_size::{TextRange, TextSize}; -use rustpython_parser::ast::{Arg, ArgData, Arguments, Constant, Expr, ExprKind, Stmt, StmtKind}; +use ruff_text_size::TextRange; +use rustpython_parser::ast::{self, Arg, ArgData, Arguments, Constant, Expr, ExprKind, Stmt}; use crate::checkers::ast::Checker; use crate::registry::AsRule; @@ -63,8 +63,8 @@ pub fn lambda_assignment( annotation: Option<&Expr>, stmt: &Stmt, ) { - if let ExprKind::Name { id, .. } = &target.node { - if let ExprKind::Lambda { args, body } = &value.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node { + if let ExprKind::Lambda(ast::ExprLambda { args, body }) = &value.node { // If the assignment is in a class body, it might not be safe // to replace it because the assignment might be // carrying a type annotation that will be used by some @@ -118,10 +118,10 @@ pub fn lambda_assignment( /// If an ellipsis is used for the argument types, an empty list is returned. /// The returned values are cloned, so they can be used as-is. fn extract_types(ctx: &Context, annotation: &Expr) -> Option<(Vec, Expr)> { - let ExprKind::Subscript { value, slice, .. } = &annotation.node else { + let ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) = &annotation.node else { return None; }; - let ExprKind::Tuple { elts, .. } = &slice.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &slice.node else { return None; }; if elts.len() != 2 { @@ -138,11 +138,11 @@ fn extract_types(ctx: &Context, annotation: &Expr) -> Option<(Vec, Expr)> // The first argument to `Callable` must be a list of types, parameter // specification, or ellipsis. let args = match &elts[0].node { - ExprKind::List { elts, .. } => elts.clone(), - ExprKind::Constant { + ExprKind::List(ast::ExprList { elts, .. }) => elts.clone(), + ExprKind::Constant(ast::ExprConstant { value: Constant::Ellipsis, .. - } => vec![], + }) => vec![], _ => return None, }; @@ -161,9 +161,8 @@ fn function( stylist: &Stylist, ) -> String { let body = Stmt::new( - TextSize::default(), - TextSize::default(), - StmtKind::Return { + TextRange::default(), + ast::StmtReturn { value: Some(Box::new(body.clone())), }, ); @@ -176,14 +175,14 @@ fn function( .iter() .enumerate() .map(|(idx, arg)| { - Arg::with_range( + Arg::new( + TextRange::default(), ArgData { annotation: arg_types .get(idx) .map(|arg_type| Box::new(arg_type.clone())), ..arg.node.clone() }, - TextRange::default(), ) }) .collect::>(); @@ -192,20 +191,21 @@ fn function( .iter() .enumerate() .map(|(idx, arg)| { - Arg::with_range( + Arg::new( + TextRange::default(), ArgData { annotation: arg_types .get(idx + new_posonlyargs.len()) .map(|arg_type| Box::new(arg_type.clone())), ..arg.node.clone() }, - TextRange::default(), ) }) .collect::>(); - let func = Stmt::with_range( - StmtKind::FunctionDef { - name: name.to_string(), + let func = Stmt::new( + TextRange::default(), + ast::StmtFunctionDef { + name: name.into(), args: Box::new(Arguments { posonlyargs: new_posonlyargs, args: new_args, @@ -216,16 +216,14 @@ fn function( returns: Some(Box::new(return_type)), type_comment: None, }, - TextRange::default(), ); return unparse_stmt(&func, stylist); } } let func = Stmt::new( - TextSize::default(), - TextSize::default(), - StmtKind::FunctionDef { - name: name.to_string(), + TextRange::default(), + ast::StmtFunctionDef { + name: name.into(), args: Box::new(args.clone()), body: vec![body], decorator_list: vec![], diff --git a/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs b/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs index a527688eb4..35298f330c 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/literal_comparisons.rs @@ -1,6 +1,6 @@ use itertools::izip; use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -157,10 +157,10 @@ pub fn literal_comparisons( if check_none_comparisons && matches!( comparator.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, kind: None - } + }) ) { if matches!(op, Cmpop::Eq) { @@ -180,10 +180,10 @@ pub fn literal_comparisons( } if check_true_false_comparisons { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(value), kind: None, - } = comparator.node + }) = comparator.node { if matches!(op, Cmpop::Eq) { let diagnostic = @@ -215,10 +215,10 @@ pub fn literal_comparisons( if check_none_comparisons && matches!( next.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, kind: None - } + }) ) { if matches!(op, Cmpop::Eq) { @@ -238,10 +238,10 @@ pub fn literal_comparisons( } if check_true_false_comparisons { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(value), kind: None, - } = next.node + }) = next.node { if matches!(op, Cmpop::Eq) { let diagnostic = diff --git a/crates/ruff/src/rules/pycodestyle/rules/not_tests.rs b/crates/ruff/src/rules/pycodestyle/rules/not_tests.rs index e1bff68f62..f58fec2fb8 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/not_tests.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/not_tests.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Cmpop, Expr, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Cmpop, Expr, ExprKind, Unaryop}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -83,12 +83,11 @@ pub fn not_tests( check_not_is: bool, ) { if matches!(op, Unaryop::Not) { - if let ExprKind::Compare { + if let ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - .. - } = &operand.node + }) = &operand.node { if !matches!(&ops[..], [Cmpop::In | Cmpop::Is]) { return; diff --git a/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs b/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs index 2ea7d24771..5adcb251fa 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/type_comparison.rs @@ -1,5 +1,5 @@ use itertools::izip; -use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprKind}; use crate::checkers::ast::Checker; use ruff_diagnostics::{Diagnostic, Violation}; @@ -43,19 +43,19 @@ pub fn type_comparison(checker: &mut Checker, expr: &Expr, ops: &[Cmpop], compar continue; } match &right.node { - ExprKind::Call { func, args, .. } => { - if let ExprKind::Name { id, .. } = &func.node { + ExprKind::Call(ast::ExprCall { func, args, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { // Ex) `type(False)` if id == "type" && checker.ctx.is_builtin("type") { if let Some(arg) = args.first() { // Allow comparison for types which are not obvious. if !matches!( arg.node, - ExprKind::Name { .. } - | ExprKind::Constant { + ExprKind::Name(_) + | ExprKind::Constant(ast::ExprConstant { value: Constant::None, kind: None - } + }) ) { checker .diagnostics @@ -65,8 +65,8 @@ pub fn type_comparison(checker: &mut Checker, expr: &Expr, ops: &[Cmpop], compar } } } - ExprKind::Attribute { value, .. } => { - if let ExprKind::Name { id, .. } = &value.node { + ExprKind::Attribute(ast::ExprAttribute { value, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node { // Ex) `types.NoneType` if id == "types" && checker diff --git a/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs b/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs index 8d635ed0f9..8ba3d3bbc3 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/no_signature.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::StmtKind; +use rustpython_parser::ast::{self, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -26,7 +26,7 @@ pub fn no_signature(checker: &mut Checker, docstring: &Docstring) { ) = docstring.kind else { return; }; - let StmtKind::FunctionDef { name, .. } = &parent.node else { + let StmtKind::FunctionDef(ast::StmtFunctionDef { name, .. }) = &parent.node else { return; }; diff --git a/crates/ruff/src/rules/pydocstyle/rules/sections.rs b/crates/ruff/src/rules/pydocstyle/rules/sections.rs index fa726e99f2..d241abfe74 100644 --- a/crates/ruff/src/rules/pydocstyle/rules/sections.rs +++ b/crates/ruff/src/rules/pydocstyle/rules/sections.rs @@ -3,7 +3,7 @@ use once_cell::sync::Lazy; use regex::Regex; use ruff_text_size::{TextLen, TextRange, TextSize}; use rustc_hash::FxHashSet; -use rustpython_parser::ast::StmtKind; +use rustpython_parser::ast::{self, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix}; @@ -733,12 +733,12 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: & return; }; let ( - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { args: arguments, .. - } - | StmtKind::AsyncFunctionDef { + }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { args: arguments, .. - } + }) ) = &parent.node else { return; }; @@ -758,7 +758,7 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: & ), ) { - let arg_name = &arg.node.arg; + let arg_name = arg.node.arg.as_str(); if !arg_name.starts_with('_') && !docstrings_args.contains(arg_name) { missing_arg_names.insert(arg_name.to_string()); } @@ -767,7 +767,7 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: & // Check specifically for `vararg` and `kwarg`, which can be prefixed with a // single or double star, respectively. if let Some(arg) = &arguments.vararg { - let arg_name = &arg.node.arg; + let arg_name = arg.node.arg.as_str(); let starred_arg_name = format!("*{arg_name}"); if !arg_name.starts_with('_') && !docstrings_args.contains(arg_name) @@ -777,7 +777,7 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: & } } if let Some(arg) = &arguments.kwarg { - let arg_name = &arg.node.arg; + let arg_name = arg.node.arg.as_str(); let starred_arg_name = format!("**{arg_name}"); if !arg_name.starts_with('_') && !docstrings_args.contains(arg_name) diff --git a/crates/ruff/src/rules/pyflakes/fixes.rs b/crates/ruff/src/rules/pyflakes/fixes.rs index 52f848fc4a..e96eef8e4c 100644 --- a/crates/ruff/src/rules/pyflakes/fixes.rs +++ b/crates/ruff/src/rules/pyflakes/fixes.rs @@ -182,7 +182,8 @@ pub fn remove_exception_handler_assignment( // End of the token just before the `as` to the semicolon. let mut prev = None; - for (tok, range) in lexer::lex_located(contents, Mode::Module, excepthandler.start()).flatten() + for (tok, range) in + lexer::lex_starts_at(contents, Mode::Module, excepthandler.start()).flatten() { if matches!(tok, Tok::As) { fix_start = prev; diff --git a/crates/ruff/src/rules/pyflakes/rules/assert_tuple.rs b/crates/ruff/src/rules/pyflakes/rules/assert_tuple.rs index f91a09ca9c..3c1be41c05 100644 --- a/crates/ruff/src/rules/pyflakes/rules/assert_tuple.rs +++ b/crates/ruff/src/rules/pyflakes/rules/assert_tuple.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -17,7 +17,7 @@ impl Violation for AssertTuple { /// F631 pub fn assert_tuple(checker: &mut Checker, stmt: &Stmt, test: &Expr) { - if let ExprKind::Tuple { elts, .. } = &test.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &test.node { if !elts.is_empty() { checker .diagnostics diff --git a/crates/ruff/src/rules/pyflakes/rules/break_outside_loop.rs b/crates/ruff/src/rules/pyflakes/rules/break_outside_loop.rs index d40f6a1714..6a3c3e6ac5 100644 --- a/crates/ruff/src/rules/pyflakes/rules/break_outside_loop.rs +++ b/crates/ruff/src/rules/pyflakes/rules/break_outside_loop.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Stmt, StmtKind}; +use rustpython_parser::ast::{self, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -22,17 +22,15 @@ pub fn break_outside_loop<'a>( let mut child = stmt; for parent in parents { match &parent.node { - StmtKind::For { orelse, .. } - | StmtKind::AsyncFor { orelse, .. } - | StmtKind::While { orelse, .. } => { + StmtKind::For(ast::StmtFor { orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { orelse, .. }) + | StmtKind::While(ast::StmtWhile { orelse, .. }) => { if !orelse.contains(child) { allowed = true; break; } } - StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } - | StmtKind::ClassDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) | StmtKind::ClassDef(_) => { break; } _ => {} diff --git a/crates/ruff/src/rules/pyflakes/rules/continue_outside_loop.rs b/crates/ruff/src/rules/pyflakes/rules/continue_outside_loop.rs index 6bee0d00b7..63077f9a9e 100644 --- a/crates/ruff/src/rules/pyflakes/rules/continue_outside_loop.rs +++ b/crates/ruff/src/rules/pyflakes/rules/continue_outside_loop.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Stmt, StmtKind}; +use rustpython_parser::ast::{self, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -22,17 +22,15 @@ pub fn continue_outside_loop<'a>( let mut child = stmt; for parent in parents { match &parent.node { - StmtKind::For { orelse, .. } - | StmtKind::AsyncFor { orelse, .. } - | StmtKind::While { orelse, .. } => { + StmtKind::For(ast::StmtFor { orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { orelse, .. }) + | StmtKind::While(ast::StmtWhile { orelse, .. }) => { if !orelse.contains(child) { allowed = true; break; } } - StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } - | StmtKind::ClassDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) | StmtKind::ClassDef(_) => { break; } _ => {} diff --git a/crates/ruff/src/rules/pyflakes/rules/default_except_not_last.rs b/crates/ruff/src/rules/pyflakes/rules/default_except_not_last.rs index 1c87c5c743..a8879fa826 100644 --- a/crates/ruff/src/rules/pyflakes/rules/default_except_not_last.rs +++ b/crates/ruff/src/rules/pyflakes/rules/default_except_not_last.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -21,7 +21,8 @@ pub fn default_except_not_last( locator: &Locator, ) -> Option { for (idx, handler) in handlers.iter().enumerate() { - let ExcepthandlerKind::ExceptHandler { type_, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = + &handler.node; if type_.is_none() && idx < handlers.len() - 1 { return Some(Diagnostic::new( DefaultExceptNotLast, diff --git a/crates/ruff/src/rules/pyflakes/rules/f_string_missing_placeholders.rs b/crates/ruff/src/rules/pyflakes/rules/f_string_missing_placeholders.rs index 4184666bc8..df57139cb9 100644 --- a/crates/ruff/src/rules/pyflakes/rules/f_string_missing_placeholders.rs +++ b/crates/ruff/src/rules/pyflakes/rules/f_string_missing_placeholders.rs @@ -54,7 +54,7 @@ fn find_useless_f_strings<'a>( locator: &'a Locator, ) -> impl Iterator + 'a { let contents = locator.slice(expr.range()); - lexer::lex_located(contents, Mode::Module, expr.start()) + lexer::lex_starts_at(contents, Mode::Module, expr.start()) .flatten() .filter_map(|(tok, range)| match tok { Tok::String { @@ -101,7 +101,7 @@ fn fix_f_string_missing_placeholders( pub fn f_string_missing_placeholders(expr: &Expr, values: &[Expr], checker: &mut Checker) { if !values .iter() - .any(|value| matches!(value.node, ExprKind::FormattedValue { .. })) + .any(|value| matches!(value.node, ExprKind::FormattedValue(_))) { for (prefix_range, tok_range) in find_useless_f_strings(expr, checker.locator) { let mut diagnostic = Diagnostic::new(FStringMissingPlaceholders, tok_range); diff --git a/crates/ruff/src/rules/pyflakes/rules/if_tuple.rs b/crates/ruff/src/rules/pyflakes/rules/if_tuple.rs index 70607fb0a9..282e2e567d 100644 --- a/crates/ruff/src/rules/pyflakes/rules/if_tuple.rs +++ b/crates/ruff/src/rules/pyflakes/rules/if_tuple.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -17,7 +17,7 @@ impl Violation for IfTuple { /// F634 pub fn if_tuple(checker: &mut Checker, stmt: &Stmt, test: &Expr) { - if let ExprKind::Tuple { elts, .. } = &test.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &test.node { if !elts.is_empty() { checker .diagnostics diff --git a/crates/ruff/src/rules/pyflakes/rules/imports.rs b/crates/ruff/src/rules/pyflakes/rules/imports.rs index 7b6b3ebf18..cf9f9290cb 100644 --- a/crates/ruff/src/rules/pyflakes/rules/imports.rs +++ b/crates/ruff/src/rules/pyflakes/rules/imports.rs @@ -136,7 +136,7 @@ impl Violation for FutureFeatureNotDefined { } pub fn future_feature_not_defined(checker: &mut Checker, alias: &Alias) { - if !ALL_FEATURE_NAMES.contains(&&*alias.node.name) { + if !ALL_FEATURE_NAMES.contains(&alias.node.name.as_str()) { checker.diagnostics.push(Diagnostic::new( FutureFeatureNotDefined { name: alias.node.name.to_string(), diff --git a/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs b/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs index d00bf69105..f75ecf9a52 100644 --- a/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs +++ b/crates/ruff/src/rules/pyflakes/rules/invalid_print_syntax.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -17,7 +17,7 @@ impl Violation for InvalidPrintSyntax { /// F633 pub fn invalid_print_syntax(checker: &mut Checker, left: &Expr) { - let ExprKind::Name { id, .. } = &left.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &left.node else { return; }; if id != "print" { diff --git a/crates/ruff/src/rules/pyflakes/rules/raise_not_implemented.rs b/crates/ruff/src/rules/pyflakes/rules/raise_not_implemented.rs index 541779f42b..fef06dfef0 100644 --- a/crates/ruff/src/rules/pyflakes/rules/raise_not_implemented.rs +++ b/crates/ruff/src/rules/pyflakes/rules/raise_not_implemented.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -22,14 +22,14 @@ impl AlwaysAutofixableViolation for RaiseNotImplemented { fn match_not_implemented(expr: &Expr) -> Option<&Expr> { match &expr.node { - ExprKind::Call { func, .. } => { - if let ExprKind::Name { id, .. } = &func.node { + ExprKind::Call(ast::ExprCall { func, .. }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { if id == "NotImplemented" { return Some(func); } } } - ExprKind::Name { id, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => { if id == "NotImplemented" { return Some(expr); } diff --git a/crates/ruff/src/rules/pyflakes/rules/repeated_keys.rs b/crates/ruff/src/rules/pyflakes/rules/repeated_keys.rs index f8a2121a94..b21b7212e6 100644 --- a/crates/ruff/src/rules/pyflakes/rules/repeated_keys.rs +++ b/crates/ruff/src/rules/pyflakes/rules/repeated_keys.rs @@ -1,7 +1,7 @@ use std::hash::{BuildHasherDefault, Hash}; use rustc_hash::{FxHashMap, FxHashSet}; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -74,8 +74,10 @@ enum DictionaryKey<'a> { fn into_dictionary_key(expr: &Expr) -> Option { match &expr.node { - ExprKind::Constant { value, .. } => Some(DictionaryKey::Constant(value.into())), - ExprKind::Name { id, .. } => Some(DictionaryKey::Variable(id)), + ExprKind::Constant(ast::ExprConstant { value, .. }) => { + Some(DictionaryKey::Constant(value.into())) + } + ExprKind::Name(ast::ExprName { id, .. }) => Some(DictionaryKey::Variable(id)), _ => None, } } diff --git a/crates/ruff/src/rules/pyflakes/rules/starred_expressions.rs b/crates/ruff/src/rules/pyflakes/rules/starred_expressions.rs index 10697f2b16..b2d327e141 100644 --- a/crates/ruff/src/rules/pyflakes/rules/starred_expressions.rs +++ b/crates/ruff/src/rules/pyflakes/rules/starred_expressions.rs @@ -34,7 +34,7 @@ pub fn starred_expressions( let mut has_starred: bool = false; let mut starred_index: Option = None; for (index, elt) in elts.iter().enumerate() { - if matches!(elt.node, ExprKind::Starred { .. }) { + if matches!(elt.node, ExprKind::Starred(_)) { if has_starred && check_two_starred_expressions { return Some(Diagnostic::new(MultipleStarredExpressions, location)); } diff --git a/crates/ruff/src/rules/pyflakes/rules/strings.rs b/crates/ruff/src/rules/pyflakes/rules/strings.rs index 31aebf98e8..b21bca31fb 100644 --- a/crates/ruff/src/rules/pyflakes/rules/strings.rs +++ b/crates/ruff/src/rules/pyflakes/rules/strings.rs @@ -2,7 +2,7 @@ use ruff_text_size::TextRange; use std::string::ToString; use rustc_hash::FxHashSet; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, KeywordData}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Identifier, Keyword, KeywordData}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -217,7 +217,7 @@ fn has_star_star_kwargs(keywords: &[Keyword]) -> bool { fn has_star_args(args: &[Expr]) -> bool { args.iter() - .any(|arg| matches!(&arg.node, ExprKind::Starred { .. })) + .any(|arg| matches!(&arg.node, ExprKind::Starred(_))) } /// F502 @@ -230,12 +230,12 @@ pub(crate) fn percent_format_expected_mapping( if !summary.keywords.is_empty() { // Tuple, List, Set (+comprehensions) match right.node { - ExprKind::List { .. } - | ExprKind::Tuple { .. } - | ExprKind::Set { .. } - | ExprKind::ListComp { .. } - | ExprKind::SetComp { .. } - | ExprKind::GeneratorExp { .. } => checker + ExprKind::List(_) + | ExprKind::Tuple(_) + | ExprKind::Set(_) + | ExprKind::ListComp(_) + | ExprKind::SetComp(_) + | ExprKind::GeneratorExp(_) => checker .diagnostics .push(Diagnostic::new(PercentFormatExpectedMapping, location)), _ => {} @@ -250,11 +250,7 @@ pub(crate) fn percent_format_expected_sequence( right: &Expr, location: TextRange, ) { - if summary.num_positional > 1 - && matches!( - right.node, - ExprKind::Dict { .. } | ExprKind::DictComp { .. } - ) + if summary.num_positional > 1 && matches!(right.node, ExprKind::Dict(_) | ExprKind::DictComp(_)) { checker .diagnostics @@ -272,7 +268,7 @@ pub(crate) fn percent_format_extra_named_arguments( if summary.num_positional > 0 { return; } - let ExprKind::Dict { keys, .. } = &right.node else { + let ExprKind::Dict(ast::ExprDict { keys, .. }) = &right.node else { return; }; if keys.iter().any(std::option::Option::is_none) { @@ -284,10 +280,10 @@ pub(crate) fn percent_format_extra_named_arguments( .filter_map(|k| match k { Some(Expr { node: - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - }, + }), .. }) => { if summary.keywords.contains(value) { @@ -335,7 +331,7 @@ pub(crate) fn percent_format_missing_arguments( return; } - if let ExprKind::Dict { keys, .. } = &right.node { + if let ExprKind::Dict(ast::ExprDict { keys, .. }) = &right.node { if keys.iter().any(std::option::Option::is_none) { return; // contains **x splat } @@ -343,10 +339,10 @@ pub(crate) fn percent_format_missing_arguments( let mut keywords = FxHashSet::default(); for key in keys.iter().flatten() { match &key.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } => { + }) => { keywords.insert(value); } _ => { @@ -398,10 +394,12 @@ pub(crate) fn percent_format_positional_count_mismatch( } match &right.node { - ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } | ExprKind::Set { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) + | ExprKind::Set(ast::ExprSet { elts }) => { let mut found = 0; for elt in elts { - if let ExprKind::Starred { .. } = &elt.node { + if let ExprKind::Starred(_) = &elt.node { return; } found += 1; @@ -430,7 +428,7 @@ pub(crate) fn percent_format_star_requires_sequence( ) { if summary.starred { match &right.node { - ExprKind::Dict { .. } | ExprKind::DictComp { .. } => checker + ExprKind::Dict(_) | ExprKind::DictComp(_) => checker .diagnostics .push(Diagnostic::new(PercentFormatStarRequiresSequence, location)), _ => {} @@ -456,7 +454,7 @@ pub(crate) fn string_dot_format_extra_named_arguments( let missing: Vec<&str> = keywords .filter_map(|arg| { - if summary.keywords.contains(arg) { + if summary.keywords.contains(arg.as_ref()) { None } else { Some(arg.as_str()) @@ -499,7 +497,7 @@ pub(crate) fn string_dot_format_extra_positional_arguments( .iter() .enumerate() .filter(|(i, arg)| { - !(matches!(arg.node, ExprKind::Starred { .. }) + !(matches!(arg.node, ExprKind::Starred(_)) || summary.autos.contains(i) || summary.indices.contains(i)) }) @@ -550,7 +548,7 @@ pub(crate) fn string_dot_format_missing_argument( .iter() .filter_map(|k| { let KeywordData { arg, .. } = &k.node; - arg.as_ref() + arg.as_ref().map(Identifier::as_str) }) .collect(); @@ -564,7 +562,7 @@ pub(crate) fn string_dot_format_missing_argument( summary .keywords .iter() - .filter(|k| !keywords.contains(k)) + .filter(|k| !keywords.contains(k.as_str())) .cloned(), ) .collect(); diff --git a/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs b/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs index a5b79ee513..77a4c1ff72 100644 --- a/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs +++ b/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use log::error; use ruff_text_size::TextRange; -use rustpython_parser::ast::{ExprKind, Located, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Attributed, ExprKind, Stmt, StmtKind}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; @@ -65,7 +65,7 @@ impl Violation for UnusedVariable { /// Return the [`TextRange`] of the token after the next match of /// the predicate, skipping over any bracketed expressions. -fn match_token_after(located: &Located, locator: &Locator, f: F) -> TextRange +fn match_token_after(located: &Attributed, locator: &Locator, f: F) -> TextRange where F: Fn(Tok) -> bool, { @@ -76,7 +76,7 @@ where let mut sqb_count = 0; let mut brace_count = 0; - for ((tok, _), (_, range)) in lexer::lex_located(contents, Mode::Module, located.start()) + for ((tok, _), (_, range)) in lexer::lex_starts_at(contents, Mode::Module, located.start()) .flatten() .tuple_windows() { @@ -127,7 +127,7 @@ where /// Return the [`TextRange`] of the token matching the predicate, /// skipping over any bracketed expressions. -fn match_token(located: &Located, locator: &Locator, f: F) -> TextRange +fn match_token(located: &Attributed, locator: &Locator, f: F) -> TextRange where F: Fn(Tok) -> bool, { @@ -138,7 +138,7 @@ where let mut sqb_count = 0; let mut brace_count = 0; - for (tok, range) in lexer::lex_located(contents, Mode::Module, located.start()).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, located.start()).flatten() { match tok { Tok::Lpar => { par_count += 1; @@ -198,9 +198,9 @@ fn remove_unused_variable( checker: &Checker, ) -> Option<(DeletionKind, Fix)> { // First case: simple assignment (`x = 1`) - if let StmtKind::Assign { targets, value, .. } = &stmt.node { + if let StmtKind::Assign(ast::StmtAssign { targets, value, .. }) = &stmt.node { if let Some(target) = targets.iter().find(|target| range == target.range()) { - if matches!(target.node, ExprKind::Name { .. }) { + if matches!(target.node, ExprKind::Name(_)) { return if targets.len() > 1 || contains_effect(value, |id| checker.ctx.is_builtin(id)) { @@ -240,13 +240,13 @@ fn remove_unused_variable( } // Second case: simple annotated assignment (`x: int = 1`) - if let StmtKind::AnnAssign { + if let StmtKind::AnnAssign(ast::StmtAnnAssign { target, value: Some(value), .. - } = &stmt.node + }) = &stmt.node { - if matches!(target.node, ExprKind::Name { .. }) { + if matches!(target.node, ExprKind::Name(_)) { return if contains_effect(value, |id| checker.ctx.is_builtin(id)) { // If the expression is complex (`x = foo()`), remove the assignment, // but preserve the right-hand side. @@ -282,7 +282,7 @@ fn remove_unused_variable( } // Third case: withitem (`with foo() as x:`) - if let StmtKind::With { items, .. } = &stmt.node { + if let StmtKind::With(ast::StmtWith { items, .. }) = &stmt.node { // Find the binding that matches the given `Range`. // TODO(charlie): Store the `Withitem` in the `Binding`. for item in items { diff --git a/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs b/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs index 839265a580..afb234367b 100644 --- a/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs +++ b/crates/ruff/src/rules/pyflakes/rules/yield_outside_function.rs @@ -44,9 +44,9 @@ pub fn yield_outside_function(checker: &mut Checker, expr: &Expr) { ScopeKind::Class(_) | ScopeKind::Module ) { let keyword = match expr.node { - ExprKind::Yield { .. } => DeferralKeyword::Yield, - ExprKind::YieldFrom { .. } => DeferralKeyword::YieldFrom, - ExprKind::Await { .. } => DeferralKeyword::Await, + ExprKind::Yield(_) => DeferralKeyword::Yield, + ExprKind::YieldFrom(_) => DeferralKeyword::YieldFrom, + ExprKind::Await(_) => DeferralKeyword::Await, _ => panic!("Expected ExprKind::Yield | ExprKind::YieldFrom | ExprKind::Await"), }; checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/pygrep_hooks/rules/invalid_mock_access.rs b/crates/ruff/src/rules/pygrep_hooks/rules/invalid_mock_access.rs index 9acdfbe321..4c148bfbe5 100644 --- a/crates/ruff/src/rules/pygrep_hooks/rules/invalid_mock_access.rs +++ b/crates/ruff/src/rules/pygrep_hooks/rules/invalid_mock_access.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -49,7 +49,7 @@ impl Violation for InvalidMockAccess { /// PGH005 pub fn uncalled_mock_method(checker: &mut Checker, expr: &Expr) { - if let ExprKind::Attribute { attr, .. } = &expr.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &expr.node { if matches!( attr.as_str(), "assert_any_call" @@ -73,9 +73,9 @@ pub fn uncalled_mock_method(checker: &mut Checker, expr: &Expr) { /// PGH005 pub fn non_existent_mock_method(checker: &mut Checker, test: &Expr) { let attr = match &test.node { - ExprKind::Attribute { attr, .. } => attr, - ExprKind::Call { func, .. } => match &func.node { - ExprKind::Attribute { attr, .. } => attr, + ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => attr, + ExprKind::Call(ast::ExprCall { func, .. }) => match &func.node { + ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => attr, _ => return, }, _ => return, diff --git a/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs b/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs index df0cc8d34c..d0513921e9 100644 --- a/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs +++ b/crates/ruff/src/rules/pygrep_hooks/rules/no_eval.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -40,7 +40,7 @@ impl Violation for Eval { /// PGH001 pub fn no_eval(checker: &mut Checker, func: &Expr) { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { return; }; if id != "eval" { diff --git a/crates/ruff/src/rules/pylint/rules/assert_on_string_literal.rs b/crates/ruff/src/rules/pylint/rules/assert_on_string_literal.rs index 3a1fc68d55..ebac688071 100644 --- a/crates/ruff/src/rules/pylint/rules/assert_on_string_literal.rs +++ b/crates/ruff/src/rules/pylint/rules/assert_on_string_literal.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -44,7 +44,7 @@ impl Violation for AssertOnStringLiteral { /// PLW0129 pub fn assert_on_string_literal(checker: &mut Checker, test: &Expr) { match &test.node { - ExprKind::Constant { value, .. } => match value { + ExprKind::Constant(ast::ExprConstant { value, .. }) => match value { Constant::Str(value, ..) => { checker.diagnostics.push(Diagnostic::new( AssertOnStringLiteral { @@ -71,11 +71,11 @@ pub fn assert_on_string_literal(checker: &mut Checker, test: &Expr) { } _ => {} }, - ExprKind::JoinedStr { values } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { checker.diagnostics.push(Diagnostic::new( AssertOnStringLiteral { kind: if values.iter().all(|value| match &value.node { - ExprKind::Constant { value, .. } => match value { + ExprKind::Constant(ast::ExprConstant { value, .. }) => match value { Constant::Str(value, ..) => value.is_empty(), Constant::Bytes(value) => value.is_empty(), _ => false, @@ -84,7 +84,7 @@ pub fn assert_on_string_literal(checker: &mut Checker, test: &Expr) { }) { Kind::Empty } else if values.iter().any(|value| match &value.node { - ExprKind::Constant { value, .. } => match value { + ExprKind::Constant(ast::ExprConstant { value, .. }) => match value { Constant::Str(value, ..) => !value.is_empty(), Constant::Bytes(value) => !value.is_empty(), _ => false, diff --git a/crates/ruff/src/rules/pylint/rules/bad_str_strip_call.rs b/crates/ruff/src/rules/pylint/rules/bad_str_strip_call.rs index 233f04e97e..d49bd42adf 100644 --- a/crates/ruff/src/rules/pylint/rules/bad_str_strip_call.rs +++ b/crates/ruff/src/rules/pylint/rules/bad_str_strip_call.rs @@ -1,7 +1,7 @@ use std::fmt; use rustc_hash::FxHashSet; -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -107,20 +107,20 @@ fn has_duplicates(s: &str) -> bool { /// PLE1310 pub fn bad_str_strip_call(checker: &mut Checker, func: &Expr, args: &[Expr]) { - if let ExprKind::Attribute { value, attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node { if matches!( value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_) | Constant::Bytes(_), .. - } + }) ) { if let Some(strip) = StripKind::from_str(attr.as_str()) { if let Some(arg) = args.get(0) { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &arg.node + }) = &arg.node { if has_duplicates(value) { let removal = if checker.settings.target_version >= PythonVersion::Py39 diff --git a/crates/ruff/src/rules/pylint/rules/bad_string_format_type.rs b/crates/ruff/src/rules/pylint/rules/bad_string_format_type.rs index 7870c0395a..c1b322d991 100644 --- a/crates/ruff/src/rules/pylint/rules/bad_string_format_type.rs +++ b/crates/ruff/src/rules/pylint/rules/bad_string_format_type.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use rustc_hash::FxHashMap; use rustpython_common::cformat::{CFormatPart, CFormatSpec, CFormatStrOrBytes, CFormatString}; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Operator}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Operator}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::{Diagnostic, Violation}; @@ -50,37 +50,37 @@ enum DataType { impl From<&Expr> for DataType { fn from(expr: &Expr) -> Self { match &expr.node { - ExprKind::NamedExpr { value, .. } => (&**value).into(), - ExprKind::UnaryOp { operand, .. } => (&**operand).into(), - ExprKind::Dict { .. } => DataType::Object, - ExprKind::Set { .. } => DataType::Object, - ExprKind::ListComp { .. } => DataType::Object, - ExprKind::SetComp { .. } => DataType::Object, - ExprKind::DictComp { .. } => DataType::Object, - ExprKind::GeneratorExp { .. } => DataType::Object, - ExprKind::JoinedStr { .. } => DataType::String, - ExprKind::BinOp { left, op, .. } => { + ExprKind::NamedExpr(ast::ExprNamedExpr { value, .. }) => (&**value).into(), + ExprKind::UnaryOp(ast::ExprUnaryOp { operand, .. }) => (&**operand).into(), + ExprKind::Dict(_) => DataType::Object, + ExprKind::Set(_) => DataType::Object, + ExprKind::ListComp(_) => DataType::Object, + ExprKind::SetComp(_) => DataType::Object, + ExprKind::DictComp(_) => DataType::Object, + ExprKind::GeneratorExp(_) => DataType::Object, + ExprKind::JoinedStr(_) => DataType::String, + ExprKind::BinOp(ast::ExprBinOp { left, op, .. }) => { // Ex) "a" % "b" if matches!( left.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..), .. - } + }) ) && matches!(op, Operator::Mod) { return DataType::String; } DataType::Unknown } - ExprKind::Constant { value, .. } => match value { + ExprKind::Constant(ast::ExprConstant { value, .. }) => match value { Constant::Str(_) => DataType::String, Constant::Int(_) => DataType::Integer, Constant::Float(_) => DataType::Float, _ => DataType::Unknown, }, - ExprKind::List { .. } => DataType::Object, - ExprKind::Tuple { .. } => DataType::Object, + ExprKind::List(_) => DataType::Object, + ExprKind::Tuple(_) => DataType::Object, _ => DataType::Unknown, } } @@ -221,10 +221,10 @@ fn is_valid_dict( let Some(key) = key else { return true; }; - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(mapping_key), .. - } = &key.node + }) = &key.node { let Some(format) = formats_hash.get(mapping_key.as_str()) else { return true; @@ -245,7 +245,7 @@ pub fn bad_string_format_type(checker: &mut Checker, expr: &Expr, right: &Expr) // Grab each string segment (in case there's an implicit concatenation). let content = checker.locator.slice(expr.range()); let mut strings: Vec = vec![]; - for (tok, range) in lexer::lex_located(content, Mode::Module, expr.start()).flatten() { + for (tok, range) in lexer::lex_starts_at(content, Mode::Module, expr.start()).flatten() { if matches!(tok, Tok::String { .. }) { strings.push(range); } else if matches!(tok, Tok::Percent) { @@ -276,9 +276,11 @@ pub fn bad_string_format_type(checker: &mut Checker, expr: &Expr, right: &Expr) // Parse the parameters. let is_valid = match &right.node { - ExprKind::Tuple { elts, .. } => is_valid_tuple(&format_strings, elts), - ExprKind::Dict { keys, values } => is_valid_dict(&format_strings, keys, values), - ExprKind::Constant { .. } => is_valid_constant(&format_strings, right), + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => is_valid_tuple(&format_strings, elts), + ExprKind::Dict(ast::ExprDict { keys, values }) => { + is_valid_dict(&format_strings, keys, values) + } + ExprKind::Constant(_) => is_valid_constant(&format_strings, right), _ => true, }; if !is_valid { diff --git a/crates/ruff/src/rules/pylint/rules/binary_op_exception.rs b/crates/ruff/src/rules/pylint/rules/binary_op_exception.rs index 65bfaa6e02..ef3d7cda55 100644 --- a/crates/ruff/src/rules/pylint/rules/binary_op_exception.rs +++ b/crates/ruff/src/rules/pylint/rules/binary_op_exception.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, ExprKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -63,13 +63,14 @@ impl Violation for BinaryOpException { /// PLW0711 pub fn binary_op_exception(checker: &mut Checker, excepthandler: &Excepthandler) { - let ExcepthandlerKind::ExceptHandler { type_, .. } = &excepthandler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = + &excepthandler.node; let Some(type_) = type_ else { return; }; - let ExprKind::BoolOp { op, .. } = &type_.node else { + let ExprKind::BoolOp(ast::ExprBoolOp { op, .. }) = &type_.node else { return; }; diff --git a/crates/ruff/src/rules/pylint/rules/collapsible_else_if.rs b/crates/ruff/src/rules/pylint/rules/collapsible_else_if.rs index acea825011..875397cbf2 100644 --- a/crates/ruff/src/rules/pylint/rules/collapsible_else_if.rs +++ b/crates/ruff/src/rules/pylint/rules/collapsible_else_if.rs @@ -18,7 +18,7 @@ impl Violation for CollapsibleElseIf { pub fn collapsible_else_if(orelse: &[Stmt], locator: &Locator) -> Option { if orelse.len() == 1 { let first = &orelse[0]; - if matches!(first.node, StmtKind::If { .. }) { + if matches!(first.node, StmtKind::If(_)) { // Determine whether this is an `elif`, or an `if` in an `else` block. if locator.slice(first.range()).starts_with("if") { return Some(Diagnostic::new(CollapsibleElseIf, first.range())); diff --git a/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs b/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs index 86d7889ec6..7f0fd30f7a 100644 --- a/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs +++ b/crates/ruff/src/rules/pylint/rules/compare_to_empty_string.rs @@ -1,6 +1,6 @@ use anyhow::bail; use itertools::Itertools; -use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -100,7 +100,7 @@ pub fn compare_to_empty_string( // Omit string comparison rules within subscripts. This is mostly commonly used within // DataFrame and np.ndarray indexing. for parent in checker.ctx.expr_ancestors() { - if matches!(parent.node, ExprKind::Subscript { .. }) { + if matches!(parent.node, ExprKind::Subscript(_)) { return; } } @@ -114,7 +114,7 @@ pub fn compare_to_empty_string( if let Ok(op) = EmptyStringCmpop::try_from(op) { if std::mem::take(&mut first) { // Check the left-most expression. - if let ExprKind::Constant { value, .. } = &lhs.node { + if let ExprKind::Constant(ast::ExprConstant { value, .. }) = &lhs.node { if let Constant::Str(s) = value { if s.is_empty() { let constant = unparse_constant(value, checker.stylist); @@ -134,7 +134,7 @@ pub fn compare_to_empty_string( } // Check all right-hand expressions. - if let ExprKind::Constant { value, .. } = &rhs.node { + if let ExprKind::Constant(ast::ExprConstant { value, .. }) = &rhs.node { if let Constant::Str(s) = value { if s.is_empty() { let expr = unparse_expr(lhs, checker.stylist); diff --git a/crates/ruff/src/rules/pylint/rules/comparison_of_constant.rs b/crates/ruff/src/rules/pylint/rules/comparison_of_constant.rs index 29a934ce15..79879d284c 100644 --- a/crates/ruff/src/rules/pylint/rules/comparison_of_constant.rs +++ b/crates/ruff/src/rules/pylint/rules/comparison_of_constant.rs @@ -1,7 +1,7 @@ use std::fmt; use itertools::Itertools; -use rustpython_parser::ast::{Cmpop, Expr, ExprKind, Located}; +use rustpython_parser::ast::{self, Attributed, Cmpop, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -90,18 +90,18 @@ pub fn comparison_of_constant( ) { for ((left, right), op) in std::iter::once(left) .chain(comparators.iter()) - .tuple_windows::<(&Located<_>, &Located<_>)>() + .tuple_windows::<(&Attributed<_>, &Attributed<_>)>() .zip(ops) { if let ( - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: left_constant, .. - }, - ExprKind::Constant { + }), + ExprKind::Constant(ast::ExprConstant { value: right_constant, .. - }, + }), ) = (&left.node, &right.node) { let diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/pylint/rules/continue_in_finally.rs b/crates/ruff/src/rules/pylint/rules/continue_in_finally.rs index 5462a3dfa8..abf952d1d1 100644 --- a/crates/ruff/src/rules/pylint/rules/continue_in_finally.rs +++ b/crates/ruff/src/rules/pylint/rules/continue_in_finally.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Stmt, StmtKind}; +use rustpython_parser::ast::{self, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -44,26 +44,27 @@ impl Violation for ContinueInFinally { fn traverse_body(checker: &mut Checker, body: &[Stmt]) { for stmt in body { - if matches!(stmt.node, StmtKind::Continue { .. }) { + if matches!(stmt.node, StmtKind::Continue) { checker .diagnostics .push(Diagnostic::new(ContinueInFinally, stmt.range())); } match &stmt.node { - StmtKind::If { body, orelse, .. } - | StmtKind::Try { body, orelse, .. } - | StmtKind::TryStar { body, orelse, .. } => { + StmtKind::If(ast::StmtIf { body, orelse, .. }) + | StmtKind::Try(ast::StmtTry { body, orelse, .. }) + | StmtKind::TryStar(ast::StmtTryStar { body, orelse, .. }) => { traverse_body(checker, body); traverse_body(checker, orelse); } - StmtKind::For { orelse, .. } - | StmtKind::AsyncFor { orelse, .. } - | StmtKind::While { orelse, .. } => traverse_body(checker, orelse), - StmtKind::With { body, .. } | StmtKind::AsyncWith { body, .. } => { + StmtKind::For(ast::StmtFor { orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { orelse, .. }) + | StmtKind::While(ast::StmtWhile { orelse, .. }) => traverse_body(checker, orelse), + StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { traverse_body(checker, body); } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { for case in cases { traverse_body(checker, &case.body); } diff --git a/crates/ruff/src/rules/pylint/rules/import_self.rs b/crates/ruff/src/rules/pylint/rules/import_self.rs index 183c0a42f6..1020a0174f 100644 --- a/crates/ruff/src/rules/pylint/rules/import_self.rs +++ b/crates/ruff/src/rules/pylint/rules/import_self.rs @@ -26,7 +26,7 @@ pub fn import_self(alias: &Alias, module_path: Option<&[String]>) -> Option) -> Option, + level: Option, module: Option<&str>, names: &[Alias], module_path: Option<&[String]>, diff --git a/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs b/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs index 1298dc155c..d0e33487a2 100644 --- a/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs +++ b/crates/ruff/src/rules/pylint/rules/invalid_envvar_default.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Operator}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Operator}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -40,30 +40,27 @@ fn is_valid_default(expr: &Expr) -> bool { // We can't infer the types of these defaults, so assume they're valid. if matches!( expr.node, - ExprKind::Name { .. } - | ExprKind::Attribute { .. } - | ExprKind::Subscript { .. } - | ExprKind::Call { .. } + ExprKind::Name(_) | ExprKind::Attribute(_) | ExprKind::Subscript(_) | ExprKind::Call(_) ) { return true; } // Allow string concatenation. - if let ExprKind::BinOp { + if let ExprKind::BinOp(ast::ExprBinOp { left, right, op: Operator::Add, - } = &expr.node + }) = &expr.node { return is_valid_default(left) && is_valid_default(right); } // Allow string formatting. - if let ExprKind::BinOp { + if let ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::Mod, .. - } = &expr.node + }) = &expr.node { return is_valid_default(left); } @@ -71,10 +68,10 @@ fn is_valid_default(expr: &Expr) -> bool { // Otherwise, the default must be a string or `None`. matches!( expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str { .. } | Constant::None { .. }, .. - } | ExprKind::JoinedStr { .. } + }) | ExprKind::JoinedStr(_) ) } @@ -94,7 +91,7 @@ pub fn invalid_envvar_default( let Some(expr) = args.get(1).or_else(|| { keywords .iter() - .find(|keyword| keyword.node.arg.as_ref().map_or(false, |arg| arg == "default")) + .find(|keyword| keyword.node.arg.as_ref().map_or(false, |arg| arg .as_str()== "default")) .map(|keyword| &keyword.node.value) }) else { return; diff --git a/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs b/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs index 7c364a5148..b4315923dd 100644 --- a/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs +++ b/crates/ruff/src/rules/pylint/rules/invalid_envvar_value.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Operator}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Operator}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -37,30 +37,27 @@ fn is_valid_key(expr: &Expr) -> bool { // We can't infer the types of these defaults, so assume they're valid. if matches!( expr.node, - ExprKind::Name { .. } - | ExprKind::Attribute { .. } - | ExprKind::Subscript { .. } - | ExprKind::Call { .. } + ExprKind::Name(_) | ExprKind::Attribute(_) | ExprKind::Subscript(_) | ExprKind::Call(_) ) { return true; } // Allow string concatenation. - if let ExprKind::BinOp { + if let ExprKind::BinOp(ast::ExprBinOp { left, right, op: Operator::Add, - } = &expr.node + }) = &expr.node { return is_valid_key(left) && is_valid_key(right); } // Allow string formatting. - if let ExprKind::BinOp { + if let ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::Mod, .. - } = &expr.node + }) = &expr.node { return is_valid_key(left); } @@ -68,10 +65,10 @@ fn is_valid_key(expr: &Expr) -> bool { // Otherwise, the default must be a string. matches!( expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str { .. }, .. - } | ExprKind::JoinedStr { .. } + }) | ExprKind::JoinedStr(_) ) } diff --git a/crates/ruff/src/rules/pylint/rules/logging.rs b/crates/ruff/src/rules/pylint/rules/logging.rs index 3dd5f7f9cb..12459fb01a 100644 --- a/crates/ruff/src/rules/pylint/rules/logging.rs +++ b/crates/ruff/src/rules/pylint/rules/logging.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -90,7 +90,7 @@ pub fn logging_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: // If there are any starred arguments, abort. if args .iter() - .any(|arg| matches!(arg.node, ExprKind::Starred { .. })) + .any(|arg| matches!(arg.node, ExprKind::Starred(_))) { return; } @@ -104,14 +104,14 @@ pub fn logging_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: return; } - if let ExprKind::Attribute { attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node { if LoggingLevel::from_attribute(attr.as_str()).is_some() { let call_args = SimpleCallArgs::new(args, keywords); if let Some(msg) = call_args.argument("msg", 0) { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &msg.node + }) = &msg.node { if let Ok(summary) = CFormatSummary::try_from(value.as_str()) { if summary.starred { diff --git a/crates/ruff/src/rules/pylint/rules/magic_value_comparison.rs b/crates/ruff/src/rules/pylint/rules/magic_value_comparison.rs index 614e916b87..ed2e0d5364 100644 --- a/crates/ruff/src/rules/pylint/rules/magic_value_comparison.rs +++ b/crates/ruff/src/rules/pylint/rules/magic_value_comparison.rs @@ -1,5 +1,5 @@ use itertools::Itertools; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Unaryop}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -26,12 +26,12 @@ impl Violation for MagicValueComparison { /// If an [`Expr`] is a constant (or unary operation on a constant), return the [`Constant`]. fn as_constant(expr: &Expr) -> Option<&Constant> { match &expr.node { - ExprKind::Constant { value, .. } => Some(value), - ExprKind::UnaryOp { + ExprKind::Constant(ast::ExprConstant { value, .. }) => Some(value), + ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::UAdd | Unaryop::USub | Unaryop::Invert, operand, - } => match &operand.node { - ExprKind::Constant { value, .. } => Some(value), + }) => match &operand.node { + ExprKind::Constant(ast::ExprConstant { value, .. }) => Some(value), _ => None, }, _ => None, diff --git a/crates/ruff/src/rules/pylint/rules/manual_import_from.rs b/crates/ruff/src/rules/pylint/rules/manual_import_from.rs index 94fb48a7c9..5a007f0a2e 100644 --- a/crates/ruff/src/rules/pylint/rules/manual_import_from.rs +++ b/crates/ruff/src/rules/pylint/rules/manual_import_from.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Alias, AliasData, Located, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Alias, AliasData, Attributed, Int, Stmt}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -36,7 +36,7 @@ pub fn manual_from_import(checker: &mut Checker, stmt: &Stmt, alias: &Alias, nam let Some((module, name)) = alias.node.name.rsplit_once('.') else { return; }; - if name != asname { + if asname != name { return; } @@ -52,16 +52,16 @@ pub fn manual_from_import(checker: &mut Checker, stmt: &Stmt, alias: &Alias, nam #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_stmt( - &create_stmt(StmtKind::ImportFrom { - module: Some(module.to_string()), - names: vec![Located::with_range( + &create_stmt(ast::StmtImportFrom { + module: Some(module.into()), + names: vec![Attributed::new( + stmt.range(), AliasData { - name: asname.into(), + name: asname.clone(), asname: None, }, - stmt.range(), )], - level: Some(0), + level: Some(Int::new(0)), }), checker.stylist, ), diff --git a/crates/ruff/src/rules/pylint/rules/nested_min_max.rs b/crates/ruff/src/rules/pylint/rules/nested_min_max.rs index 8ea7901063..f8e596b75a 100644 --- a/crates/ruff/src/rules/pylint/rules/nested_min_max.rs +++ b/crates/ruff/src/rules/pylint/rules/nested_min_max.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -39,7 +39,7 @@ impl MinMax { if !keywords.is_empty() { return None; } - let ExprKind::Name { id, .. } = func.node() else { + let ExprKind::Name(ast::ExprName { id, .. }) = func.node() else { return None; }; if id == "min" && context.is_builtin("min") { @@ -66,11 +66,11 @@ impl std::fmt::Display for MinMax { fn collect_nested_args(context: &Context, min_max: MinMax, args: &[Expr]) -> Vec { fn inner(context: &Context, min_max: MinMax, args: &[Expr], new_args: &mut Vec) { for arg in args { - if let ExprKind::Call { + if let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = arg.node() + }) = arg.node() { if MinMax::try_from_call(func, keywords, context) == Some(min_max) { inner(context, min_max, args, new_args); @@ -99,7 +99,7 @@ pub fn nested_min_max( }; if args.iter().any(|arg| { - let ExprKind::Call { func, keywords, ..} = arg.node() else { + let ExprKind::Call(ast::ExprCall { func, keywords, ..} )= arg.node() else { return false; }; MinMax::try_from_call(func, keywords, &checker.ctx) == Some(min_max) @@ -107,13 +107,13 @@ pub fn nested_min_max( let fixable = !has_comments(expr, checker.locator); let mut diagnostic = Diagnostic::new(NestedMinMax { func: min_max }, expr.range()); if fixable && checker.patch(diagnostic.kind.rule()) { - let flattened_expr = Expr::with_range( - ExprKind::Call { + let flattened_expr = Expr::new( + TextRange::default(), + ast::ExprCall { func: Box::new(func.clone()), args: collect_nested_args(&checker.ctx, min_max, args), keywords: keywords.to_owned(), }, - TextRange::default(), ); #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( diff --git a/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs b/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs index d33e77ea87..93496c0c73 100644 --- a/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs +++ b/crates/ruff/src/rules/pylint/rules/property_with_parameters.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Arguments, Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Arguments, Expr, ExprKind, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -25,7 +25,7 @@ pub fn property_with_parameters( ) { if !decorator_list .iter() - .any(|d| matches!(&d.node, ExprKind::Name { id, .. } if id == "property")) + .any(|d| matches!(&d.node, ExprKind::Name(ast::ExprName { id, .. }) if id == "property")) { return; } diff --git a/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs b/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs index 4fbcd3866c..72d4099e89 100644 --- a/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs +++ b/crates/ruff/src/rules/pylint/rules/redefined_loop_name.rs @@ -1,7 +1,7 @@ use std::{fmt, iter}; use regex::Regex; -use rustpython_parser::ast::{Expr, ExprContext, ExprKind, Stmt, StmtKind, Withitem}; +use rustpython_parser::ast::{self, Expr, ExprContext, ExprKind, Stmt, StmtKind, Withitem}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -153,7 +153,8 @@ where // Collect target expressions. match &stmt.node { // For and async for. - StmtKind::For { target, .. } | StmtKind::AsyncFor { target, .. } => { + StmtKind::For(ast::StmtFor { target, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { target, .. }) => { self.assignment_targets.extend( assignment_targets_from_expr(target, self.dummy_variable_rgx).map(|expr| { ExprWithInnerBindingKind { @@ -164,7 +165,7 @@ where ); } // With. - StmtKind::With { items, .. } => { + StmtKind::With(ast::StmtWith { items, .. }) => { self.assignment_targets.extend( assignment_targets_from_with_items(items, self.dummy_variable_rgx).map( |expr| ExprWithInnerBindingKind { @@ -175,7 +176,7 @@ where ); } // Assignment, augmented assignment, and annotated assignment. - StmtKind::Assign { targets, value, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { // Check for single-target assignments which are of the // form `x = cast(..., x)`. if targets.first().map_or(false, |target| { @@ -192,7 +193,7 @@ where ), ); } - StmtKind::AugAssign { target, .. } => { + StmtKind::AugAssign(ast::StmtAugAssign { target, .. }) => { self.assignment_targets.extend( assignment_targets_from_expr(target, self.dummy_variable_rgx).map(|expr| { ExprWithInnerBindingKind { @@ -202,7 +203,7 @@ where }), ); } - StmtKind::AnnAssign { target, value, .. } => { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, value, .. }) => { if value.is_none() { return; } @@ -220,8 +221,8 @@ where // Decide whether to recurse. match &stmt.node { // Don't recurse into blocks that create a new scope. - StmtKind::ClassDef { .. } => {} - StmtKind::FunctionDef { .. } => {} + StmtKind::ClassDef(_) => {} + StmtKind::FunctionDef(_) => {} // Otherwise, do recurse. _ => { walk_stmt(self, stmt); @@ -240,16 +241,16 @@ where /// x = cast(int, x) /// ``` fn assignment_is_cast_expr(context: &Context, value: &Expr, target: &Expr) -> bool { - let ExprKind::Call { func, args, .. } = &value.node else { + let ExprKind::Call(ast::ExprCall { func, args, .. }) = &value.node else { return false; }; - let ExprKind::Name { id: target_id, .. } = &target.node else { + let ExprKind::Name(ast::ExprName { id: target_id, .. }) = &target.node else { return false; }; if args.len() != 2 { return false; } - let ExprKind::Name { id: arg_id, .. } = &args[1].node else { + let ExprKind::Name(ast::ExprName { id: arg_id, .. }) = &args[1].node else { return false; }; if arg_id != target_id { @@ -266,24 +267,22 @@ fn assignment_targets_from_expr<'a, U>( // a cast to "impl Iterator", since at the time of writing that is only allowed for // return types and argument types. match &expr.node { - ExprKind::Attribute { + ExprKind::Attribute(ast::ExprAttribute { ctx: ExprContext::Store, .. - } => Box::new(iter::once(expr)), - ExprKind::Subscript { + }) => Box::new(iter::once(expr)), + ExprKind::Subscript(ast::ExprSubscript { ctx: ExprContext::Store, .. - } => Box::new(iter::once(expr)), - ExprKind::Starred { + }) => Box::new(iter::once(expr)), + ExprKind::Starred(ast::ExprStarred { ctx: ExprContext::Store, value, - .. - } => Box::new(iter::once(&**value)), - ExprKind::Name { + }) => Box::new(iter::once(&**value)), + ExprKind::Name(ast::ExprName { ctx: ExprContext::Store, id, - .. - } => { + }) => { // Ignore dummy variables. if dummy_variable_rgx.is_match(id) { Box::new(iter::empty()) @@ -291,19 +290,17 @@ fn assignment_targets_from_expr<'a, U>( Box::new(iter::once(expr)) } } - ExprKind::List { + ExprKind::List(ast::ExprList { ctx: ExprContext::Store, elts, - .. - } => Box::new( + }) => Box::new( elts.iter() .flat_map(|elt| assignment_targets_from_expr(elt, dummy_variable_rgx)), ), - ExprKind::Tuple { + ExprKind::Tuple(ast::ExprTuple { ctx: ExprContext::Store, elts, - .. - } => Box::new( + }) => Box::new( elts.iter() .flat_map(|elt| assignment_targets_from_expr(elt, dummy_variable_rgx)), ), @@ -339,7 +336,7 @@ pub fn redefined_loop_name<'a, 'b>(checker: &'a mut Checker<'b>, node: &Node<'b> let (outer_assignment_targets, inner_assignment_targets) = match node { Node::Stmt(stmt) => match &stmt.node { // With. - StmtKind::With { items, body, .. } => { + StmtKind::With(ast::StmtWith { items, body, .. }) => { let outer_assignment_targets: Vec> = assignment_targets_from_with_items(items, &checker.settings.dummy_variable_rgx) .map(|expr| ExprWithOuterBindingKind { @@ -358,7 +355,8 @@ pub fn redefined_loop_name<'a, 'b>(checker: &'a mut Checker<'b>, node: &Node<'b> (outer_assignment_targets, visitor.assignment_targets) } // For and async for. - StmtKind::For { target, body, .. } | StmtKind::AsyncFor { target, body, .. } => { + StmtKind::For(ast::StmtFor { target, body, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { target, body, .. }) => { let outer_assignment_targets: Vec> = assignment_targets_from_expr(target, &checker.settings.dummy_variable_rgx) .map(|expr| ExprWithOuterBindingKind { diff --git a/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs b/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs index 9b5a44fb73..73779f10ff 100644 --- a/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs +++ b/crates/ruff/src/rules/pylint/rules/repeated_isinstance_calls.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; -use rustpython_parser::ast::{Boolop, Expr, ExprKind}; +use rustpython_parser::ast::{self, Boolop, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -33,10 +33,10 @@ pub fn repeated_isinstance_calls(checker: &mut Checker, expr: &Expr, op: &Boolop let mut obj_to_types: FxHashMap)> = FxHashMap::default(); for value in values { - let ExprKind::Call { func, args, .. } = &value.node else { + let ExprKind::Call(ast::ExprCall { func, args, .. }) = &value.node else { continue; }; - if !matches!(&func.node, ExprKind::Name { id, .. } if id == "isinstance") { + if !matches!(&func.node, ExprKind::Name(ast::ExprName { id, .. }) if id == "isinstance") { continue; } let [obj, types] = &args[..] else { @@ -48,7 +48,9 @@ pub fn repeated_isinstance_calls(checker: &mut Checker, expr: &Expr, op: &Boolop *num_calls += 1; matches.extend(match &types.node { - ExprKind::Tuple { elts, .. } => elts.iter().map(HashableExpr::from_expr).collect(), + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { + elts.iter().map(HashableExpr::from_expr).collect() + } _ => { vec![types.into()] } diff --git a/crates/ruff/src/rules/pylint/rules/return_in_init.rs b/crates/ruff/src/rules/pylint/rules/return_in_init.rs index ddf1c715ae..98f620ed9e 100644 --- a/crates/ruff/src/rules/pylint/rules/return_in_init.rs +++ b/crates/ruff/src/rules/pylint/rules/return_in_init.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -44,14 +44,14 @@ impl Violation for ReturnInInit { /// PLE0101 pub fn return_in_init(checker: &mut Checker, stmt: &Stmt) { - if let StmtKind::Return { value } = &stmt.node { + if let StmtKind::Return(ast::StmtReturn { value }) = &stmt.node { if let Some(expr) = value { if matches!( expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } + }) ) { // Explicit `return None`. return; diff --git a/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs b/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs index 9028013b87..0984da585e 100644 --- a/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs +++ b/crates/ruff/src/rules/pylint/rules/sys_exit_alias.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -29,7 +29,7 @@ impl Violation for SysExitAlias { /// PLR1722 pub fn sys_exit_alias(checker: &mut Checker, func: &Expr) { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { return; }; for name in ["exit", "quit"] { diff --git a/crates/ruff/src/rules/pylint/rules/too_many_branches.rs b/crates/ruff/src/rules/pylint/rules/too_many_branches.rs index 842cfabfda..2854eb2247 100644 --- a/crates/ruff/src/rules/pylint/rules/too_many_branches.rs +++ b/crates/ruff/src/rules/pylint/rules/too_many_branches.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ExcepthandlerKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, ExcepthandlerKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -27,26 +27,26 @@ fn num_branches(stmts: &[Stmt]) -> usize { .iter() .map(|stmt| { match &stmt.node { - StmtKind::If { body, orelse, .. } => { + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { 1 + num_branches(body) + (if let Some(stmt) = orelse.first() { // `elif:` and `else: if:` have the same AST representation. // Avoid treating `elif:` as two statements. - usize::from(!matches!(stmt.node, StmtKind::If { .. })) + usize::from(!matches!(stmt.node, StmtKind::If(_))) } else { 0 }) + num_branches(orelse) } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { 1 + cases .iter() .map(|case| num_branches(&case.body)) .sum::() } - StmtKind::For { body, orelse, .. } - | StmtKind::AsyncFor { body, orelse, .. } - | StmtKind::While { body, orelse, .. } => { + StmtKind::For(ast::StmtFor { body, orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. }) + | StmtKind::While(ast::StmtWhile { body, orelse, .. }) => { 1 + num_branches(body) + (if orelse.is_empty() { 0 @@ -54,18 +54,18 @@ fn num_branches(stmts: &[Stmt]) -> usize { 1 + num_branches(orelse) }) } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { 1 + num_branches(body) + (if orelse.is_empty() { 0 @@ -81,8 +81,9 @@ fn num_branches(stmts: &[Stmt]) -> usize { .iter() .map(|handler| { 1 + { - let ExcepthandlerKind::ExceptHandler { body, .. } = - &handler.node; + let ExcepthandlerKind::ExceptHandler( + ast::ExcepthandlerExceptHandler { body, .. }, + ) = &handler.node; num_branches(body) } }) diff --git a/crates/ruff/src/rules/pylint/rules/too_many_statements.rs b/crates/ruff/src/rules/pylint/rules/too_many_statements.rs index ab2433be61..bde1847404 100644 --- a/crates/ruff/src/rules/pylint/rules/too_many_statements.rs +++ b/crates/ruff/src/rules/pylint/rules/too_many_statements.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ExcepthandlerKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, ExcepthandlerKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -26,45 +26,46 @@ fn num_statements(stmts: &[Stmt]) -> usize { let mut count = 0; for stmt in stmts { match &stmt.node { - StmtKind::If { body, orelse, .. } => { + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { count += 1; count += num_statements(body); if let Some(stmt) = orelse.first() { // `elif:` and `else: if:` have the same AST representation. // Avoid treating `elif:` as two statements. - if !matches!(stmt.node, StmtKind::If { .. }) { + if !matches!(stmt.node, StmtKind::If(_)) { count += 1; } count += num_statements(orelse); } } - StmtKind::For { body, orelse, .. } | StmtKind::AsyncFor { body, orelse, .. } => { + StmtKind::For(ast::StmtFor { body, orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. }) => { count += num_statements(body); count += num_statements(orelse); } - StmtKind::While { body, orelse, .. } => { + StmtKind::While(ast::StmtWhile { body, orelse, .. }) => { count += 1; count += num_statements(body); count += num_statements(orelse); } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { count += 1; for case in cases { count += num_statements(&case.body); } } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { count += 1; count += num_statements(body); if !orelse.is_empty() { @@ -79,17 +80,20 @@ fn num_statements(stmts: &[Stmt]) -> usize { } for handler in handlers { count += 1; - let ExcepthandlerKind::ExceptHandler { body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + body, + .. + }) = &handler.node; count += num_statements(body); } } - StmtKind::FunctionDef { body, .. } - | StmtKind::AsyncFunctionDef { body, .. } - | StmtKind::With { body, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { body, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) + | StmtKind::With(ast::StmtWith { body, .. }) => { count += 1; count += num_statements(body); } - StmtKind::Return { .. } => {} + StmtKind::Return(_) => {} _ => { count += 1; } diff --git a/crates/ruff/src/rules/pylint/rules/unnecessary_direct_lambda_call.rs b/crates/ruff/src/rules/pylint/rules/unnecessary_direct_lambda_call.rs index 45433d3d38..fffc3c3cf6 100644 --- a/crates/ruff/src/rules/pylint/rules/unnecessary_direct_lambda_call.rs +++ b/crates/ruff/src/rules/pylint/rules/unnecessary_direct_lambda_call.rs @@ -36,7 +36,7 @@ impl Violation for UnnecessaryDirectLambdaCall { /// PLC3002 pub fn unnecessary_direct_lambda_call(checker: &mut Checker, expr: &Expr, func: &Expr) { - if let ExprKind::Lambda { .. } = &func.node { + if let ExprKind::Lambda(_) = &func.node { checker .diagnostics .push(Diagnostic::new(UnnecessaryDirectLambdaCall, expr.range())); diff --git a/crates/ruff/src/rules/pylint/rules/useless_else_on_loop.rs b/crates/ruff/src/rules/pylint/rules/useless_else_on_loop.rs index 691606fb52..9608d15e5e 100644 --- a/crates/ruff/src/rules/pylint/rules/useless_else_on_loop.rs +++ b/crates/ruff/src/rules/pylint/rules/useless_else_on_loop.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ExcepthandlerKind, MatchCase, Stmt, StmtKind}; +use rustpython_parser::ast::{self, ExcepthandlerKind, MatchCase, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -21,36 +21,40 @@ impl Violation for UselessElseOnLoop { fn loop_exits_early(body: &[Stmt]) -> bool { body.iter().any(|stmt| match &stmt.node { - StmtKind::If { body, orelse, .. } => loop_exits_early(body) || loop_exits_early(orelse), - StmtKind::With { body, .. } | StmtKind::AsyncWith { body, .. } => loop_exits_early(body), - StmtKind::Match { cases, .. } => cases + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { + loop_exits_early(body) || loop_exits_early(orelse) + } + StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => loop_exits_early(body), + StmtKind::Match(ast::StmtMatch { cases, .. }) => cases .iter() .any(|MatchCase { body, .. }| loop_exits_early(body)), - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - .. - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - .. - } => { + }) => { loop_exits_early(body) || loop_exits_early(orelse) || loop_exits_early(finalbody) || handlers.iter().any(|handler| match &handler.node { - ExcepthandlerKind::ExceptHandler { body, .. } => loop_exits_early(body), + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + body, + .. + }) => loop_exits_early(body), }) } - StmtKind::For { orelse, .. } - | StmtKind::AsyncFor { orelse, .. } - | StmtKind::While { orelse, .. } => loop_exits_early(orelse), - StmtKind::Break { .. } => true, + StmtKind::For(ast::StmtFor { orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { orelse, .. }) + | StmtKind::While(ast::StmtWhile { orelse, .. }) => loop_exits_early(orelse), + StmtKind::Break => true, _ => false, }) } diff --git a/crates/ruff/src/rules/pylint/rules/useless_return.rs b/crates/ruff/src/rules/pylint/rules/useless_return.rs index 65f87cfb92..1ccf8c3fa8 100644 --- a/crates/ruff/src/rules/pylint/rules/useless_return.rs +++ b/crates/ruff/src/rules/pylint/rules/useless_return.rs @@ -1,5 +1,5 @@ use log::error; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -64,7 +64,7 @@ pub fn useless_return<'a>( // Find the last statement in the function. let last_stmt = body.last().unwrap(); - if !matches!(last_stmt.node, StmtKind::Return { .. }) { + if !matches!(last_stmt.node, StmtKind::Return(_)) { return; } @@ -75,13 +75,13 @@ pub fn useless_return<'a>( // Skip functions that consist of a docstring and a return statement. if body.len() == 2 { - if let StmtKind::Expr { value } = &body[0].node { + if let StmtKind::Expr(ast::StmtExpr { value }) = &body[0].node { if matches!( value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - } + }) ) { return; } @@ -89,7 +89,7 @@ pub fn useless_return<'a>( } // Verify that the last statement is a return statement. - let StmtKind::Return { value} = &last_stmt.node else { + let StmtKind::Return(ast::StmtReturn { value}) = &last_stmt.node else { return; }; diff --git a/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs b/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs index 40c18824fd..8917829df3 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/convert_named_tuple_functional_to_class.rs @@ -1,6 +1,8 @@ use anyhow::{bail, Result}; use log::debug; -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind}; +use rustpython_parser::ast::{ + self, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind, +}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -39,14 +41,14 @@ fn match_named_tuple_assign<'a>( value: &'a Expr, ) -> Option<(&'a str, &'a [Expr], &'a [Keyword], &'a Expr)> { let target = targets.get(0)?; - let ExprKind::Name { id: typename, .. } = &target.node else { + let ExprKind::Name(ast::ExprName { id: typename, .. }) = &target.node else { return None; }; - let ExprKind::Call { + let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &value.node else { + }) = &value.node else { return None; }; if !checker @@ -68,14 +70,14 @@ fn create_property_assignment_stmt( annotation: &Expr, value: Option<&Expr>, ) -> Stmt { - create_stmt(StmtKind::AnnAssign { - target: Box::new(create_expr(ExprKind::Name { - id: property.to_string(), + create_stmt(ast::StmtAnnAssign { + target: Box::new(create_expr(ast::ExprName { + id: property.into(), ctx: ExprContext::Load, })), annotation: Box::new(annotation.clone()), value: value.map(|value| Box::new(value.clone())), - simple: 1, + simple: true, }) } @@ -83,15 +85,15 @@ fn create_property_assignment_stmt( fn match_defaults(keywords: &[Keyword]) -> Result<&[Expr]> { let defaults = keywords.iter().find(|keyword| { if let Some(arg) = &keyword.node.arg { - arg.as_str() == "defaults" + arg == "defaults" } else { false } }); match defaults { Some(defaults) => match &defaults.node.value.node { - ExprKind::List { elts, .. } => Ok(elts), - ExprKind::Tuple { elts, .. } => Ok(elts), + ExprKind::List(ast::ExprList { elts, .. }) => Ok(elts), + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => Ok(elts), _ => bail!("Expected defaults to be `ExprKind::List` | `ExprKind::Tuple`"), }, None => Ok(&[]), @@ -103,7 +105,7 @@ fn create_properties_from_args(args: &[Expr], defaults: &[Expr]) -> Result Result Result, base_class: &Expr) -> Stmt { - create_stmt(StmtKind::ClassDef { - name: typename.to_string(), + create_stmt(ast::StmtClassDef { + name: typename.into(), bases: vec![base_class.clone()], keywords: vec![], body, diff --git a/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs b/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs index 761f27bffb..af28ea9c87 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/convert_typed_dict_functional_to_class.rs @@ -1,6 +1,8 @@ use anyhow::{bail, Result}; use log::debug; -use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind}; +use rustpython_parser::ast::{ + self, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind, +}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -40,14 +42,14 @@ fn match_typed_dict_assign<'a>( value: &'a Expr, ) -> Option<(&'a str, &'a [Expr], &'a [Keyword], &'a Expr)> { let target = targets.get(0)?; - let ExprKind::Name { id: class_name, .. } = &target.node else { + let ExprKind::Name(ast::ExprName { id: class_name, .. }) = &target.node else { return None; }; - let ExprKind::Call { + let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &value.node else { + }) = &value.node else { return None; }; if !checker @@ -65,14 +67,14 @@ fn match_typed_dict_assign<'a>( /// Generate a `StmtKind::AnnAssign` representing the provided property /// definition. fn create_property_assignment_stmt(property: &str, annotation: &ExprKind) -> Stmt { - create_stmt(StmtKind::AnnAssign { - target: Box::new(create_expr(ExprKind::Name { - id: property.to_string(), + create_stmt(ast::StmtAnnAssign { + target: Box::new(create_expr(ast::ExprName { + id: property.into(), ctx: ExprContext::Load, })), annotation: Box::new(create_expr(annotation.clone())), value: None, - simple: 1, + simple: true, }) } @@ -88,8 +90,8 @@ fn create_class_def_stmt( Some(keyword) => vec![keyword.clone()], None => vec![], }; - create_stmt(StmtKind::ClassDef { - name: class_name.to_string(), + create_stmt(ast::StmtClassDef { + name: class_name.into(), bases: vec![base_class.clone()], keywords, body, @@ -107,10 +109,10 @@ fn properties_from_dict_literal(keys: &[Option], values: &[Expr]) -> Resul .map(|(key, value)| match key { Some(Expr { node: - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(property), .. - }, + }), .. }) => { if is_identifier(property) { @@ -125,7 +127,7 @@ fn properties_from_dict_literal(keys: &[Option], values: &[Expr]) -> Resul } fn properties_from_dict_call(func: &Expr, keywords: &[Keyword]) -> Result> { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { bail!("Expected `func` to be `ExprKind::Name`") }; if id != "dict" { @@ -184,10 +186,10 @@ fn match_properties_and_total<'a>( if let Some(dict) = args.get(1) { let total = match_total_from_only_keyword(keywords); match &dict.node { - ExprKind::Dict { keys, values } => { + ExprKind::Dict(ast::ExprDict { keys, values }) => { Ok((properties_from_dict_literal(keys, values)?, total)) } - ExprKind::Call { func, keywords, .. } => { + ExprKind::Call(ast::ExprCall { func, keywords, .. }) => { Ok((properties_from_dict_call(func, keywords)?, total)) } _ => bail!("Expected `arg` to be `ExprKind::Dict` or `ExprKind::Call`"), diff --git a/crates/ruff/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs b/crates/ruff/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs index 6b573261bd..68b9f8579e 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/deprecated_c_element_tree.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Located, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Attributed, Stmt, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -20,7 +20,7 @@ impl AlwaysAutofixableViolation for DeprecatedCElementTree { } } -fn add_check_for_node(checker: &mut Checker, node: &Located) { +fn add_check_for_node(checker: &mut Checker, node: &Attributed) { let mut diagnostic = Diagnostic::new(DeprecatedCElementTree, node.range()); if checker.patch(diagnostic.kind.rule()) { let contents = checker.locator.slice(node.range()); @@ -36,20 +36,20 @@ fn add_check_for_node(checker: &mut Checker, node: &Located) { /// UP023 pub fn deprecated_c_element_tree(checker: &mut Checker, stmt: &Stmt) { match &stmt.node { - StmtKind::Import { names } => { + StmtKind::Import(ast::StmtImport { names }) => { // Ex) `import xml.etree.cElementTree as ET` for name in names { - if name.node.name == "xml.etree.cElementTree" && name.node.asname.is_some() { + if &name.node.name == "xml.etree.cElementTree" && name.node.asname.is_some() { add_check_for_node(checker, name); } } } - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } => { - if level.map_or(false, |level| level > 0) { + }) => { + if level.map_or(false, |level| level.to_u32() > 0) { // Ex) `import .xml.etree.cElementTree as ET` } else if let Some(module) = module { if module == "xml.etree.cElementTree" { @@ -58,7 +58,7 @@ pub fn deprecated_c_element_tree(checker: &mut Checker, stmt: &Stmt) { } else if module == "xml.etree" { // Ex) `from xml.etree import cElementTree as ET` for name in names { - if name.node.name == "cElementTree" && name.node.asname.is_some() { + if &name.node.name == "cElementTree" && name.node.asname.is_some() { add_check_for_node(checker, name); } } diff --git a/crates/ruff/src/rules/pyupgrade/rules/deprecated_import.rs b/crates/ruff/src/rules/pyupgrade/rules/deprecated_import.rs index c4310a39c1..147c1ce405 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/deprecated_import.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/deprecated_import.rs @@ -293,7 +293,7 @@ impl<'a> ImportReplacer<'a> { if self.version >= PythonVersion::Py39 { for member in self.members { if let Some(target) = TYPING_TO_RENAME_PY39.iter().find_map(|(name, target)| { - if member.name == *name { + if &member.name == *name { Some(*target) } else { None @@ -496,7 +496,7 @@ impl<'a> ImportReplacer<'a> { let full_names: String = names .iter() .map(|name| match &name.asname { - Some(asname) => format!("{} as {asname}", name.name), + Some(asname) => format!("{} as {}", name.name, asname), None => format!("{}", name.name), }) .join(", "); @@ -510,13 +510,13 @@ pub fn deprecated_import( stmt: &Stmt, names: &[Alias], module: Option<&str>, - level: Option, + level: Option, ) { // Avoid relative and star imports. if level.map_or(false, |level| level > 0) { return; } - if names.first().map_or(false, |name| name.node.name == "*") { + if names.first().map_or(false, |name| &name.node.name == "*") { return; } let Some(module) = module else { diff --git a/crates/ruff/src/rules/pyupgrade/rules/deprecated_mock_import.rs b/crates/ruff/src/rules/pyupgrade/rules/deprecated_mock_import.rs index 61daf5e2a7..70c8617572 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/deprecated_mock_import.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/deprecated_mock_import.rs @@ -4,7 +4,7 @@ use libcst_native::{ ImportAlias, ImportFrom, ImportNames, Name, NameOrAttribute, ParenthesizableWhitespace, }; use log::error; -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -246,7 +246,7 @@ fn format_import_from( /// UP026 pub fn deprecated_mock_attribute(checker: &mut Checker, expr: &Expr) { - if let ExprKind::Attribute { value, .. } = &expr.node { + if let ExprKind::Attribute(ast::ExprAttribute { value, .. }) = &expr.node { if collect_call_path(value) .map_or(false, |call_path| call_path.as_slice() == ["mock", "mock"]) { @@ -271,11 +271,11 @@ pub fn deprecated_mock_attribute(checker: &mut Checker, expr: &Expr) { /// UP026 pub fn deprecated_mock_import(checker: &mut Checker, stmt: &Stmt) { match &stmt.node { - StmtKind::Import { names } => { + StmtKind::Import(ast::StmtImport { names }) => { // Find all `mock` imports. if names .iter() - .any(|name| name.node.name == "mock" || name.node.name == "mock.mock") + .any(|name| &name.node.name == "mock" || &name.node.name == "mock.mock") { // Generate the fix, if needed, which is shared between all `mock` imports. let content = if checker.patch(Rule::DeprecatedMockImport) { @@ -296,7 +296,7 @@ pub fn deprecated_mock_import(checker: &mut Checker, stmt: &Stmt) { // Add a `Diagnostic` for each `mock` import. for name in names { - if name.node.name == "mock" || name.node.name == "mock.mock" { + if &name.node.name == "mock" || &name.node.name == "mock.mock" { let mut diagnostic = Diagnostic::new( DeprecatedMockImport { reference_type: MockReference::Import, @@ -315,12 +315,12 @@ pub fn deprecated_mock_import(checker: &mut Checker, stmt: &Stmt) { } } } - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { module: Some(module), level, .. - } => { - if level.map_or(false, |level| level > 0) { + }) => { + if level.map_or(false, |level| level.to_u32() > 0) { return; } diff --git a/crates/ruff/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs b/crates/ruff/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs index b079bc86d2..dd5c9978ac 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/deprecated_unittest_alias.rs @@ -1,6 +1,6 @@ use once_cell::sync::Lazy; use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -49,13 +49,13 @@ static DEPRECATED_ALIASES: Lazy> = Lazy::n /// UP005 pub fn deprecated_unittest_alias(checker: &mut Checker, expr: &Expr) { - let ExprKind::Attribute { value, attr, .. } = &expr.node else { + let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &expr.node else { return; }; let Some(&target) = DEPRECATED_ALIASES.get(attr.as_str()) else { return; }; - let ExprKind::Name { id, .. } = &value.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &value.node else { return; }; if id != "self" { diff --git a/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs b/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs index 620ea7449a..6b2987eea5 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/f_strings.rs @@ -3,7 +3,7 @@ use rustc_hash::FxHashMap; use rustpython_common::format::{ FieldName, FieldNamePart, FieldType, FormatPart, FormatString, FromTemplate, }; -use rustpython_parser::ast::{Constant, Expr, ExprKind, KeywordData}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, KeywordData}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -42,7 +42,7 @@ impl<'a> FormatSummaryValues<'a> { fn try_from_expr(checker: &'a Checker, expr: &'a Expr) -> Option { let mut extracted_args: Vec = Vec::new(); let mut extracted_kwargs: FxHashMap<&str, String> = FxHashMap::default(); - if let ExprKind::Call { args, keywords, .. } = &expr.node { + if let ExprKind::Call(ast::ExprCall { args, keywords, .. }) = &expr.node { for arg in args { let arg = checker.locator.slice(arg.range()); if contains_invalids(arg) { @@ -104,18 +104,18 @@ fn contains_invalids(string: &str) -> bool { /// Generate an f-string from an [`Expr`]. fn try_convert_to_f_string(checker: &Checker, expr: &Expr) -> Option { - let ExprKind::Call { func, .. } = &expr.node else { + let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node else { return None; }; - let ExprKind::Attribute { value, .. } = &func.node else { + let ExprKind::Attribute(ast::ExprAttribute { value, .. }) = &func.node else { return None; }; if !matches!( &value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(..), .. - }, + }), ) { return None; }; diff --git a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs index 9be90ee11c..18405c6846 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_with_maxsize_none.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Constant, Expr, ExprKind, KeywordData}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, KeywordData}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -25,11 +25,11 @@ impl AlwaysAutofixableViolation for LRUCacheWithMaxsizeNone { /// UP033 pub fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list: &[Expr]) { for expr in decorator_list.iter() { - let ExprKind::Call { + let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &expr.node else { + }) = &expr.node else { continue; }; @@ -47,10 +47,10 @@ pub fn lru_cache_with_maxsize_none(checker: &mut Checker, decorator_list: &[Expr if arg.as_ref().map_or(false, |arg| arg == "maxsize") && matches!( value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, kind: None, - } + }) ) { let mut diagnostic = Diagnostic::new( diff --git a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs index d341cd211f..1144859acf 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -25,11 +25,11 @@ impl AlwaysAutofixableViolation for LRUCacheWithoutParameters { /// UP011 pub fn lru_cache_without_parameters(checker: &mut Checker, decorator_list: &[Expr]) { for expr in decorator_list.iter() { - let ExprKind::Call { + let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &expr.node else { + }) = &expr.node else { continue; }; diff --git a/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs b/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs index c607f33881..57d844e758 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/native_literals.rs @@ -1,6 +1,6 @@ use std::fmt; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -50,7 +50,7 @@ pub fn native_literals( args: &[Expr], keywords: &[Keyword], ) { - let ExprKind::Name { id, .. } = &func.node else { return; }; + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { return; }; if !keywords.is_empty() || args.len() > 1 { return; @@ -89,10 +89,10 @@ pub fn native_literals( if id == "str" && !matches!( &arg.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - }, + }), ) { return; @@ -102,10 +102,10 @@ pub fn native_literals( if id == "bytes" && !matches!( &arg.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bytes(_), .. - }, + }), ) { return; diff --git a/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs b/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs index 24de8961fa..2034bec781 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/os_error_alias.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -76,7 +76,7 @@ fn atom_diagnostic(checker: &mut Checker, target: &Expr) { fn tuple_diagnostic(checker: &mut Checker, target: &Expr, aliases: &[&Expr]) { let mut diagnostic = Diagnostic::new(OSErrorAlias { name: None }, target.range()); if checker.patch(diagnostic.kind.rule()) { - let ExprKind::Tuple { elts, ..} = &target.node else { + let ExprKind::Tuple(ast::ExprTuple { elts, ..}) = &target.node else { panic!("Expected ExprKind::Tuple"); }; @@ -96,8 +96,8 @@ fn tuple_diagnostic(checker: &mut Checker, target: &Expr, aliases: &[&Expr]) { if elts.iter().all(|elt| !is_os_error(&checker.ctx, elt)) { remaining.insert( 0, - create_expr(ExprKind::Name { - id: "OSError".to_string(), + create_expr(ast::ExprName { + id: "OSError".into(), ctx: ExprContext::Load, }), ); @@ -115,7 +115,7 @@ fn tuple_diagnostic(checker: &mut Checker, target: &Expr, aliases: &[&Expr]) { format!( "({})", unparse_expr( - &create_expr(ExprKind::Tuple { + &create_expr(ast::ExprTuple { elts: remaining, ctx: ExprContext::Load, }), @@ -132,17 +132,18 @@ fn tuple_diagnostic(checker: &mut Checker, target: &Expr, aliases: &[&Expr]) { /// UP024 pub fn os_error_alias_handlers(checker: &mut Checker, handlers: &[Excepthandler]) { for handler in handlers { - let ExcepthandlerKind::ExceptHandler { type_, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = + &handler.node; let Some(expr) = type_.as_ref() else { continue; }; match &expr.node { - ExprKind::Name { .. } | ExprKind::Attribute { .. } => { + ExprKind::Name(_) | ExprKind::Attribute(_) => { if is_alias(&checker.ctx, expr) { atom_diagnostic(checker, expr); } } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { // List of aliases to replace with `OSError`. let mut aliases: Vec<&Expr> = vec![]; for elt in elts { @@ -168,10 +169,7 @@ pub fn os_error_alias_call(checker: &mut Checker, func: &Expr) { /// UP024 pub fn os_error_alias_raise(checker: &mut Checker, expr: &Expr) { - if matches!( - expr.node, - ExprKind::Name { .. } | ExprKind::Attribute { .. } - ) { + if matches!(expr.node, ExprKind::Name(_) | ExprKind::Attribute(_)) { if is_alias(&checker.ctx, expr) { atom_diagnostic(checker, expr); } diff --git a/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs b/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs index 8299e99992..200b532fef 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/outdated_version_block.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; use log::error; use num_bigint::{BigInt, Sign}; use ruff_text_size::{TextRange, TextSize}; -use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind, Located, Stmt}; +use rustpython_parser::ast::{self, Attributed, Cmpop, Constant, Expr, ExprKind, Stmt}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; @@ -52,7 +52,7 @@ impl BlockMetadata { } } -fn metadata(locator: &Locator, located: &Located) -> Option { +fn metadata(locator: &Locator, located: &Attributed) -> Option { indentation(locator, located)?; let line_start = locator.line_start(located.start()); @@ -64,7 +64,7 @@ fn metadata(locator: &Locator, located: &Located) -> Option let mut elif = None; let mut else_ = None; - for (tok, range) in lexer::lex_located(text, Mode::Module, line_start) + for (tok, range) in lexer::lex_starts_at(text, Mode::Module, line_start) .flatten() .filter(|(tok, _)| { !matches!( @@ -107,10 +107,10 @@ fn bigint_to_u32(number: &BigInt) -> u32 { fn extract_version(elts: &[Expr]) -> Vec { let mut version: Vec = vec![]; for elt in elts { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(item), .. - } = &elt.node + }) = &elt.node { let number = bigint_to_u32(item); version.push(number); @@ -310,11 +310,11 @@ pub fn outdated_version_block( body: &[Stmt], orelse: &[Stmt], ) { - let ExprKind::Compare { + let ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } = &test.node else { + }) = &test.node else { return; }; @@ -332,7 +332,7 @@ pub fn outdated_version_block( let comparison = &comparators[0].node; let op = &ops[0]; match comparison { - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { let version = extract_version(elts); let target = checker.settings.target_version; if op == &Cmpop::Lt || op == &Cmpop::LtE { @@ -364,10 +364,10 @@ pub fn outdated_version_block( } } } - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(number), .. - } => { + }) => { let version_number = bigint_to_u32(number); if version_number == 2 && op == &Cmpop::Eq { let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range()); diff --git a/crates/ruff/src/rules/pyupgrade/rules/printf_string_formatting.rs b/crates/ruff/src/rules/pyupgrade/rules/printf_string_formatting.rs index a9923d86a1..b2d7852664 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/printf_string_formatting.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/printf_string_formatting.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use rustpython_common::cformat::{ CConversionFlags, CFormatPart, CFormatPrecision, CFormatQuantity, CFormatString, }; -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; @@ -140,7 +140,7 @@ fn percent_to_format(format_string: &CFormatString) -> String { /// If a tuple has one argument, remove the comma; otherwise, return it as-is. fn clean_params_tuple(checker: &mut Checker, right: &Expr, locator: &Locator) -> String { let mut contents = checker.locator.slice(right.range()).to_string(); - if let ExprKind::Tuple { elts, .. } = &right.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &right.node { if elts.len() == 1 { if !locator.contains_line_break(right.range()) { for (i, character) in contents.chars().rev().enumerate() { @@ -165,17 +165,17 @@ fn clean_params_dictionary( ) -> Option { let is_multi_line = locator.contains_line_break(right.range()); let mut contents = String::new(); - if let ExprKind::Dict { keys, values } = &right.node { + if let ExprKind::Dict(ast::ExprDict { keys, values }) = &right.node { let mut arguments: Vec = vec![]; let mut seen: Vec<&str> = vec![]; let mut indent = None; for (key, value) in keys.iter().zip(values.iter()) { match key { Some(key) => { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(key_string), .. - } = &key.node + }) = &key.node { // If the dictionary key is not a valid variable name, abort. if !is_identifier(key_string) { @@ -291,7 +291,7 @@ fn convertible(format_string: &CFormatString, params: &Expr) -> bool { } // All dict substitutions must be named. - if let ExprKind::Dict { .. } = ¶ms.node { + if let ExprKind::Dict(_) = ¶ms.node { if fmt.mapping_key.is_none() { return false; } @@ -310,7 +310,7 @@ pub(crate) fn printf_string_formatting( // Grab each string segment (in case there's an implicit concatenation). let mut strings: Vec = vec![]; let mut extension = None; - for (tok, range) in lexer::lex_located( + for (tok, range) in lexer::lex_starts_at( checker.locator.slice(expr.range()), Mode::Module, expr.start(), @@ -371,13 +371,10 @@ pub(crate) fn printf_string_formatting( // Parse the parameters. let params_string = match right.node { - ExprKind::Constant { .. } | ExprKind::JoinedStr { .. } => { + ExprKind::Constant(_) | ExprKind::JoinedStr(_) => { format!("({})", checker.locator.slice(right.range())) } - ExprKind::Name { .. } - | ExprKind::Attribute { .. } - | ExprKind::Subscript { .. } - | ExprKind::Call { .. } => { + ExprKind::Name(_) | ExprKind::Attribute(_) | ExprKind::Subscript(_) | ExprKind::Call(_) => { if num_keyword_arguments > 0 { // If we have _any_ named fields, assume the right-hand side is a mapping. format!("(**{})", checker.locator.slice(right.range())) @@ -398,8 +395,8 @@ pub(crate) fn printf_string_formatting( return; } } - ExprKind::Tuple { .. } => clean_params_tuple(checker, right, locator), - ExprKind::Dict { .. } => { + ExprKind::Tuple(_) => clean_params_tuple(checker, right, locator), + ExprKind::Dict(_) => { if let Some(params_string) = clean_params_dictionary(checker, right, locator) { params_string } else { diff --git a/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs b/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs index aed1012f2d..796ade1ed8 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/redundant_open_modes.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use anyhow::{anyhow, Result}; use ruff_text_size::TextSize; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; @@ -87,13 +87,13 @@ impl OpenMode { } fn match_open(expr: &Expr) -> (Option<&Expr>, Vec) { - if let ExprKind::Call { + if let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &expr.node + }) = &expr.node { - if matches!(&func.node, ExprKind::Name {id, ..} if id == OPEN_FUNC_NAME) { + if matches!(&func.node, ExprKind::Name(ast::ExprName {id, ..}) if id == OPEN_FUNC_NAME) { // Return the "open mode" parameter and keywords. return (args.get(1), keywords.clone()); } @@ -137,7 +137,7 @@ fn create_remove_param_fix(locator: &Locator, expr: &Expr, mode_param: &Expr) -> let mut fix_end: Option = None; let mut is_first_arg: bool = false; let mut delete_first_arg: bool = false; - for (tok, range) in lexer::lex_located(content, Mode::Module, expr.start()).flatten() { + for (tok, range) in lexer::lex_starts_at(content, Mode::Module, expr.start()).flatten() { if range.start() == mode_param.start() { if is_first_arg { delete_first_arg = true; @@ -178,10 +178,10 @@ pub fn redundant_open_modes(checker: &mut Checker, expr: &Expr) { let (mode_param, keywords): (Option<&Expr>, Vec) = match_open(expr); if mode_param.is_none() && !keywords.is_empty() { if let Some(keyword) = find_keyword(&keywords, MODE_KEYWORD_ARGUMENT) { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(mode_param_value), .. - } = &keyword.node.value.node + }) = &keyword.node.value.node { if let Ok(mode) = OpenMode::from_str(mode_param_value.as_str()) { checker.diagnostics.push(create_check( @@ -195,10 +195,10 @@ pub fn redundant_open_modes(checker: &mut Checker, expr: &Expr) { } } } else if let Some(mode_param) = mode_param { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(mode_param_value), .. - } = &mode_param.node + }) = &mode_param.node { if let Ok(mode) = OpenMode::from_str(mode_param_value.as_str()) { checker.diagnostics.push(create_check( diff --git a/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs b/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs index d5ef517b85..5eea2ed6e5 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/super_call_with_parameters.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{ArgData, Expr, ExprKind, StmtKind}; +use rustpython_parser::ast::{self, ArgData, Expr, ExprKind, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -24,7 +24,7 @@ impl AlwaysAutofixableViolation for SuperCallWithParameters { /// Returns `true` if a call is an argumented `super` invocation. fn is_super_call_with_arguments(func: &Expr, args: &[Expr]) -> bool { - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { id == "super" && !args.is_empty() } else { false @@ -41,7 +41,7 @@ pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Exp let scope = checker.ctx.scope(); // Check: are we in a Function scope? - if !matches!(scope.kind, ScopeKind::Function { .. }) { + if !matches!(scope.kind, ScopeKind::Function(_)) { return; } @@ -55,10 +55,10 @@ pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Exp }; // Find the enclosing function definition (if any). - let Some(StmtKind::FunctionDef { + let Some(StmtKind::FunctionDef(ast::StmtFunctionDef { args: parent_args, .. - }) = parents - .find(|stmt| matches!(stmt.node, StmtKind::FunctionDef { .. })) + })) = parents + .find(|stmt| matches!(stmt.node, StmtKind::FunctionDef ( _))) .map(|stmt| &stmt.node) else { return; }; @@ -71,21 +71,21 @@ pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Exp }; // Find the enclosing class definition (if any). - let Some(StmtKind::ClassDef { + let Some(StmtKind::ClassDef(ast::StmtClassDef { name: parent_name, .. - }) = parents - .find(|stmt| matches!(stmt.node, StmtKind::ClassDef { .. })) + })) = parents + .find(|stmt| matches!(stmt.node, StmtKind::ClassDef (_))) .map(|stmt| &stmt.node) else { return; }; let ( - ExprKind::Name { + ExprKind::Name(ast::ExprName { id: first_arg_id, .. - }, - ExprKind::Name { + }), + ExprKind::Name(ast::ExprName { id: second_arg_id, .. - }, + }), ) = (&first_arg.node, &second_arg.node) else { return; }; diff --git a/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs b/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs index 29f66b5fb7..c593a3f3d3 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/type_of_primitive.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -38,7 +38,7 @@ pub fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, args: { return; } - let ExprKind::Constant { value, .. } = &args[0].node else { + let ExprKind::Constant(ast::ExprConstant { value, .. } )= &args[0].node else { return; }; let Some(primitive) = Primitive::from_constant(value) else { diff --git a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs index a9c57f2fed..a945469e18 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_builtin_import.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use log::error; -use rustpython_parser::ast::{Alias, AliasData, Located, Stmt}; +use rustpython_parser::ast::{Alias, AliasData, Attributed, Stmt}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -69,7 +69,7 @@ pub fn unnecessary_builtin_import( checker: &mut Checker, stmt: &Stmt, module: &str, - names: &[Located], + names: &[Attributed], ) { let deprecated_names = match module { "builtins" => BUILTINS, diff --git a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs index 3f3a49f122..bf36be59c0 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_encode_utf8.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword}; use rustpython_parser::{lexer, Mode, Tok}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; @@ -38,11 +38,11 @@ impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 { const UTF8_LITERALS: &[&str] = &["utf-8", "utf8", "utf_8", "u8", "utf", "cp65001"]; fn match_encoded_variable(func: &Expr) -> Option<&Expr> { - let ExprKind::Attribute { + let ExprKind::Attribute(ast::ExprAttribute { value: variable, attr, .. - } = &func.node else { + }) = &func.node else { return None; }; if attr != "encode" { @@ -52,10 +52,10 @@ fn match_encoded_variable(func: &Expr) -> Option<&Expr> { } fn is_utf8_encoding_arg(arg: &Expr) -> bool { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &arg.node + }) = &arg.node { UTF8_LITERALS.contains(&value.to_lowercase().as_str()) } else { @@ -112,7 +112,7 @@ fn replace_with_bytes_literal(locator: &Locator, expr: &Expr) -> Fix { let contents = locator.slice(expr.range()); let mut replacement = String::with_capacity(contents.len() + 1); let mut prev = expr.start(); - for (tok, range) in lexer::lex_located(contents, Mode::Module, expr.start()).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, expr.start()).flatten() { match tok { Tok::Dot => break, Tok::String { .. } => { @@ -145,10 +145,10 @@ pub fn unnecessary_encode_utf8( return; }; match &variable.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(literal), .. - } => { + }) => { // Ex) `"str".encode()`, `"str".encode("utf-8")` if let Some(encoding_arg) = match_encoding_arg(args, kwargs) { if literal.is_ascii() { @@ -212,7 +212,7 @@ pub fn unnecessary_encode_utf8( } } // Ex) `f"foo{bar}".encode("utf-8")` - ExprKind::JoinedStr { .. } => { + ExprKind::JoinedStr(_) => { if let Some(encoding_arg) = match_encoding_arg(args, kwargs) { if let EncodingArg::Keyword(kwarg) = encoding_arg { // Ex) Convert `f"unicode text©".encode(encoding="utf-8")` to diff --git a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs index 4aea314746..3fca159635 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/unnecessary_future_import.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use log::error; -use rustpython_parser::ast::{Alias, AliasData, Located, Stmt}; +use rustpython_parser::ast::{Alias, AliasData, Attributed, Stmt}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -57,7 +57,11 @@ const PY37_PLUS_REMOVE_FUTURES: &[&str] = &[ ]; /// UP010 -pub fn unnecessary_future_import(checker: &mut Checker, stmt: &Stmt, names: &[Located]) { +pub fn unnecessary_future_import( + checker: &mut Checker, + stmt: &Stmt, + names: &[Attributed], +) { let mut unused_imports: Vec<&Alias> = vec![]; for alias in names { if alias.node.asname.is_some() { diff --git a/crates/ruff/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs b/crates/ruff/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs index 1c76299241..b86ebe8253 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/unpacked_list_comprehension.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -23,58 +23,68 @@ impl AlwaysAutofixableViolation for UnpackedListComprehension { /// Returns `true` if `expr` contains an `ExprKind::Await`. fn contains_await(expr: &Expr) -> bool { match &expr.node { - ExprKind::Await { .. } => true, - ExprKind::BoolOp { values, .. } => values.iter().any(contains_await), - ExprKind::NamedExpr { target, value } => contains_await(target) || contains_await(value), - ExprKind::BinOp { left, right, .. } => contains_await(left) || contains_await(right), - ExprKind::UnaryOp { operand, .. } => contains_await(operand), - ExprKind::Lambda { body, .. } => contains_await(body), - ExprKind::IfExp { test, body, orelse } => { + ExprKind::Await(_) => true, + ExprKind::BoolOp(ast::ExprBoolOp { values, .. }) => values.iter().any(contains_await), + ExprKind::NamedExpr(ast::ExprNamedExpr { target, value }) => { + contains_await(target) || contains_await(value) + } + ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) => { + contains_await(left) || contains_await(right) + } + ExprKind::UnaryOp(ast::ExprUnaryOp { operand, .. }) => contains_await(operand), + ExprKind::Lambda(ast::ExprLambda { body, .. }) => contains_await(body), + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { contains_await(test) || contains_await(body) || contains_await(orelse) } - ExprKind::Dict { keys, values } => keys + ExprKind::Dict(ast::ExprDict { keys, values }) => keys .iter() .flatten() .chain(values.iter()) .any(contains_await), - ExprKind::Set { elts } => elts.iter().any(contains_await), - ExprKind::ListComp { elt, .. } => contains_await(elt), - ExprKind::SetComp { elt, .. } => contains_await(elt), - ExprKind::DictComp { key, value, .. } => contains_await(key) || contains_await(value), - ExprKind::GeneratorExp { elt, .. } => contains_await(elt), - ExprKind::Yield { value } => value.as_ref().map_or(false, |value| contains_await(value)), - ExprKind::YieldFrom { value } => contains_await(value), - ExprKind::Compare { + ExprKind::Set(ast::ExprSet { elts }) => elts.iter().any(contains_await), + ExprKind::ListComp(ast::ExprListComp { elt, .. }) => contains_await(elt), + ExprKind::SetComp(ast::ExprSetComp { elt, .. }) => contains_await(elt), + ExprKind::DictComp(ast::ExprDictComp { key, value, .. }) => { + contains_await(key) || contains_await(value) + } + ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, .. }) => contains_await(elt), + ExprKind::Yield(ast::ExprYield { value }) => { + value.as_ref().map_or(false, |value| contains_await(value)) + } + ExprKind::YieldFrom(ast::ExprYieldFrom { value }) => contains_await(value), + ExprKind::Compare(ast::ExprCompare { left, comparators, .. - } => contains_await(left) || comparators.iter().any(contains_await), - ExprKind::Call { + }) => contains_await(left) || comparators.iter().any(contains_await), + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { + }) => { contains_await(func) || args.iter().any(contains_await) || keywords .iter() .any(|keyword| contains_await(&keyword.node.value)) } - ExprKind::FormattedValue { + ExprKind::FormattedValue(ast::ExprFormattedValue { value, format_spec, .. - } => { + }) => { contains_await(value) || format_spec .as_ref() .map_or(false, |value| contains_await(value)) } - ExprKind::JoinedStr { values } => values.iter().any(contains_await), - ExprKind::Constant { .. } => false, - ExprKind::Attribute { value, .. } => contains_await(value), - ExprKind::Subscript { value, slice, .. } => contains_await(value) || contains_await(slice), - ExprKind::Starred { value, .. } => contains_await(value), - ExprKind::Name { .. } => false, - ExprKind::List { elts, .. } => elts.iter().any(contains_await), - ExprKind::Tuple { elts, .. } => elts.iter().any(contains_await), - ExprKind::Slice { lower, upper, step } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => values.iter().any(contains_await), + ExprKind::Constant(_) => false, + ExprKind::Attribute(ast::ExprAttribute { value, .. }) => contains_await(value), + ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => { + contains_await(value) || contains_await(slice) + } + ExprKind::Starred(ast::ExprStarred { value, .. }) => contains_await(value), + ExprKind::Name(_) => false, + ExprKind::List(ast::ExprList { elts, .. }) => elts.iter().any(contains_await), + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().any(contains_await), + ExprKind::Slice(ast::ExprSlice { lower, upper, step }) => { lower.as_ref().map_or(false, |value| contains_await(value)) || upper.as_ref().map_or(false, |value| contains_await(value)) || step.as_ref().map_or(false, |value| contains_await(value)) @@ -87,9 +97,9 @@ pub fn unpacked_list_comprehension(checker: &mut Checker, targets: &[Expr], valu let Some(target) = targets.get(0) else { return; }; - if let ExprKind::Tuple { .. } = target.node { - if let ExprKind::ListComp { elt, generators } = &value.node { - if generators.iter().any(|generator| generator.is_async > 0) || contains_await(elt) { + if let ExprKind::Tuple(_) = target.node { + if let ExprKind::ListComp(ast::ExprListComp { elt, generators }) = &value.node { + if generators.iter().any(|generator| generator.is_async) || contains_await(elt) { return; } diff --git a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs index f8163bd354..3c94ee816d 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_annotation.rs @@ -1,5 +1,5 @@ -use ruff_text_size::TextSize; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Operator}; +use ruff_text_size::TextRange; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Operator}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -27,15 +27,13 @@ impl Violation for NonPEP604Annotation { fn optional(expr: &Expr) -> Expr { Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::BinOp { + TextRange::default(), + ast::ExprBinOp { left: Box::new(expr.clone()), op: Operator::BitOr, right: Box::new(Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::Constant { + TextRange::default(), + ast::ExprConstant { value: Constant::None, kind: None, }, @@ -49,9 +47,8 @@ fn union(elts: &[Expr]) -> Expr { elts[0].clone() } else { Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::BinOp { + TextRange::default(), + ast::ExprBinOp { left: Box::new(union(&elts[..elts.len() - 1])), op: Operator::BitOr, right: Box::new(elts[elts.len() - 1].clone()), @@ -63,11 +60,11 @@ fn union(elts: &[Expr]) -> Expr { /// Returns `true` if any argument in the slice is a string. fn any_arg_is_str(slice: &Expr) -> bool { match &slice.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(_), .. - } => true, - ExprKind::Tuple { elts, .. } => elts.iter().any(any_arg_is_str), + }) => true, + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().any(any_arg_is_str), _ => false, } } @@ -122,10 +119,10 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s let mut diagnostic = Diagnostic::new(NonPEP604Annotation, expr.range()); if fixable && checker.patch(diagnostic.kind.rule()) { match &slice.node { - ExprKind::Slice { .. } => { + ExprKind::Slice(_) => { // Invalid type annotation. } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { #[allow(deprecated)] diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( unparse_expr(&union(elts), checker.stylist), diff --git a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs index bd330a41e1..881e366194 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/use_pep604_isinstance.rs @@ -1,7 +1,7 @@ -use ruff_text_size::TextSize; +use ruff_text_size::TextRange; use std::fmt; -use rustpython_parser::ast::{Expr, ExprKind, Operator}; +use rustpython_parser::ast::{self, Expr, ExprKind, Operator}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -56,9 +56,8 @@ fn union(elts: &[Expr]) -> Expr { elts[0].clone() } else { Expr::new( - TextSize::default(), - TextSize::default(), - ExprKind::BinOp { + TextRange::default(), + ast::ExprBinOp { left: Box::new(union(&elts[..elts.len() - 1])), op: Operator::BitOr, right: Box::new(elts[elts.len() - 1].clone()), @@ -69,7 +68,7 @@ fn union(elts: &[Expr]) -> Expr { /// UP038 pub fn use_pep604_isinstance(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) { - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { let Some(kind) = CallKind::from_name(id) else { return; }; @@ -77,7 +76,7 @@ pub fn use_pep604_isinstance(checker: &mut Checker, expr: &Expr, func: &Expr, ar return; }; if let Some(types) = args.get(1) { - if let ExprKind::Tuple { elts, .. } = &types.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &types.node { // Ex) `()` if elts.is_empty() { return; @@ -86,7 +85,7 @@ pub fn use_pep604_isinstance(checker: &mut Checker, expr: &Expr, func: &Expr, ar // Ex) `(*args,)` if elts .iter() - .any(|elt| matches!(elt.node, ExprKind::Starred { .. })) + .any(|elt| matches!(elt.node, ExprKind::Starred(_))) { return; } diff --git a/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs b/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs index af024faf21..85f84fe9c2 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/useless_metaclass_type.rs @@ -1,6 +1,6 @@ use log::error; use ruff_text_size::TextRange; -use rustpython_parser::ast::{Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -28,13 +28,13 @@ fn rule(targets: &[Expr], value: &Expr, location: TextRange) -> Option Option { for expr in bases { - let ExprKind::Name { id, .. } = &expr.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node else { continue; }; if id != "object" { diff --git a/crates/ruff/src/rules/pyupgrade/rules/yield_in_for_loop.rs b/crates/ruff/src/rules/pyupgrade/rules/yield_in_for_loop.rs index 7c5e9690c3..aa37f2db70 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/yield_in_for_loop.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/yield_in_for_loop.rs @@ -1,5 +1,5 @@ use rustc_hash::FxHashMap; -use rustpython_parser::ast::{Expr, ExprContext, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprContext, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; @@ -29,10 +29,14 @@ impl AlwaysAutofixableViolation for YieldInForLoop { /// of tuples and names. fn is_same_expr(a: &Expr, b: &Expr) -> bool { match (&a.node, &b.node) { - (ExprKind::Name { id: a, .. }, ExprKind::Name { id: b, .. }) => a == b, - (ExprKind::Tuple { elts: a, .. }, ExprKind::Tuple { elts: b, .. }) => { - a.len() == b.len() && a.iter().zip(b).all(|(a, b)| is_same_expr(a, b)) - } + ( + ExprKind::Name(ast::ExprName { id: a, .. }), + ExprKind::Name(ast::ExprName { id: b, .. }), + ) => a == b, + ( + ExprKind::Tuple(ast::ExprTuple { elts: a, .. }), + ExprKind::Tuple(ast::ExprTuple { elts: b, .. }), + ) => a.len() == b.len() && a.iter().zip(b).all(|(a, b)| is_same_expr(a, b)), _ => false, } } @@ -41,8 +45,10 @@ fn is_same_expr(a: &Expr, b: &Expr) -> bool { /// names. fn collect_names(expr: &Expr) -> Vec<&str> { match &expr.node { - ExprKind::Name { id, .. } => vec![id], - ExprKind::Tuple { elts, .. } => elts.iter().flat_map(collect_names).collect(), + ExprKind::Name(ast::ExprName { id, .. }) => vec![id], + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { + elts.iter().flat_map(collect_names).collect() + } _ => panic!("Expected: ExprKind::Name | ExprKind::Tuple"), } } @@ -63,13 +69,13 @@ struct YieldFromVisitor<'a> { impl<'a> StatementVisitor<'a> for YieldFromVisitor<'a> { fn visit_stmt(&mut self, stmt: &'a Stmt) { match &stmt.node { - StmtKind::For { + StmtKind::For(ast::StmtFor { target, body, orelse, iter, .. - } => { + }) => { // If there is an else statement, don't rewrite. if !orelse.is_empty() { return; @@ -80,8 +86,8 @@ impl<'a> StatementVisitor<'a> for YieldFromVisitor<'a> { } // If the body is not a yield, don't rewrite. let body = &body[0]; - if let StmtKind::Expr { value } = &body.node { - if let ExprKind::Yield { value: Some(value) } = &value.node { + if let StmtKind::Expr(ast::StmtExpr { value }) = &body.node { + if let ExprKind::Yield(ast::ExprYield { value: Some(value) }) = &value.node { if is_same_expr(target, value) { self.yields.push(YieldFrom { stmt, @@ -93,9 +99,7 @@ impl<'a> StatementVisitor<'a> for YieldFromVisitor<'a> { } } } - StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } - | StmtKind::ClassDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) | StmtKind::ClassDef(_) => { // Don't recurse into anything that defines a new scope. } _ => statement_visitor::walk_stmt(self, stmt), @@ -119,7 +123,7 @@ impl<'a> Visitor<'a> for ReferenceVisitor<'a> { fn visit_expr(&mut self, expr: &'a Expr) { match &expr.node { - ExprKind::Name { id, ctx } => { + ExprKind::Name(ast::ExprName { id, ctx }) => { if matches!(ctx, ExprContext::Load | ExprContext::Del) { if let Some(parent) = self.parent { self.references @@ -137,7 +141,7 @@ impl<'a> Visitor<'a> for ReferenceVisitor<'a> { /// UP028 pub fn yield_in_for_loop(checker: &mut Checker, stmt: &Stmt) { // Intentionally omit async functions. - if let StmtKind::FunctionDef { body, .. } = &stmt.node { + if let StmtKind::FunctionDef(ast::StmtFunctionDef { body, .. }) = &stmt.node { let yields = { let mut visitor = YieldFromVisitor::default(); visitor.visit_body(body); diff --git a/crates/ruff/src/rules/ruff/rules/asyncio_dangling_task.rs b/crates/ruff/src/rules/ruff/rules/asyncio_dangling_task.rs index 42ba7a9901..b883143a39 100644 --- a/crates/ruff/src/rules/ruff/rules/asyncio_dangling_task.rs +++ b/crates/ruff/src/rules/ruff/rules/asyncio_dangling_task.rs @@ -1,6 +1,6 @@ use std::fmt; -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -82,7 +82,7 @@ pub fn asyncio_dangling_task<'a, F>(expr: &'a Expr, resolve_call_path: F) -> Opt where F: FnOnce(&'a Expr) -> Option>, { - if let ExprKind::Call { func, .. } = &expr.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node { match resolve_call_path(func).as_deref() { Some(["asyncio", "create_task"]) => Some(Diagnostic::new( AsyncioDanglingTask { diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 52d0fed36b..9cf3b55fda 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprContext, ExprKind, Operator}; +use rustpython_parser::ast::{self, Expr, ExprContext, ExprKind, Operator}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -33,7 +33,7 @@ fn make_splat_elts( splat_at_left: bool, ) -> Vec { let mut new_elts = other_elements.to_owned(); - let splat = create_expr(ExprKind::Starred { + let splat = create_expr(ast::ExprStarred { value: Box::from(splat_element.clone()), ctx: ExprContext::Load, }); @@ -55,17 +55,25 @@ enum Kind { /// This suggestion could be unsafe if the non-literal expression in the /// expression has overridden the `__add__` (or `__radd__`) magic methods. pub fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { - let ExprKind::BinOp { left, op: Operator::Add, right } = &expr.node else { + let ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::Add, right }) = &expr.node else { return; }; // Figure out which way the splat is, and what the kind of the collection is. let (kind, splat_element, other_elements, splat_at_left, ctx) = match (&left.node, &right.node) { - (ExprKind::List { elts: l_elts, ctx }, _) => (Kind::List, right, l_elts, false, ctx), - (ExprKind::Tuple { elts: l_elts, ctx }, _) => (Kind::Tuple, right, l_elts, false, ctx), - (_, ExprKind::List { elts: r_elts, ctx }) => (Kind::List, left, r_elts, true, ctx), - (_, ExprKind::Tuple { elts: r_elts, ctx }) => (Kind::Tuple, left, r_elts, true, ctx), + (ExprKind::List(ast::ExprList { elts: l_elts, ctx }), _) => { + (Kind::List, right, l_elts, false, ctx) + } + (ExprKind::Tuple(ast::ExprTuple { elts: l_elts, ctx }), _) => { + (Kind::Tuple, right, l_elts, false, ctx) + } + (_, ExprKind::List(ast::ExprList { elts: r_elts, ctx })) => { + (Kind::List, left, r_elts, true, ctx) + } + (_, ExprKind::Tuple(ast::ExprTuple { elts: r_elts, ctx })) => { + (Kind::Tuple, left, r_elts, true, ctx) + } _ => return, }; @@ -73,17 +81,17 @@ pub fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { // will be considered as splat elements. if !matches!( splat_element.node, - ExprKind::Call { .. } | ExprKind::Name { .. } | ExprKind::Attribute { .. } + ExprKind::Call(_) | ExprKind::Name(_) | ExprKind::Attribute(_) ) { return; } let new_expr = match kind { - Kind::List => create_expr(ExprKind::List { + Kind::List => create_expr(ast::ExprList { elts: make_splat_elts(splat_element, other_elements, splat_at_left), ctx: ctx.clone(), }), - Kind::Tuple => create_expr(ExprKind::Tuple { + Kind::Tuple => create_expr(ast::ExprTuple { elts: make_splat_elts(splat_element, other_elements, splat_at_left), ctx: ctx.clone(), }), diff --git a/crates/ruff/src/rules/ruff/rules/mutable_defaults_in_dataclass_fields.rs b/crates/ruff/src/rules/ruff/rules/mutable_defaults_in_dataclass_fields.rs index cacb2238e5..92217019f0 100644 --- a/crates/ruff/src/rules/ruff/rules/mutable_defaults_in_dataclass_fields.rs +++ b/crates/ruff/src/rules/ruff/rules/mutable_defaults_in_dataclass_fields.rs @@ -1,5 +1,5 @@ use ruff_python_ast::call_path::{from_qualified_name, CallPath}; -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -151,12 +151,12 @@ impl Violation for FunctionCallInDataclassDefaultArgument { fn is_mutable_expr(expr: &Expr) -> bool { matches!( &expr.node, - ExprKind::List { .. } - | ExprKind::Dict { .. } - | ExprKind::Set { .. } - | ExprKind::ListComp { .. } - | ExprKind::DictComp { .. } - | ExprKind::SetComp { .. } + ExprKind::List(_) + | ExprKind::Dict(_) + | ExprKind::Set(_) + | ExprKind::ListComp(_) + | ExprKind::DictComp(_) + | ExprKind::SetComp(_) ) } @@ -172,7 +172,7 @@ fn is_allowed_dataclass_function(context: &Context, func: &Expr) -> bool { /// Returns `true` if the given [`Expr`] is a `typing.ClassVar` annotation. fn is_class_var_annotation(context: &Context, annotation: &Expr) -> bool { - let ExprKind::Subscript { value, .. } = &annotation.node else { + let ExprKind::Subscript(ast::ExprSubscript { value, .. }) = &annotation.node else { return false; }; context.match_typing_expr(value, "ClassVar") @@ -189,16 +189,16 @@ pub fn function_call_in_dataclass_defaults(checker: &mut Checker, body: &[Stmt]) .collect(); for statement in body { - if let StmtKind::AnnAssign { + if let StmtKind::AnnAssign(ast::StmtAnnAssign { annotation, value: Some(expr), .. - } = &statement.node + }) = &statement.node { if is_class_var_annotation(&checker.ctx, annotation) { continue; } - if let ExprKind::Call { func, .. } = &expr.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node { if !is_immutable_func(&checker.ctx, func, &extend_immutable_calls) && !is_allowed_dataclass_function(&checker.ctx, func) { @@ -218,11 +218,11 @@ pub fn function_call_in_dataclass_defaults(checker: &mut Checker, body: &[Stmt]) pub fn mutable_dataclass_default(checker: &mut Checker, body: &[Stmt]) { for statement in body { match &statement.node { - StmtKind::AnnAssign { + StmtKind::AnnAssign(ast::StmtAnnAssign { annotation, value: Some(value), .. - } => { + }) => { if !is_class_var_annotation(&checker.ctx, annotation) && !is_immutable_annotation(&checker.ctx, annotation) && is_mutable_expr(value) @@ -232,7 +232,7 @@ pub fn mutable_dataclass_default(checker: &mut Checker, body: &[Stmt]) { .push(Diagnostic::new(MutableDataclassDefault, value.range())); } } - StmtKind::Assign { value, .. } => { + StmtKind::Assign(ast::StmtAssign { value, .. }) => { if is_mutable_expr(value) { checker .diagnostics diff --git a/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs b/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs index 0e05c76424..fc95c612a5 100644 --- a/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs +++ b/crates/ruff/src/rules/ruff/rules/pairwise_over_zipped.rs @@ -1,5 +1,5 @@ use num_traits::ToPrimitive; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Unaryop}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Unaryop}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -33,15 +33,15 @@ impl SliceInfo { /// Return the argument name, lower bound, and upper bound for an expression, if it's a slice. fn match_slice_info(expr: &Expr) -> Option { - let ExprKind::Subscript { value, slice, .. } = &expr.node else { + let ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) = &expr.node else { return None; }; - let ExprKind::Name { id: arg_id, .. } = &value.node else { + let ExprKind::Name(ast::ExprName { id: arg_id, .. }) = &value.node else { return None; }; - let ExprKind::Slice { lower, step, .. } = &slice.node else { + let ExprKind::Slice(ast::ExprSlice { lower, step, .. }) = &slice.node else { return None; }; @@ -64,18 +64,18 @@ fn match_slice_info(expr: &Expr) -> Option { fn to_bound(expr: &Expr) -> Option { match &expr.node { - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Int(value), .. - } => value.to_i64(), - ExprKind::UnaryOp { + }) => value.to_i64(), + ExprKind::UnaryOp(ast::ExprUnaryOp { op: Unaryop::USub | Unaryop::Invert, operand, - } => { - if let ExprKind::Constant { + }) => { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(value), .. - } = &operand.node + }) = &operand.node { value.to_i64().map(|v| -v) } else { @@ -88,7 +88,7 @@ fn to_bound(expr: &Expr) -> Option { /// RUF007 pub fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[Expr]) { - let ExprKind::Name { id, .. } = &func.node else { + let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else { return; }; @@ -107,7 +107,7 @@ pub fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[Expr]) { // Allow the first argument to be a `Name` or `Subscript`. let Some(first_arg_info) = ({ - if let ExprKind::Name { id, .. } = &args[0].node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &args[0].node { Some(SliceInfo::new(id.to_string(), None)) } else { match_slice_info(&args[0]) @@ -117,7 +117,7 @@ pub fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[Expr]) { }; // Require second argument to be a `Subscript`. - let ExprKind::Subscript { .. } = &args[1].node else { + let ExprKind::Subscript (_) = &args[1].node else { return; }; let Some(second_arg_info) = match_slice_info(&args[1]) else { diff --git a/crates/ruff/src/rules/tryceratops/helpers.rs b/crates/ruff/src/rules/tryceratops/helpers.rs index f9a204dc69..36641f9069 100644 --- a/crates/ruff/src/rules/tryceratops/helpers.rs +++ b/crates/ruff/src/rules/tryceratops/helpers.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_python_ast::visitor; use ruff_python_ast::visitor::Visitor; @@ -25,7 +25,7 @@ where 'b: 'a, { fn visit_expr(&mut self, expr: &'b Expr) { - if let ExprKind::Call { func, .. } = &expr.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node { if logging::is_logger_candidate(self.context, func) { self.calls.push((expr, func)); } diff --git a/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs b/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs index 3557348e35..0ad5ef2fe5 100644 --- a/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs +++ b/crates/ruff/src/rules/tryceratops/rules/error_instead_of_exception.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, ExprKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -55,14 +55,15 @@ impl Violation for ErrorInsteadOfException { /// TRY400 pub fn error_instead_of_exception(checker: &mut Checker, handlers: &[Excepthandler]) { for handler in handlers { - let ExcepthandlerKind::ExceptHandler { body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = + &handler.node; let calls = { let mut visitor = LoggerCandidateVisitor::new(&checker.ctx); visitor.visit_body(body); visitor.calls }; for (expr, func) in calls { - if let ExprKind::Attribute { attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node { if attr == "error" { checker .diagnostics diff --git a/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_args.rs b/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_args.rs index 600e4e1a82..0da77ad04d 100644 --- a/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_args.rs +++ b/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_args.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -54,17 +54,17 @@ where F: (Fn(&str) -> bool) + Copy, { match &expr.node { - ExprKind::JoinedStr { values } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { for value in values { if any_string(value, predicate) { return true; } } } - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str(val), .. - } => { + }) => { if predicate(val.as_str()) { return true; } @@ -77,7 +77,7 @@ where /// TRY003 pub fn raise_vanilla_args(checker: &mut Checker, expr: &Expr) { - if let ExprKind::Call { args, .. } = &expr.node { + if let ExprKind::Call(ast::ExprCall { args, .. }) = &expr.node { if let Some(arg) = args.first() { if any_string(arg, |part| part.chars().any(char::is_whitespace)) { checker diff --git a/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs b/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs index dd315bda2e..5a1f080947 100644 --- a/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs +++ b/crates/ruff/src/rules/tryceratops/rules/raise_vanilla_class.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -64,11 +64,13 @@ impl Violation for RaiseVanillaClass { pub fn raise_vanilla_class(checker: &mut Checker, expr: &Expr) { if checker .ctx - .resolve_call_path(if let ExprKind::Call { func, .. } = &expr.node { - func - } else { - expr - }) + .resolve_call_path( + if let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node { + func + } else { + expr + }, + ) .map_or(false, |call_path| call_path.as_slice() == ["", "Exception"]) { checker diff --git a/crates/ruff/src/rules/tryceratops/rules/raise_within_try.rs b/crates/ruff/src/rules/tryceratops/rules/raise_within_try.rs index 3e88717162..615fb7c2c0 100644 --- a/crates/ruff/src/rules/tryceratops/rules/raise_within_try.rs +++ b/crates/ruff/src/rules/tryceratops/rules/raise_within_try.rs @@ -64,8 +64,8 @@ where { fn visit_stmt(&mut self, stmt: &'b Stmt) { match stmt.node { - StmtKind::Raise { .. } => self.raises.push(stmt), - StmtKind::Try { .. } | StmtKind::TryStar { .. } => (), + StmtKind::Raise(_) => self.raises.push(stmt), + StmtKind::Try(_) | StmtKind::TryStar(_) => (), _ => walk_stmt(self, stmt), } } diff --git a/crates/ruff/src/rules/tryceratops/rules/reraise_no_cause.rs b/crates/ruff/src/rules/tryceratops/rules/reraise_no_cause.rs index 6d17cb0a66..f192d2a760 100644 --- a/crates/ruff/src/rules/tryceratops/rules/reraise_no_cause.rs +++ b/crates/ruff/src/rules/tryceratops/rules/reraise_no_cause.rs @@ -55,7 +55,9 @@ pub fn reraise_no_cause(checker: &mut Checker, body: &[Stmt]) { }; for (range, exc, cause) in raises { - if exc.map_or(false, |expr| matches!(expr.node, ExprKind::Call { .. })) && cause.is_none() { + if exc.map_or(false, |expr| { + matches!(expr.node, ExprKind::Call(_)) && cause.is_none() + }) { checker .diagnostics .push(Diagnostic::new(ReraiseNoCause, range)); diff --git a/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs b/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs index db322c19e1..8e58377472 100644 --- a/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs +++ b/crates/ruff/src/rules/tryceratops/rules/try_consider_else.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Excepthandler, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -64,7 +64,7 @@ pub fn try_consider_else( ) { if body.len() > 1 && orelse.is_empty() && !handler.is_empty() { if let Some(stmt) = body.last() { - if let StmtKind::Return { value } = &stmt.node { + if let StmtKind::Return(ast::StmtReturn { value }) = &stmt.node { if let Some(value) = value { if contains_effect(value, |id| checker.ctx.is_builtin(id)) { return; diff --git a/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs b/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs index baf85fa206..449dad2231 100644 --- a/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs +++ b/crates/ruff/src/rules/tryceratops/rules/type_check_without_type_error.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -56,12 +56,10 @@ where { fn visit_stmt(&mut self, stmt: &'b Stmt) { match &stmt.node { - StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } - | StmtKind::ClassDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) | StmtKind::ClassDef(_) => { // Don't recurse. } - StmtKind::Return { .. } => self.returns.push(stmt), + StmtKind::Return(_) => self.returns.push(stmt), StmtKind::Break => self.breaks.push(stmt), StmtKind::Continue => self.continues.push(stmt), _ => walk_stmt(self, stmt), @@ -91,11 +89,13 @@ fn check_type_check_call(checker: &mut Checker, call: &Expr) -> bool { /// Returns `true` if an [`Expr`] is a test to check types (e.g. via isinstance) fn check_type_check_test(checker: &mut Checker, test: &Expr) -> bool { match &test.node { - ExprKind::BoolOp { values, .. } => values + ExprKind::BoolOp(ast::ExprBoolOp { values, .. }) => values .iter() .all(|expr| check_type_check_test(checker, expr)), - ExprKind::UnaryOp { operand, .. } => check_type_check_test(checker, operand), - ExprKind::Call { func, .. } => check_type_check_call(checker, func), + ExprKind::UnaryOp(ast::ExprUnaryOp { operand, .. }) => { + check_type_check_test(checker, operand) + } + ExprKind::Call(ast::ExprCall { func, .. }) => check_type_check_call(checker, func), _ => false, } } @@ -131,9 +131,9 @@ fn is_builtin_exception(checker: &mut Checker, exc: &Expr) -> bool { /// Returns `true` if an [`Expr`] is a reference to a builtin exception. fn check_raise_type(checker: &mut Checker, exc: &Expr) -> bool { match &exc.node { - ExprKind::Name { .. } => is_builtin_exception(checker, exc), - ExprKind::Call { func, .. } => { - if let ExprKind::Name { .. } = &func.node { + ExprKind::Name(_) => is_builtin_exception(checker, exc), + ExprKind::Call(ast::ExprCall { func, .. }) => { + if let ExprKind::Name(_) = &func.node { is_builtin_exception(checker, func) } else { false @@ -157,7 +157,7 @@ fn check_body(checker: &mut Checker, body: &[Stmt]) { if has_control_flow(item) { return; } - if let StmtKind::Raise { exc: Some(exc), .. } = &item.node { + if let StmtKind::Raise(ast::StmtRaise { exc: Some(exc), .. }) = &item.node { check_raise(checker, exc, item); } } @@ -170,12 +170,12 @@ fn check_orelse(checker: &mut Checker, body: &[Stmt]) { return; } match &item.node { - StmtKind::If { test, .. } => { + StmtKind::If(ast::StmtIf { test, .. }) => { if !check_type_check_test(checker, test) { return; } } - StmtKind::Raise { exc: Some(exc), .. } => { + StmtKind::Raise(ast::StmtRaise { exc: Some(exc), .. }) => { check_raise(checker, exc, item); } _ => {} @@ -192,7 +192,7 @@ pub fn type_check_without_type_error( parent: Option<&Stmt>, ) { if let Some(parent) = parent { - if let StmtKind::If { test, .. } = &parent.node { + if let StmtKind::If(ast::StmtIf { test, .. }) = &parent.node { if !check_type_check_test(checker, test) { return; } diff --git a/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs b/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs index 9ca1f8cb53..97d711377f 100644 --- a/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs +++ b/crates/ruff/src/rules/tryceratops/rules/verbose_log_message.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -52,11 +52,11 @@ where { fn visit_expr(&mut self, expr: &'b Expr) { match &expr.node { - ExprKind::Name { + ExprKind::Name(ast::ExprName { id, ctx: ExprContext::Load, - } => self.names.push((id, expr)), - ExprKind::Attribute { .. } => {} + }) => self.names.push((id, expr)), + ExprKind::Attribute(_) => {} _ => visitor::walk_expr(self, expr), } } @@ -65,7 +65,9 @@ where /// TRY401 pub fn verbose_log_message(checker: &mut Checker, handlers: &[Excepthandler]) { for handler in handlers { - let ExcepthandlerKind::ExceptHandler { name, body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + name, body, .. + }) = &handler.node; let Some(target) = name else { continue; }; @@ -78,10 +80,10 @@ pub fn verbose_log_message(checker: &mut Checker, handlers: &[Excepthandler]) { }; for (expr, func) in calls { - let ExprKind::Call { args, .. } = &expr.node else { + let ExprKind::Call(ast::ExprCall { args, .. }) = &expr.node else { continue; }; - if let ExprKind::Attribute { attr, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node { if attr == "exception" { // Collect all referenced names in the `logging.exception` call. let names: Vec<(&str, &Expr)> = { @@ -94,7 +96,7 @@ pub fn verbose_log_message(checker: &mut Checker, handlers: &[Excepthandler]) { names }; for (id, expr) in names { - if id == target { + if target == id { checker .diagnostics .push(Diagnostic::new(VerboseLogMessage, expr.range())); diff --git a/crates/ruff/src/rules/tryceratops/rules/verbose_raise.rs b/crates/ruff/src/rules/tryceratops/rules/verbose_raise.rs index 672d730895..342ac65e36 100644 --- a/crates/ruff/src/rules/tryceratops/rules/verbose_raise.rs +++ b/crates/ruff/src/rules/tryceratops/rules/verbose_raise.rs @@ -1,4 +1,6 @@ -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{ + self, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Stmt, StmtKind, +}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -51,13 +53,15 @@ where { fn visit_stmt(&mut self, stmt: &'b Stmt) { match &stmt.node { - StmtKind::Raise { exc, cause } => self.raises.push((exc.as_deref(), cause.as_deref())), - StmtKind::Try { - body, finalbody, .. + StmtKind::Raise(ast::StmtRaise { exc, cause }) => { + self.raises.push((exc.as_deref(), cause.as_deref())); } - | StmtKind::TryStar { + StmtKind::Try(ast::StmtTry { body, finalbody, .. - } => { + }) + | StmtKind::TryStar(ast::StmtTryStar { + body, finalbody, .. + }) => { for stmt in body.iter().chain(finalbody.iter()) { walk_stmt(self, stmt); } @@ -71,11 +75,11 @@ where pub fn verbose_raise(checker: &mut Checker, handlers: &[Excepthandler]) { for handler in handlers { // If the handler assigned a name to the exception... - if let ExcepthandlerKind::ExceptHandler { + if let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { name: Some(exception_name), body, .. - } = &handler.node + }) = &handler.node { let raises = { let mut visitor = RaiseStatementVisitor::default(); @@ -88,7 +92,7 @@ pub fn verbose_raise(checker: &mut Checker, handlers: &[Excepthandler]) { } if let Some(exc) = exc { // ...and the raised object is bound to the same name... - if let ExprKind::Name { id, .. } = &exc.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &exc.node { if id == exception_name { checker .diagnostics diff --git a/crates/ruff_python_ast/Cargo.toml b/crates/ruff_python_ast/Cargo.toml index 7cd8eb3523..c61b487ae2 100644 --- a/crates/ruff_python_ast/Cargo.toml +++ b/crates/ruff_python_ast/Cargo.toml @@ -8,7 +8,6 @@ rust-version = { workspace = true } [lib] [dependencies] -ruff_rustpython = { path = "../ruff_rustpython" } ruff_text_size = { workspace = true } anyhow = { workspace = true } @@ -22,7 +21,7 @@ num-traits = { version = "0.2.15" } once_cell = { workspace = true } regex = { workspace = true } rustc-hash = { workspace = true } -rustpython-common = { workspace = true } +rustpython-literal = { workspace = true } rustpython-parser = { workspace = true } serde = { workspace = true, optional = true } smallvec = { workspace = true } diff --git a/crates/ruff_python_ast/src/all.rs b/crates/ruff_python_ast/src/all.rs index 1e2a4df836..9d0cd2d42e 100644 --- a/crates/ruff_python_ast/src/all.rs +++ b/crates/ruff_python_ast/src/all.rs @@ -1,5 +1,5 @@ use bitflags::bitflags; -use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind}; bitflags! { #[derive(Default, Debug, Copy, Clone, PartialEq, Eq)] @@ -18,10 +18,10 @@ where { fn add_to_names<'a>(elts: &'a [Expr], names: &mut Vec<&'a str>, flags: &mut AllNamesFlags) { for elt in elts { - if let ExprKind::Constant { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(value), .. - } = &elt.node + }) = &elt.node { names.push(value); } else { @@ -35,39 +35,39 @@ where F: Fn(&str) -> bool, { match &expr.node { - ExprKind::List { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) => { return (Some(elts), AllNamesFlags::empty()); } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { return (Some(elts), AllNamesFlags::empty()); } - ExprKind::ListComp { .. } => { + ExprKind::ListComp(_) => { // Allow comprehensions, even though we can't statically analyze them. return (None, AllNamesFlags::empty()); } - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - .. - } => { + }) => { // Allow `tuple()` and `list()` calls. if keywords.is_empty() && args.len() <= 1 { - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { + let id = id.as_str(); if id == "tuple" || id == "list" { if is_builtin(id) { if args.is_empty() { return (None, AllNamesFlags::empty()); } match &args[0].node { - ExprKind::List { elts, .. } - | ExprKind::Set { elts, .. } - | ExprKind::Tuple { elts, .. } => { + ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Set(ast::ExprSet { elts }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { return (Some(elts), AllNamesFlags::empty()); } - ExprKind::ListComp { .. } - | ExprKind::SetComp { .. } - | ExprKind::GeneratorExp { .. } => { + ExprKind::ListComp(_) + | ExprKind::SetComp(_) + | ExprKind::GeneratorExp(_) => { // Allow comprehensions, even though we can't statically analyze // them. return (None, AllNamesFlags::empty()); @@ -88,12 +88,12 @@ where let mut flags = AllNamesFlags::empty(); if let Some(value) = match &stmt.node { - StmtKind::Assign { value, .. } => Some(value), - StmtKind::AnnAssign { value, .. } => value.as_ref(), - StmtKind::AugAssign { value, .. } => Some(value), + StmtKind::Assign(ast::StmtAssign { value, .. }) => Some(value), + StmtKind::AnnAssign(ast::StmtAnnAssign { value, .. }) => value.as_ref(), + StmtKind::AugAssign(ast::StmtAugAssign { value, .. }) => Some(value), _ => None, } { - if let ExprKind::BinOp { left, right, .. } = &value.node { + if let ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) = &value.node { let mut current_left = left; let mut current_right = right; loop { @@ -106,7 +106,7 @@ where // Process the left side, which can be a "real" value or the "rest" of the // binary operation. - if let ExprKind::BinOp { left, right, .. } = ¤t_left.node { + if let ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) = ¤t_left.node { current_left = left; current_right = right; } else { diff --git a/crates/ruff_python_ast/src/call_path.rs b/crates/ruff_python_ast/src/call_path.rs index 24cbee3e63..4266490e57 100644 --- a/crates/ruff_python_ast/src/call_path.rs +++ b/crates/ruff_python_ast/src/call_path.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use smallvec::smallvec; /// A representation of a qualified name, like `typing.List`. @@ -6,16 +6,16 @@ pub type CallPath<'a> = smallvec::SmallVec<[&'a str; 8]>; fn collect_call_path_inner<'a>(expr: &'a Expr, parts: &mut CallPath<'a>) -> bool { match &expr.node { - ExprKind::Attribute { value, attr, .. } => { + ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) => { if collect_call_path_inner(value, parts) { - parts.push(attr); + parts.push(attr.as_str()); true } else { false } } - ExprKind::Name { id, .. } => { - parts.push(id); + ExprKind::Name(ast::ExprName { id, .. }) => { + parts.push(id.as_str()); true } _ => false, diff --git a/crates/ruff_python_ast/src/cast.rs b/crates/ruff_python_ast/src/cast.rs index 8a893bedfb..527cb6e883 100644 --- a/crates/ruff_python_ast/src/cast.rs +++ b/crates/ruff_python_ast/src/cast.rs @@ -1,16 +1,19 @@ -use rustpython_parser::ast::{Expr, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, Stmt, StmtKind}; pub fn name(stmt: &Stmt) -> &str { match &stmt.node { - StmtKind::FunctionDef { name, .. } | StmtKind::AsyncFunctionDef { name, .. } => name, + StmtKind::FunctionDef(ast::StmtFunctionDef { name, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, .. }) => name.as_str(), _ => panic!("Expected StmtKind::FunctionDef | StmtKind::AsyncFunctionDef"), } } pub fn decorator_list(stmt: &Stmt) -> &Vec { match &stmt.node { - StmtKind::FunctionDef { decorator_list, .. } - | StmtKind::AsyncFunctionDef { decorator_list, .. } => decorator_list, + StmtKind::FunctionDef(ast::StmtFunctionDef { decorator_list, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { decorator_list, .. }) => { + decorator_list + } _ => panic!("Expected StmtKind::FunctionDef | StmtKind::AsyncFunctionDef"), } } diff --git a/crates/ruff_python_ast/src/comparable.rs b/crates/ruff_python_ast/src/comparable.rs index 3ddad10a94..2a28f3dc81 100644 --- a/crates/ruff_python_ast/src/comparable.rs +++ b/crates/ruff_python_ast/src/comparable.rs @@ -3,9 +3,9 @@ use num_bigint::BigInt; use rustpython_parser::ast::{ - Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, Excepthandler, - ExcepthandlerKind, Expr, ExprContext, ExprKind, Keyword, MatchCase, Operator, Pattern, - PatternKind, Stmt, StmtKind, Unaryop, Withitem, + self, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, Excepthandler, + ExcepthandlerKind, Expr, ExprContext, ExprKind, Identifier, Int, Keyword, MatchCase, Operator, + Pattern, PatternKind, Stmt, StmtKind, Unaryop, Withitem, }; #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] @@ -136,7 +136,7 @@ pub struct ComparableAlias<'a> { impl<'a> From<&'a Alias> for ComparableAlias<'a> { fn from(alias: &'a Alias) -> Self { Self { - name: &alias.node.name, + name: alias.node.name.as_str(), asname: alias.node.asname.as_deref(), } } @@ -195,43 +195,47 @@ pub enum ComparablePattern<'a> { impl<'a> From<&'a Pattern> for ComparablePattern<'a> { fn from(pattern: &'a Pattern) -> Self { match &pattern.node { - PatternKind::MatchValue { value } => Self::MatchValue { + PatternKind::MatchValue(ast::PatternMatchValue { value }) => Self::MatchValue { value: value.into(), }, - PatternKind::MatchSingleton { value } => Self::MatchSingleton { - value: value.into(), - }, - PatternKind::MatchSequence { patterns } => Self::MatchSequence { - patterns: patterns.iter().map(Into::into).collect(), - }, - PatternKind::MatchMapping { + PatternKind::MatchSingleton(ast::PatternMatchSingleton { value }) => { + Self::MatchSingleton { + value: value.into(), + } + } + PatternKind::MatchSequence(ast::PatternMatchSequence { patterns }) => { + Self::MatchSequence { + patterns: patterns.iter().map(Into::into).collect(), + } + } + PatternKind::MatchMapping(ast::PatternMatchMapping { keys, patterns, rest, - } => Self::MatchMapping { + }) => Self::MatchMapping { keys: keys.iter().map(Into::into).collect(), patterns: patterns.iter().map(Into::into).collect(), rest: rest.as_deref(), }, - PatternKind::MatchClass { + PatternKind::MatchClass(ast::PatternMatchClass { cls, patterns, kwd_attrs, kwd_patterns, - } => Self::MatchClass { + }) => Self::MatchClass { cls: cls.into(), patterns: patterns.iter().map(Into::into).collect(), - kwd_attrs: kwd_attrs.iter().map(String::as_str).collect(), + kwd_attrs: kwd_attrs.iter().map(Identifier::as_str).collect(), kwd_patterns: kwd_patterns.iter().map(Into::into).collect(), }, - PatternKind::MatchStar { name } => Self::MatchStar { + PatternKind::MatchStar(ast::PatternMatchStar { name }) => Self::MatchStar { name: name.as_deref(), }, - PatternKind::MatchAs { pattern, name } => Self::MatchAs { + PatternKind::MatchAs(ast::PatternMatchAs { pattern, name }) => Self::MatchAs { pattern: pattern.as_ref().map(Into::into), name: name.as_deref(), }, - PatternKind::MatchOr { patterns } => Self::MatchOr { + PatternKind::MatchOr(ast::PatternMatchOr { patterns }) => Self::MatchOr { patterns: patterns.iter().map(Into::into).collect(), }, } @@ -340,7 +344,7 @@ pub struct ComparableArg<'a> { impl<'a> From<&'a Arg> for ComparableArg<'a> { fn from(arg: &'a Arg) -> Self { Self { - arg: &arg.node.arg, + arg: arg.node.arg.as_str(), annotation: arg.node.annotation.as_ref().map(Into::into), type_comment: arg.node.type_comment.as_deref(), } @@ -356,7 +360,7 @@ pub struct ComparableKeyword<'a> { impl<'a> From<&'a Keyword> for ComparableKeyword<'a> { fn from(keyword: &'a Keyword) -> Self { Self { - arg: keyword.node.arg.as_deref(), + arg: keyword.node.arg.as_ref().map(Identifier::as_str), value: (&keyword.node.value).into(), } } @@ -367,7 +371,7 @@ pub struct ComparableComprehension<'a> { pub target: ComparableExpr<'a>, pub iter: ComparableExpr<'a>, pub ifs: Vec>, - pub is_async: usize, + pub is_async: bool, } impl<'a> From<&'a Comprehension> for ComparableComprehension<'a> { @@ -392,7 +396,8 @@ pub enum ComparableExcepthandler<'a> { impl<'a> From<&'a Excepthandler> for ComparableExcepthandler<'a> { fn from(excepthandler: &'a Excepthandler) -> Self { - let ExcepthandlerKind::ExceptHandler { type_, name, body } = &excepthandler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, name, body }) = + &excepthandler.node; Self::ExceptHandler { type_: type_.as_ref().map(Into::into), name: name.as_deref(), @@ -474,7 +479,7 @@ pub enum ComparableExpr<'a> { }, FormattedValue { value: Box>, - conversion: usize, + conversion: Int, format_spec: Option>>, }, JoinedStr { @@ -532,133 +537,135 @@ impl<'a> From<&'a Box> for ComparableExpr<'a> { impl<'a> From<&'a Expr> for ComparableExpr<'a> { fn from(expr: &'a Expr) -> Self { match &expr.node { - ExprKind::BoolOp { op, values } => Self::BoolOp { + ExprKind::BoolOp(ast::ExprBoolOp { op, values }) => Self::BoolOp { op: op.into(), values: values.iter().map(Into::into).collect(), }, - ExprKind::NamedExpr { target, value } => Self::NamedExpr { + ExprKind::NamedExpr(ast::ExprNamedExpr { target, value }) => Self::NamedExpr { target: target.into(), value: value.into(), }, - ExprKind::BinOp { left, op, right } => Self::BinOp { + ExprKind::BinOp(ast::ExprBinOp { left, op, right }) => Self::BinOp { left: left.into(), op: op.into(), right: right.into(), }, - ExprKind::UnaryOp { op, operand } => Self::UnaryOp { + ExprKind::UnaryOp(ast::ExprUnaryOp { op, operand }) => Self::UnaryOp { op: op.into(), operand: operand.into(), }, - ExprKind::Lambda { args, body } => Self::Lambda { + ExprKind::Lambda(ast::ExprLambda { args, body }) => Self::Lambda { args: (&**args).into(), body: body.into(), }, - ExprKind::IfExp { test, body, orelse } => Self::IfExp { + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => Self::IfExp { test: test.into(), body: body.into(), orelse: orelse.into(), }, - ExprKind::Dict { keys, values } => Self::Dict { + ExprKind::Dict(ast::ExprDict { keys, values }) => Self::Dict { keys: keys .iter() .map(|expr| expr.as_ref().map(Into::into)) .collect(), values: values.iter().map(Into::into).collect(), }, - ExprKind::Set { elts } => Self::Set { + ExprKind::Set(ast::ExprSet { elts }) => Self::Set { elts: elts.iter().map(Into::into).collect(), }, - ExprKind::ListComp { elt, generators } => Self::ListComp { + ExprKind::ListComp(ast::ExprListComp { elt, generators }) => Self::ListComp { elt: elt.into(), generators: generators.iter().map(Into::into).collect(), }, - ExprKind::SetComp { elt, generators } => Self::SetComp { + ExprKind::SetComp(ast::ExprSetComp { elt, generators }) => Self::SetComp { elt: elt.into(), generators: generators.iter().map(Into::into).collect(), }, - ExprKind::DictComp { + ExprKind::DictComp(ast::ExprDictComp { key, value, generators, - } => Self::DictComp { + }) => Self::DictComp { key: key.into(), value: value.into(), generators: generators.iter().map(Into::into).collect(), }, - ExprKind::GeneratorExp { elt, generators } => Self::GeneratorExp { - elt: elt.into(), - generators: generators.iter().map(Into::into).collect(), - }, - ExprKind::Await { value } => Self::Await { + ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, generators }) => { + Self::GeneratorExp { + elt: elt.into(), + generators: generators.iter().map(Into::into).collect(), + } + } + ExprKind::Await(ast::ExprAwait { value }) => Self::Await { value: value.into(), }, - ExprKind::Yield { value } => Self::Yield { + ExprKind::Yield(ast::ExprYield { value }) => Self::Yield { value: value.as_ref().map(Into::into), }, - ExprKind::YieldFrom { value } => Self::YieldFrom { + ExprKind::YieldFrom(ast::ExprYieldFrom { value }) => Self::YieldFrom { value: value.into(), }, - ExprKind::Compare { + ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } => Self::Compare { + }) => Self::Compare { left: left.into(), ops: ops.iter().map(Into::into).collect(), comparators: comparators.iter().map(Into::into).collect(), }, - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => Self::Call { + }) => Self::Call { func: func.into(), args: args.iter().map(Into::into).collect(), keywords: keywords.iter().map(Into::into).collect(), }, - ExprKind::FormattedValue { + ExprKind::FormattedValue(ast::ExprFormattedValue { value, conversion, format_spec, - } => Self::FormattedValue { + }) => Self::FormattedValue { value: value.into(), conversion: *conversion, format_spec: format_spec.as_ref().map(Into::into), }, - ExprKind::JoinedStr { values } => Self::JoinedStr { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => Self::JoinedStr { values: values.iter().map(Into::into).collect(), }, - ExprKind::Constant { value, kind } => Self::Constant { + ExprKind::Constant(ast::ExprConstant { value, kind }) => Self::Constant { value: value.into(), kind: kind.as_ref().map(String::as_str), }, - ExprKind::Attribute { value, attr, ctx } => Self::Attribute { + ExprKind::Attribute(ast::ExprAttribute { value, attr, ctx }) => Self::Attribute { value: value.into(), - attr, + attr: attr.as_str(), ctx: ctx.into(), }, - ExprKind::Subscript { value, slice, ctx } => Self::Subscript { + ExprKind::Subscript(ast::ExprSubscript { value, slice, ctx }) => Self::Subscript { value: value.into(), slice: slice.into(), ctx: ctx.into(), }, - ExprKind::Starred { value, ctx } => Self::Starred { + ExprKind::Starred(ast::ExprStarred { value, ctx }) => Self::Starred { value: value.into(), ctx: ctx.into(), }, - ExprKind::Name { id, ctx } => Self::Name { - id, + ExprKind::Name(ast::ExprName { id, ctx }) => Self::Name { + id: id.as_str(), ctx: ctx.into(), }, - ExprKind::List { elts, ctx } => Self::List { + ExprKind::List(ast::ExprList { elts, ctx }) => Self::List { elts: elts.iter().map(Into::into).collect(), ctx: ctx.into(), }, - ExprKind::Tuple { elts, ctx } => Self::Tuple { + ExprKind::Tuple(ast::ExprTuple { elts, ctx }) => Self::Tuple { elts: elts.iter().map(Into::into).collect(), ctx: ctx.into(), }, - ExprKind::Slice { lower, upper, step } => Self::Slice { + ExprKind::Slice(ast::ExprSlice { lower, upper, step }) => Self::Slice { lower: lower.as_ref().map(Into::into), upper: upper.as_ref().map(Into::into), step: step.as_ref().map(Into::into), @@ -712,7 +719,7 @@ pub enum ComparableStmt<'a> { target: ComparableExpr<'a>, annotation: ComparableExpr<'a>, value: Option>, - simple: usize, + simple: bool, }, For { target: ComparableExpr<'a>, @@ -778,7 +785,7 @@ pub enum ComparableStmt<'a> { ImportFrom { module: Option<&'a str>, names: Vec>, - level: Option, + level: Option, }, Global { names: Vec<&'a str>, @@ -797,187 +804,187 @@ pub enum ComparableStmt<'a> { impl<'a> From<&'a Stmt> for ComparableStmt<'a> { fn from(stmt: &'a Stmt) -> Self { match &stmt.node { - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment, - } => Self::FunctionDef { - name, + }) => Self::FunctionDef { + name: name.as_str(), args: args.into(), body: body.iter().map(Into::into).collect(), decorator_list: decorator_list.iter().map(Into::into).collect(), returns: returns.as_ref().map(Into::into), type_comment: type_comment.as_ref().map(std::string::String::as_str), }, - StmtKind::AsyncFunctionDef { + StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, args, body, decorator_list, returns, type_comment, - } => Self::AsyncFunctionDef { - name, + }) => Self::AsyncFunctionDef { + name: name.as_str(), args: args.into(), body: body.iter().map(Into::into).collect(), decorator_list: decorator_list.iter().map(Into::into).collect(), returns: returns.as_ref().map(Into::into), type_comment: type_comment.as_ref().map(std::string::String::as_str), }, - StmtKind::ClassDef { + StmtKind::ClassDef(ast::StmtClassDef { name, bases, keywords, body, decorator_list, - } => Self::ClassDef { - name, + }) => Self::ClassDef { + name: name.as_str(), bases: bases.iter().map(Into::into).collect(), keywords: keywords.iter().map(Into::into).collect(), body: body.iter().map(Into::into).collect(), decorator_list: decorator_list.iter().map(Into::into).collect(), }, - StmtKind::Return { value } => Self::Return { + StmtKind::Return(ast::StmtReturn { value }) => Self::Return { value: value.as_ref().map(Into::into), }, - StmtKind::Delete { targets } => Self::Delete { + StmtKind::Delete(ast::StmtDelete { targets }) => Self::Delete { targets: targets.iter().map(Into::into).collect(), }, - StmtKind::Assign { + StmtKind::Assign(ast::StmtAssign { targets, value, type_comment, - } => Self::Assign { + }) => Self::Assign { targets: targets.iter().map(Into::into).collect(), value: value.into(), type_comment: type_comment.as_ref().map(std::string::String::as_str), }, - StmtKind::AugAssign { target, op, value } => Self::AugAssign { + StmtKind::AugAssign(ast::StmtAugAssign { target, op, value }) => Self::AugAssign { target: target.into(), op: op.into(), value: value.into(), }, - StmtKind::AnnAssign { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, annotation, value, simple, - } => Self::AnnAssign { + }) => Self::AnnAssign { target: target.into(), annotation: annotation.into(), value: value.as_ref().map(Into::into), simple: *simple, }, - StmtKind::For { + StmtKind::For(ast::StmtFor { target, iter, body, orelse, type_comment, - } => Self::For { + }) => Self::For { target: target.into(), iter: iter.into(), body: body.iter().map(Into::into).collect(), orelse: orelse.iter().map(Into::into).collect(), type_comment: type_comment.as_ref().map(String::as_str), }, - StmtKind::AsyncFor { + StmtKind::AsyncFor(ast::StmtAsyncFor { target, iter, body, orelse, type_comment, - } => Self::AsyncFor { + }) => Self::AsyncFor { target: target.into(), iter: iter.into(), body: body.iter().map(Into::into).collect(), orelse: orelse.iter().map(Into::into).collect(), type_comment: type_comment.as_ref().map(String::as_str), }, - StmtKind::While { test, body, orelse } => Self::While { + StmtKind::While(ast::StmtWhile { test, body, orelse }) => Self::While { test: test.into(), body: body.iter().map(Into::into).collect(), orelse: orelse.iter().map(Into::into).collect(), }, - StmtKind::If { test, body, orelse } => Self::If { + StmtKind::If(ast::StmtIf { test, body, orelse }) => Self::If { test: test.into(), body: body.iter().map(Into::into).collect(), orelse: orelse.iter().map(Into::into).collect(), }, - StmtKind::With { + StmtKind::With(ast::StmtWith { items, body, type_comment, - } => Self::With { + }) => Self::With { items: items.iter().map(Into::into).collect(), body: body.iter().map(Into::into).collect(), type_comment: type_comment.as_ref().map(String::as_str), }, - StmtKind::AsyncWith { + StmtKind::AsyncWith(ast::StmtAsyncWith { items, body, type_comment, - } => Self::AsyncWith { + }) => Self::AsyncWith { items: items.iter().map(Into::into).collect(), body: body.iter().map(Into::into).collect(), type_comment: type_comment.as_ref().map(String::as_str), }, - StmtKind::Match { subject, cases } => Self::Match { + StmtKind::Match(ast::StmtMatch { subject, cases }) => Self::Match { subject: subject.into(), cases: cases.iter().map(Into::into).collect(), }, - StmtKind::Raise { exc, cause } => Self::Raise { + StmtKind::Raise(ast::StmtRaise { exc, cause }) => Self::Raise { exc: exc.as_ref().map(Into::into), cause: cause.as_ref().map(Into::into), }, - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } => Self::Try { + }) => Self::Try { body: body.iter().map(Into::into).collect(), handlers: handlers.iter().map(Into::into).collect(), orelse: orelse.iter().map(Into::into).collect(), finalbody: finalbody.iter().map(Into::into).collect(), }, - StmtKind::TryStar { + StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => Self::TryStar { + }) => Self::TryStar { body: body.iter().map(Into::into).collect(), handlers: handlers.iter().map(Into::into).collect(), orelse: orelse.iter().map(Into::into).collect(), finalbody: finalbody.iter().map(Into::into).collect(), }, - StmtKind::Assert { test, msg } => Self::Assert { + StmtKind::Assert(ast::StmtAssert { test, msg }) => Self::Assert { test: test.into(), msg: msg.as_ref().map(Into::into), }, - StmtKind::Import { names } => Self::Import { + StmtKind::Import(ast::StmtImport { names }) => Self::Import { names: names.iter().map(Into::into).collect(), }, - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } => Self::ImportFrom { - module: module.as_ref().map(String::as_str), + }) => Self::ImportFrom { + module: module.as_deref(), names: names.iter().map(Into::into).collect(), level: *level, }, - StmtKind::Global { names } => Self::Global { - names: names.iter().map(String::as_str).collect(), + StmtKind::Global(ast::StmtGlobal { names }) => Self::Global { + names: names.iter().map(Identifier::as_str).collect(), }, - StmtKind::Nonlocal { names } => Self::Nonlocal { - names: names.iter().map(String::as_str).collect(), + StmtKind::Nonlocal(ast::StmtNonlocal { names }) => Self::Nonlocal { + names: names.iter().map(Identifier::as_str).collect(), }, - StmtKind::Expr { value } => Self::Expr { + StmtKind::Expr(ast::StmtExpr { value }) => Self::Expr { value: value.into(), }, StmtKind::Pass => Self::Pass, diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index e6915dccc1..8338391533 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -9,8 +9,8 @@ use regex::Regex; use ruff_text_size::{TextRange, TextSize}; use rustc_hash::{FxHashMap, FxHashSet}; use rustpython_parser::ast::{ - Arguments, Cmpop, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Keyword, - KeywordData, Located, MatchCase, Pattern, PatternKind, Stmt, StmtKind, + self, Arguments, Attributed, Cmpop, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprKind, + Keyword, KeywordData, MatchCase, Pattern, PatternKind, Stmt, StmtKind, }; use rustpython_parser::{lexer, Mode, Tok}; use smallvec::SmallVec; @@ -21,13 +21,13 @@ use crate::source_code::{Generator, Indexer, Locator, Stylist}; use crate::statement_visitor::{walk_body, walk_stmt, StatementVisitor}; /// Create an `Expr` with default location from an `ExprKind`. -pub fn create_expr(node: ExprKind) -> Expr { - Expr::with_range(node, TextRange::default()) +pub fn create_expr(node: impl Into) -> Expr { + Expr::new(TextRange::default(), node.into()) } /// Create a `Stmt` with a default location from a `StmtKind`. -pub fn create_stmt(node: StmtKind) -> Stmt { - Stmt::with_range(node, TextRange::default()) +pub fn create_stmt(node: impl Into) -> Stmt { + Stmt::new(TextRange::default(), node.into()) } /// Generate source code from an [`Expr`]. @@ -68,14 +68,14 @@ where { any_over_expr(expr, &|expr| { // Accept empty initializers. - if let ExprKind::Call { + if let ExprKind::Call(ast::ExprCall { func, args, keywords, - } = &expr.node + }) = &expr.node { if args.is_empty() && keywords.is_empty() { - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { if !is_iterable_initializer(id.as_str(), |id| is_builtin(id)) { return true; } @@ -85,32 +85,32 @@ where } // Avoid false positive for overloaded operators. - if let ExprKind::BinOp { left, right, .. } = &expr.node { + if let ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) = &expr.node { if !matches!( left.node, - ExprKind::Constant { .. } - | ExprKind::JoinedStr { .. } - | ExprKind::List { .. } - | ExprKind::Tuple { .. } - | ExprKind::Set { .. } - | ExprKind::Dict { .. } - | ExprKind::ListComp { .. } - | ExprKind::SetComp { .. } - | ExprKind::DictComp { .. } + ExprKind::Constant(_) + | ExprKind::JoinedStr(_) + | ExprKind::List(_) + | ExprKind::Tuple(_) + | ExprKind::Set(_) + | ExprKind::Dict(_) + | ExprKind::ListComp(_) + | ExprKind::SetComp(_) + | ExprKind::DictComp(_) ) { return true; } if !matches!( right.node, - ExprKind::Constant { .. } - | ExprKind::JoinedStr { .. } - | ExprKind::List { .. } - | ExprKind::Tuple { .. } - | ExprKind::Set { .. } - | ExprKind::Dict { .. } - | ExprKind::ListComp { .. } - | ExprKind::SetComp { .. } - | ExprKind::DictComp { .. } + ExprKind::Constant(_) + | ExprKind::JoinedStr(_) + | ExprKind::List(_) + | ExprKind::Tuple(_) + | ExprKind::Set(_) + | ExprKind::Dict(_) + | ExprKind::ListComp(_) + | ExprKind::SetComp(_) + | ExprKind::DictComp(_) ) { return true; } @@ -120,15 +120,15 @@ where // Otherwise, avoid all complex expressions. matches!( expr.node, - ExprKind::Await { .. } - | ExprKind::Call { .. } - | ExprKind::DictComp { .. } - | ExprKind::GeneratorExp { .. } - | ExprKind::ListComp { .. } - | ExprKind::SetComp { .. } - | ExprKind::Subscript { .. } - | ExprKind::Yield { .. } - | ExprKind::YieldFrom { .. } + ExprKind::Await(_) + | ExprKind::Call(_) + | ExprKind::DictComp(_) + | ExprKind::GeneratorExp(_) + | ExprKind::ListComp(_) + | ExprKind::SetComp(_) + | ExprKind::Subscript(_) + | ExprKind::Yield(_) + | ExprKind::YieldFrom(_) ) }) } @@ -143,30 +143,33 @@ where return true; } match &expr.node { - ExprKind::BoolOp { values, .. } | ExprKind::JoinedStr { values } => { + ExprKind::BoolOp(ast::ExprBoolOp { values, .. }) + | ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { values.iter().any(|expr| any_over_expr(expr, func)) } - ExprKind::NamedExpr { target, value } => { + ExprKind::NamedExpr(ast::ExprNamedExpr { target, value }) => { any_over_expr(target, func) || any_over_expr(value, func) } - ExprKind::BinOp { left, right, .. } => { + ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) => { any_over_expr(left, func) || any_over_expr(right, func) } - ExprKind::UnaryOp { operand, .. } => any_over_expr(operand, func), - ExprKind::Lambda { body, .. } => any_over_expr(body, func), - ExprKind::IfExp { test, body, orelse } => { + ExprKind::UnaryOp(ast::ExprUnaryOp { operand, .. }) => any_over_expr(operand, func), + ExprKind::Lambda(ast::ExprLambda { body, .. }) => any_over_expr(body, func), + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { any_over_expr(test, func) || any_over_expr(body, func) || any_over_expr(orelse, func) } - ExprKind::Dict { keys, values } => values + ExprKind::Dict(ast::ExprDict { keys, values }) => values .iter() .chain(keys.iter().flatten()) .any(|expr| any_over_expr(expr, func)), - ExprKind::Set { elts } | ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => { + ExprKind::Set(ast::ExprSet { elts }) + | ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { elts.iter().any(|expr| any_over_expr(expr, func)) } - ExprKind::ListComp { elt, generators } - | ExprKind::SetComp { elt, generators } - | ExprKind::GeneratorExp { elt, generators } => { + ExprKind::ListComp(ast::ExprListComp { elt, generators }) + | ExprKind::SetComp(ast::ExprSetComp { elt, generators }) + | ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, generators }) => { any_over_expr(elt, func) || generators.iter().any(|generator| { any_over_expr(&generator.target, func) @@ -174,11 +177,11 @@ where || generator.ifs.iter().any(|expr| any_over_expr(expr, func)) }) } - ExprKind::DictComp { + ExprKind::DictComp(ast::ExprDictComp { key, value, generators, - } => { + }) => { any_over_expr(key, func) || any_over_expr(value, func) || generators.iter().any(|generator| { @@ -187,39 +190,39 @@ where || generator.ifs.iter().any(|expr| any_over_expr(expr, func)) }) } - ExprKind::Await { value } - | ExprKind::YieldFrom { value } - | ExprKind::Attribute { value, .. } - | ExprKind::Starred { value, .. } => any_over_expr(value, func), - ExprKind::Yield { value } => value + ExprKind::Await(ast::ExprAwait { value }) + | ExprKind::YieldFrom(ast::ExprYieldFrom { value }) + | ExprKind::Attribute(ast::ExprAttribute { value, .. }) + | ExprKind::Starred(ast::ExprStarred { value, .. }) => any_over_expr(value, func), + ExprKind::Yield(ast::ExprYield { value }) => value .as_ref() .map_or(false, |value| any_over_expr(value, func)), - ExprKind::Compare { + ExprKind::Compare(ast::ExprCompare { left, comparators, .. - } => any_over_expr(left, func) || comparators.iter().any(|expr| any_over_expr(expr, func)), - ExprKind::Call { + }) => any_over_expr(left, func) || comparators.iter().any(|expr| any_over_expr(expr, func)), + ExprKind::Call(ast::ExprCall { func: call_func, args, keywords, - } => { + }) => { any_over_expr(call_func, func) || args.iter().any(|expr| any_over_expr(expr, func)) || keywords .iter() .any(|keyword| any_over_expr(&keyword.node.value, func)) } - ExprKind::FormattedValue { + ExprKind::FormattedValue(ast::ExprFormattedValue { value, format_spec, .. - } => { + }) => { any_over_expr(value, func) || format_spec .as_ref() .map_or(false, |value| any_over_expr(value, func)) } - ExprKind::Subscript { value, slice, .. } => { + ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => { any_over_expr(value, func) || any_over_expr(slice, func) } - ExprKind::Slice { lower, upper, step } => { + ExprKind::Slice(ast::ExprSlice { lower, upper, step }) => { lower .as_ref() .map_or(false, |value| any_over_expr(value, func)) @@ -230,7 +233,7 @@ where .as_ref() .map_or(false, |value| any_over_expr(value, func)) } - ExprKind::Name { .. } | ExprKind::Constant { .. } => false, + ExprKind::Name(_) | ExprKind::Constant(_) => false, } } @@ -239,23 +242,23 @@ where F: Fn(&Expr) -> bool, { match &pattern.node { - PatternKind::MatchValue { value } => any_over_expr(value, func), - PatternKind::MatchSingleton { .. } => false, - PatternKind::MatchSequence { patterns } => patterns + PatternKind::MatchValue(ast::PatternMatchValue { value }) => any_over_expr(value, func), + PatternKind::MatchSingleton(_) => false, + PatternKind::MatchSequence(ast::PatternMatchSequence { patterns }) => patterns .iter() .any(|pattern| any_over_pattern(pattern, func)), - PatternKind::MatchMapping { keys, patterns, .. } => { + PatternKind::MatchMapping(ast::PatternMatchMapping { keys, patterns, .. }) => { keys.iter().any(|key| any_over_expr(key, func)) || patterns .iter() .any(|pattern| any_over_pattern(pattern, func)) } - PatternKind::MatchClass { + PatternKind::MatchClass(ast::PatternMatchClass { cls, patterns, kwd_patterns, .. - } => { + }) => { any_over_expr(cls, func) || patterns .iter() @@ -264,11 +267,11 @@ where .iter() .any(|pattern| any_over_pattern(pattern, func)) } - PatternKind::MatchStar { .. } => false, - PatternKind::MatchAs { pattern, .. } => pattern + PatternKind::MatchStar(_) => false, + PatternKind::MatchAs(ast::PatternMatchAs { pattern, .. }) => pattern .as_ref() .map_or(false, |pattern| any_over_pattern(pattern, func)), - PatternKind::MatchOr { patterns } => patterns + PatternKind::MatchOr(ast::PatternMatchOr { patterns }) => patterns .iter() .any(|pattern| any_over_pattern(pattern, func)), } @@ -279,20 +282,20 @@ where F: Fn(&Expr) -> bool, { match &stmt.node { - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { args, body, decorator_list, returns, .. - } - | StmtKind::AsyncFunctionDef { + }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { args, body, decorator_list, returns, .. - } => { + }) => { args.defaults.iter().any(|expr| any_over_expr(expr, func)) || args .kw_defaults @@ -334,13 +337,13 @@ where .as_ref() .map_or(false, |value| any_over_expr(value, func)) } - StmtKind::ClassDef { + StmtKind::ClassDef(ast::StmtClassDef { bases, keywords, body, decorator_list, .. - } => { + }) => { bases.iter().any(|expr| any_over_expr(expr, func)) || keywords .iter() @@ -348,54 +351,57 @@ where || body.iter().any(|stmt| any_over_stmt(stmt, func)) || decorator_list.iter().any(|expr| any_over_expr(expr, func)) } - StmtKind::Return { value } => value + StmtKind::Return(ast::StmtReturn { value }) => value .as_ref() .map_or(false, |value| any_over_expr(value, func)), - StmtKind::Delete { targets } => targets.iter().any(|expr| any_over_expr(expr, func)), - StmtKind::Assign { targets, value, .. } => { + StmtKind::Delete(ast::StmtDelete { targets }) => { + targets.iter().any(|expr| any_over_expr(expr, func)) + } + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { targets.iter().any(|expr| any_over_expr(expr, func)) || any_over_expr(value, func) } - StmtKind::AugAssign { target, value, .. } => { + StmtKind::AugAssign(ast::StmtAugAssign { target, value, .. }) => { any_over_expr(target, func) || any_over_expr(value, func) } - StmtKind::AnnAssign { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, annotation, value, .. - } => { + }) => { any_over_expr(target, func) || any_over_expr(annotation, func) || value .as_ref() .map_or(false, |value| any_over_expr(value, func)) } - StmtKind::For { + StmtKind::For(ast::StmtFor { target, iter, body, orelse, .. - } - | StmtKind::AsyncFor { + }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { target, iter, body, orelse, .. - } => { + }) => { any_over_expr(target, func) || any_over_expr(iter, func) || any_over_body(body, func) || any_over_body(orelse, func) } - StmtKind::While { test, body, orelse } => { + StmtKind::While(ast::StmtWhile { test, body, orelse }) => { any_over_expr(test, func) || any_over_body(body, func) || any_over_body(orelse, func) } - StmtKind::If { test, body, orelse } => { + StmtKind::If(ast::StmtIf { test, body, orelse }) => { any_over_expr(test, func) || any_over_body(body, func) || any_over_body(orelse, func) } - StmtKind::With { items, body, .. } | StmtKind::AsyncWith { items, body, .. } => { + StmtKind::With(ast::StmtWith { items, body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => { items.iter().any(|withitem| { any_over_expr(&withitem.context_expr, func) || withitem @@ -404,28 +410,32 @@ where .map_or(false, |expr| any_over_expr(expr, func)) }) || any_over_body(body, func) } - StmtKind::Raise { exc, cause } => { + StmtKind::Raise(ast::StmtRaise { exc, cause }) => { exc.as_ref() .map_or(false, |value| any_over_expr(value, func)) || cause .as_ref() .map_or(false, |value| any_over_expr(value, func)) } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { any_over_body(body, func) || handlers.iter().any(|handler| { - let ExcepthandlerKind::ExceptHandler { type_, body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + type_, + body, + .. + }) = &handler.node; type_ .as_ref() .map_or(false, |expr| any_over_expr(expr, func)) @@ -434,13 +444,13 @@ where || any_over_body(orelse, func) || any_over_body(finalbody, func) } - StmtKind::Assert { test, msg } => { + StmtKind::Assert(ast::StmtAssert { test, msg }) => { any_over_expr(test, func) || msg .as_ref() .map_or(false, |value| any_over_expr(value, func)) } - StmtKind::Match { subject, cases } => { + StmtKind::Match(ast::StmtMatch { subject, cases }) => { any_over_expr(subject, func) || cases.iter().any(|case| { let MatchCase { @@ -455,11 +465,11 @@ where || any_over_body(body, func) }) } - StmtKind::Import { .. } => false, - StmtKind::ImportFrom { .. } => false, - StmtKind::Global { .. } => false, - StmtKind::Nonlocal { .. } => false, - StmtKind::Expr { value } => any_over_expr(value, func), + StmtKind::Import(_) => false, + StmtKind::ImportFrom(_) => false, + StmtKind::Global(_) => false, + StmtKind::Nonlocal(_) => false, + StmtKind::Expr(ast::StmtExpr { value }) => any_over_expr(value, func), StmtKind::Pass => false, StmtKind::Break => false, StmtKind::Continue => false, @@ -480,17 +490,17 @@ pub fn is_assignment_to_a_dunder(stmt: &Stmt) -> bool { // Check whether it's an assignment to a dunder, with or without a type // annotation. This is what pycodestyle (as of 2.9.1) does. match &stmt.node { - StmtKind::Assign { targets, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, .. }) => { if targets.len() != 1 { return false; } match &targets[0].node { - ExprKind::Name { id, .. } => DUNDER_REGEX.is_match(id), + ExprKind::Name(ast::ExprName { id, .. }) => DUNDER_REGEX.is_match(id.as_str()), _ => false, } } - StmtKind::AnnAssign { target, .. } => match &target.node { - ExprKind::Name { id, .. } => DUNDER_REGEX.is_match(id), + StmtKind::AnnAssign(ast::StmtAnnAssign { target, .. }) => match &target.node { + ExprKind::Name(ast::ExprName { id, .. }) => DUNDER_REGEX.is_match(id.as_str()), _ => false, }, _ => false, @@ -502,18 +512,18 @@ pub fn is_assignment_to_a_dunder(stmt: &Stmt) -> bool { pub const fn is_singleton(expr: &Expr) -> bool { matches!( expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None | Constant::Bool(_) | Constant::Ellipsis, .. - } + }) ) } /// Return `true` if the [`Expr`] is a constant or tuple of constants. pub fn is_constant(expr: &Expr) -> bool { match &expr.node { - ExprKind::Constant { .. } => true, - ExprKind::Tuple { elts, .. } => elts.iter().all(is_constant), + ExprKind::Constant(_) => true, + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().all(is_constant), _ => false, } } @@ -536,10 +546,10 @@ pub fn find_keyword<'a>(keywords: &'a [Keyword], keyword_name: &str) -> Option<& pub const fn is_const_none(expr: &Expr) -> bool { matches!( &expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::None, kind: None - }, + }), ) } @@ -547,10 +557,10 @@ pub const fn is_const_none(expr: &Expr) -> bool { pub const fn is_const_true(expr: &Expr) -> bool { matches!( &expr.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Bool(true), kind: None - }, + }), ) } @@ -567,9 +577,9 @@ pub fn extract_handled_exceptions(handlers: &[Excepthandler]) -> Vec<&Expr> { let mut handled_exceptions = Vec::new(); for handler in handlers { match &handler.node { - ExcepthandlerKind::ExceptHandler { type_, .. } => { + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) => { if let Some(type_) = type_ { - if let ExprKind::Tuple { elts, .. } = &type_.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &type_.node { for type_ in elts { handled_exceptions.push(type_); } @@ -608,7 +618,7 @@ pub fn collect_arg_names<'a>(arguments: &'a Arguments) -> FxHashSet<&'a str> { /// be used with or without explicit call syntax), return the underlying /// callable. pub fn map_callable(decorator: &Expr) -> &Expr { - if let ExprKind::Call { func, .. } = &decorator.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &decorator.node { func } else { decorator @@ -616,7 +626,7 @@ pub fn map_callable(decorator: &Expr) -> &Expr { } /// Returns `true` if a statement or expression includes at least one comment. -pub fn has_comments(located: &Located, locator: &Locator) -> bool { +pub fn has_comments(located: &Attributed, locator: &Locator) -> bool { let start = if has_leading_content(located, locator) { located.start() } else { @@ -635,7 +645,7 @@ pub fn has_comments(located: &Located, locator: &Locator) -> bool { pub fn has_comments_in(range: TextRange, locator: &Locator) -> bool { let source = &locator.contents()[range]; - for tok in lexer::lex_located(source, Mode::Module, range.start()) { + for tok in lexer::lex_starts_at(source, Mode::Module, range.start()) { match tok { Ok((tok, _)) => { if matches!(tok, Tok::Comment(..)) { @@ -658,8 +668,8 @@ where F: Fn(&str) -> bool, { any_over_body(body, &|expr| { - if let ExprKind::Call { func, .. } = &expr.node { - if let ExprKind::Name { id, .. } = &func.node { + if let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { if matches!(id.as_str(), "locals" | "globals" | "vars" | "exec" | "eval") { if is_builtin(id.as_str()) { return true; @@ -682,7 +692,7 @@ where /// assert_eq!(format_import_from(Some(1), None), ".".to_string()); /// assert_eq!(format_import_from(Some(1), Some("foo")), ".foo".to_string()); /// ``` -pub fn format_import_from(level: Option, module: Option<&str>) -> String { +pub fn format_import_from(level: Option, module: Option<&str>) -> String { let mut module_name = String::with_capacity(16); if let Some(level) = level { for _ in 0..level { @@ -706,13 +716,9 @@ pub fn format_import_from(level: Option, module: Option<&str>) -> String /// assert_eq!(format_import_from_member(Some(1), None, "bar"), ".bar".to_string()); /// assert_eq!(format_import_from_member(Some(1), Some("foo"), "bar"), ".foo.bar".to_string()); /// ``` -pub fn format_import_from_member( - level: Option, - module: Option<&str>, - member: &str, -) -> String { +pub fn format_import_from_member(level: Option, module: Option<&str>, member: &str) -> String { let mut full_name = String::with_capacity( - level.map_or(0, |level| level) + (level.unwrap_or(0) as usize) + module.as_ref().map_or(0, |module| module.len()) + 1 + member.len(), @@ -785,7 +791,7 @@ pub fn from_relative_import<'a>(module: &'a [String], name: &'a str) -> CallPath /// Given an imported module (based on its relative import level and module name), return the /// fully-qualified module path. pub fn resolve_imported_module_path<'a>( - level: Option, + level: Option, module: Option<&'a str>, module_path: Option<&[String]>, ) -> Option> { @@ -801,11 +807,11 @@ pub fn resolve_imported_module_path<'a>( return None; }; - if level >= module_path.len() { + if level as usize >= module_path.len() { return None; } - let mut qualified_path = module_path[..module_path.len() - level].join("."); + let mut qualified_path = module_path[..module_path.len() - level as usize].join("."); if let Some(module) = module { if !qualified_path.is_empty() { qualified_path.push('.'); @@ -827,10 +833,10 @@ where { fn visit_stmt(&mut self, stmt: &'b Stmt) { match &stmt.node { - StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) => { // Don't recurse. } - StmtKind::Return { value } => self.returns.push(value.as_deref()), + StmtKind::Return(ast::StmtReturn { value }) => self.returns.push(value.as_deref()), _ => walk_stmt(self, stmt), } } @@ -848,27 +854,27 @@ where { fn visit_stmt(&mut self, stmt: &'b Stmt) { match &stmt.node { - StmtKind::Raise { exc, cause } => { + StmtKind::Raise(ast::StmtRaise { exc, cause }) => { self.raises .push((stmt.range(), exc.as_deref(), cause.as_deref())); } - StmtKind::ClassDef { .. } - | StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } - | StmtKind::Try { .. } - | StmtKind::TryStar { .. } => {} - StmtKind::If { body, orelse, .. } => { + StmtKind::ClassDef(_) + | StmtKind::FunctionDef(_) + | StmtKind::AsyncFunctionDef(_) + | StmtKind::Try(_) + | StmtKind::TryStar(_) => {} + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { walk_body(self, body); walk_body(self, orelse); } - StmtKind::While { body, .. } - | StmtKind::With { body, .. } - | StmtKind::AsyncWith { body, .. } - | StmtKind::For { body, .. } - | StmtKind::AsyncFor { body, .. } => { + StmtKind::While(ast::StmtWhile { body, .. }) + | StmtKind::With(ast::StmtWith { body, .. }) + | StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) + | StmtKind::For(ast::StmtFor { body, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { body, .. }) => { walk_body(self, body); } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { for case in cases { walk_body(self, &case.body); } @@ -886,14 +892,12 @@ struct GlobalStatementVisitor<'a> { impl<'a> StatementVisitor<'a> for GlobalStatementVisitor<'a> { fn visit_stmt(&mut self, stmt: &'a Stmt) { match &stmt.node { - StmtKind::Global { names } => { + StmtKind::Global(ast::StmtGlobal { names }) => { for name in names { - self.globals.insert(name, stmt); + self.globals.insert(name.as_str(), stmt); } } - StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } - | StmtKind::ClassDef { .. } => { + StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) | StmtKind::ClassDef(_) => { // Don't recurse. } _ => walk_stmt(self, stmt), @@ -910,15 +914,15 @@ pub fn extract_globals(body: &[Stmt]) -> FxHashMap<&str, &Stmt> { visitor.globals } -/// Return `true` if a [`Located`] has leading content. -pub fn has_leading_content(located: &Located, locator: &Locator) -> bool { +/// Return `true` if a [`Attributed`] has leading content. +pub fn has_leading_content(located: &Attributed, locator: &Locator) -> bool { let line_start = locator.line_start(located.start()); let leading = &locator.contents()[TextRange::new(line_start, located.start())]; leading.chars().any(|char| !char.is_whitespace()) } -/// Return `true` if a [`Located`] has trailing content. -pub fn has_trailing_content(located: &Located, locator: &Locator) -> bool { +/// Return `true` if a [`Attributed`] has trailing content. +pub fn has_trailing_content(located: &Attributed, locator: &Locator) -> bool { let line_end = locator.line_end(located.end()); let trailing = &locator.contents()[TextRange::new(located.end(), line_end)]; @@ -933,9 +937,9 @@ pub fn has_trailing_content(located: &Located, locator: &Locator) -> bool false } -/// If a [`Located`] has a trailing comment, return the index of the hash. +/// If a [`Attributed`] has a trailing comment, return the index of the hash. pub fn trailing_comment_start_offset( - located: &Located, + located: &Attributed, locator: &Locator, ) -> Option { let line_end = locator.line_end(located.end()); @@ -973,7 +977,7 @@ pub fn match_parens(start: TextSize, locator: &Locator) -> Option { let mut fix_end = None; let mut count: usize = 0; - for (tok, range) in lexer::lex_located(contents, Mode::Module, start).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, start).flatten() { match tok { Tok::Lpar => { if count == 0 { @@ -1004,13 +1008,11 @@ pub fn match_parens(start: TextSize, locator: &Locator) -> Option { pub fn identifier_range(stmt: &Stmt, locator: &Locator) -> TextRange { if matches!( stmt.node, - StmtKind::ClassDef { .. } - | StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } + StmtKind::ClassDef(_) | StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) ) { let contents = &locator.contents()[stmt.range()]; - for (tok, range) in lexer::lex_located(contents, Mode::Module, stmt.start()).flatten() { + for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, stmt.start()).flatten() { if matches!(tok, Tok::Name { .. }) { return range; } @@ -1023,12 +1025,12 @@ pub fn identifier_range(stmt: &Stmt, locator: &Locator) -> TextRange { /// Return the ranges of [`Tok::Name`] tokens within a specified node. pub fn find_names<'a, T>( - located: &'a Located, + located: &'a Attributed, locator: &'a Locator, ) -> impl Iterator + 'a { let contents = locator.slice(located.range()); - lexer::lex_located(contents, Mode::Module, located.start()) + lexer::lex_starts_at(contents, Mode::Module, located.start()) .flatten() .filter(|(tok, _)| matches!(tok, Tok::Name { .. })) .map(|(_, range)| range) @@ -1036,15 +1038,14 @@ pub fn find_names<'a, T>( /// Return the `Range` of `name` in `Excepthandler`. pub fn excepthandler_name_range(handler: &Excepthandler, locator: &Locator) -> Option { - let ExcepthandlerKind::ExceptHandler { - name, type_, body, .. - } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { name, type_, body }) = + &handler.node; match (name, type_) { (Some(_), Some(type_)) => { let contents = &locator.contents()[TextRange::new(type_.end(), body[0].start())]; - lexer::lex_located(contents, Mode::Module, type_.end()) + lexer::lex_starts_at(contents, Mode::Module, type_.end()) .flatten() .tuple_windows() .find(|(tok, next_tok)| { @@ -1058,7 +1059,8 @@ pub fn excepthandler_name_range(handler: &Excepthandler, locator: &Locator) -> O /// Return the `Range` of `except` in `Excepthandler`. pub fn except_range(handler: &Excepthandler, locator: &Locator) -> TextRange { - let ExcepthandlerKind::ExceptHandler { body, type_, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { body, type_, .. }) = + &handler.node; let end = if let Some(type_) = type_ { type_.end() } else { @@ -1066,7 +1068,7 @@ pub fn except_range(handler: &Excepthandler, locator: &Locator) -> TextRange { }; let contents = &locator.contents()[TextRange::new(handler.start(), end)]; - lexer::lex_located(contents, Mode::Module, handler.start()) + lexer::lex_starts_at(contents, Mode::Module, handler.start()) .flatten() .find(|(kind, _)| matches!(kind, Tok::Except { .. })) .map(|(_, range)| range) @@ -1076,9 +1078,9 @@ pub fn except_range(handler: &Excepthandler, locator: &Locator) -> TextRange { /// Return the `Range` of `else` in `For`, `AsyncFor`, and `While` statements. pub fn else_range(stmt: &Stmt, locator: &Locator) -> Option { match &stmt.node { - StmtKind::For { body, orelse, .. } - | StmtKind::AsyncFor { body, orelse, .. } - | StmtKind::While { body, orelse, .. } + StmtKind::For(ast::StmtFor { body, orelse, .. }) + | StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. }) + | StmtKind::While(ast::StmtWhile { body, orelse, .. }) if !orelse.is_empty() => { let body_end = body.last().expect("Expected body to be non-empty").end(); @@ -1088,7 +1090,7 @@ pub fn else_range(stmt: &Stmt, locator: &Locator) -> Option { .start(); let contents = &locator.contents()[TextRange::new(body_end, or_else_start)]; - lexer::lex_located(contents, Mode::Module, body_end) + lexer::lex_starts_at(contents, Mode::Module, body_end) .flatten() .find(|(kind, _)| matches!(kind, Tok::Else)) .map(|(_, range)| range) @@ -1100,7 +1102,7 @@ pub fn else_range(stmt: &Stmt, locator: &Locator) -> Option { /// Return the `Range` of the first `Tok::Colon` token in a `Range`. pub fn first_colon_range(range: TextRange, locator: &Locator) -> Option { let contents = &locator.contents()[range]; - let range = lexer::lex_located(contents, Mode::Module, range.start()) + let range = lexer::lex_starts_at(contents, Mode::Module, range.start()) .flatten() .find(|(kind, _)| matches!(kind, Tok::Colon)) .map(|(_, range)| range); @@ -1109,7 +1111,7 @@ pub fn first_colon_range(range: TextRange, locator: &Locator) -> Option Option { - let StmtKind::If { body, orelse, .. } = &stmt.node else { + let StmtKind::If(ast::StmtIf { body, orelse, .. } )= &stmt.node else { return None; }; @@ -1117,7 +1119,7 @@ pub fn elif_else_range(stmt: &Stmt, locator: &Locator) -> Option { let end = match &orelse[..] { [Stmt { - node: StmtKind::If { test, .. }, + node: StmtKind::If(ast::StmtIf { test, .. }), .. }] => test.start(), [stmt, ..] => stmt.start(), @@ -1125,7 +1127,7 @@ pub fn elif_else_range(stmt: &Stmt, locator: &Locator) -> Option { }; let contents = &locator.contents()[TextRange::new(start, end)]; - lexer::lex_located(contents, Mode::Module, start) + lexer::lex_starts_at(contents, Mode::Module, start) .flatten() .find(|(kind, _)| matches!(kind, Tok::Elif | Tok::Else)) .map(|(_, range)| range) @@ -1174,13 +1176,13 @@ pub fn followed_by_multi_statement_line(stmt: &Stmt, locator: &Locator) -> bool /// Return `true` if a `Stmt` is a docstring. pub const fn is_docstring_stmt(stmt: &Stmt) -> bool { - if let StmtKind::Expr { value } = &stmt.node { + if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node { matches!( value.node, - ExprKind::Constant { + ExprKind::Constant(ast::ExprConstant { value: Constant::Str { .. }, .. - } + }) ) } else { false @@ -1201,14 +1203,14 @@ impl<'a> SimpleCallArgs<'a> { ) -> Self { let args = args .into_iter() - .take_while(|arg| !matches!(arg.node, ExprKind::Starred { .. })) + .take_while(|arg| !matches!(arg.node, ExprKind::Starred(_))) .collect(); let kwargs = keywords .into_iter() .filter_map(|keyword| { let node = &keyword.node; - node.arg.as_ref().map(|arg| (arg.as_ref(), &node.value)) + node.arg.as_ref().map(|arg| (arg.as_str(), &node.value)) }) .collect(); @@ -1246,12 +1248,12 @@ pub fn on_conditional_branch<'a>(parents: &mut impl Iterator) - parents.any(|parent| { if matches!( parent.node, - StmtKind::If { .. } | StmtKind::While { .. } | StmtKind::Match { .. } + StmtKind::If(_) | StmtKind::While(_) | StmtKind::Match(_) ) { return true; } - if let StmtKind::Expr { value } = &parent.node { - if matches!(value.node, ExprKind::IfExp { .. }) { + if let StmtKind::Expr(ast::StmtExpr { value }) = &parent.node { + if matches!(value.node, ExprKind::IfExp(_)) { return true; } } @@ -1264,11 +1266,11 @@ pub fn in_nested_block<'a>(mut parents: impl Iterator) -> bool parents.any(|parent| { matches!( parent.node, - StmtKind::Try { .. } - | StmtKind::TryStar { .. } - | StmtKind::If { .. } - | StmtKind::With { .. } - | StmtKind::Match { .. } + StmtKind::Try(_) + | StmtKind::TryStar(_) + | StmtKind::If(_) + | StmtKind::With(_) + | StmtKind::Match(_) ) }) } @@ -1276,9 +1278,9 @@ pub fn in_nested_block<'a>(mut parents: impl Iterator) -> bool /// Check if a node represents an unpacking assignment. pub fn is_unpacking_assignment(parent: &Stmt, child: &Expr) -> bool { match &parent.node { - StmtKind::With { items, .. } => items.iter().any(|item| { + StmtKind::With(ast::StmtWith { items, .. }) => items.iter().any(|item| { if let Some(optional_vars) = &item.optional_vars { - if matches!(optional_vars.node, ExprKind::Tuple { .. }) { + if matches!(optional_vars.node, ExprKind::Tuple(_)) { if any_over_expr(optional_vars, &|expr| expr == child) { return true; } @@ -1286,11 +1288,11 @@ pub fn is_unpacking_assignment(parent: &Stmt, child: &Expr) -> bool { } false }), - StmtKind::Assign { targets, value, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { // In `(a, b) = (1, 2)`, `(1, 2)` is the target, and it is a tuple. let value_is_tuple = matches!( &value.node, - ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. } + ExprKind::Set(_) | ExprKind::List(_) | ExprKind::Tuple(_) ); // In `(a, b) = coords = (1, 2)`, `(a, b)` and `coords` are the targets, and // `(a, b)` is a tuple. (We use "tuple" as a placeholder for any @@ -1298,7 +1300,7 @@ pub fn is_unpacking_assignment(parent: &Stmt, child: &Expr) -> bool { let targets_are_tuples = targets.iter().all(|item| { matches!( item.node, - ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. } + ExprKind::Set(_) | ExprKind::List(_) | ExprKind::Tuple(_) ) }); // If we're looking at `a` in `(a, b) = coords = (1, 2)`, then we should @@ -1307,7 +1309,7 @@ pub fn is_unpacking_assignment(parent: &Stmt, child: &Expr) -> bool { || targets.iter().any(|item| { matches!( item.node, - ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. } + ExprKind::Set(_) | ExprKind::List(_) | ExprKind::Tuple(_) ) && any_over_expr(item, &|expr| expr == child) }); @@ -1338,7 +1340,7 @@ pub fn is_unpacking_assignment(parent: &Stmt, child: &Expr) -> bool { } } -pub type LocatedCmpop = Located; +pub type AttributedCmpop = Attributed; /// Extract all [`Cmpop`] operators from a source code snippet, with appropriate /// ranges. @@ -1346,9 +1348,9 @@ pub type LocatedCmpop = Located; /// `RustPython` doesn't include line and column information on [`Cmpop`] nodes. /// `CPython` doesn't either. This method iterates over the token stream and /// re-identifies [`Cmpop`] nodes, annotating them with valid ranges. -pub fn locate_cmpops(contents: &str) -> Vec { +pub fn locate_cmpops(contents: &str) -> Vec { let mut tok_iter = lexer::lex(contents, Mode::Module).flatten().peekable(); - let mut ops: Vec = vec![]; + let mut ops: Vec = vec![]; let mut count: usize = 0; loop { let Some((tok, range)) = tok_iter.next() else { @@ -1367,43 +1369,42 @@ pub fn locate_cmpops(contents: &str) -> Vec { if let Some((_, next_range)) = tok_iter.next_if(|(tok, _)| matches!(tok, Tok::In)) { - ops.push(LocatedCmpop::new( - range.start(), - next_range.end(), + ops.push(AttributedCmpop::new( + range.start()..next_range.end(), Cmpop::NotIn, )); } } Tok::In => { - ops.push(LocatedCmpop::with_range(Cmpop::In, range)); + ops.push(AttributedCmpop::new(range, Cmpop::In)); } Tok::Is => { let op = if let Some((_, next_range)) = tok_iter.next_if(|(tok, _)| matches!(tok, Tok::Not)) { - LocatedCmpop::new(range.start(), next_range.end(), Cmpop::IsNot) + AttributedCmpop::new(range.start()..next_range.end(), Cmpop::IsNot) } else { - LocatedCmpop::with_range(Cmpop::Is, range) + AttributedCmpop::new(range, Cmpop::Is) }; ops.push(op); } Tok::NotEqual => { - ops.push(LocatedCmpop::with_range(Cmpop::NotEq, range)); + ops.push(AttributedCmpop::new(range, Cmpop::NotEq)); } Tok::EqEqual => { - ops.push(LocatedCmpop::with_range(Cmpop::Eq, range)); + ops.push(AttributedCmpop::new(range, Cmpop::Eq)); } Tok::GreaterEqual => { - ops.push(LocatedCmpop::with_range(Cmpop::GtE, range)); + ops.push(AttributedCmpop::new(range, Cmpop::GtE)); } Tok::Greater => { - ops.push(LocatedCmpop::with_range(Cmpop::Gt, range)); + ops.push(AttributedCmpop::new(range, Cmpop::Gt)); } Tok::LessEqual => { - ops.push(LocatedCmpop::with_range(Cmpop::LtE, range)); + ops.push(AttributedCmpop::new(range, Cmpop::LtE)); } Tok::Less => { - ops.push(LocatedCmpop::with_range(Cmpop::Lt, range)); + ops.push(AttributedCmpop::new(range, Cmpop::Lt)); } _ => {} } @@ -1448,7 +1449,7 @@ impl Truthiness { F: Fn(&str) -> bool, { match &expr.node { - ExprKind::Constant { value, .. } => match value { + ExprKind::Constant(ast::ExprConstant { value, .. }) => match value { Constant::Bool(value) => Some(*value), Constant::None => Some(false), Constant::Str(string) => Some(!string.is_empty()), @@ -1459,11 +1460,11 @@ impl Truthiness { Constant::Ellipsis => Some(true), Constant::Tuple(elts) => Some(!elts.is_empty()), }, - ExprKind::JoinedStr { values, .. } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { if values.is_empty() { Some(false) } else if values.iter().any(|value| { - let ExprKind::Constant { value: Constant::Str(string), .. } = &value.node else { + let ExprKind::Constant(ast::ExprConstant { value: Constant::Str(string), .. } )= &value.node else { return false; }; !string.is_empty() @@ -1473,16 +1474,16 @@ impl Truthiness { None } } - ExprKind::List { elts, .. } - | ExprKind::Set { elts, .. } - | ExprKind::Tuple { elts, .. } => Some(!elts.is_empty()), - ExprKind::Dict { keys, .. } => Some(!keys.is_empty()), - ExprKind::Call { + ExprKind::List(ast::ExprList { elts, .. }) + | ExprKind::Set(ast::ExprSet { elts }) + | ExprKind::Tuple(ast::ExprTuple { elts, .. }) => Some(!elts.is_empty()), + ExprKind::Dict(ast::ExprDict { keys, .. }) => Some(!keys.is_empty()), + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { - if let ExprKind::Name { id, .. } = &func.node { + }) => { + if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node { if is_iterable_initializer(id.as_str(), |id| is_builtin(id)) { if args.is_empty() && keywords.is_empty() { Some(false) @@ -1515,7 +1516,7 @@ mod tests { use crate::helpers::{ elif_else_range, else_range, first_colon_range, has_trailing_content, identifier_range, - locate_cmpops, resolve_imported_module_path, LocatedCmpop, + locate_cmpops, resolve_imported_module_path, AttributedCmpop, }; use crate::source_code::Locator; @@ -1735,63 +1736,56 @@ else: fn extract_cmpop_location() { assert_eq!( locate_cmpops("x == 1"), - vec![LocatedCmpop::new( - TextSize::from(2), - TextSize::from(4), + vec![AttributedCmpop::new( + TextSize::from(2)..TextSize::from(4), Cmpop::Eq )] ); assert_eq!( locate_cmpops("x != 1"), - vec![LocatedCmpop::new( - TextSize::from(2), - TextSize::from(4), + vec![AttributedCmpop::new( + TextSize::from(2)..TextSize::from(4), Cmpop::NotEq )] ); assert_eq!( locate_cmpops("x is 1"), - vec![LocatedCmpop::new( - TextSize::from(2), - TextSize::from(4), + vec![AttributedCmpop::new( + TextSize::from(2)..TextSize::from(4), Cmpop::Is )] ); assert_eq!( locate_cmpops("x is not 1"), - vec![LocatedCmpop::new( - TextSize::from(2), - TextSize::from(8), + vec![AttributedCmpop::new( + TextSize::from(2)..TextSize::from(8), Cmpop::IsNot )] ); assert_eq!( locate_cmpops("x in 1"), - vec![LocatedCmpop::new( - TextSize::from(2), - TextSize::from(4), + vec![AttributedCmpop::new( + TextSize::from(2)..TextSize::from(4), Cmpop::In )] ); assert_eq!( locate_cmpops("x not in 1"), - vec![LocatedCmpop::new( - TextSize::from(2), - TextSize::from(8), + vec![AttributedCmpop::new( + TextSize::from(2)..TextSize::from(8), Cmpop::NotIn )] ); assert_eq!( locate_cmpops("x != (1 is not 2)"), - vec![LocatedCmpop::new( - TextSize::from(2), - TextSize::from(4), + vec![AttributedCmpop::new( + TextSize::from(2)..TextSize::from(4), Cmpop::NotEq )] ); diff --git a/crates/ruff_python_ast/src/imports.rs b/crates/ruff_python_ast/src/imports.rs index f3913d225d..3b92b8c067 100644 --- a/crates/ruff_python_ast/src/imports.rs +++ b/crates/ruff_python_ast/src/imports.rs @@ -22,7 +22,7 @@ pub struct Import<'a> { pub struct ImportFrom<'a> { pub module: Option<&'a str>, pub name: Alias<'a>, - pub level: Option, + pub level: Option, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -65,7 +65,7 @@ impl std::fmt::Display for ImportFrom<'_> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "from ")?; if let Some(level) = self.level { - write!(f, "{}", ".".repeat(level))?; + write!(f, "{}", ".".repeat(level as usize))?; } if let Some(module) = self.module { write!(f, "{module}")?; diff --git a/crates/ruff_python_ast/src/relocate.rs b/crates/ruff_python_ast/src/relocate.rs index a618105f1a..c4c40eb724 100644 --- a/crates/ruff_python_ast/src/relocate.rs +++ b/crates/ruff_python_ast/src/relocate.rs @@ -1,5 +1,5 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::{Expr, ExprKind, Keyword}; +use rustpython_parser::ast::{self, Expr, ExprKind, Keyword}; fn relocate_keyword(keyword: &mut Keyword, location: TextRange) { keyword.range = location; @@ -11,31 +11,31 @@ fn relocate_keyword(keyword: &mut Keyword, location: TextRange) { pub fn relocate_expr(expr: &mut Expr, location: TextRange) { expr.range = location; match &mut expr.node { - ExprKind::BoolOp { values, .. } => { + ExprKind::BoolOp(ast::ExprBoolOp { values, .. }) => { for expr in values { relocate_expr(expr, location); } } - ExprKind::NamedExpr { target, value } => { + ExprKind::NamedExpr(ast::ExprNamedExpr { target, value }) => { relocate_expr(target, location); relocate_expr(value, location); } - ExprKind::BinOp { left, right, .. } => { + ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) => { relocate_expr(left, location); relocate_expr(right, location); } - ExprKind::UnaryOp { operand, .. } => { + ExprKind::UnaryOp(ast::ExprUnaryOp { operand, .. }) => { relocate_expr(operand, location); } - ExprKind::Lambda { body, .. } => { + ExprKind::Lambda(ast::ExprLambda { body, .. }) => { relocate_expr(body, location); } - ExprKind::IfExp { test, body, orelse } => { + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { relocate_expr(test, location); relocate_expr(body, location); relocate_expr(orelse, location); } - ExprKind::Dict { keys, values } => { + ExprKind::Dict(ast::ExprDict { keys, values }) => { for expr in keys.iter_mut().flatten() { relocate_expr(expr, location); } @@ -43,44 +43,44 @@ pub fn relocate_expr(expr: &mut Expr, location: TextRange) { relocate_expr(expr, location); } } - ExprKind::Set { elts } => { + ExprKind::Set(ast::ExprSet { elts }) => { for expr in elts { relocate_expr(expr, location); } } - ExprKind::ListComp { elt, .. } => { + ExprKind::ListComp(ast::ExprListComp { elt, .. }) => { relocate_expr(elt, location); } - ExprKind::SetComp { elt, .. } => { + ExprKind::SetComp(ast::ExprSetComp { elt, .. }) => { relocate_expr(elt, location); } - ExprKind::DictComp { key, value, .. } => { + ExprKind::DictComp(ast::ExprDictComp { key, value, .. }) => { relocate_expr(key, location); relocate_expr(value, location); } - ExprKind::GeneratorExp { elt, .. } => { + ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, .. }) => { relocate_expr(elt, location); } - ExprKind::Await { value } => relocate_expr(value, location), - ExprKind::Yield { value } => { + ExprKind::Await(ast::ExprAwait { value }) => relocate_expr(value, location), + ExprKind::Yield(ast::ExprYield { value }) => { if let Some(expr) = value { relocate_expr(expr, location); } } - ExprKind::YieldFrom { value } => relocate_expr(value, location), - ExprKind::Compare { + ExprKind::YieldFrom(ast::ExprYieldFrom { value }) => relocate_expr(value, location), + ExprKind::Compare(ast::ExprCompare { left, comparators, .. - } => { + }) => { relocate_expr(left, location); for expr in comparators { relocate_expr(expr, location); } } - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { + }) => { relocate_expr(func, location); for expr in args { relocate_expr(expr, location); @@ -89,42 +89,42 @@ pub fn relocate_expr(expr: &mut Expr, location: TextRange) { relocate_keyword(keyword, location); } } - ExprKind::FormattedValue { + ExprKind::FormattedValue(ast::ExprFormattedValue { value, format_spec, .. - } => { + }) => { relocate_expr(value, location); if let Some(expr) = format_spec { relocate_expr(expr, location); } } - ExprKind::JoinedStr { values } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { for expr in values { relocate_expr(expr, location); } } - ExprKind::Constant { .. } => {} - ExprKind::Attribute { value, .. } => { + ExprKind::Constant(_) => {} + ExprKind::Attribute(ast::ExprAttribute { value, .. }) => { relocate_expr(value, location); } - ExprKind::Subscript { value, slice, .. } => { + ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => { relocate_expr(value, location); relocate_expr(slice, location); } - ExprKind::Starred { value, .. } => { + ExprKind::Starred(ast::ExprStarred { value, .. }) => { relocate_expr(value, location); } - ExprKind::Name { .. } => {} - ExprKind::List { elts, .. } => { + ExprKind::Name(_) => {} + ExprKind::List(ast::ExprList { elts, .. }) => { for expr in elts { relocate_expr(expr, location); } } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { for expr in elts { relocate_expr(expr, location); } } - ExprKind::Slice { lower, upper, step } => { + ExprKind::Slice(ast::ExprSlice { lower, upper, step }) => { if let Some(expr) = lower { relocate_expr(expr, location); } diff --git a/crates/ruff_python_ast/src/source_code/generator.rs b/crates/ruff_python_ast/src/source_code/generator.rs index f1e4bf7f84..d9b4de2cd5 100644 --- a/crates/ruff_python_ast/src/source_code/generator.rs +++ b/crates/ruff_python_ast/src/source_code/generator.rs @@ -2,15 +2,14 @@ use std::ops::Deref; +use rustpython_literal::escape::{AsciiEscape, Escape, UnicodeEscape}; use rustpython_parser::ast::{ - Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, Excepthandler, - ExcepthandlerKind, Expr, ExprKind, MatchCase, Operator, Pattern, PatternKind, Stmt, StmtKind, - Suite, Withitem, + self, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, ConversionFlag, + Excepthandler, ExcepthandlerKind, Expr, ExprKind, Identifier, Int, MatchCase, Operator, + Pattern, PatternKind, Stmt, StmtKind, Suite, Withitem, }; -use rustpython_parser::ConversionFlag; use crate::newlines::LineEnding; -use ruff_rustpython::vendor::{bytes, str}; use crate::source_code::stylist::{Indentation, Quote, Stylist}; @@ -137,6 +136,26 @@ impl<'a> Generator<'a> { self.buffer += s; } + fn p_id(&mut self, s: &Identifier) { + self.p(s.as_str()); + } + + fn p_bytes_repr(&mut self, s: &[u8]) { + let escape = AsciiEscape::with_preferred_quote(s, self.quote.into()); + if let Some(len) = escape.layout().len { + self.buffer.reserve(len); + } + escape.bytes_repr().write(&mut self.buffer).unwrap(); // write to string doesn't fail + } + + fn p_str_repr(&mut self, s: &str) { + let escape = UnicodeEscape::with_preferred_quote(s, self.quote.into()); + if let Some(len) = escape.layout().len { + self.buffer.reserve(len); + } + escape.str_repr().write(&mut self.buffer).unwrap(); // write to string doesn't fail + } + fn p_if(&mut self, cond: bool, s: &str) { if cond { self.p(s); @@ -164,14 +183,14 @@ impl<'a> Generator<'a> { } match &ast.node { - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, args, body, returns, decorator_list, .. - } => { + }) => { self.newlines(if self.indent_depth == 0 { 2 } else { 1 }); statement!({ for decorator in decorator_list { @@ -182,7 +201,7 @@ impl<'a> Generator<'a> { } self.newline(); self.p("def "); - self.p(name); + self.p_id(name); self.p("("); self.unparse_args(args); self.p(")"); @@ -197,14 +216,14 @@ impl<'a> Generator<'a> { self.newlines(2); } } - StmtKind::AsyncFunctionDef { + StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, args, body, returns, decorator_list, .. - } => { + }) => { self.newlines(if self.indent_depth == 0 { 2 } else { 1 }); statement!({ for decorator in decorator_list { @@ -214,7 +233,7 @@ impl<'a> Generator<'a> { } self.newline(); self.p("async def "); - self.p(name); + self.p_id(name); self.p("("); self.unparse_args(args); self.p(")"); @@ -229,14 +248,13 @@ impl<'a> Generator<'a> { self.newlines(2); } } - StmtKind::ClassDef { + StmtKind::ClassDef(ast::StmtClassDef { name, bases, keywords, body, decorator_list, - .. - } => { + }) => { self.newlines(if self.indent_depth == 0 { 2 } else { 1 }); statement!({ for decorator in decorator_list { @@ -246,7 +264,7 @@ impl<'a> Generator<'a> { } self.newline(); self.p("class "); - self.p(name); + self.p_id(name); let mut first = true; for base in bases { self.p_if(first, "("); @@ -257,7 +275,7 @@ impl<'a> Generator<'a> { self.p_if(first, "("); self.p_delim(&mut first, ", "); if let Some(arg) = &keyword.node.arg { - self.p(arg); + self.p_id(arg); self.p("="); } else { self.p("**"); @@ -272,7 +290,7 @@ impl<'a> Generator<'a> { self.newlines(2); } } - StmtKind::Return { value } => { + StmtKind::Return(ast::StmtReturn { value }) => { statement!({ if let Some(expr) = value { self.p("return "); @@ -282,7 +300,7 @@ impl<'a> Generator<'a> { } }); } - StmtKind::Delete { targets } => { + StmtKind::Delete(ast::StmtDelete { targets }) => { statement!({ self.p("del "); let mut first = true; @@ -292,7 +310,7 @@ impl<'a> Generator<'a> { } }); } - StmtKind::Assign { targets, value, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { statement!({ for target in targets { self.unparse_expr(target, precedence::ASSIGN); @@ -301,7 +319,7 @@ impl<'a> Generator<'a> { self.unparse_expr(value, precedence::ASSIGN); }); } - StmtKind::AugAssign { target, op, value } => { + StmtKind::AugAssign(ast::StmtAugAssign { target, op, value }) => { statement!({ self.unparse_expr(target, precedence::AUG_ASSIGN); self.p(" "); @@ -324,14 +342,14 @@ impl<'a> Generator<'a> { self.unparse_expr(value, precedence::AUG_ASSIGN); }); } - StmtKind::AnnAssign { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, annotation, value, simple, - } => { + }) => { statement!({ - let need_parens = matches!(target.node, ExprKind::Name { .. }) && simple == &0; + let need_parens = matches!(target.node, ExprKind::Name(_)) && !simple; self.p_if(need_parens, "("); self.unparse_expr(target, precedence::ANN_ASSIGN); self.p_if(need_parens, ")"); @@ -343,13 +361,13 @@ impl<'a> Generator<'a> { } }); } - StmtKind::For { + StmtKind::For(ast::StmtFor { target, iter, body, orelse, .. - } => { + }) => { statement!({ self.p("for "); self.unparse_expr(target, precedence::FOR); @@ -365,13 +383,13 @@ impl<'a> Generator<'a> { self.body(orelse); } } - StmtKind::AsyncFor { + StmtKind::AsyncFor(ast::StmtAsyncFor { target, iter, body, orelse, .. - } => { + }) => { statement!({ self.p("async for "); self.unparse_expr(target, precedence::ASYNC_FOR); @@ -387,7 +405,7 @@ impl<'a> Generator<'a> { self.body(orelse); } } - StmtKind::While { test, body, orelse } => { + StmtKind::While(ast::StmtWhile { test, body, orelse }) => { statement!({ self.p("while "); self.unparse_expr(test, precedence::WHILE); @@ -401,7 +419,7 @@ impl<'a> Generator<'a> { self.body(orelse); } } - StmtKind::If { test, body, orelse } => { + StmtKind::If(ast::StmtIf { test, body, orelse }) => { statement!({ self.p("if "); self.unparse_expr(test, precedence::IF); @@ -411,8 +429,8 @@ impl<'a> Generator<'a> { let mut orelse_: &Vec> = orelse; loop { - if orelse_.len() == 1 && matches!(orelse_[0].node, StmtKind::If { .. }) { - if let StmtKind::If { body, test, orelse } = &orelse_[0].node { + if orelse_.len() == 1 && matches!(orelse_[0].node, StmtKind::If(_)) { + if let StmtKind::If(ast::StmtIf { body, test, orelse }) = &orelse_[0].node { statement!({ self.p("elif "); self.unparse_expr(test, precedence::IF); @@ -432,7 +450,7 @@ impl<'a> Generator<'a> { } } } - StmtKind::With { items, body, .. } => { + StmtKind::With(ast::StmtWith { items, body, .. }) => { statement!({ self.p("with "); let mut first = true; @@ -444,7 +462,7 @@ impl<'a> Generator<'a> { }); self.body(body); } - StmtKind::AsyncWith { items, body, .. } => { + StmtKind::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => { statement!({ self.p("async with "); let mut first = true; @@ -456,7 +474,7 @@ impl<'a> Generator<'a> { }); self.body(body); } - StmtKind::Match { subject, cases } => { + StmtKind::Match(ast::StmtMatch { subject, cases }) => { statement!({ self.p("match "); self.unparse_expr(subject, precedence::MAX); @@ -470,7 +488,7 @@ impl<'a> Generator<'a> { self.indent_depth -= 1; } } - StmtKind::Raise { exc, cause } => { + StmtKind::Raise(ast::StmtRaise { exc, cause }) => { statement!({ self.p("raise"); if let Some(exc) = exc { @@ -483,12 +501,12 @@ impl<'a> Generator<'a> { } }); } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } => { + }) => { statement!({ self.p("try:"); }); @@ -513,12 +531,12 @@ impl<'a> Generator<'a> { self.body(finalbody); } } - StmtKind::TryStar { + StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { statement!({ self.p("try:"); }); @@ -543,7 +561,7 @@ impl<'a> Generator<'a> { self.body(finalbody); } } - StmtKind::Assert { test, msg } => { + StmtKind::Assert(ast::StmtAssert { test, msg }) => { statement!({ self.p("assert "); self.unparse_expr(test, precedence::ASSERT); @@ -553,7 +571,7 @@ impl<'a> Generator<'a> { } }); } - StmtKind::Import { names } => { + StmtKind::Import(ast::StmtImport { names }) => { statement!({ self.p("import "); let mut first = true; @@ -563,18 +581,18 @@ impl<'a> Generator<'a> { } }); } - StmtKind::ImportFrom { + StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } => { + }) => { statement!({ self.p("from "); if let Some(level) = level { - self.p(&".".repeat(*level)); + self.p(&".".repeat(level.to_usize())); } if let Some(module) = module { - self.p(module); + self.p_id(module); } self.p(" import "); let mut first = true; @@ -584,27 +602,27 @@ impl<'a> Generator<'a> { } }); } - StmtKind::Global { names } => { + StmtKind::Global(ast::StmtGlobal { names }) => { statement!({ self.p("global "); let mut first = true; for name in names { self.p_delim(&mut first, ", "); - self.p(name); + self.p_id(name); } }); } - StmtKind::Nonlocal { names } => { + StmtKind::Nonlocal(ast::StmtNonlocal { names }) => { statement!({ self.p("nonlocal "); let mut first = true; for name in names { self.p_delim(&mut first, ", "); - self.p(name); + self.p_id(name); } }); } - StmtKind::Expr { value } => { + StmtKind::Expr(ast::StmtExpr { value }) => { statement!({ self.unparse_expr(value, precedence::EXPR); }); @@ -629,7 +647,11 @@ impl<'a> Generator<'a> { fn unparse_excepthandler(&mut self, ast: &Excepthandler, star: bool) { match &ast.node { - ExcepthandlerKind::ExceptHandler { type_, name, body } => { + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + type_, + name, + body, + }) => { self.p("except"); if star { self.p("*"); @@ -640,7 +662,7 @@ impl<'a> Generator<'a> { } if let Some(name) = name { self.p(" as "); - self.p(name); + self.p_id(name); } self.p(":"); self.body(body); @@ -650,13 +672,13 @@ impl<'a> Generator<'a> { fn unparse_pattern(&mut self, ast: &Pattern) { match &ast.node { - PatternKind::MatchValue { value } => { + PatternKind::MatchValue(ast::PatternMatchValue { value }) => { self.unparse_expr(value, precedence::MAX); } - PatternKind::MatchSingleton { value } => { + PatternKind::MatchSingleton(ast::PatternMatchSingleton { value }) => { self.unparse_constant(value); } - PatternKind::MatchSequence { patterns } => { + PatternKind::MatchSequence(ast::PatternMatchSequence { patterns }) => { self.p("["); let mut first = true; for pattern in patterns { @@ -665,11 +687,11 @@ impl<'a> Generator<'a> { } self.p("]"); } - PatternKind::MatchMapping { + PatternKind::MatchMapping(ast::PatternMatchMapping { keys, patterns, rest, - } => { + }) => { self.p("{"); let mut first = true; for (key, pattern) in keys.iter().zip(patterns) { @@ -681,31 +703,31 @@ impl<'a> Generator<'a> { if let Some(rest) = rest { self.p_delim(&mut first, ", "); self.p("**"); - self.p(rest); + self.p_id(rest); } self.p("}"); } - PatternKind::MatchClass { .. } => {} - PatternKind::MatchStar { name } => { + PatternKind::MatchClass(_) => {} + PatternKind::MatchStar(ast::PatternMatchStar { name }) => { self.p("*"); if let Some(name) = name { - self.p(name); + self.p_id(name); } else { self.p("_"); } } - PatternKind::MatchAs { pattern, name } => { + PatternKind::MatchAs(ast::PatternMatchAs { pattern, name }) => { if let Some(pattern) = pattern { self.unparse_pattern(pattern); self.p(" as "); } if let Some(name) = name { - self.p(name); + self.p_id(name); } else { self.p("_"); } } - PatternKind::MatchOr { patterns } => { + PatternKind::MatchOr(ast::PatternMatchOr { patterns }) => { let mut first = true; for pattern in patterns { self.p_delim(&mut first, " | "); @@ -750,7 +772,7 @@ impl<'a> Generator<'a> { }}; } match &ast.node { - ExprKind::BoolOp { op, values } => { + ExprKind::BoolOp(ast::ExprBoolOp { op, values }) => { let (op, prec) = opprec!(bin, op, Boolop, And("and", AND), Or("or", OR)); group_if!(prec, { let mut first = true; @@ -760,14 +782,14 @@ impl<'a> Generator<'a> { } }); } - ExprKind::NamedExpr { target, value } => { + ExprKind::NamedExpr(ast::ExprNamedExpr { target, value }) => { group_if!(precedence::NAMED_EXPR, { self.unparse_expr(target, precedence::NAMED_EXPR); self.p(" := "); self.unparse_expr(value, precedence::NAMED_EXPR + 1); }); } - ExprKind::BinOp { left, op, right } => { + ExprKind::BinOp(ast::ExprBinOp { left, op, right }) => { let rassoc = matches!(op, Operator::Pow); let (op, prec) = opprec!( bin, @@ -793,7 +815,7 @@ impl<'a> Generator<'a> { self.unparse_expr(right, prec + u8::from(!rassoc)); }); } - ExprKind::UnaryOp { op, operand } => { + ExprKind::UnaryOp(ast::ExprUnaryOp { op, operand }) => { let (op, prec) = opprec!( un, op, @@ -808,7 +830,7 @@ impl<'a> Generator<'a> { self.unparse_expr(operand, prec); }); } - ExprKind::Lambda { args, body } => { + ExprKind::Lambda(ast::ExprLambda { args, body }) => { group_if!(precedence::LAMBDA, { let npos = args.args.len() + args.posonlyargs.len(); self.p(if npos > 0 { "lambda " } else { "lambda" }); @@ -817,7 +839,7 @@ impl<'a> Generator<'a> { self.unparse_expr(body, precedence::LAMBDA); }); } - ExprKind::IfExp { test, body, orelse } => { + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { group_if!(precedence::IF_EXP, { self.unparse_expr(body, precedence::IF_EXP + 1); self.p(" if "); @@ -826,7 +848,7 @@ impl<'a> Generator<'a> { self.unparse_expr(orelse, precedence::IF_EXP); }); } - ExprKind::Dict { keys, values } => { + ExprKind::Dict(ast::ExprDict { keys, values }) => { self.p("{"); let mut first = true; for (k, v) in keys.iter().zip(values) { @@ -842,7 +864,7 @@ impl<'a> Generator<'a> { } self.p("}"); } - ExprKind::Set { elts } => { + ExprKind::Set(ast::ExprSet { elts }) => { if elts.is_empty() { self.p("set()"); } else { @@ -855,23 +877,23 @@ impl<'a> Generator<'a> { self.p("}"); } } - ExprKind::ListComp { elt, generators } => { + ExprKind::ListComp(ast::ExprListComp { elt, generators }) => { self.p("["); self.unparse_expr(elt, precedence::MAX); self.unparse_comp(generators); self.p("]"); } - ExprKind::SetComp { elt, generators } => { + ExprKind::SetComp(ast::ExprSetComp { elt, generators }) => { self.p("{"); self.unparse_expr(elt, precedence::MAX); self.unparse_comp(generators); self.p("}"); } - ExprKind::DictComp { + ExprKind::DictComp(ast::ExprDictComp { key, value, generators, - } => { + }) => { self.p("{"); self.unparse_expr(key, precedence::MAX); self.p(": "); @@ -879,19 +901,19 @@ impl<'a> Generator<'a> { self.unparse_comp(generators); self.p("}"); } - ExprKind::GeneratorExp { elt, generators } => { + ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, generators }) => { self.p("("); self.unparse_expr(elt, precedence::COMMA); self.unparse_comp(generators); self.p(")"); } - ExprKind::Await { value } => { + ExprKind::Await(ast::ExprAwait { value }) => { group_if!(precedence::AWAIT, { self.p("await "); self.unparse_expr(value, precedence::MAX); }); } - ExprKind::Yield { value } => { + ExprKind::Yield(ast::ExprYield { value }) => { group_if!(precedence::YIELD, { self.p("yield"); if let Some(value) = value { @@ -900,17 +922,17 @@ impl<'a> Generator<'a> { } }); } - ExprKind::YieldFrom { value } => { + ExprKind::YieldFrom(ast::ExprYieldFrom { value }) => { group_if!(precedence::YIELD_FROM, { self.p("yield from "); self.unparse_expr(value, precedence::MAX); }); } - ExprKind::Compare { + ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } => { + }) => { group_if!(precedence::CMP, { let new_lvl = precedence::CMP + 1; self.unparse_expr(left, new_lvl); @@ -932,16 +954,16 @@ impl<'a> Generator<'a> { } }); } - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { + }) => { self.unparse_expr(func, precedence::MAX); self.p("("); if let ( [Expr { - node: ExprKind::GeneratorExp { elt, generators }, + node: ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, generators }), .. }], [], @@ -959,7 +981,7 @@ impl<'a> Generator<'a> { for kw in keywords { self.p_delim(&mut first, ", "); if let Some(arg) = &kw.node.arg { - self.p(arg); + self.p_id(arg); self.p("="); self.unparse_expr(&kw.node.value, precedence::COMMA); } else { @@ -970,23 +992,25 @@ impl<'a> Generator<'a> { } self.p(")"); } - ExprKind::FormattedValue { + ExprKind::FormattedValue(ast::ExprFormattedValue { value, conversion, format_spec, - } => self.unparse_formatted(value, *conversion, format_spec.as_deref()), - ExprKind::JoinedStr { values } => self.unparse_joinedstr(values, false), - ExprKind::Constant { value, kind } => { + }) => self.unparse_formatted(value, *conversion, format_spec.as_deref()), + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { + self.unparse_joinedstr(values, false); + } + ExprKind::Constant(ast::ExprConstant { value, kind }) => { if let Some(kind) = kind { self.p(kind); } self.unparse_constant(value); } - ExprKind::Attribute { value, attr, .. } => { - if let ExprKind::Constant { + ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) => { + if let ExprKind::Constant(ast::ExprConstant { value: Constant::Int(_), .. - } = &value.node + }) = &value.node { self.p("("); self.unparse_expr(value, precedence::MAX); @@ -995,20 +1019,20 @@ impl<'a> Generator<'a> { self.unparse_expr(value, precedence::MAX); self.p("."); }; - self.p(attr); + self.p_id(attr); } - ExprKind::Subscript { value, slice, .. } => { + ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => { self.unparse_expr(value, precedence::MAX); self.p("["); self.unparse_expr(slice, precedence::SUBSCRIPT); self.p("]"); } - ExprKind::Starred { value, .. } => { + ExprKind::Starred(ast::ExprStarred { value, .. }) => { self.p("*"); self.unparse_expr(value, precedence::MAX); } - ExprKind::Name { id, .. } => self.p(id), - ExprKind::List { elts, .. } => { + ExprKind::Name(ast::ExprName { id, .. }) => self.p_id(id), + ExprKind::List(ast::ExprList { elts, .. }) => { self.p("["); let mut first = true; for elt in elts { @@ -1017,7 +1041,7 @@ impl<'a> Generator<'a> { } self.p("]"); } - ExprKind::Tuple { elts, .. } => { + ExprKind::Tuple(ast::ExprTuple { elts, .. }) => { if elts.is_empty() { self.p("()"); } else { @@ -1031,7 +1055,7 @@ impl<'a> Generator<'a> { }); } } - ExprKind::Slice { lower, upper, step } => { + ExprKind::Slice(ast::ExprSlice { lower, upper, step }) => { if let Some(lower) = lower { self.unparse_expr(lower, precedence::SLICE); } @@ -1052,10 +1076,10 @@ impl<'a> Generator<'a> { let inf_str = "1e309"; match constant { Constant::Bytes(b) => { - self.p(&bytes::repr(b, self.quote.into())); + self.p_bytes_repr(b); } Constant::Str(s) => { - self.p(&format!("{}", str::repr(s, self.quote.into()))); + self.p_str_repr(s); } Constant::None => self.p("None"), Constant::Bool(b) => self.p(if *b { "True" } else { "False" }), @@ -1081,7 +1105,7 @@ impl<'a> Generator<'a> { if fp.is_infinite() { self.p(inf_str); } else { - self.p(&rustpython_common::float_ops::to_string(*fp)); + self.p(&rustpython_literal::float::to_string(*fp)); } } Constant::Complex { real, imag } => { @@ -1139,7 +1163,7 @@ impl<'a> Generator<'a> { } fn unparse_arg(&mut self, arg: &Arg) { - self.p(&arg.node.arg); + self.p_id(&arg.node.arg); if let Some(ann) = &arg.node.annotation { self.p(": "); self.unparse_expr(ann, precedence::COMMA); @@ -1148,7 +1172,7 @@ impl<'a> Generator<'a> { fn unparse_comp(&mut self, generators: &[Comprehension]) { for comp in generators { - self.p(if comp.is_async > 0 { + self.p(if comp.is_async { " async for " } else { " for " @@ -1169,7 +1193,7 @@ impl<'a> Generator<'a> { } } - fn unparse_formatted(&mut self, val: &Expr, conversion: usize, spec: Option<&Expr>) { + fn unparse_formatted(&mut self, val: &Expr, conversion: Int, spec: Option<&Expr>) { let mut generator = Generator::new(self.indent, self.quote, self.line_ending); generator.unparse_expr(val, precedence::FORMATTED_VALUE); let brace = if generator.buffer.starts_with('{') { @@ -1181,10 +1205,10 @@ impl<'a> Generator<'a> { self.p(brace); self.buffer += &generator.buffer; - if conversion != ConversionFlag::None as usize { + if conversion.to_u32() != ConversionFlag::None as u32 { self.p("!"); #[allow(clippy::cast_possible_truncation)] - self.p(&format!("{}", conversion as u8 as char)); + self.p(&format!("{}", conversion.to_u32() as u8 as char)); } if let Some(spec) = spec { @@ -1197,19 +1221,21 @@ impl<'a> Generator<'a> { fn unparse_fstring_elem(&mut self, expr: &Expr, is_spec: bool) { match &expr.node { - ExprKind::Constant { value, .. } => { + ExprKind::Constant(ast::ExprConstant { value, .. }) => { if let Constant::Str(s) = value { self.unparse_fstring_str(s); } else { unreachable!() } } - ExprKind::JoinedStr { values } => self.unparse_joinedstr(values, is_spec), - ExprKind::FormattedValue { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { + self.unparse_joinedstr(values, is_spec); + } + ExprKind::FormattedValue(ast::ExprFormattedValue { value, conversion, format_spec, - } => self.unparse_formatted(value, *conversion, format_spec.as_deref()), + }) => self.unparse_formatted(value, *conversion, format_spec.as_deref()), _ => unreachable!(), } } @@ -1234,15 +1260,15 @@ impl<'a> Generator<'a> { ); generator.unparse_fstring_body(values, is_spec); let body = &generator.buffer; - self.p(&format!("{}", str::repr(body, self.quote.into()))); + self.p_str_repr(body); } } fn unparse_alias(&mut self, alias: &Alias) { - self.p(&alias.node.name); + self.p_id(&alias.node.name); if let Some(asname) = &alias.node.asname { self.p(" as "); - self.p(asname); + self.p_id(asname); } } diff --git a/crates/ruff_python_ast/src/source_code/stylist.rs b/crates/ruff_python_ast/src/source_code/stylist.rs index 0c45351618..5074beb1a5 100644 --- a/crates/ruff_python_ast/src/source_code/stylist.rs +++ b/crates/ruff_python_ast/src/source_code/stylist.rs @@ -4,11 +4,11 @@ use std::fmt; use std::ops::Deref; use once_cell::unsync::OnceCell; +use rustpython_literal::escape::Quote as StrQuote; use rustpython_parser::lexer::LexResult; use rustpython_parser::Tok; use crate::newlines::{find_newline, LineEnding}; -use ruff_rustpython::vendor; use crate::source_code::Locator; use crate::str::leading_quote; @@ -110,11 +110,11 @@ impl From for char { } } -impl From for vendor::str::Quote { +impl From for StrQuote { fn from(val: Quote) -> Self { match val { - Quote::Single => vendor::str::Quote::Single, - Quote::Double => vendor::str::Quote::Double, + Quote::Single => StrQuote::Single, + Quote::Double => StrQuote::Double, } } } diff --git a/crates/ruff_python_ast/src/statement_visitor.rs b/crates/ruff_python_ast/src/statement_visitor.rs index 9b666a602f..55121f3cbb 100644 --- a/crates/ruff_python_ast/src/statement_visitor.rs +++ b/crates/ruff_python_ast/src/statement_visitor.rs @@ -1,6 +1,6 @@ //! Specialized AST visitor trait and walk functions that only visit statements. -use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, MatchCase, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, MatchCase, Stmt, StmtKind}; /// A trait for AST visitors that only need to visit statements. pub trait StatementVisitor<'a> { @@ -26,48 +26,48 @@ pub fn walk_body<'a, V: StatementVisitor<'a> + ?Sized>(visitor: &mut V, body: &' pub fn walk_stmt<'a, V: StatementVisitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { match &stmt.node { - StmtKind::FunctionDef { body, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { body, .. }) => { visitor.visit_body(body); } - StmtKind::AsyncFunctionDef { body, .. } => { + StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. }) => { visitor.visit_body(body); } - StmtKind::For { body, orelse, .. } => { + StmtKind::For(ast::StmtFor { body, orelse, .. }) => { visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::ClassDef { body, .. } => { + StmtKind::ClassDef(ast::StmtClassDef { body, .. }) => { visitor.visit_body(body); } - StmtKind::AsyncFor { body, orelse, .. } => { + StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. }) => { visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::While { body, orelse, .. } => { + StmtKind::While(ast::StmtWhile { body, orelse, .. }) => { visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::If { body, orelse, .. } => { + StmtKind::If(ast::StmtIf { body, orelse, .. }) => { visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::With { body, .. } => { + StmtKind::With(ast::StmtWith { body, .. }) => { visitor.visit_body(body); } - StmtKind::AsyncWith { body, .. } => { + StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => { visitor.visit_body(body); } - StmtKind::Match { cases, .. } => { + StmtKind::Match(ast::StmtMatch { cases, .. }) => { for match_case in cases { visitor.visit_match_case(match_case); } } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } => { + }) => { visitor.visit_body(body); for excepthandler in handlers { visitor.visit_excepthandler(excepthandler); @@ -75,12 +75,12 @@ pub fn walk_stmt<'a, V: StatementVisitor<'a> + ?Sized>(visitor: &mut V, stmt: &' visitor.visit_body(orelse); visitor.visit_body(finalbody); } - StmtKind::TryStar { + StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { visitor.visit_body(body); for excepthandler in handlers { visitor.visit_excepthandler(excepthandler); @@ -97,7 +97,7 @@ pub fn walk_excepthandler<'a, V: StatementVisitor<'a> + ?Sized>( excepthandler: &'a Excepthandler, ) { match &excepthandler.node { - ExcepthandlerKind::ExceptHandler { body, .. } => { + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) => { visitor.visit_body(body); } } diff --git a/crates/ruff_python_ast/src/typing.rs b/crates/ruff_python_ast/src/typing.rs index 5c5128e808..58540e6d6a 100644 --- a/crates/ruff_python_ast/src/typing.rs +++ b/crates/ruff_python_ast/src/typing.rs @@ -35,7 +35,7 @@ pub fn parse_type_annotation( // isn't the case, e.g., for implicit concatenations, or for annotations that contain // escaped quotes. let leading_quote = str::leading_quote(expression).unwrap(); - let expr = parser::parse_expression_located( + let expr = parser::parse_expression_starts_at( value, "", range.start() + leading_quote.text_len(), diff --git a/crates/ruff_python_ast/src/visitor.rs b/crates/ruff_python_ast/src/visitor.rs index d64e1c5745..caa8ffa3ea 100644 --- a/crates/ruff_python_ast/src/visitor.rs +++ b/crates/ruff_python_ast/src/visitor.rs @@ -1,7 +1,7 @@ //! AST visitor trait and walk functions. use rustpython_parser::ast::{ - Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, Excepthandler, + self, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind, Keyword, MatchCase, Operator, Pattern, PatternKind, Stmt, StmtKind, Unaryop, Withitem, }; @@ -81,13 +81,13 @@ pub fn walk_body<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, body: &'a [Stmt]) pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { match &stmt.node { - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { args, body, decorator_list, returns, .. - } => { + }) => { visitor.visit_arguments(args); for expr in decorator_list { visitor.visit_expr(expr); @@ -97,13 +97,13 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { } visitor.visit_body(body); } - StmtKind::AsyncFunctionDef { + StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { args, body, decorator_list, returns, .. - } => { + }) => { visitor.visit_arguments(args); for expr in decorator_list { visitor.visit_expr(expr); @@ -113,13 +113,13 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { } visitor.visit_body(body); } - StmtKind::ClassDef { + StmtKind::ClassDef(ast::StmtClassDef { bases, keywords, body, decorator_list, .. - } => { + }) => { for expr in bases { visitor.visit_expr(expr); } @@ -131,92 +131,92 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { } visitor.visit_body(body); } - StmtKind::Return { value } => { + StmtKind::Return(ast::StmtReturn { value }) => { if let Some(expr) = value { visitor.visit_expr(expr); } } - StmtKind::Delete { targets } => { + StmtKind::Delete(ast::StmtDelete { targets }) => { for expr in targets { visitor.visit_expr(expr); } } - StmtKind::Assign { targets, value, .. } => { + StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => { visitor.visit_expr(value); for expr in targets { visitor.visit_expr(expr); } } - StmtKind::AugAssign { target, op, value } => { + StmtKind::AugAssign(ast::StmtAugAssign { target, op, value }) => { visitor.visit_expr(target); visitor.visit_operator(op); visitor.visit_expr(value); } - StmtKind::AnnAssign { + StmtKind::AnnAssign(ast::StmtAnnAssign { target, annotation, value, .. - } => { + }) => { visitor.visit_annotation(annotation); if let Some(expr) = value { visitor.visit_expr(expr); } visitor.visit_expr(target); } - StmtKind::For { + StmtKind::For(ast::StmtFor { target, iter, body, orelse, .. - } => { + }) => { visitor.visit_expr(iter); visitor.visit_expr(target); visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::AsyncFor { + StmtKind::AsyncFor(ast::StmtAsyncFor { target, iter, body, orelse, .. - } => { + }) => { visitor.visit_expr(iter); visitor.visit_expr(target); visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::While { test, body, orelse } => { + StmtKind::While(ast::StmtWhile { test, body, orelse }) => { visitor.visit_expr(test); visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::If { test, body, orelse } => { + StmtKind::If(ast::StmtIf { test, body, orelse }) => { visitor.visit_expr(test); visitor.visit_body(body); visitor.visit_body(orelse); } - StmtKind::With { items, body, .. } => { + StmtKind::With(ast::StmtWith { items, body, .. }) => { for withitem in items { visitor.visit_withitem(withitem); } visitor.visit_body(body); } - StmtKind::AsyncWith { items, body, .. } => { + StmtKind::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => { for withitem in items { visitor.visit_withitem(withitem); } visitor.visit_body(body); } - StmtKind::Match { subject, cases } => { + StmtKind::Match(ast::StmtMatch { subject, cases }) => { visitor.visit_expr(subject); for match_case in cases { visitor.visit_match_case(match_case); } } - StmtKind::Raise { exc, cause } => { + StmtKind::Raise(ast::StmtRaise { exc, cause }) => { if let Some(expr) = exc { visitor.visit_expr(expr); }; @@ -224,12 +224,12 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { visitor.visit_expr(expr); }; } - StmtKind::Try { + StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } => { + }) => { visitor.visit_body(body); for excepthandler in handlers { visitor.visit_excepthandler(excepthandler); @@ -237,12 +237,12 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { visitor.visit_body(orelse); visitor.visit_body(finalbody); } - StmtKind::TryStar { + StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { visitor.visit_body(body); for excepthandler in handlers { visitor.visit_excepthandler(excepthandler); @@ -250,25 +250,25 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { visitor.visit_body(orelse); visitor.visit_body(finalbody); } - StmtKind::Assert { test, msg } => { + StmtKind::Assert(ast::StmtAssert { test, msg }) => { visitor.visit_expr(test); if let Some(expr) = msg { visitor.visit_expr(expr); } } - StmtKind::Import { names } => { + StmtKind::Import(ast::StmtImport { names }) => { for alias in names { visitor.visit_alias(alias); } } - StmtKind::ImportFrom { names, .. } => { + StmtKind::ImportFrom(ast::StmtImportFrom { names, .. }) => { for alias in names { visitor.visit_alias(alias); } } - StmtKind::Global { .. } => {} - StmtKind::Nonlocal { .. } => {} - StmtKind::Expr { value } => visitor.visit_expr(value), + StmtKind::Global(_) => {} + StmtKind::Nonlocal(_) => {} + StmtKind::Expr(ast::StmtExpr { value }) => visitor.visit_expr(value), StmtKind::Pass => {} StmtKind::Break => {} StmtKind::Continue => {} @@ -277,35 +277,35 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) { pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) { match &expr.node { - ExprKind::BoolOp { op, values } => { + ExprKind::BoolOp(ast::ExprBoolOp { op, values }) => { visitor.visit_boolop(op); for expr in values { visitor.visit_expr(expr); } } - ExprKind::NamedExpr { target, value } => { + ExprKind::NamedExpr(ast::ExprNamedExpr { target, value }) => { visitor.visit_expr(value); visitor.visit_expr(target); } - ExprKind::BinOp { left, op, right } => { + ExprKind::BinOp(ast::ExprBinOp { left, op, right }) => { visitor.visit_expr(left); visitor.visit_operator(op); visitor.visit_expr(right); } - ExprKind::UnaryOp { op, operand } => { + ExprKind::UnaryOp(ast::ExprUnaryOp { op, operand }) => { visitor.visit_unaryop(op); visitor.visit_expr(operand); } - ExprKind::Lambda { args, body } => { + ExprKind::Lambda(ast::ExprLambda { args, body }) => { visitor.visit_arguments(args); visitor.visit_expr(body); } - ExprKind::IfExp { test, body, orelse } => { + ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { visitor.visit_expr(test); visitor.visit_expr(body); visitor.visit_expr(orelse); } - ExprKind::Dict { keys, values } => { + ExprKind::Dict(ast::ExprDict { keys, values }) => { for expr in keys.iter().flatten() { visitor.visit_expr(expr); } @@ -313,52 +313,52 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) { visitor.visit_expr(expr); } } - ExprKind::Set { elts } => { + ExprKind::Set(ast::ExprSet { elts }) => { for expr in elts { visitor.visit_expr(expr); } } - ExprKind::ListComp { elt, generators } => { + ExprKind::ListComp(ast::ExprListComp { elt, generators }) => { for comprehension in generators { visitor.visit_comprehension(comprehension); } visitor.visit_expr(elt); } - ExprKind::SetComp { elt, generators } => { + ExprKind::SetComp(ast::ExprSetComp { elt, generators }) => { for comprehension in generators { visitor.visit_comprehension(comprehension); } visitor.visit_expr(elt); } - ExprKind::DictComp { + ExprKind::DictComp(ast::ExprDictComp { key, value, generators, - } => { + }) => { for comprehension in generators { visitor.visit_comprehension(comprehension); } visitor.visit_expr(key); visitor.visit_expr(value); } - ExprKind::GeneratorExp { elt, generators } => { + ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, generators }) => { for comprehension in generators { visitor.visit_comprehension(comprehension); } visitor.visit_expr(elt); } - ExprKind::Await { value } => visitor.visit_expr(value), - ExprKind::Yield { value } => { + ExprKind::Await(ast::ExprAwait { value }) => visitor.visit_expr(value), + ExprKind::Yield(ast::ExprYield { value }) => { if let Some(expr) = value { visitor.visit_expr(expr); } } - ExprKind::YieldFrom { value } => visitor.visit_expr(value), - ExprKind::Compare { + ExprKind::YieldFrom(ast::ExprYieldFrom { value }) => visitor.visit_expr(value), + ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } => { + }) => { visitor.visit_expr(left); for cmpop in ops { visitor.visit_cmpop(cmpop); @@ -367,11 +367,11 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) { visitor.visit_expr(expr); } } - ExprKind::Call { + ExprKind::Call(ast::ExprCall { func, args, keywords, - } => { + }) => { visitor.visit_expr(func); for expr in args { visitor.visit_expr(expr); @@ -380,49 +380,49 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) { visitor.visit_keyword(keyword); } } - ExprKind::FormattedValue { + ExprKind::FormattedValue(ast::ExprFormattedValue { value, format_spec, .. - } => { + }) => { visitor.visit_expr(value); if let Some(expr) = format_spec { visitor.visit_format_spec(expr); } } - ExprKind::JoinedStr { values } => { + ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => { for expr in values { visitor.visit_expr(expr); } } - ExprKind::Constant { value, .. } => visitor.visit_constant(value), - ExprKind::Attribute { value, ctx, .. } => { + ExprKind::Constant(ast::ExprConstant { value, .. }) => visitor.visit_constant(value), + ExprKind::Attribute(ast::ExprAttribute { value, ctx, .. }) => { visitor.visit_expr(value); visitor.visit_expr_context(ctx); } - ExprKind::Subscript { value, slice, ctx } => { + ExprKind::Subscript(ast::ExprSubscript { value, slice, ctx }) => { visitor.visit_expr(value); visitor.visit_expr(slice); visitor.visit_expr_context(ctx); } - ExprKind::Starred { value, ctx } => { + ExprKind::Starred(ast::ExprStarred { value, ctx }) => { visitor.visit_expr(value); visitor.visit_expr_context(ctx); } - ExprKind::Name { ctx, .. } => { + ExprKind::Name(ast::ExprName { ctx, .. }) => { visitor.visit_expr_context(ctx); } - ExprKind::List { elts, ctx } => { + ExprKind::List(ast::ExprList { elts, ctx }) => { for expr in elts { visitor.visit_expr(expr); } visitor.visit_expr_context(ctx); } - ExprKind::Tuple { elts, ctx } => { + ExprKind::Tuple(ast::ExprTuple { elts, ctx }) => { for expr in elts { visitor.visit_expr(expr); } visitor.visit_expr_context(ctx); } - ExprKind::Slice { lower, upper, step } => { + ExprKind::Slice(ast::ExprSlice { lower, upper, step }) => { if let Some(expr) = lower { visitor.visit_expr(expr); } @@ -460,7 +460,9 @@ pub fn walk_excepthandler<'a, V: Visitor<'a> + ?Sized>( excepthandler: &'a Excepthandler, ) { match &excepthandler.node { - ExcepthandlerKind::ExceptHandler { type_, body, .. } => { + ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + type_, body, .. + }) => { if let Some(expr) = type_ { visitor.visit_expr(expr); } @@ -520,14 +522,16 @@ pub fn walk_match_case<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, match_case: pub fn walk_pattern<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, pattern: &'a Pattern) { match &pattern.node { - PatternKind::MatchValue { value } => visitor.visit_expr(value), - PatternKind::MatchSingleton { value } => visitor.visit_constant(value), - PatternKind::MatchSequence { patterns } => { + PatternKind::MatchValue(ast::PatternMatchValue { value }) => visitor.visit_expr(value), + PatternKind::MatchSingleton(ast::PatternMatchSingleton { value }) => { + visitor.visit_constant(value); + } + PatternKind::MatchSequence(ast::PatternMatchSequence { patterns }) => { for pattern in patterns { visitor.visit_pattern(pattern); } } - PatternKind::MatchMapping { keys, patterns, .. } => { + PatternKind::MatchMapping(ast::PatternMatchMapping { keys, patterns, .. }) => { for expr in keys { visitor.visit_expr(expr); } @@ -535,12 +539,12 @@ pub fn walk_pattern<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, pattern: &'a P visitor.visit_pattern(pattern); } } - PatternKind::MatchClass { + PatternKind::MatchClass(ast::PatternMatchClass { cls, patterns, kwd_patterns, .. - } => { + }) => { visitor.visit_expr(cls); for pattern in patterns { visitor.visit_pattern(pattern); @@ -550,13 +554,13 @@ pub fn walk_pattern<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, pattern: &'a P visitor.visit_pattern(pattern); } } - PatternKind::MatchStar { .. } => {} - PatternKind::MatchAs { pattern, .. } => { + PatternKind::MatchStar(_) => {} + PatternKind::MatchAs(ast::PatternMatchAs { pattern, .. }) => { if let Some(pattern) = pattern { visitor.visit_pattern(pattern); } } - PatternKind::MatchOr { patterns } => { + PatternKind::MatchOr(ast::PatternMatchOr { patterns }) => { for pattern in patterns { visitor.visit_pattern(pattern); } diff --git a/crates/ruff_python_ast/src/whitespace.rs b/crates/ruff_python_ast/src/whitespace.rs index 8893c2d087..4757381d7d 100644 --- a/crates/ruff_python_ast/src/whitespace.rs +++ b/crates/ruff_python_ast/src/whitespace.rs @@ -1,10 +1,10 @@ use ruff_text_size::TextRange; -use rustpython_parser::ast::Located; +use rustpython_parser::ast::Attributed; use crate::source_code::Locator; /// Extract the leading indentation from a line. -pub fn indentation<'a, T>(locator: &'a Locator, located: &Located) -> Option<&'a str> { +pub fn indentation<'a, T>(locator: &'a Locator, located: &Attributed) -> Option<&'a str> { let line_start = locator.line_start(located.start()); let indentation = &locator.contents()[TextRange::new(line_start, located.start())]; diff --git a/crates/ruff_python_formatter/Cargo.toml b/crates/ruff_python_formatter/Cargo.toml index 4ca22b16b8..1e7003c7a5 100644 --- a/crates/ruff_python_formatter/Cargo.toml +++ b/crates/ruff_python_formatter/Cargo.toml @@ -17,7 +17,6 @@ is-macro = { workspace = true } itertools = { workspace = true } once_cell = { workspace = true } rustc-hash = { workspace = true } -rustpython-common = { workspace = true } rustpython-parser = { workspace = true } [dev-dependencies] diff --git a/crates/ruff_python_formatter/src/cst/helpers.rs b/crates/ruff_python_formatter/src/cst/helpers.rs index 0770992463..f61c9872bb 100644 --- a/crates/ruff_python_formatter/src/cst/helpers.rs +++ b/crates/ruff_python_formatter/src/cst/helpers.rs @@ -17,7 +17,7 @@ pub fn find_tok( locator: &Locator, f: impl Fn(rustpython_parser::Tok) -> bool, ) -> TextRange { - for (tok, tok_range) in rustpython_parser::lexer::lex_located( + for (tok, tok_range) in rustpython_parser::lexer::lex_starts_at( &locator.contents()[range], rustpython_parser::Mode::Module, range.start(), @@ -45,7 +45,7 @@ pub fn expand_indented_block( // Find the colon, which indicates the end of the header. let mut nesting = 0; let mut colon = None; - for (tok, tok_range) in rustpython_parser::lexer::lex_located( + for (tok, tok_range) in rustpython_parser::lexer::lex_starts_at( &contents[TextRange::new(location, end_location)], rustpython_parser::Mode::Module, location, @@ -69,7 +69,7 @@ pub fn expand_indented_block( let colon_location = colon.unwrap(); // From here, we have two options: simple statement or compound statement. - let indent = rustpython_parser::lexer::lex_located( + let indent = rustpython_parser::lexer::lex_starts_at( &contents[TextRange::new(colon_location, end_location)], rustpython_parser::Mode::Module, colon_location, diff --git a/crates/ruff_python_formatter/src/cst/mod.rs b/crates/ruff_python_formatter/src/cst/mod.rs index 4731174fe5..01a91756a2 100644 --- a/crates/ruff_python_formatter/src/cst/mod.rs +++ b/crates/ruff_python_formatter/src/cst/mod.rs @@ -19,14 +19,14 @@ pub mod visitor; type Ident = String; #[derive(Clone, Debug, PartialEq)] -pub struct Located { +pub struct Attributed { pub range: TextRange, pub node: T, pub trivia: Vec, pub parentheses: Parenthesize, } -impl Located { +impl Attributed { pub fn new(range: TextRange, node: T) -> Self { Self { range, @@ -57,7 +57,7 @@ impl Located { } } -impl Deref for Located { +impl Deref for Attributed { type Target = T; fn deref(&self) -> &Self::Target { &self.node @@ -96,7 +96,7 @@ impl From<&rustpython_parser::ast::Boolop> for BoolOpKind { } } -pub type BoolOp = Located; +pub type BoolOp = Attributed; #[derive(Clone, Debug, PartialEq)] pub enum OperatorKind { @@ -115,7 +115,7 @@ pub enum OperatorKind { FloorDiv, } -pub type Operator = Located; +pub type Operator = Attributed; impl From<&rustpython_parser::ast::Operator> for OperatorKind { fn from(op: &rustpython_parser::ast::Operator) -> Self { @@ -145,7 +145,7 @@ pub enum UnaryOpKind { USub, } -pub type UnaryOp = Located; +pub type UnaryOp = Attributed; impl From<&rustpython_parser::ast::Unaryop> for UnaryOpKind { fn from(op: &rustpython_parser::ast::Unaryop) -> Self { @@ -172,7 +172,7 @@ pub enum CmpOpKind { NotIn, } -pub type CmpOp = Located; +pub type CmpOp = Attributed; impl From<&rustpython_parser::ast::Cmpop> for CmpOpKind { fn from(op: &rustpython_parser::ast::Cmpop) -> Self { @@ -191,7 +191,7 @@ impl From<&rustpython_parser::ast::Cmpop> for CmpOpKind { } } -pub type Body = Located>; +pub type Body = Attributed>; impl From<(Vec, &Locator<'_>)> for Body { fn from((body, locator): (Vec, &Locator)) -> Self { @@ -319,7 +319,7 @@ pub enum StmtKind { ImportFrom { module: Option, names: Vec, - level: Option, + level: Option, }, Global { names: Vec, @@ -335,7 +335,7 @@ pub enum StmtKind { Continue, } -pub type Stmt = Located; +pub type Stmt = Attributed; #[derive(Clone, Debug, PartialEq)] pub enum ExprKind { @@ -453,7 +453,7 @@ pub enum ExprKind { }, } -pub type Expr = Located; +pub type Expr = Attributed; #[derive(Clone, Debug, PartialEq)] pub struct Comprehension { @@ -472,7 +472,7 @@ pub enum ExcepthandlerKind { }, } -pub type Excepthandler = Located; +pub type Excepthandler = Attributed; #[derive(Clone, Debug, PartialEq)] pub enum SliceIndexKind { @@ -482,7 +482,7 @@ pub enum SliceIndexKind { Index { value: Box }, } -pub type SliceIndex = Located; +pub type SliceIndex = Attributed; #[derive(Clone, Debug, PartialEq)] pub struct Arguments { @@ -502,7 +502,7 @@ pub struct ArgData { pub type_comment: Option, } -pub type Arg = Located; +pub type Arg = Attributed; #[derive(Clone, Debug, PartialEq)] pub struct KeywordData { @@ -510,7 +510,7 @@ pub struct KeywordData { pub value: Expr, } -pub type Keyword = Located; +pub type Keyword = Attributed; #[derive(Clone, Debug, PartialEq)] pub struct AliasData { @@ -518,7 +518,7 @@ pub struct AliasData { pub asname: Option, } -pub type Alias = Located; +pub type Alias = Attributed; #[derive(Clone, Debug, PartialEq)] pub struct Withitem { @@ -568,15 +568,19 @@ pub enum PatternKind { }, } -pub type Pattern = Located; +pub type Pattern = Attributed; impl From<(rustpython_parser::ast::Alias, &Locator<'_>)> for Alias { fn from((alias, _locator): (rustpython_parser::ast::Alias, &Locator)) -> Self { Alias { range: alias.range(), node: AliasData { - name: alias.node.name, - asname: alias.node.asname, + name: alias.node.name.to_string(), + asname: alias + .node + .asname + .as_ref() + .map(rustpython_parser::ast::Identifier::to_string), }, trivia: vec![], parentheses: Parenthesize::Never, @@ -597,8 +601,9 @@ impl From<(rustpython_parser::ast::Withitem, &Locator<'_>)> for Withitem { impl From<(rustpython_parser::ast::Excepthandler, &Locator<'_>)> for Excepthandler { fn from((excepthandler, locator): (rustpython_parser::ast::Excepthandler, &Locator)) -> Self { - let rustpython_parser::ast::ExcepthandlerKind::ExceptHandler { type_, name, body } = - excepthandler.node; + let rustpython_parser::ast::ExcepthandlerKind::ExceptHandler( + ast::ExcepthandlerExceptHandler { type_, name, body }, + ) = excepthandler.node; // Find the start and end of the `body`. let body = { @@ -622,7 +627,7 @@ impl From<(rustpython_parser::ast::Excepthandler, &Locator<'_>)> for Excepthandl range: TextRange::new(excepthandler.range.start(), body.end()), node: ExcepthandlerKind::ExceptHandler { type_: type_.map(|type_| Box::new((*type_, locator).into())), - name, + name: name.map(Into::into), body, }, trivia: vec![], @@ -636,61 +641,69 @@ impl From<(rustpython_parser::ast::Pattern, &Locator<'_>)> for Pattern { Pattern { range: pattern.range(), node: match pattern.node { - rustpython_parser::ast::PatternKind::MatchValue { value } => { - PatternKind::MatchValue { - value: Box::new((*value, locator).into()), - } - } - rustpython_parser::ast::PatternKind::MatchSingleton { value } => { - PatternKind::MatchSingleton { value } - } - rustpython_parser::ast::PatternKind::MatchSequence { patterns } => { - PatternKind::MatchSequence { - patterns: patterns - .into_iter() - .map(|pattern| (pattern, locator).into()) - .collect(), - } - } - rustpython_parser::ast::PatternKind::MatchMapping { - keys, - patterns, - rest, - } => PatternKind::MatchMapping { + rustpython_parser::ast::PatternKind::MatchValue( + rustpython_parser::ast::PatternMatchValue { value }, + ) => PatternKind::MatchValue { + value: Box::new((*value, locator).into()), + }, + rustpython_parser::ast::PatternKind::MatchSingleton( + rustpython_parser::ast::PatternMatchSingleton { value }, + ) => PatternKind::MatchSingleton { value }, + rustpython_parser::ast::PatternKind::MatchSequence( + rustpython_parser::ast::PatternMatchSequence { patterns }, + ) => PatternKind::MatchSequence { + patterns: patterns + .into_iter() + .map(|pattern| (pattern, locator).into()) + .collect(), + }, + rustpython_parser::ast::PatternKind::MatchMapping( + rustpython_parser::ast::PatternMatchMapping { + keys, + patterns, + rest, + }, + ) => PatternKind::MatchMapping { keys: keys.into_iter().map(|key| (key, locator).into()).collect(), patterns: patterns .into_iter() .map(|pattern| (pattern, locator).into()) .collect(), - rest, + rest: rest.map(Into::into), }, - rustpython_parser::ast::PatternKind::MatchClass { - cls, - patterns, - kwd_attrs, - kwd_patterns, - } => PatternKind::MatchClass { + rustpython_parser::ast::PatternKind::MatchClass( + rustpython_parser::ast::PatternMatchClass { + cls, + patterns, + kwd_attrs, + kwd_patterns, + }, + ) => PatternKind::MatchClass { cls: Box::new((*cls, locator).into()), patterns: patterns .into_iter() .map(|pattern| (pattern, locator).into()) .collect(), - kwd_attrs, + kwd_attrs: kwd_attrs.into_iter().map(Into::into).collect(), kwd_patterns: kwd_patterns .into_iter() .map(|pattern| (pattern, locator).into()) .collect(), }, - rustpython_parser::ast::PatternKind::MatchStar { name } => { - PatternKind::MatchStar { name } - } - rustpython_parser::ast::PatternKind::MatchAs { pattern, name } => { - PatternKind::MatchAs { - pattern: pattern.map(|pattern| Box::new((*pattern, locator).into())), - name, - } - } - rustpython_parser::ast::PatternKind::MatchOr { patterns } => PatternKind::MatchOr { + rustpython_parser::ast::PatternKind::MatchStar( + rustpython_parser::ast::PatternMatchStar { name }, + ) => PatternKind::MatchStar { + name: name.map(Into::into), + }, + rustpython_parser::ast::PatternKind::MatchAs( + rustpython_parser::ast::PatternMatchAs { pattern, name }, + ) => PatternKind::MatchAs { + pattern: pattern.map(|pattern| Box::new((*pattern, locator).into())), + name: name.map(Into::into), + }, + rustpython_parser::ast::PatternKind::MatchOr( + rustpython_parser::ast::PatternMatchOr { patterns }, + ) => PatternKind::MatchOr { patterns: patterns .into_iter() .map(|pattern| (pattern, locator).into()) @@ -737,7 +750,7 @@ impl From<(rustpython_parser::ast::MatchCase, &Locator<'_>)> for MatchCase { impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { fn from((stmt, locator): (rustpython_parser::ast::Stmt, &Locator)) -> Self { match stmt.node { - rustpython_parser::ast::StmtKind::Expr { value } => Stmt { + rustpython_parser::ast::StmtKind::Expr(ast::StmtExpr { value }) => Stmt { range: stmt.range, node: StmtKind::Expr { value: Box::new((*value, locator).into()), @@ -751,7 +764,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::Return { value } => Stmt { + rustpython_parser::ast::StmtKind::Return(ast::StmtReturn { value }) => Stmt { range: stmt.range, node: StmtKind::Return { value: value.map(|v| (*v, locator).into()), @@ -759,11 +772,11 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::Assign { + rustpython_parser::ast::StmtKind::Assign(ast::StmtAssign { targets, value, type_comment, - } => Stmt { + }) => Stmt { range: stmt.range, node: StmtKind::Assign { targets: targets @@ -776,13 +789,13 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::ClassDef { + rustpython_parser::ast::StmtKind::ClassDef(ast::StmtClassDef { name, bases, keywords, body, decorator_list, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -804,7 +817,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { Stmt { range: TextRange::new(stmt.range.start(), body.end()), node: StmtKind::ClassDef { - name, + name: name.into(), bases: bases .into_iter() .map(|node| (node, locator).into()) @@ -823,7 +836,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::If { test, body, orelse } => { + rustpython_parser::ast::StmtKind::If(ast::StmtIf { test, body, orelse }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -907,7 +920,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { } } } - rustpython_parser::ast::StmtKind::Assert { test, msg } => Stmt { + rustpython_parser::ast::StmtKind::Assert(ast::StmtAssert { test, msg }) => Stmt { range: stmt.range, node: StmtKind::Assert { test: Box::new((*test, locator).into()), @@ -916,14 +929,14 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::FunctionDef { + rustpython_parser::ast::StmtKind::FunctionDef(ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -946,11 +959,11 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { range: TextRange::new( decorator_list .first() - .map_or(stmt.range.start(), ast::Located::start), + .map_or(stmt.range.start(), ast::Attributed::start), body.end(), ), node: StmtKind::FunctionDef { - name, + name: name.into(), args: Box::new((*args, locator).into()), body, decorator_list: decorator_list @@ -964,14 +977,14 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::AsyncFunctionDef { + rustpython_parser::ast::StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, args, body, decorator_list, returns, type_comment, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -998,7 +1011,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { body.end(), ), node: StmtKind::AsyncFunctionDef { - name, + name: name.into(), args: Box::new((*args, locator).into()), body, decorator_list: decorator_list @@ -1012,7 +1025,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::Delete { targets } => Stmt { + rustpython_parser::ast::StmtKind::Delete(ast::StmtDelete { targets }) => Stmt { range: stmt.range, node: StmtKind::Delete { targets: targets @@ -1023,7 +1036,11 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::AugAssign { target, op, value } => Stmt { + rustpython_parser::ast::StmtKind::AugAssign(ast::StmtAugAssign { + target, + op, + value, + }) => Stmt { range: stmt.range, node: StmtKind::AugAssign { op: { @@ -1080,29 +1097,29 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::AnnAssign { + rustpython_parser::ast::StmtKind::AnnAssign(ast::StmtAnnAssign { target, annotation, value, simple, - } => Stmt { + }) => Stmt { range: stmt.range, node: StmtKind::AnnAssign { target: Box::new((*target, locator).into()), annotation: Box::new((*annotation, locator).into()), value: value.map(|node| Box::new((*node, locator).into())), - simple, + simple: usize::from(simple), }, trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::For { + rustpython_parser::ast::StmtKind::For(ast::StmtFor { target, iter, body, orelse, type_comment, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -1152,13 +1169,13 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::AsyncFor { + rustpython_parser::ast::StmtKind::AsyncFor(ast::StmtAsyncFor { target, iter, body, orelse, type_comment, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -1208,7 +1225,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::While { test, body, orelse } => { + rustpython_parser::ast::StmtKind::While(ast::StmtWhile { test, body, orelse }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -1256,11 +1273,11 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::With { + rustpython_parser::ast::StmtKind::With(ast::StmtWith { items, body, type_comment, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -1293,11 +1310,11 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::AsyncWith { + rustpython_parser::ast::StmtKind::AsyncWith(ast::StmtAsyncWith { items, body, type_comment, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -1330,7 +1347,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::Match { subject, cases } => Stmt { + rustpython_parser::ast::StmtKind::Match(ast::StmtMatch { subject, cases }) => Stmt { range: stmt.range, node: StmtKind::Match { subject: Box::new((*subject, locator).into()), @@ -1342,7 +1359,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::Raise { exc, cause } => Stmt { + rustpython_parser::ast::StmtKind::Raise(ast::StmtRaise { exc, cause }) => Stmt { range: stmt.range, node: StmtKind::Raise { exc: exc.map(|exc| Box::new((*exc, locator).into())), @@ -1351,12 +1368,12 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::Try { + rustpython_parser::ast::StmtKind::Try(ast::StmtTry { body, handlers, orelse, finalbody, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -1383,7 +1400,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { // Find the start and end of the `orelse`. let orelse = (!orelse.is_empty()).then(|| { let orelse_range = expand_indented_block( - handlers.last().map_or(body.end(), Located::end), + handlers.last().map_or(body.end(), Attributed::end), orelse.last().unwrap().end(), locator, ); @@ -1402,8 +1419,8 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { let finalbody = (!finalbody.is_empty()).then(|| { let finalbody_range = expand_indented_block( orelse.as_ref().map_or( - handlers.last().map_or(body.end(), Located::end), - Located::end, + handlers.last().map_or(body.end(), Attributed::end), + Attributed::end, ), finalbody.last().unwrap().end(), locator, @@ -1421,10 +1438,10 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { let end_location = finalbody.as_ref().map_or( orelse.as_ref().map_or( - handlers.last().map_or(body.end(), Located::end), - Located::end, + handlers.last().map_or(body.end(), Attributed::end), + Attributed::end, ), - Located::end, + Attributed::end, ); Stmt { @@ -1439,12 +1456,12 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::TryStar { + rustpython_parser::ast::StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, finalbody, - } => { + }) => { // Find the start and end of the `body`. let body = { let body_range = expand_indented_block( @@ -1471,7 +1488,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { // Find the start and end of the `orelse`. let orelse = (!orelse.is_empty()).then(|| { let orelse_range = expand_indented_block( - handlers.last().map_or(body.end(), Located::end), + handlers.last().map_or(body.end(), Attributed::end), orelse.last().unwrap().end(), locator, ); @@ -1490,8 +1507,8 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { let finalbody = (!finalbody.is_empty()).then(|| { let finalbody_range = expand_indented_block( orelse.as_ref().map_or( - handlers.last().map_or(body.end(), Located::end), - Located::end, + handlers.last().map_or(body.end(), Attributed::end), + Attributed::end, ), finalbody.last().unwrap().end(), locator, @@ -1509,10 +1526,10 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { let end_location = finalbody.as_ref().map_or( orelse.as_ref().map_or( - handlers.last().map_or(body.end(), Located::end), - Located::end, + handlers.last().map_or(body.end(), Attributed::end), + Attributed::end, ), - Located::end, + Attributed::end, ); Stmt { @@ -1527,7 +1544,7 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { parentheses: Parenthesize::Never, } } - rustpython_parser::ast::StmtKind::Import { names } => Stmt { + rustpython_parser::ast::StmtKind::Import(ast::StmtImport { names }) => Stmt { range: stmt.range, node: StmtKind::Import { names: names @@ -1538,32 +1555,36 @@ impl From<(rustpython_parser::ast::Stmt, &Locator<'_>)> for Stmt { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::ImportFrom { + rustpython_parser::ast::StmtKind::ImportFrom(ast::StmtImportFrom { module, names, level, - } => Stmt { + }) => Stmt { range: stmt.range, node: StmtKind::ImportFrom { - module, + module: module.map(Into::into), names: names .into_iter() .map(|node| (node, locator).into()) .collect(), - level, + level: level.map(|level| level.to_u32()), }, trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::Global { names } => Stmt { + rustpython_parser::ast::StmtKind::Global(ast::StmtGlobal { names }) => Stmt { range: stmt.range, - node: StmtKind::Global { names }, + node: StmtKind::Global { + names: names.into_iter().map(Into::into).collect(), + }, trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::StmtKind::Nonlocal { names } => Stmt { + rustpython_parser::ast::StmtKind::Nonlocal(ast::StmtNonlocal { names }) => Stmt { range: stmt.range, - node: StmtKind::Nonlocal { names }, + node: StmtKind::Nonlocal { + names: names.into_iter().map(Into::into).collect(), + }, trivia: vec![], parentheses: Parenthesize::Never, }, @@ -1588,7 +1609,7 @@ impl From<(rustpython_parser::ast::Keyword, &Locator<'_>)> for Keyword { Keyword { range: keyword.range(), node: KeywordData { - arg: keyword.node.arg, + arg: keyword.node.arg.map(Into::into), value: (keyword.node.value, locator).into(), }, trivia: vec![], @@ -1602,7 +1623,7 @@ impl From<(rustpython_parser::ast::Arg, &Locator<'_>)> for Arg { Arg { range: arg.range(), node: ArgData { - arg: arg.node.arg, + arg: arg.node.arg.into(), annotation: arg .node .annotation @@ -1663,7 +1684,7 @@ impl From<(rustpython_parser::ast::Comprehension, &Locator<'_>)> for Comprehensi .into_iter() .map(|node| (node, locator).into()) .collect(), - is_async: comprehension.is_async, + is_async: usize::from(comprehension.is_async), } } } @@ -1671,16 +1692,16 @@ impl From<(rustpython_parser::ast::Comprehension, &Locator<'_>)> for Comprehensi impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { fn from((expr, locator): (rustpython_parser::ast::Expr, &Locator)) -> Self { match expr.node { - rustpython_parser::ast::ExprKind::Name { id, ctx } => Expr { + rustpython_parser::ast::ExprKind::Name(ast::ExprName { id, ctx }) => Expr { range: expr.range, node: ExprKind::Name { - id, + id: id.into(), ctx: ctx.into(), }, trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::BoolOp { op, values } => Expr { + rustpython_parser::ast::ExprKind::BoolOp(ast::ExprBoolOp { op, values }) => Expr { range: expr.range, node: ExprKind::BoolOp { ops: values @@ -1707,16 +1728,18 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::NamedExpr { target, value } => Expr { - range: expr.range, - node: ExprKind::NamedExpr { - target: Box::new((*target, locator).into()), - value: Box::new((*value, locator).into()), - }, - trivia: vec![], - parentheses: Parenthesize::Never, - }, - rustpython_parser::ast::ExprKind::BinOp { left, op, right } => Expr { + rustpython_parser::ast::ExprKind::NamedExpr(ast::ExprNamedExpr { target, value }) => { + Expr { + range: expr.range, + node: ExprKind::NamedExpr { + target: Box::new((*target, locator).into()), + value: Box::new((*value, locator).into()), + }, + trivia: vec![], + parentheses: Parenthesize::Never, + } + } + rustpython_parser::ast::ExprKind::BinOp(ast::ExprBinOp { left, op, right }) => Expr { range: expr.range, node: ExprKind::BinOp { op: { @@ -1761,7 +1784,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::UnaryOp { op, operand } => Expr { + rustpython_parser::ast::ExprKind::UnaryOp(ast::ExprUnaryOp { op, operand }) => Expr { range: expr.range, node: ExprKind::UnaryOp { op: { @@ -1785,7 +1808,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Lambda { args, body } => Expr { + rustpython_parser::ast::ExprKind::Lambda(ast::ExprLambda { args, body }) => Expr { range: expr.range, node: ExprKind::Lambda { args: Box::new((*args, locator).into()), @@ -1794,17 +1817,19 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::IfExp { test, body, orelse } => Expr { - range: expr.range, - node: ExprKind::IfExp { - test: Box::new((*test, locator).into()), - body: Box::new((*body, locator).into()), - orelse: Box::new((*orelse, locator).into()), - }, - trivia: vec![], - parentheses: Parenthesize::Never, - }, - rustpython_parser::ast::ExprKind::Dict { keys, values } => Expr { + rustpython_parser::ast::ExprKind::IfExp(ast::ExprIfExp { test, body, orelse }) => { + Expr { + range: expr.range, + node: ExprKind::IfExp { + test: Box::new((*test, locator).into()), + body: Box::new((*body, locator).into()), + orelse: Box::new((*orelse, locator).into()), + }, + trivia: vec![], + parentheses: Parenthesize::Never, + } + } + rustpython_parser::ast::ExprKind::Dict(ast::ExprDict { keys, values }) => Expr { range: expr.range, node: ExprKind::Dict { keys: keys @@ -1819,7 +1844,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Set { elts } => Expr { + rustpython_parser::ast::ExprKind::Set(ast::ExprSet { elts }) => Expr { range: expr.range, node: ExprKind::Set { elts: elts @@ -1830,35 +1855,39 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::ListComp { elt, generators } => Expr { - range: expr.range, - node: ExprKind::ListComp { - elt: Box::new((*elt, locator).into()), - generators: generators - .into_iter() - .map(|node| (node, locator).into()) - .collect(), - }, - trivia: vec![], - parentheses: Parenthesize::Never, - }, - rustpython_parser::ast::ExprKind::SetComp { elt, generators } => Expr { - range: expr.range, - node: ExprKind::SetComp { - elt: Box::new((*elt, locator).into()), - generators: generators - .into_iter() - .map(|node| (node, locator).into()) - .collect(), - }, - trivia: vec![], - parentheses: Parenthesize::Never, - }, - rustpython_parser::ast::ExprKind::DictComp { + rustpython_parser::ast::ExprKind::ListComp(ast::ExprListComp { elt, generators }) => { + Expr { + range: expr.range, + node: ExprKind::ListComp { + elt: Box::new((*elt, locator).into()), + generators: generators + .into_iter() + .map(|node| (node, locator).into()) + .collect(), + }, + trivia: vec![], + parentheses: Parenthesize::Never, + } + } + rustpython_parser::ast::ExprKind::SetComp(ast::ExprSetComp { elt, generators }) => { + Expr { + range: expr.range, + node: ExprKind::SetComp { + elt: Box::new((*elt, locator).into()), + generators: generators + .into_iter() + .map(|node| (node, locator).into()) + .collect(), + }, + trivia: vec![], + parentheses: Parenthesize::Never, + } + } + rustpython_parser::ast::ExprKind::DictComp(ast::ExprDictComp { key, value, generators, - } => Expr { + }) => Expr { range: expr.range, node: ExprKind::DictComp { key: Box::new((*key, locator).into()), @@ -1871,7 +1900,10 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::GeneratorExp { elt, generators } => Expr { + rustpython_parser::ast::ExprKind::GeneratorExp(ast::ExprGeneratorExp { + elt, + generators, + }) => Expr { range: expr.range, node: ExprKind::GeneratorExp { elt: Box::new((*elt, locator).into()), @@ -1883,7 +1915,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Await { value } => Expr { + rustpython_parser::ast::ExprKind::Await(ast::ExprAwait { value }) => Expr { range: expr.range, node: ExprKind::Await { value: Box::new((*value, locator).into()), @@ -1891,7 +1923,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Yield { value } => Expr { + rustpython_parser::ast::ExprKind::Yield(ast::ExprYield { value }) => Expr { range: expr.range, node: ExprKind::Yield { value: value.map(|v| Box::new((*v, locator).into())), @@ -1899,7 +1931,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::YieldFrom { value } => Expr { + rustpython_parser::ast::ExprKind::YieldFrom(ast::ExprYieldFrom { value }) => Expr { range: expr.range, node: ExprKind::YieldFrom { value: Box::new((*value, locator).into()), @@ -1907,11 +1939,11 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Compare { + rustpython_parser::ast::ExprKind::Compare(ast::ExprCompare { left, ops, comparators, - } => Expr { + }) => Expr { range: expr.range, node: ExprKind::Compare { ops: iter::once(left.as_ref()) @@ -1960,11 +1992,11 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Call { + rustpython_parser::ast::ExprKind::Call(ast::ExprCall { func, args, keywords, - } => Expr { + }) => Expr { range: expr.range, node: ExprKind::Call { func: Box::new((*func, locator).into()), @@ -1980,21 +2012,21 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::FormattedValue { + rustpython_parser::ast::ExprKind::FormattedValue(ast::ExprFormattedValue { value, conversion, format_spec, - } => Expr { + }) => Expr { range: expr.range, node: ExprKind::FormattedValue { value: Box::new((*value, locator).into()), - conversion, + conversion: conversion.to_usize(), format_spec: format_spec.map(|f| Box::new((*f, locator).into())), }, trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::JoinedStr { values } => Expr { + rustpython_parser::ast::ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => Expr { range: expr.range, node: ExprKind::JoinedStr { values: values @@ -2005,23 +2037,31 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Constant { value, kind } => Expr { + rustpython_parser::ast::ExprKind::Constant(ast::ExprConstant { value, kind }) => Expr { range: expr.range, node: ExprKind::Constant { value, kind }, trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Attribute { value, attr, ctx } => Expr { + rustpython_parser::ast::ExprKind::Attribute(ast::ExprAttribute { + value, + attr, + ctx, + }) => Expr { range: expr.range, node: ExprKind::Attribute { value: Box::new((*value, locator).into()), - attr, + attr: attr.into(), ctx: ctx.into(), }, trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Subscript { value, slice, ctx } => Expr { + rustpython_parser::ast::ExprKind::Subscript(ast::ExprSubscript { + value, + slice, + ctx, + }) => Expr { range: expr.range, node: ExprKind::Subscript { value: Box::new((*value, locator).into()), @@ -2031,7 +2071,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Starred { value, ctx } => Expr { + rustpython_parser::ast::ExprKind::Starred(ast::ExprStarred { value, ctx }) => Expr { range: expr.range, node: ExprKind::Starred { value: Box::new((*value, locator).into()), @@ -2040,7 +2080,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::List { elts, ctx } => Expr { + rustpython_parser::ast::ExprKind::List(ast::ExprList { elts, ctx }) => Expr { range: expr.range, node: ExprKind::List { elts: elts @@ -2052,7 +2092,7 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Tuple { elts, ctx } => Expr { + rustpython_parser::ast::ExprKind::Tuple(ast::ExprTuple { elts, ctx }) => Expr { range: expr.range, node: ExprKind::Tuple { elts: elts @@ -2064,9 +2104,9 @@ impl From<(rustpython_parser::ast::Expr, &Locator<'_>)> for Expr { trivia: vec![], parentheses: Parenthesize::Never, }, - rustpython_parser::ast::ExprKind::Slice { lower, upper, step } => { + rustpython_parser::ast::ExprKind::Slice(ast::ExprSlice { lower, upper, step }) => { // Locate the colon tokens, which indicate the number of index segments. - let tokens = rustpython_parser::lexer::lex_located( + let tokens = rustpython_parser::lexer::lex_starts_at( &locator.contents()[expr.range], Mode::Module, expr.range.start(), diff --git a/crates/ruff_python_formatter/src/format/comments.rs b/crates/ruff_python_formatter/src/format/comments.rs index 9d7b3cc42b..c21a1fd8d2 100644 --- a/crates/ruff_python_formatter/src/format/comments.rs +++ b/crates/ruff_python_formatter/src/format/comments.rs @@ -2,13 +2,13 @@ use ruff_formatter::prelude::*; use ruff_formatter::{write, Format}; use crate::context::ASTFormatContext; -use crate::cst::Located; +use crate::cst::Attributed; use crate::format::builders::literal; use crate::trivia::TriviaKind; #[derive(Debug)] pub struct LeadingComments<'a, T> { - item: &'a Located, + item: &'a Attributed, } impl Format> for LeadingComments<'_, T> { @@ -31,13 +31,13 @@ impl Format> for LeadingComments<'_, T> { } #[inline] -pub const fn leading_comments(item: &Located) -> LeadingComments<'_, T> { +pub const fn leading_comments(item: &Attributed) -> LeadingComments<'_, T> { LeadingComments { item } } #[derive(Debug)] pub struct TrailingComments<'a, T> { - item: &'a Located, + item: &'a Attributed, } impl Format> for TrailingComments<'_, T> { @@ -60,13 +60,13 @@ impl Format> for TrailingComments<'_, T> { } #[inline] -pub const fn trailing_comments(item: &Located) -> TrailingComments<'_, T> { +pub const fn trailing_comments(item: &Attributed) -> TrailingComments<'_, T> { TrailingComments { item } } #[derive(Debug)] pub struct EndOfLineComments<'a, T> { - item: &'a Located, + item: &'a Attributed, } impl Format> for EndOfLineComments<'_, T> { @@ -88,13 +88,13 @@ impl Format> for EndOfLineComments<'_, T> { } #[inline] -pub const fn end_of_line_comments(item: &Located) -> EndOfLineComments<'_, T> { +pub const fn end_of_line_comments(item: &Attributed) -> EndOfLineComments<'_, T> { EndOfLineComments { item } } #[derive(Debug)] pub struct DanglingComments<'a, T> { - item: &'a Located, + item: &'a Attributed, } impl Format> for DanglingComments<'_, T> { @@ -113,6 +113,6 @@ impl Format> for DanglingComments<'_, T> { } #[inline] -pub const fn dangling_comments(item: &Located) -> DanglingComments<'_, T> { +pub const fn dangling_comments(item: &Attributed) -> DanglingComments<'_, T> { DanglingComments { item } } diff --git a/crates/ruff_python_formatter/src/format/stmt.rs b/crates/ruff_python_formatter/src/format/stmt.rs index 40fcfbc9d1..b3f6fdb655 100644 --- a/crates/ruff_python_formatter/src/format/stmt.rs +++ b/crates/ruff_python_formatter/src/format/stmt.rs @@ -642,7 +642,7 @@ fn format_import_from( stmt: &Stmt, module: Option<&str>, names: &[Alias], - level: Option, + level: Option, ) -> FormatResult<()> { write!(f, [text("from")])?; write!(f, [space()])?; diff --git a/crates/ruff_python_formatter/src/format/strings.rs b/crates/ruff_python_formatter/src/format/strings.rs index c008824832..299ee23ade 100644 --- a/crates/ruff_python_formatter/src/format/strings.rs +++ b/crates/ruff_python_formatter/src/format/strings.rs @@ -126,7 +126,7 @@ impl Format> for StringLiteral<'_> { // TODO(charlie): This tokenization needs to happen earlier, so that we can attach // comments to individual string literals. let contents = f.context().locator().slice(expr.range()); - let elts = rustpython_parser::lexer::lex_located(contents, Mode::Module, expr.start()) + let elts = rustpython_parser::lexer::lex_starts_at(contents, Mode::Module, expr.start()) .flatten() .filter_map(|(tok, range)| { if matches!(tok, Tok::String { .. }) { diff --git a/crates/ruff_python_semantic/src/analyze/branch_detection.rs b/crates/ruff_python_semantic/src/analyze/branch_detection.rs index efc60fbdad..c5cf134aff 100644 --- a/crates/ruff_python_semantic/src/analyze/branch_detection.rs +++ b/crates/ruff_python_semantic/src/analyze/branch_detection.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use rustpython_parser::ast::ExcepthandlerKind::ExceptHandler; -use rustpython_parser::ast::{Stmt, StmtKind}; +use rustpython_parser::ast::{self, ExcepthandlerKind, Stmt, StmtKind}; use crate::node::{NodeId, Nodes}; @@ -43,26 +42,28 @@ fn common_ancestor( /// Return the alternative branches for a given node. fn alternatives(stmt: &Stmt) -> Vec> { match &stmt.node { - StmtKind::If { body, .. } => vec![body.iter().collect()], - StmtKind::Try { + StmtKind::If(ast::StmtIf { body, .. }) => vec![body.iter().collect()], + StmtKind::Try(ast::StmtTry { body, handlers, orelse, .. - } - | StmtKind::TryStar { + }) + | StmtKind::TryStar(ast::StmtTryStar { body, handlers, orelse, .. - } => vec![body.iter().chain(orelse.iter()).collect()] + }) => vec![body.iter().chain(orelse.iter()).collect()] .into_iter() .chain(handlers.iter().map(|handler| { - let ExceptHandler { body, .. } = &handler.node; + let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { + body, .. + }) = &handler.node; body.iter().collect() })) .collect(), - StmtKind::Match { cases, .. } => cases + StmtKind::Match(ast::StmtMatch { cases, .. }) => cases .iter() .map(|case| case.body.iter().collect()) .collect(), diff --git a/crates/ruff_python_semantic/src/analyze/logging.rs b/crates/ruff_python_semantic/src/analyze/logging.rs index fc1160279a..efc9ca9474 100644 --- a/crates/ruff_python_semantic/src/analyze/logging.rs +++ b/crates/ruff_python_semantic/src/analyze/logging.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{self, Expr, ExprKind}; use ruff_python_ast::call_path::collect_call_path; @@ -17,7 +17,7 @@ use crate::context::Context; /// bar.error() /// ``` pub fn is_logger_candidate(context: &Context, func: &Expr) -> bool { - if let ExprKind::Attribute { value, .. } = &func.node { + if let ExprKind::Attribute(ast::ExprAttribute { value, .. }) = &func.node { let Some(call_path) = (if let Some(call_path) = context.resolve_call_path(value) { if call_path.first().map_or(false, |module| *module == "logging") || call_path.as_slice() == ["flask", "current_app", "logger"] { Some(call_path) diff --git a/crates/ruff_python_semantic/src/analyze/typing.rs b/crates/ruff_python_semantic/src/analyze/typing.rs index 850e1c03bc..586f9f2359 100644 --- a/crates/ruff_python_semantic/src/analyze/typing.rs +++ b/crates/ruff_python_semantic/src/analyze/typing.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Constant, Expr, ExprKind, Operator}; +use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Operator}; use ruff_python_ast::call_path::{from_unqualified_name, CallPath}; use ruff_python_stdlib::typing::{ @@ -30,10 +30,7 @@ pub fn match_annotated_subscript<'a>( context: &Context, typing_modules: impl Iterator, ) -> Option { - if !matches!( - expr.node, - ExprKind::Name { .. } | ExprKind::Attribute { .. } - ) { + if !matches!(expr.node, ExprKind::Name(_) | ExprKind::Attribute(_)) { return None; } @@ -75,7 +72,7 @@ pub fn is_pep585_builtin(expr: &Expr, context: &Context) -> bool { pub fn is_immutable_annotation(context: &Context, expr: &Expr) -> bool { match &expr.node { - ExprKind::Name { .. } | ExprKind::Attribute { .. } => { + ExprKind::Name(_) | ExprKind::Attribute(_) => { context.resolve_call_path(expr).map_or(false, |call_path| { IMMUTABLE_TYPES .iter() @@ -83,7 +80,7 @@ pub fn is_immutable_annotation(context: &Context, expr: &Expr) -> bool { .any(|target| call_path.as_slice() == *target) }) } - ExprKind::Subscript { value, slice, .. } => { + ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => { context.resolve_call_path(value).map_or(false, |call_path| { if IMMUTABLE_GENERIC_TYPES .iter() @@ -91,7 +88,7 @@ pub fn is_immutable_annotation(context: &Context, expr: &Expr) -> bool { { true } else if call_path.as_slice() == ["typing", "Union"] { - if let ExprKind::Tuple { elts, .. } = &slice.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &slice.node { elts.iter().all(|elt| is_immutable_annotation(context, elt)) } else { false @@ -99,7 +96,7 @@ pub fn is_immutable_annotation(context: &Context, expr: &Expr) -> bool { } else if call_path.as_slice() == ["typing", "Optional"] { is_immutable_annotation(context, slice) } else if call_path.as_slice() == ["typing", "Annotated"] { - if let ExprKind::Tuple { elts, .. } = &slice.node { + if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &slice.node { elts.first() .map_or(false, |elt| is_immutable_annotation(context, elt)) } else { @@ -110,15 +107,15 @@ pub fn is_immutable_annotation(context: &Context, expr: &Expr) -> bool { } }) } - ExprKind::BinOp { + ExprKind::BinOp(ast::ExprBinOp { left, op: Operator::BitOr, right, - } => is_immutable_annotation(context, left) && is_immutable_annotation(context, right), - ExprKind::Constant { + }) => is_immutable_annotation(context, left) && is_immutable_annotation(context, right), + ExprKind::Constant(ast::ExprConstant { value: Constant::None, .. - } => true, + }) => true, _ => false, } } diff --git a/crates/ruff_python_semantic/src/analyze/visibility.rs b/crates/ruff_python_semantic/src/analyze/visibility.rs index 83d55bed2b..9d241c5e57 100644 --- a/crates/ruff_python_semantic/src/analyze/visibility.rs +++ b/crates/ruff_python_semantic/src/analyze/visibility.rs @@ -1,6 +1,6 @@ use std::path::Path; -use rustpython_parser::ast::{Expr, Stmt, StmtKind}; +use rustpython_parser::ast::{self, Expr, Stmt, StmtKind}; use ruff_python_ast::call_path::{collect_call_path, CallPath}; use ruff_python_ast::helpers::map_callable; @@ -162,7 +162,8 @@ pub fn module_visibility(module_path: Option<&[String]>, path: &Path) -> Visibil pub fn function_visibility(stmt: &Stmt) -> Visibility { match &stmt.node { - StmtKind::FunctionDef { name, .. } | StmtKind::AsyncFunctionDef { name, .. } => { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, .. }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, .. }) => { if name.starts_with('_') { Visibility::Private } else { @@ -175,16 +176,16 @@ pub fn function_visibility(stmt: &Stmt) -> Visibility { pub fn method_visibility(stmt: &Stmt) -> Visibility { match &stmt.node { - StmtKind::FunctionDef { + StmtKind::FunctionDef(ast::StmtFunctionDef { name, decorator_list, .. - } - | StmtKind::AsyncFunctionDef { + }) + | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { name, decorator_list, .. - } => { + }) => { // Is this a setter or deleter? if decorator_list.iter().any(|expr| { collect_call_path(expr).map_or(false, |call_path| { @@ -213,7 +214,7 @@ pub fn method_visibility(stmt: &Stmt) -> Visibility { pub fn class_visibility(stmt: &Stmt) -> Visibility { match &stmt.node { - StmtKind::ClassDef { name, .. } => { + StmtKind::ClassDef(ast::StmtClassDef { name, .. }) => { if name.starts_with('_') { Visibility::Private } else { diff --git a/crates/ruff_python_semantic/src/binding.rs b/crates/ruff_python_semantic/src/binding.rs index fe0d2ceadd..53092906c0 100644 --- a/crates/ruff_python_semantic/src/binding.rs +++ b/crates/ruff_python_semantic/src/binding.rs @@ -185,7 +185,7 @@ impl From for usize { #[derive(Debug, Clone)] pub struct StarImportation<'a> { /// The level of the import. `None` or `Some(0)` indicate an absolute import. - pub level: Option, + pub level: Option, /// The module being imported. `None` indicates a wildcard import. pub module: Option<&'a str>, } diff --git a/crates/ruff_rustpython/Cargo.toml b/crates/ruff_rustpython/Cargo.toml index 3c4b893d07..e66ba4caa6 100644 --- a/crates/ruff_rustpython/Cargo.toml +++ b/crates/ruff_rustpython/Cargo.toml @@ -9,6 +9,4 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } -once_cell = { workspace = true } -rustpython-common = { workspace = true } rustpython-parser = { workspace = true } diff --git a/crates/ruff_rustpython/src/lib.rs b/crates/ruff_rustpython/src/lib.rs index a40a9db739..c0fcd72e28 100644 --- a/crates/ruff_rustpython/src/lib.rs +++ b/crates/ruff_rustpython/src/lib.rs @@ -1,10 +1,8 @@ use rustpython_parser as parser; -use rustpython_parser::ast::{Mod, Suite}; +use rustpython_parser::ast::{Mod, ModModule, Suite}; use rustpython_parser::lexer::LexResult; use rustpython_parser::{lexer, Mode, ParseError}; -pub mod vendor; - /// Collect tokens up to and including the first error. pub fn tokenize(contents: &str) -> Vec { let mut tokens: Vec = vec![]; @@ -24,7 +22,7 @@ pub fn parse_program_tokens( source_path: &str, ) -> anyhow::Result { parser::parse_tokens(lxr, Mode::Module, source_path).map(|top| match top { - Mod::Module { body, .. } => body, + Mod::Module(ModModule { body, .. }) => body, _ => unreachable!(), }) } diff --git a/crates/ruff_rustpython/src/vendor/bytes.rs b/crates/ruff_rustpython/src/vendor/bytes.rs deleted file mode 100644 index f7f5cdb7ca..0000000000 --- a/crates/ruff_rustpython/src/vendor/bytes.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Vendored from [bytes.rs in rustpython-common](https://github.com/RustPython/RustPython/blob/1d8269fb729c91fc56064e975172d3a11bd62d07/common/src/bytes.rs). -//! The only changes we make are to remove dead code and make the default quote -//! type configurable. - -use crate::vendor; -use crate::vendor::str::Quote; - -pub fn repr(b: &[u8], quote: Quote) -> String { - repr_with(b, &[], "", quote) -} - -pub fn repr_with(b: &[u8], prefixes: &[&str], suffix: &str, quote: Quote) -> String { - use std::fmt::Write; - - let mut out_len = 0usize; - let mut squote = 0; - let mut dquote = 0; - - for &ch in b { - let incr = match ch { - b'\'' => { - squote += 1; - 1 - } - b'"' => { - dquote += 1; - 1 - } - b'\\' | b'\t' | b'\r' | b'\n' => 2, - 0x20..=0x7e => 1, - _ => 4, // \xHH - }; - // TODO: OverflowError - out_len = out_len.checked_add(incr).unwrap(); - } - - let (quote, num_escaped_quotes) = vendor::str::choose_quotes_for_repr(squote, dquote, quote); - // we'll be adding backslashes in front of the existing inner quotes - out_len += num_escaped_quotes; - - // 3 is for b prefix + outer quotes - out_len += 3 + prefixes.iter().map(|s| s.len()).sum::() + suffix.len(); - - let mut res = String::with_capacity(out_len); - res.extend(prefixes.iter().copied()); - res.push('b'); - res.push(quote); - for &ch in b { - match ch { - b'\t' => res.push_str("\\t"), - b'\n' => res.push_str("\\n"), - b'\r' => res.push_str("\\r"), - // printable ascii range - 0x20..=0x7e => { - let ch = ch as char; - if ch == quote || ch == '\\' { - res.push('\\'); - } - res.push(ch); - } - _ => write!(res, "\\x{ch:02x}").unwrap(), - } - } - res.push(quote); - res.push_str(suffix); - - res -} diff --git a/crates/ruff_rustpython/src/vendor/mod.rs b/crates/ruff_rustpython/src/vendor/mod.rs deleted file mode 100644 index e852de30db..0000000000 --- a/crates/ruff_rustpython/src/vendor/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod bytes; -pub mod str; diff --git a/crates/ruff_rustpython/src/vendor/str.rs b/crates/ruff_rustpython/src/vendor/str.rs deleted file mode 100644 index 42920dda22..0000000000 --- a/crates/ruff_rustpython/src/vendor/str.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! Vendored from [str.rs in rustpython-common](https://github.com/RustPython/RustPython/blob/1d8269fb729c91fc56064e975172d3a11bd62d07/common/src/str.rs). -//! The only changes we make are to remove dead code and make the default quote -//! type configurable. - -use std::fmt; - -use once_cell::unsync::OnceCell; - -#[derive(Debug, Clone, Copy)] -pub enum Quote { - Single, - Double, -} - -/// Get a Display-able type that formats to the python `repr()` of the string -/// value. -#[inline] -pub fn repr(s: &str, quote: Quote) -> Repr<'_> { - Repr { - s, - quote, - info: OnceCell::new(), - } -} - -#[derive(Debug, Copy, Clone)] -#[non_exhaustive] -pub struct ReprOverflowError; - -impl fmt::Display for ReprOverflowError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("string is too long to generate repr") - } -} - -#[derive(Copy, Clone)] -struct ReprInfo { - dquoted: bool, - out_len: usize, -} - -impl ReprInfo { - fn get(s: &str, quote: Quote) -> Result { - let mut out_len = 0usize; - let mut squote = 0; - let mut dquote = 0; - - for ch in s.chars() { - let incr = match ch { - '\'' => { - squote += 1; - 1 - } - '"' => { - dquote += 1; - 1 - } - '\\' | '\t' | '\r' | '\n' => 2, - ch if ch < ' ' || ch as u32 == 0x7f => 4, // \xHH - ch if ch.is_ascii() => 1, - ch if rustpython_common::char::is_printable(ch) => { - // max = std::cmp::max(ch, max); - ch.len_utf8() - } - ch if (ch as u32) < 0x100 => 4, // \xHH - ch if (ch as u32) < 0x10000 => 6, // \uHHHH - _ => 10, // \uHHHHHHHH - }; - out_len += incr; - if out_len > std::isize::MAX as usize { - return Err(ReprOverflowError); - } - } - - let (quote, num_escaped_quotes) = choose_quotes_for_repr(squote, dquote, quote); - // we'll be adding backslashes in front of the existing inner quotes - out_len += num_escaped_quotes; - - // start and ending quotes - out_len += 2; - - let dquoted = quote == '"'; - - Ok(ReprInfo { dquoted, out_len }) - } -} - -pub struct Repr<'a> { - s: &'a str, - // the quote type we prefer to use - quote: Quote, - // the tuple is dquouted, out_len - info: OnceCell>, -} - -impl Repr<'_> { - fn get_info(&self) -> Result { - *self.info.get_or_init(|| ReprInfo::get(self.s, self.quote)) - } - - fn _fmt(&self, repr: &mut W, info: ReprInfo) -> fmt::Result { - let s = self.s; - let in_len = s.len(); - let ReprInfo { dquoted, out_len } = info; - - let quote = if dquoted { '"' } else { '\'' }; - // if we don't need to escape anything we can just copy - let unchanged = out_len == in_len; - - repr.write_char(quote)?; - if unchanged { - repr.write_str(s)?; - } else { - for ch in s.chars() { - match ch { - '\n' => repr.write_str("\\n"), - '\t' => repr.write_str("\\t"), - '\r' => repr.write_str("\\r"), - // these 2 branches *would* be handled below, but we shouldn't have to do a - // unicodedata lookup just for ascii characters - '\x20'..='\x7e' => { - // printable ascii range - if ch == quote || ch == '\\' { - repr.write_char('\\')?; - } - repr.write_char(ch) - } - ch if ch.is_ascii() => { - write!(repr, "\\x{:02x}", ch as u8) - } - ch if rustpython_common::char::is_printable(ch) => repr.write_char(ch), - '\0'..='\u{ff}' => { - write!(repr, "\\x{:02x}", ch as u32) - } - '\0'..='\u{ffff}' => { - write!(repr, "\\u{:04x}", ch as u32) - } - _ => { - write!(repr, "\\U{:08x}", ch as u32) - } - }?; - } - } - repr.write_char(quote) - } -} - -impl fmt::Display for Repr<'_> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let info = self.get_info().unwrap(); - self._fmt(f, info) - } -} - -/// Returns the outer quotes to use and the number of quotes that need to be -/// escaped. -pub(crate) const fn choose_quotes_for_repr( - num_squotes: usize, - num_dquotes: usize, - quote: Quote, -) -> (char, usize) { - match quote { - Quote::Single => { - // always use squote unless we have squotes but no dquotes - let use_dquote = num_squotes > 0 && num_dquotes == 0; - if use_dquote { - ('"', num_dquotes) - } else { - ('\'', num_squotes) - } - } - Quote::Double => { - // always use dquote unless we have dquotes but no squotes - let use_squote = num_dquotes > 0 && num_squotes == 0; - if use_squote { - ('\'', num_squotes) - } else { - ('"', num_dquotes) - } - } - } -}