openrewrite-migrate-python 0.12.0.dev20260811172040__tar.gz → 0.13.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/PKG-INFO +2 -2
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/pyproject.toml +6 -7
- openrewrite_migrate_python-0.13.0/src/openrewrite_code_quality_python/codequality/find_suspicious_chained_comparison.py +122 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +5 -15
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python.egg-info/PKG-INFO +2 -2
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +1 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python.egg-info/requires.txt +1 -1
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_typing_alias_moves.py +32 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_typing_deprecations.py +93 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_upgrade_recipes.py +104 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/setup.cfg +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/__init__.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/_semantically_equal.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/all_branches_identical.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/boolean_checks_not_inverted.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/collapsible_if_statements.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/merge_identical_branches.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/remove_duplicate_conditions.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/remove_unconditional_value_overwrite.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/simplify_boolean_literal.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_code_quality_python/codequality/simplify_redundant_logical_expression.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/__init__.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/_import_hygiene.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/_markers.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/_typing_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/future_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/platform_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/string_formatting.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/typing_callable.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/uu_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_asyncio_coroutine_to_async.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_cgi_parse_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_change_import_recipes.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_datetime_utc.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_future_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_gettext_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_langchain_classic_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_langchain_community_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_locale_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_pep594_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_platform_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_ssl_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_string_formatting.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_sys_last_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_threading_extended.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_typing_callable.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/tests/test_xml_deprecations.py +0 -0
{openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrewrite-migrate-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
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.89.1; 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.
|
|
8
|
+
version = "0.13.0" # 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,12 +30,11 @@ dependencies = []
|
|
|
30
30
|
|
|
31
31
|
[project.optional-dependencies]
|
|
32
32
|
dev = [
|
|
33
|
-
# 8.
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
"openrewrite>=8.84.3",
|
|
33
|
+
# 8.89.1 for `python.scope_utils.LocalBindings`, which tells a local apart from a
|
|
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",
|
|
39
38
|
# Needed so type-attribution tests can resolve `pydantic` types.
|
|
40
39
|
"pydantic>=2.11",
|
|
41
40
|
"pytest>=8.0.0",
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Recipe to find suspicious chained comparisons with conflicting direction.
|
|
3
|
+
|
|
4
|
+
Python evaluates ``a < b < c`` as ``(a < b) and (b < c)``. When the two
|
|
5
|
+
links point in opposite directions--one of ``<``/``<=`` and the other of
|
|
6
|
+
``>``/``>=``--the chain is almost always a mistake, e.g. ``0 <= x >= 10``
|
|
7
|
+
was likely meant to be ``0 <= x <= 10``. This is a search recipe: the
|
|
8
|
+
intent is ambiguous, so it flags the expression rather than rewriting it.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typing import Any, List, Optional
|
|
12
|
+
|
|
13
|
+
from rewrite import ExecutionContext, Recipe, TreeVisitor
|
|
14
|
+
from rewrite.category import CategoryDescriptor
|
|
15
|
+
from rewrite.decorators import categorize
|
|
16
|
+
from rewrite.marketplace import Python
|
|
17
|
+
from rewrite.markers import Markers, SearchResult
|
|
18
|
+
from rewrite.python.visitor import PythonVisitor
|
|
19
|
+
from rewrite.java.tree import Binary as JBinary, Expression
|
|
20
|
+
from rewrite.utils import random_id
|
|
21
|
+
|
|
22
|
+
_CodeQuality = [
|
|
23
|
+
*Python,
|
|
24
|
+
CategoryDescriptor(display_name="Code quality"),
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
_LESS = (JBinary.Type.LessThan, JBinary.Type.LessThanOrEqual)
|
|
28
|
+
_GREATER = (JBinary.Type.GreaterThan, JBinary.Type.GreaterThanOrEqual)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _direction(operator: JBinary.Type) -> Optional[str]:
|
|
32
|
+
"""Classify an ordering operator as ``"less"``, ``"greater"``, or None."""
|
|
33
|
+
if operator in _LESS:
|
|
34
|
+
return "less"
|
|
35
|
+
if operator in _GREATER:
|
|
36
|
+
return "greater"
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _mark(tree: Expression) -> Expression:
|
|
41
|
+
"""Attach a SearchResult flagging the conflicting chained comparison."""
|
|
42
|
+
message = (
|
|
43
|
+
"Suspicious chained comparison: the two comparisons point in "
|
|
44
|
+
"opposite directions, so the chain narrows to a surprising range. "
|
|
45
|
+
"Did you mean to keep both comparisons in the same direction?"
|
|
46
|
+
)
|
|
47
|
+
marker = SearchResult(random_id(), message)
|
|
48
|
+
current = tree.markers
|
|
49
|
+
return tree.replace(
|
|
50
|
+
_markers=Markers(current.id, list(current.markers) + [marker])
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@categorize(_CodeQuality)
|
|
55
|
+
class FindSuspiciousChainedComparison(Recipe):
|
|
56
|
+
"""
|
|
57
|
+
Find chained comparisons whose links point in opposite directions.
|
|
58
|
+
|
|
59
|
+
A chain such as ``0 <= x >= 10`` reads as ``0 <= x and x >= 10``, which
|
|
60
|
+
is a needlessly convoluted way to say ``x >= 10`` and is almost always a
|
|
61
|
+
typo for ``0 <= x <= 10``. Mixing ``<``/``<=`` with ``>``/``>=`` in a
|
|
62
|
+
single chain is the tell-tale sign.
|
|
63
|
+
|
|
64
|
+
Example:
|
|
65
|
+
Flagged:
|
|
66
|
+
if 0 <= x >= 10:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
Not flagged (monotonic):
|
|
70
|
+
if 0 <= x <= 10:
|
|
71
|
+
pass
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def name(self) -> str:
|
|
76
|
+
return "org.openrewrite.python.codequality.FindSuspiciousChainedComparison"
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def display_name(self) -> str:
|
|
80
|
+
return "Find suspicious chained comparisons"
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def description(self) -> str:
|
|
84
|
+
return (
|
|
85
|
+
"Find chained comparisons that mix `<`/`<=` with `>`/`>=` (for "
|
|
86
|
+
"example `0 <= x >= 10`), where the links point in opposite "
|
|
87
|
+
"directions and the chain is almost always a mistake."
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def tags(self) -> List[str]:
|
|
92
|
+
return ["python", "code-quality"]
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def estimated_effort_per_occurrence(self) -> int:
|
|
96
|
+
return 5
|
|
97
|
+
|
|
98
|
+
def editor(self) -> TreeVisitor[Any, ExecutionContext]:
|
|
99
|
+
class Visitor(PythonVisitor[ExecutionContext]):
|
|
100
|
+
def visit_binary(
|
|
101
|
+
self, binary: JBinary, p: ExecutionContext
|
|
102
|
+
) -> Optional[Expression]:
|
|
103
|
+
binary = super().visit_binary(binary, p)
|
|
104
|
+
|
|
105
|
+
if not isinstance(binary, JBinary):
|
|
106
|
+
return binary
|
|
107
|
+
|
|
108
|
+
outer = _direction(binary.operator)
|
|
109
|
+
if outer is None:
|
|
110
|
+
return binary
|
|
111
|
+
|
|
112
|
+
inner = binary.left
|
|
113
|
+
if not isinstance(inner, JBinary):
|
|
114
|
+
return binary
|
|
115
|
+
|
|
116
|
+
left = _direction(inner.operator)
|
|
117
|
+
if left is None or left == outer:
|
|
118
|
+
return binary
|
|
119
|
+
|
|
120
|
+
return _mark(binary)
|
|
121
|
+
|
|
122
|
+
return Visitor()
|
|
@@ -29,6 +29,7 @@ from rewrite.decorators import categorize
|
|
|
29
29
|
from rewrite.marketplace import Python
|
|
30
30
|
from rewrite.python.import_utils import get_alias_name, get_name_string, get_qualid_name
|
|
31
31
|
from rewrite.python.remove_import import RemoveImportOptions, maybe_remove_import
|
|
32
|
+
from rewrite.python.scope_utils import LocalBindings
|
|
32
33
|
|
|
33
34
|
from ._typing_imports import maybe_remove_typing_module_import
|
|
34
35
|
from rewrite.python.tree import CompilationUnit, MultiImport, NamedArgument
|
|
@@ -39,8 +40,6 @@ from rewrite.java.tree import (
|
|
|
39
40
|
Import,
|
|
40
41
|
J,
|
|
41
42
|
Literal,
|
|
42
|
-
MethodDeclaration,
|
|
43
|
-
VariableDeclarations,
|
|
44
43
|
)
|
|
45
44
|
|
|
46
45
|
# Define category paths
|
|
@@ -81,6 +80,7 @@ def _make_builtin_alias_editor(old_name: str, new_name: str) -> "TreeVisitor[Any
|
|
|
81
80
|
self._module_refs: Set[str] = set()
|
|
82
81
|
self._keep_from_import: bool = False
|
|
83
82
|
self._rewrote_qualified: bool = False
|
|
83
|
+
self._local_bindings = LocalBindings()
|
|
84
84
|
|
|
85
85
|
def visit_compilation_unit(
|
|
86
86
|
self, cu: CompilationUnit, p: ExecutionContext
|
|
@@ -88,6 +88,7 @@ def _make_builtin_alias_editor(old_name: str, new_name: str) -> "TreeVisitor[Any
|
|
|
88
88
|
self._bare_ref = None
|
|
89
89
|
self._module_refs = set()
|
|
90
90
|
self._rewrote_qualified = False
|
|
91
|
+
self._local_bindings = LocalBindings()
|
|
91
92
|
|
|
92
93
|
for stmt in cu.statements:
|
|
93
94
|
if isinstance(stmt, MultiImport):
|
|
@@ -172,19 +173,8 @@ def _make_builtin_alias_editor(old_name: str, new_name: str) -> "TreeVisitor[Any
|
|
|
172
173
|
# A keyword-argument name (`f(List=...)`) names a parameter.
|
|
173
174
|
if isinstance(parent, NamedArgument) and parent.name.id == ident.id:
|
|
174
175
|
return ident
|
|
175
|
-
# A
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
isinstance(parent, VariableDeclarations.NamedVariable)
|
|
179
|
-
and parent.name.id == ident.id
|
|
180
|
-
):
|
|
181
|
-
return ident
|
|
182
|
-
# Inside function scopes, type attribution marks shadowed locals
|
|
183
|
-
# with a field type; module-level references never carry one.
|
|
184
|
-
if (
|
|
185
|
-
self.cursor.first_enclosing(MethodDeclaration) is not None
|
|
186
|
-
and ident.field_type is not None
|
|
187
|
-
):
|
|
176
|
+
# A name bound by an enclosing scope is that local, not the import.
|
|
177
|
+
if self._local_bindings.is_bound(self.cursor, self._bare_ref):
|
|
188
178
|
return ident
|
|
189
179
|
|
|
190
180
|
return ident.replace(_simple_name=new_name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrewrite-migrate-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
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.89.1; 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,6 +5,7 @@ src/openrewrite_code_quality_python/codequality/_semantically_equal.py
|
|
|
5
5
|
src/openrewrite_code_quality_python/codequality/all_branches_identical.py
|
|
6
6
|
src/openrewrite_code_quality_python/codequality/boolean_checks_not_inverted.py
|
|
7
7
|
src/openrewrite_code_quality_python/codequality/collapsible_if_statements.py
|
|
8
|
+
src/openrewrite_code_quality_python/codequality/find_suspicious_chained_comparison.py
|
|
8
9
|
src/openrewrite_code_quality_python/codequality/merge_identical_branches.py
|
|
9
10
|
src/openrewrite_code_quality_python/codequality/remove_duplicate_conditions.py
|
|
10
11
|
src/openrewrite_code_quality_python/codequality/remove_self_assignment.py
|
|
@@ -120,6 +120,38 @@ class TestTypingAliasMoves:
|
|
|
120
120
|
)
|
|
121
121
|
)
|
|
122
122
|
|
|
123
|
+
@pytest.mark.parametrize("alias", sorted(a for a in EXPECTED_MOVES if EXPECTED_MOVES[a][1]))
|
|
124
|
+
def test_migrates_alias_referenced_inside_a_function(self, alias):
|
|
125
|
+
module, new_name = EXPECTED_MOVES[alias]
|
|
126
|
+
spec = RecipeSpec(
|
|
127
|
+
recipe=ChangeImport(
|
|
128
|
+
old_module="typing",
|
|
129
|
+
old_name=alias,
|
|
130
|
+
new_module=module,
|
|
131
|
+
new_name=new_name,
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
spec.rewrite_run(
|
|
135
|
+
python(
|
|
136
|
+
f"""
|
|
137
|
+
from typing import {alias}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def f(q: {alias}) -> {alias}:
|
|
141
|
+
local: {alias} = q
|
|
142
|
+
return local
|
|
143
|
+
""",
|
|
144
|
+
f"""
|
|
145
|
+
from {module} import {new_name}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def f(q: {new_name}) -> {new_name}:
|
|
149
|
+
local: {new_name} = q
|
|
150
|
+
return local
|
|
151
|
+
""",
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
|
|
123
155
|
def test_migrating_all_names_of_an_import_leaves_no_blank_line(self):
|
|
124
156
|
spec = RecipeSpec().with_recipes(
|
|
125
157
|
ChangeImport(old_module="typing", old_name="Iterable", new_module="collections.abc"),
|
|
@@ -317,6 +317,99 @@ class TestPep585CornerCases:
|
|
|
317
317
|
)
|
|
318
318
|
)
|
|
319
319
|
|
|
320
|
+
def test_renames_usages_inside_functions(self):
|
|
321
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
322
|
+
spec.rewrite_run(
|
|
323
|
+
python(
|
|
324
|
+
"""
|
|
325
|
+
from typing import List
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def collect(items: List[str]) -> List[int]:
|
|
329
|
+
order: List[int] = []
|
|
330
|
+
for item in items:
|
|
331
|
+
order.append(len(item))
|
|
332
|
+
return order
|
|
333
|
+
""",
|
|
334
|
+
"""
|
|
335
|
+
def collect(items: list[str]) -> list[int]:
|
|
336
|
+
order: list[int] = []
|
|
337
|
+
for item in items:
|
|
338
|
+
order.append(len(item))
|
|
339
|
+
return order
|
|
340
|
+
""",
|
|
341
|
+
)
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
def test_narrows_import_to_names_without_builtin_equivalents(self):
|
|
345
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
346
|
+
spec.rewrite_run(
|
|
347
|
+
python(
|
|
348
|
+
"""
|
|
349
|
+
from typing import Dict, List, Optional
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def resolve(names: List[str], mapping: Dict[str, str]) -> Optional[str]:
|
|
353
|
+
return mapping.get(names[0])
|
|
354
|
+
""",
|
|
355
|
+
"""
|
|
356
|
+
from typing import Dict, Optional
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def resolve(names: list[str], mapping: Dict[str, str]) -> Optional[str]:
|
|
360
|
+
return mapping.get(names[0])
|
|
361
|
+
""",
|
|
362
|
+
)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
def test_leaves_a_local_that_shadows_the_import(self):
|
|
366
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
367
|
+
spec.rewrite_run(
|
|
368
|
+
python(
|
|
369
|
+
"""
|
|
370
|
+
from typing import List
|
|
371
|
+
|
|
372
|
+
x: List[int] = []
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def render():
|
|
376
|
+
List = ", ".join(str(i) for i in x)
|
|
377
|
+
return List
|
|
378
|
+
""",
|
|
379
|
+
"""
|
|
380
|
+
x: list[int] = []
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def render():
|
|
384
|
+
List = ", ".join(str(i) for i in x)
|
|
385
|
+
return List
|
|
386
|
+
""",
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
def test_leaves_a_parameter_that_shadows_the_import(self):
|
|
391
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
392
|
+
spec.rewrite_run(
|
|
393
|
+
python(
|
|
394
|
+
"""
|
|
395
|
+
from typing import List
|
|
396
|
+
|
|
397
|
+
x: List[int] = []
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def render(List):
|
|
401
|
+
return List
|
|
402
|
+
""",
|
|
403
|
+
"""
|
|
404
|
+
x: list[int] = []
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def render(List):
|
|
408
|
+
return List
|
|
409
|
+
""",
|
|
410
|
+
)
|
|
411
|
+
)
|
|
412
|
+
|
|
320
413
|
def test_keeps_import_used_by_string_annotation(self):
|
|
321
414
|
"""The import stays while a string annotation still references it."""
|
|
322
415
|
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
@@ -9,7 +9,9 @@ from openrewrite_migrate_python.migrate import (
|
|
|
9
9
|
UpgradeToPython313,
|
|
10
10
|
UpgradeToPython314,
|
|
11
11
|
)
|
|
12
|
+
from rewrite import Recipe
|
|
12
13
|
from rewrite.rpc import RpcRecipe
|
|
14
|
+
from rewrite.test import RecipeSpec, python
|
|
13
15
|
|
|
14
16
|
class TestUpgradeRecipeChaining:
|
|
15
17
|
"""Tests for verifying upgrade recipe chaining."""
|
|
@@ -203,3 +205,105 @@ class TestPydanticUpgradeChaining:
|
|
|
203
205
|
recipe = UpgradeToPydantic211()
|
|
204
206
|
assert recipe.name == "org.openrewrite.python.migrate.pydantic.UpgradeToPydantic211"
|
|
205
207
|
assert "pydantic" in recipe.tags
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class _NativeUpgradeToPython313(Recipe):
|
|
211
|
+
"""`UpgradeToPython313` without its `RpcRecipe` steps, which need a Java host."""
|
|
212
|
+
|
|
213
|
+
@property
|
|
214
|
+
def name(self) -> str:
|
|
215
|
+
return "test.NativeUpgradeToPython313"
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def display_name(self) -> str:
|
|
219
|
+
return "Upgrade to Python 3.13 (native steps only)"
|
|
220
|
+
|
|
221
|
+
@property
|
|
222
|
+
def description(self) -> str:
|
|
223
|
+
return "Runs the in-process steps of `UpgradeToPython313` in composite order."
|
|
224
|
+
|
|
225
|
+
def recipe_list(self):
|
|
226
|
+
def leaves(recipe):
|
|
227
|
+
for sub in recipe.recipe_list():
|
|
228
|
+
if isinstance(sub, RpcRecipe):
|
|
229
|
+
continue
|
|
230
|
+
nested = sub.recipe_list()
|
|
231
|
+
if nested:
|
|
232
|
+
yield from leaves(sub)
|
|
233
|
+
else:
|
|
234
|
+
yield sub
|
|
235
|
+
|
|
236
|
+
return list(leaves(UpgradeToPython313()))
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class TestUpgradeToPython313TypingConsistency:
|
|
240
|
+
"""The typing imports a file keeps must match the names it still uses."""
|
|
241
|
+
|
|
242
|
+
def test_migrates_imports_and_usages_together(self):
|
|
243
|
+
spec = RecipeSpec(recipe=_NativeUpgradeToPython313())
|
|
244
|
+
spec.rewrite_run(
|
|
245
|
+
python(
|
|
246
|
+
"""
|
|
247
|
+
from typing import List, Dict, Set, Tuple, Optional, Callable, Iterable
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def collect(items: List[str], index: Dict[str, int]) -> Tuple[Set[str], List[int]]:
|
|
251
|
+
seen: Set[str] = set()
|
|
252
|
+
order: List[int] = []
|
|
253
|
+
for item in items:
|
|
254
|
+
if item not in seen:
|
|
255
|
+
seen.add(item)
|
|
256
|
+
order.append(index.get(item, -1))
|
|
257
|
+
return seen, order
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def apply_all(fns: Iterable[Callable[[int], int]], value: int) -> Optional[int]:
|
|
261
|
+
for fn in fns:
|
|
262
|
+
value = fn(value)
|
|
263
|
+
return value
|
|
264
|
+
""",
|
|
265
|
+
"""
|
|
266
|
+
from collections.abc import Callable, Iterable
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def collect(items: list[str], index: dict[str, int]) -> tuple[set[str], list[int]]:
|
|
270
|
+
seen: set[str] = set()
|
|
271
|
+
order: list[int] = []
|
|
272
|
+
for item in items:
|
|
273
|
+
if item not in seen:
|
|
274
|
+
seen.add(item)
|
|
275
|
+
order.append(index.get(item, -1))
|
|
276
|
+
return seen, order
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def apply_all(fns: Iterable[Callable[[int], int]], value: int) -> int | None:
|
|
280
|
+
for fn in fns:
|
|
281
|
+
value = fn(value)
|
|
282
|
+
return value
|
|
283
|
+
""",
|
|
284
|
+
)
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
def test_migrates_imports_and_usages_together_in_a_smaller_file(self):
|
|
288
|
+
spec = RecipeSpec(recipe=_NativeUpgradeToPython313())
|
|
289
|
+
spec.rewrite_run(
|
|
290
|
+
python(
|
|
291
|
+
"""
|
|
292
|
+
from typing import List, Dict, Optional
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def resolve(names: List[str], mapping: Dict[str, str]) -> Optional[str]:
|
|
296
|
+
for name in names:
|
|
297
|
+
if name in mapping:
|
|
298
|
+
return mapping[name]
|
|
299
|
+
return None
|
|
300
|
+
""",
|
|
301
|
+
"""
|
|
302
|
+
def resolve(names: list[str], mapping: dict[str, str]) -> str | None:
|
|
303
|
+
for name in names:
|
|
304
|
+
if name in mapping:
|
|
305
|
+
return mapping[name]
|
|
306
|
+
return None
|
|
307
|
+
""",
|
|
308
|
+
)
|
|
309
|
+
)
|
{openrewrite_migrate_python-0.12.0.dev20260811172040 → openrewrite_migrate_python-0.13.0}/setup.cfg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|