openrewrite-migrate-python 0.13.1__tar.gz → 0.13.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/PKG-INFO +2 -2
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/pyproject.toml +2 -6
- openrewrite_migrate_python-0.13.2/src/openrewrite_code_quality_python/codequality/_reindent.py +77 -0
- openrewrite_migrate_python-0.13.2/src/openrewrite_code_quality_python/codequality/_trivia.py +139 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/all_branches_identical.py +31 -32
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/collapsible_if_statements.py +69 -46
- openrewrite_migrate_python-0.13.2/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +172 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/remove_unconditional_value_overwrite.py +106 -55
- openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/_from_imports.py +68 -0
- openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/_langchain_tables.py +716 -0
- openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/_slots.py +14 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/_typing_imports.py +28 -5
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +37 -25
- openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/datetime_utc.py +274 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +26 -4
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +44 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +52 -42
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +35 -8
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +8 -10
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/platform_deprecations.py +47 -18
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +13 -2
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/string_formatting.py +98 -31
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +109 -53
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +14 -5
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/PKG-INFO +2 -2
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +5 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/requires.txt +1 -1
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_asyncio_coroutine_to_async.py +52 -0
- openrewrite_migrate_python-0.13.2/tests/test_datetime_utc.py +225 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_gettext_deprecations.py +32 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_langchain_classic_imports.py +52 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_langchain_community_imports.py +69 -0
- openrewrite_migrate_python-0.13.2/tests/test_locale_deprecations.py +154 -0
- openrewrite_migrate_python-0.13.2/tests/test_locale_getdefaultlocale_deprecation.py +45 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_platform_deprecations.py +28 -8
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_ssl_deprecations.py +16 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_string_formatting.py +155 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_deprecations.py +343 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_union_to_pipe.py +26 -0
- openrewrite_migrate_python-0.13.1/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +0 -152
- openrewrite_migrate_python-0.13.1/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -137
- openrewrite_migrate_python-0.13.1/tests/test_datetime_utc.py +0 -85
- openrewrite_migrate_python-0.13.1/tests/test_locale_deprecations.py +0 -53
- openrewrite_migrate_python-0.13.1/tests/test_locale_getdefaultlocale_deprecation.py +0 -26
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/setup.cfg +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/__init__.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/_semantically_equal.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/boolean_checks_not_inverted.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/find_suspicious_chained_comparison.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/merge_identical_branches.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/remove_duplicate_conditions.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/simplify_boolean_literal.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/simplify_redundant_logical_expression.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/__init__.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/_import_hygiene.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/_markers.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/future_imports.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/typing_callable.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/uu_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_cgi_parse_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_change_import_recipes.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_future_imports.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pep594_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_sys_last_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_threading_extended.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_alias_moves.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_callable.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_upgrade_recipes.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_xml_deprecations.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrewrite-migrate-python
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
4
4
|
Summary: OpenRewrite recipes for migrating Python codebases to newer Python versions.
|
|
5
5
|
Author-email: "Moderne Inc." <support@moderne.io>
|
|
6
6
|
License: Moderne Proprietary
|
|
@@ -21,7 +21,7 @@ Classifier: Typing :: Typed
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
Provides-Extra: dev
|
|
24
|
-
Requires-Dist: openrewrite>=8.
|
|
24
|
+
Requires-Dist: openrewrite>=8.91.5; extra == "dev"
|
|
25
25
|
Requires-Dist: pydantic>=2.11; extra == "dev"
|
|
26
26
|
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
27
27
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openrewrite-migrate-python"
|
|
7
7
|
description = "OpenRewrite recipes for migrating Python codebases to newer Python versions."
|
|
8
|
-
version = "0.13.
|
|
8
|
+
version = "0.13.2" # Updated dynamically during release
|
|
9
9
|
authors = [{ name = "Moderne Inc.", email = "support@moderne.io" }]
|
|
10
10
|
license = { text = "Moderne Proprietary" }
|
|
11
11
|
readme = "README.md"
|
|
@@ -30,11 +30,7 @@ dependencies = []
|
|
|
30
30
|
|
|
31
31
|
[project.optional-dependencies]
|
|
32
32
|
dev = [
|
|
33
|
-
|
|
34
|
-
# reference to an import: the PEP 585 recipes use it directly, and `ChangeImport`
|
|
35
|
-
# and `RemoveImport` need it to see references inside functions. openrewrite is
|
|
36
|
-
# host-provided at runtime, so this floor only affects dev/CI.
|
|
37
|
-
"openrewrite>=8.89.1",
|
|
33
|
+
"openrewrite>=8.91.5",
|
|
38
34
|
# Needed so type-attribution tests can resolve `pydantic` types.
|
|
39
35
|
"pydantic>=2.11",
|
|
40
36
|
"pytest>=8.0.0",
|
openrewrite_migrate_python-0.13.2/src/openrewrite_code_quality_python/codequality/_reindent.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""Shared indentation helpers for recipes that lift a block out of its parent.
|
|
2
|
+
|
|
3
|
+
Python indentation lives in the ``Space`` before each token, so moving a block
|
|
4
|
+
to a shallower nesting level means rewriting every line it spans.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional, TypeVar
|
|
8
|
+
|
|
9
|
+
from rewrite.java.support_types import Space
|
|
10
|
+
from rewrite.python.visitor import PythonVisitor
|
|
11
|
+
|
|
12
|
+
T = TypeVar("T")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def inherited_prefix(dropped: Space, body: Space) -> Space:
|
|
16
|
+
"""Prefix for the statement that takes the place of a dropped enclosing node.
|
|
17
|
+
|
|
18
|
+
It starts where the dropped node started, and the comments the dropped node
|
|
19
|
+
carried stay ahead of the body's own. Those comments' suffixes already
|
|
20
|
+
indent to the level the body now occupies.
|
|
21
|
+
"""
|
|
22
|
+
return Space(
|
|
23
|
+
_comments=[*dropped.comments, *body.comments],
|
|
24
|
+
_whitespace=dropped.whitespace,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def line_indent(space: Space) -> Optional[str]:
|
|
29
|
+
"""Indentation of the line the token following *space* starts on, or
|
|
30
|
+
``None`` when that token shares a line with what precedes it.
|
|
31
|
+
|
|
32
|
+
A trailing comment puts the newline in the comment's suffix rather than in
|
|
33
|
+
``Space.whitespace``; empty whitespace is a file's first token, at column 0.
|
|
34
|
+
"""
|
|
35
|
+
text = space.comments[-1].suffix if space.comments else space.whitespace
|
|
36
|
+
if "\n" in text:
|
|
37
|
+
return text.rsplit("\n", 1)[-1]
|
|
38
|
+
return text if text == "" else None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _rebase(text: str, old_base: str, new_base: str) -> str:
|
|
42
|
+
head, sep, indent = text.rpartition("\n")
|
|
43
|
+
if not sep or not indent.startswith(old_base):
|
|
44
|
+
return text
|
|
45
|
+
return head + sep + new_base + indent[len(old_base):]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class _Reindent(PythonVisitor[None]):
|
|
49
|
+
def __init__(self, old_base: str, new_base: str):
|
|
50
|
+
super().__init__()
|
|
51
|
+
self._old_base = old_base
|
|
52
|
+
self._new_base = new_base
|
|
53
|
+
|
|
54
|
+
def visit_space(self, space: Optional[Space], p: None) -> Space:
|
|
55
|
+
if space is None:
|
|
56
|
+
return Space.EMPTY
|
|
57
|
+
whitespace = _rebase(space.whitespace, self._old_base, self._new_base)
|
|
58
|
+
comments = [
|
|
59
|
+
c.replace(suffix=_rebase(c.suffix, self._old_base, self._new_base))
|
|
60
|
+
for c in space.comments
|
|
61
|
+
]
|
|
62
|
+
if whitespace == space.whitespace and all(
|
|
63
|
+
c.suffix == o.suffix for c, o in zip(comments, space.comments)
|
|
64
|
+
):
|
|
65
|
+
return space
|
|
66
|
+
return Space(_comments=comments, _whitespace=whitespace)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def reindent(tree: T, old_base: str, new_base: str) -> T:
|
|
70
|
+
"""Re-base every line in *tree* that is indented at least to *old_base*.
|
|
71
|
+
|
|
72
|
+
Lines indented less deeply are continuation lines whose alignment is
|
|
73
|
+
independent of the block's nesting, so they are left alone.
|
|
74
|
+
"""
|
|
75
|
+
if old_base == new_base:
|
|
76
|
+
return tree
|
|
77
|
+
return _Reindent(old_base, new_base).visit(tree, None)
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Line-level trivia splicing for recipes that delete whole statements.
|
|
3
|
+
|
|
4
|
+
A statement's *trailing* comment is stored on whatever the printer emits
|
|
5
|
+
next -- the following statement's prefix, or, for a block's last statement,
|
|
6
|
+
trivia outside the block. Deleting a statement therefore moves trivia
|
|
7
|
+
between its neighbours.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from itertools import islice
|
|
11
|
+
from typing import Optional, Tuple
|
|
12
|
+
|
|
13
|
+
from rewrite import Cursor
|
|
14
|
+
from rewrite.java.support_types import Space
|
|
15
|
+
from rewrite.java.tree import Block, ClassDeclaration, If, MethodDeclaration
|
|
16
|
+
from rewrite.python.tree import CompilationUnit
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def split_line(space: Space) -> Optional[Tuple[Space, Space]]:
|
|
20
|
+
"""Split ``space`` at its first newline, or return None if it has no newline.
|
|
21
|
+
|
|
22
|
+
The head is the trivia that still belongs to the preceding line -- most
|
|
23
|
+
importantly that line's trailing comment. The tail starts with the
|
|
24
|
+
newline itself.
|
|
25
|
+
"""
|
|
26
|
+
newline = space.whitespace.find("\n")
|
|
27
|
+
if newline != -1:
|
|
28
|
+
return (
|
|
29
|
+
Space(_comments=[], _whitespace=space.whitespace[:newline]),
|
|
30
|
+
Space(_comments=space.comments, _whitespace=space.whitespace[newline:]),
|
|
31
|
+
)
|
|
32
|
+
for i, comment in enumerate(space.comments):
|
|
33
|
+
newline = comment.suffix.find("\n")
|
|
34
|
+
if newline != -1:
|
|
35
|
+
return (
|
|
36
|
+
Space(
|
|
37
|
+
_comments=[
|
|
38
|
+
*space.comments[:i],
|
|
39
|
+
comment.replace(_suffix=comment.suffix[:newline]),
|
|
40
|
+
],
|
|
41
|
+
_whitespace=space.whitespace,
|
|
42
|
+
),
|
|
43
|
+
Space(
|
|
44
|
+
_comments=space.comments[i + 1:],
|
|
45
|
+
_whitespace=comment.suffix[newline:],
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def concat(left: Space, right: Space) -> Space:
|
|
52
|
+
"""Return the trivia that prints as ``left`` followed by ``right``."""
|
|
53
|
+
if not left.comments:
|
|
54
|
+
return Space(
|
|
55
|
+
_comments=right.comments,
|
|
56
|
+
_whitespace=left.whitespace + right.whitespace,
|
|
57
|
+
)
|
|
58
|
+
last = left.comments[-1]
|
|
59
|
+
return Space(
|
|
60
|
+
_comments=[
|
|
61
|
+
*left.comments[:-1],
|
|
62
|
+
last.replace(_suffix=last.suffix + right.whitespace),
|
|
63
|
+
*right.comments,
|
|
64
|
+
],
|
|
65
|
+
_whitespace=left.whitespace,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def opens_with_trailing_comment(space: Space) -> bool:
|
|
70
|
+
"""Return True when ``space`` opens with a comment on the line it continues."""
|
|
71
|
+
split = split_line(space)
|
|
72
|
+
return bool((split[0] if split else space).comments)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def space_after_block(cursor: Cursor) -> Optional[Space]:
|
|
76
|
+
"""The trivia the printer emits after the block at ``cursor``.
|
|
77
|
+
|
|
78
|
+
A block's last statement keeps its trailing comment outside the block --
|
|
79
|
+
on the next statement of an enclosing block, on the `else` of an enclosing
|
|
80
|
+
`if`, or at end of file. Returns None for the containers this does not
|
|
81
|
+
know how to look past.
|
|
82
|
+
"""
|
|
83
|
+
child = cursor.value
|
|
84
|
+
for parent in islice(cursor.get_path(), 1, None):
|
|
85
|
+
if isinstance(parent, (Block, CompilationUnit)):
|
|
86
|
+
statements = parent._statements
|
|
87
|
+
index = next(
|
|
88
|
+
(i for i, s in enumerate(statements) if s.element.id == child.id),
|
|
89
|
+
None,
|
|
90
|
+
)
|
|
91
|
+
if index is None:
|
|
92
|
+
return None
|
|
93
|
+
if index + 1 < len(statements):
|
|
94
|
+
return statements[index + 1].element.prefix
|
|
95
|
+
if isinstance(parent, CompilationUnit):
|
|
96
|
+
return parent.eof
|
|
97
|
+
elif isinstance(parent, If):
|
|
98
|
+
if parent.else_part is not None and parent.else_part.id != child.id:
|
|
99
|
+
return parent.else_part.prefix
|
|
100
|
+
elif not isinstance(parent, (ClassDeclaration, If.Else, MethodDeclaration)):
|
|
101
|
+
return None
|
|
102
|
+
child = parent
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def splice_out(
|
|
107
|
+
padded_statements: list, end: Space, to_remove: set[int]
|
|
108
|
+
) -> Tuple[list, Space]:
|
|
109
|
+
"""Return the statements without those at ``to_remove``, and the new end trivia.
|
|
110
|
+
|
|
111
|
+
The survivor takes the removed statement's place on the page: the trivia
|
|
112
|
+
up to the removed statement's own line, which holds the preceding
|
|
113
|
+
statement's trailing comment, then that line's break and indent. Only
|
|
114
|
+
comments standing on their own line before the survivor come from the
|
|
115
|
+
survivor; the removed statement's go with it.
|
|
116
|
+
"""
|
|
117
|
+
result = []
|
|
118
|
+
pending: Optional[Tuple[Space, Space]] = None
|
|
119
|
+
for i, padded in enumerate(padded_statements):
|
|
120
|
+
if i in to_remove:
|
|
121
|
+
if pending is None:
|
|
122
|
+
prefix = padded.element.prefix
|
|
123
|
+
# A file's first statement starts a line without a break to show for it.
|
|
124
|
+
pending = split_line(prefix) or (prefix, Space.EMPTY)
|
|
125
|
+
continue
|
|
126
|
+
if pending is not None:
|
|
127
|
+
head, line = pending
|
|
128
|
+
_, tail = split_line(padded.element.prefix)
|
|
129
|
+
padded = padded.replace(
|
|
130
|
+
_element=padded.element.replace(
|
|
131
|
+
_prefix=concat(
|
|
132
|
+
head,
|
|
133
|
+
Space(_comments=tail.comments, _whitespace=line.whitespace),
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
pending = None
|
|
138
|
+
result.append(padded)
|
|
139
|
+
return result, end if pending is None else concat(pending[0], end)
|
|
@@ -16,12 +16,16 @@ from rewrite.category import CategoryDescriptor
|
|
|
16
16
|
from rewrite.decorators import categorize
|
|
17
17
|
from rewrite.marketplace import Python
|
|
18
18
|
from rewrite.python.visitor import PythonVisitor
|
|
19
|
-
from rewrite.java.support_types import Space
|
|
20
19
|
from rewrite.java.tree import (
|
|
21
20
|
Block,
|
|
22
21
|
If,
|
|
23
22
|
Statement,
|
|
24
23
|
)
|
|
24
|
+
from openrewrite_code_quality_python.codequality._reindent import (
|
|
25
|
+
inherited_prefix,
|
|
26
|
+
line_indent,
|
|
27
|
+
reindent,
|
|
28
|
+
)
|
|
25
29
|
from openrewrite_code_quality_python.codequality._semantically_equal import SemanticallyEqual
|
|
26
30
|
|
|
27
31
|
_CodeQuality = [
|
|
@@ -152,9 +156,6 @@ def _replace_identical_ifs_padded(padded_stmts) -> Optional[list]:
|
|
|
152
156
|
Works on a list of JRightPadded[Statement] and returns a new padded list,
|
|
153
157
|
or None if nothing changed.
|
|
154
158
|
"""
|
|
155
|
-
from rewrite.java.support_types import JRightPadded
|
|
156
|
-
from rewrite.markers import Markers
|
|
157
|
-
|
|
158
159
|
result = []
|
|
159
160
|
changed = False
|
|
160
161
|
for rp in padded_stmts:
|
|
@@ -170,36 +171,34 @@ def _replace_identical_ifs_padded(padded_stmts) -> Optional[list]:
|
|
|
170
171
|
result.append(rp)
|
|
171
172
|
continue
|
|
172
173
|
|
|
173
|
-
# Extract the body statements from the then_part Block.
|
|
174
174
|
body = s.then_part
|
|
175
|
-
if isinstance(body, Block)
|
|
176
|
-
first = True
|
|
177
|
-
for body_rp in body._statements:
|
|
178
|
-
bs = body_rp.element
|
|
179
|
-
if first:
|
|
180
|
-
# First body statement gets the if statement's prefix
|
|
181
|
-
new_elem = bs.replace(_prefix=s.prefix)
|
|
182
|
-
result.append(rp.replace(_element=new_elem))
|
|
183
|
-
first = False
|
|
184
|
-
else:
|
|
185
|
-
# Subsequent body statements keep their whitespace
|
|
186
|
-
# but with one indent level removed
|
|
187
|
-
ws = bs.prefix.whitespace
|
|
188
|
-
if_ws = s.prefix.whitespace
|
|
189
|
-
base = if_ws.split("\n")[-1] if "\n" in if_ws else if_ws
|
|
190
|
-
body_indent = ws.split("\n")[-1] if "\n" in ws else ws
|
|
191
|
-
if len(body_indent) > len(base):
|
|
192
|
-
new_ws = ws.replace(body_indent, base, 1)
|
|
193
|
-
else:
|
|
194
|
-
new_ws = ws
|
|
195
|
-
new_elem = bs.replace(_prefix=Space(
|
|
196
|
-
_comments=bs.prefix.comments,
|
|
197
|
-
_whitespace=new_ws,
|
|
198
|
-
))
|
|
199
|
-
result.append(body_rp.replace(_element=new_elem))
|
|
200
|
-
changed = True
|
|
201
|
-
else:
|
|
175
|
+
if not isinstance(body, Block) or not body._statements:
|
|
202
176
|
result.append(rp)
|
|
177
|
+
continue
|
|
178
|
+
|
|
179
|
+
if_indent = line_indent(s.prefix)
|
|
180
|
+
body_indent = line_indent(body._statements[0].element.prefix)
|
|
181
|
+
if (
|
|
182
|
+
if_indent is None
|
|
183
|
+
or body_indent is None
|
|
184
|
+
or not body_indent.startswith(if_indent)
|
|
185
|
+
):
|
|
186
|
+
result.append(rp)
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
body = reindent(body, body_indent, if_indent)
|
|
190
|
+
first = body._statements[0]
|
|
191
|
+
# Each lifted statement keeps its own padding, which is where a `;`
|
|
192
|
+
# separating it from the next one is recorded.
|
|
193
|
+
result.append(
|
|
194
|
+
first.replace(
|
|
195
|
+
_element=first.element.replace(
|
|
196
|
+
_prefix=inherited_prefix(s.prefix, first.element.prefix)
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
result.extend(body._statements[1:])
|
|
201
|
+
changed = True
|
|
203
202
|
|
|
204
203
|
if not changed:
|
|
205
204
|
return None
|
|
@@ -16,43 +16,61 @@ from rewrite.category import CategoryDescriptor
|
|
|
16
16
|
from rewrite.decorators import categorize
|
|
17
17
|
from rewrite.marketplace import Python
|
|
18
18
|
from rewrite.markers import Markers
|
|
19
|
+
from rewrite.python.tree import StatementExpression
|
|
19
20
|
from rewrite.python.visitor import PythonVisitor
|
|
20
21
|
from rewrite.java.support_types import JLeftPadded, JRightPadded, Space
|
|
21
22
|
from rewrite.java.tree import (
|
|
23
|
+
Assignment,
|
|
22
24
|
Binary as JBinary,
|
|
23
25
|
Block,
|
|
24
26
|
ControlParentheses,
|
|
25
27
|
Expression,
|
|
26
28
|
If,
|
|
29
|
+
Lambda,
|
|
27
30
|
Parentheses,
|
|
31
|
+
Ternary,
|
|
28
32
|
)
|
|
29
33
|
from rewrite.utils import random_id
|
|
30
34
|
|
|
35
|
+
from openrewrite_code_quality_python.codequality._reindent import (
|
|
36
|
+
inherited_prefix,
|
|
37
|
+
line_indent,
|
|
38
|
+
reindent,
|
|
39
|
+
)
|
|
40
|
+
|
|
31
41
|
_CodeQuality = [
|
|
32
42
|
*Python,
|
|
33
43
|
CategoryDescriptor(display_name="Code quality"),
|
|
34
44
|
]
|
|
35
45
|
|
|
36
46
|
|
|
37
|
-
def
|
|
38
|
-
"""Return True
|
|
39
|
-
return isinstance(expr, JBinary) and expr.operator == JBinary.Type.Or
|
|
47
|
+
def _binds_looser_than_and(expr: Expression) -> bool:
|
|
48
|
+
"""Return True for the operand forms that ``and`` would capture.
|
|
40
49
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
Everything below ``and`` in Python's precedence table: ``or``, the
|
|
51
|
+
conditional expression, ``lambda``, ``:=`` (a ``J.Assignment`` here) and
|
|
52
|
+
``yield`` (a ``Py.StatementExpression``).
|
|
53
|
+
"""
|
|
54
|
+
if isinstance(expr, JBinary):
|
|
55
|
+
return expr.operator == JBinary.Type.Or
|
|
56
|
+
return isinstance(expr, (Ternary, Lambda, Assignment, StatementExpression))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _operand(expr: Expression, prefix: Space) -> Expression:
|
|
60
|
+
"""Prepare *expr* as an operand of the merged ``and``, parenthesizing it
|
|
61
|
+
when its own operator would otherwise be captured."""
|
|
62
|
+
if _binds_looser_than_and(expr):
|
|
63
|
+
return Parentheses(
|
|
64
|
+
_id=random_id(),
|
|
65
|
+
_prefix=prefix,
|
|
66
|
+
_markers=Markers.EMPTY,
|
|
67
|
+
_tree=JRightPadded(
|
|
68
|
+
_element=expr.replace(_prefix=Space.EMPTY),
|
|
69
|
+
_after=Space.EMPTY,
|
|
70
|
+
_markers=Markers.EMPTY,
|
|
71
|
+
),
|
|
72
|
+
)
|
|
73
|
+
return expr.replace(_prefix=prefix)
|
|
56
74
|
|
|
57
75
|
|
|
58
76
|
@categorize(_CodeQuality)
|
|
@@ -129,36 +147,34 @@ class CollapsibleIfStatements(Recipe):
|
|
|
129
147
|
if inner.else_part is not None:
|
|
130
148
|
return if_
|
|
131
149
|
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
inner_body = inner.then_part
|
|
151
|
+
if not isinstance(inner_body, Block) or not inner_body.statements:
|
|
152
|
+
return if_
|
|
134
153
|
|
|
135
|
-
#
|
|
136
|
-
#
|
|
137
|
-
if
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
)
|
|
148
|
-
else:
|
|
149
|
-
inner_cond = inner_cond.replace(_prefix=Space.SINGLE_SPACE)
|
|
154
|
+
# The body rises to where the inner `if` header sat, which is
|
|
155
|
+
# always deeper than the surviving header whatever the file's
|
|
156
|
+
# indent unit -- and is a line start even when the outer `if`
|
|
157
|
+
# is an `elif`, whose own prefix holds no newline.
|
|
158
|
+
header_indent = line_indent(inner.prefix)
|
|
159
|
+
body_indent = line_indent(inner_body.statements[0].prefix)
|
|
160
|
+
if (
|
|
161
|
+
header_indent is None
|
|
162
|
+
or body_indent is None
|
|
163
|
+
or not body_indent.startswith(header_indent)
|
|
164
|
+
):
|
|
165
|
+
return if_
|
|
150
166
|
|
|
151
167
|
combined = JBinary(
|
|
152
168
|
_id=random_id(),
|
|
153
|
-
_prefix=
|
|
169
|
+
_prefix=if_.if_condition.tree.prefix,
|
|
154
170
|
_markers=Markers.EMPTY,
|
|
155
|
-
_left=
|
|
171
|
+
_left=_operand(if_.if_condition.tree, Space.EMPTY),
|
|
156
172
|
_operator=JLeftPadded(
|
|
157
173
|
_before=Space.SINGLE_SPACE,
|
|
158
174
|
_element=JBinary.Type.And,
|
|
159
175
|
_markers=Markers.EMPTY,
|
|
160
176
|
),
|
|
161
|
-
_right=
|
|
177
|
+
_right=_operand(inner.if_condition.tree, Space.SINGLE_SPACE),
|
|
162
178
|
_type=None,
|
|
163
179
|
)
|
|
164
180
|
|
|
@@ -173,14 +189,21 @@ class CollapsibleIfStatements(Recipe):
|
|
|
173
189
|
),
|
|
174
190
|
)
|
|
175
191
|
|
|
176
|
-
#
|
|
177
|
-
#
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
192
|
+
# One level per visit: a chain of three or more `if`s merges a
|
|
193
|
+
# level at a time, and each pass rebases the comments the
|
|
194
|
+
# previous one left at the level it dropped.
|
|
195
|
+
inner_body = reindent(inner_body, body_indent, header_indent)
|
|
196
|
+
first = inner_body._statements[0]
|
|
197
|
+
inner_body = inner_body.replace(
|
|
198
|
+
_statements=[
|
|
199
|
+
first.replace(
|
|
200
|
+
_element=first.element.replace(
|
|
201
|
+
_prefix=inherited_prefix(inner.prefix, first.element.prefix)
|
|
202
|
+
)
|
|
203
|
+
),
|
|
204
|
+
*inner_body._statements[1:],
|
|
205
|
+
]
|
|
206
|
+
)
|
|
184
207
|
|
|
185
208
|
return if_.replace(
|
|
186
209
|
_if_condition=new_condition,
|