openrewrite-migrate-python 0.14.0.dev20260909084854__tar.gz → 0.14.0.dev20260909112655__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.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/PKG-INFO +1 -1
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/pyproject.toml +1 -1
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +73 -15
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python.egg-info/PKG-INFO +1 -1
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_typing_deprecations.py +152 -33
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/setup.cfg +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/__init__.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/_reindent.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/_semantically_equal.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/_trivia.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/all_branches_identical.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/boolean_checks_not_inverted.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/collapsible_if_statements.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/find_suspicious_chained_comparison.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/merge_identical_branches.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/remove_duplicate_conditions.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/remove_unconditional_value_overwrite.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/simplify_boolean_literal.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_code_quality_python/codequality/simplify_redundant_logical_expression.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/__init__.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/_from_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/_import_hygiene.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/_langchain_tables.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/_markers.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/_slots.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/_typing_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/future_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/platform_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/string_formatting.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/typing_callable.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/uu_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python.egg-info/requires.txt +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_asyncio_coroutine_to_async.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_cgi_parse_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_change_import_recipes.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_datetime_utc.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_distutils_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_functools_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_future_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_gettext_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_langchain_classic_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_langchain_community_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_locale_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_mailcap_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_markers.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_pathlib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_pep594_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_platform_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_socket_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_ssl_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_string_formatting.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_sys_last_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_tempfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_threading_extended.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_typing_alias_moves.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_typing_callable.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_upgrade_recipes.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_urllib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/tests/test_xdrlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.14.0.dev20260909084854 → openrewrite_migrate_python-0.14.0.dev20260909112655}/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.14.0.
|
|
3
|
+
Version: 0.14.0.dev20260909112655
|
|
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
|
|
@@ -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.14.0.
|
|
8
|
+
version = "0.14.0.dev20260909112655" # 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"
|
|
@@ -20,12 +20,15 @@ handled with `ChangeImport` in `upgrade_to_python39`.
|
|
|
20
20
|
See: https://peps.python.org/pep-0585/
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
+
import ast
|
|
23
24
|
from typing import Any, ClassVar, Optional, Set, cast
|
|
24
25
|
|
|
25
26
|
from rewrite import ExecutionContext, Recipe, Tree, TreeVisitor
|
|
26
27
|
from rewrite.category import CategoryDescriptor
|
|
27
28
|
from rewrite.decorators import categorize
|
|
28
29
|
from rewrite.marketplace import Python
|
|
30
|
+
from rewrite.python.import_utils import referenced_names
|
|
31
|
+
from rewrite.python.markers import Quoted
|
|
29
32
|
from rewrite.python.scope_utils import LocalBindings
|
|
30
33
|
from rewrite.visitor import Cursor
|
|
31
34
|
|
|
@@ -37,6 +40,7 @@ from ._typing_imports import (
|
|
|
37
40
|
from rewrite.python.tree import (
|
|
38
41
|
CollectionLiteral,
|
|
39
42
|
CompilationUnit,
|
|
43
|
+
ExpressionTypeTree,
|
|
40
44
|
MultiImport,
|
|
41
45
|
NamedArgument,
|
|
42
46
|
TypeAlias,
|
|
@@ -47,11 +51,13 @@ from rewrite.python.visitor import PythonVisitor
|
|
|
47
51
|
from rewrite.java.tree import (
|
|
48
52
|
ArrayAccess,
|
|
49
53
|
Assignment,
|
|
54
|
+
ClassDeclaration,
|
|
50
55
|
FieldAccess,
|
|
51
56
|
Identifier,
|
|
52
57
|
Import,
|
|
53
58
|
J,
|
|
54
59
|
ParameterizedType,
|
|
60
|
+
TypeParameter,
|
|
55
61
|
VariableDeclarations,
|
|
56
62
|
)
|
|
57
63
|
|
|
@@ -102,12 +108,12 @@ def _annotated_type_argument(subscript: Tree) -> Optional[J]:
|
|
|
102
108
|
return arguments[0]
|
|
103
109
|
|
|
104
110
|
|
|
105
|
-
def
|
|
111
|
+
def _in_type_position(cursor: Cursor) -> bool:
|
|
106
112
|
"""True when the cursor's node stands where a type expression is expected.
|
|
107
113
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
A type position is the only one where a `typing` alias and its built-in are
|
|
115
|
+
interchangeable; elsewhere they are distinct objects, so a dict key or a
|
|
116
|
+
call argument spelling the alias must keep naming it.
|
|
111
117
|
"""
|
|
112
118
|
walked = [cursor.value]
|
|
113
119
|
parent_cursor = cursor.parent_tree_cursor()
|
|
@@ -122,6 +128,16 @@ def _in_annotation(cursor: Cursor) -> bool:
|
|
|
122
128
|
return parent.value is child
|
|
123
129
|
if isinstance(parent, Assignment):
|
|
124
130
|
return parent.assignment is child and _names_type_alias(parent.variable)
|
|
131
|
+
# A type parameter's bound, constraint tuple and PEP 696 default are
|
|
132
|
+
# types; its name is the type parameter being declared.
|
|
133
|
+
if isinstance(parent, TypeParameter):
|
|
134
|
+
return parent.name is not child
|
|
135
|
+
# `implements` holds the base list, where an `ExpressionTypeTree` wraps
|
|
136
|
+
# a keyword argument or a computed base rather than a type.
|
|
137
|
+
if isinstance(parent, ClassDeclaration):
|
|
138
|
+
return not isinstance(child, ExpressionTypeTree) and any(
|
|
139
|
+
base is child for base in (parent.implements or [])
|
|
140
|
+
)
|
|
125
141
|
# `Annotated` carries a type in its first argument and runtime metadata
|
|
126
142
|
# in the rest, which a tuple wraps a level below the subscript.
|
|
127
143
|
annotated_type = _annotated_type_argument(parent)
|
|
@@ -132,8 +148,46 @@ def _in_annotation(cursor: Cursor) -> bool:
|
|
|
132
148
|
return False
|
|
133
149
|
|
|
134
150
|
|
|
151
|
+
def _rename_in_quoted_body(body: str, old_name: str, new_name: str) -> Optional[str]:
|
|
152
|
+
"""`body` with each name lookup of `old_name` renamed, or None when it holds none.
|
|
153
|
+
|
|
154
|
+
A quoted annotation carries a whole expression in one identifier, so the
|
|
155
|
+
rename has to land on its `ast.Name` nodes. Only parsing separates those
|
|
156
|
+
from a string constant the body encloses, where the name is a value:
|
|
157
|
+
renaming in `Literal['Text', 'Binary']` would change the type.
|
|
158
|
+
"""
|
|
159
|
+
stripped = body.strip()
|
|
160
|
+
try:
|
|
161
|
+
expression = ast.parse(stripped, mode="eval")
|
|
162
|
+
except (SyntaxError, ValueError):
|
|
163
|
+
return None
|
|
164
|
+
matches = [
|
|
165
|
+
node
|
|
166
|
+
for node in ast.walk(expression)
|
|
167
|
+
if isinstance(node, ast.Name) and node.id == old_name
|
|
168
|
+
]
|
|
169
|
+
if not matches:
|
|
170
|
+
return None
|
|
171
|
+
|
|
172
|
+
# `col_offset` counts UTF-8 bytes, so the splice has to happen in bytes.
|
|
173
|
+
source = stripped.encode()
|
|
174
|
+
line_starts = [0]
|
|
175
|
+
for line in source.split(b"\n"):
|
|
176
|
+
line_starts.append(line_starts[-1] + len(line) + 1)
|
|
177
|
+
for node in sorted(matches, key=lambda n: (n.lineno, n.col_offset), reverse=True):
|
|
178
|
+
line = line_starts[node.lineno - 1]
|
|
179
|
+
source = (
|
|
180
|
+
source[: line + node.col_offset]
|
|
181
|
+
+ new_name.encode()
|
|
182
|
+
+ source[line + cast(int, node.end_col_offset) :]
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
leading = len(body) - len(body.lstrip())
|
|
186
|
+
return body[:leading] + source.decode() + body[leading + len(stripped) :]
|
|
187
|
+
|
|
188
|
+
|
|
135
189
|
def _make_builtin_alias_editor(
|
|
136
|
-
old_name: str, new_name: str,
|
|
190
|
+
old_name: str, new_name: str, type_positions_only: bool
|
|
137
191
|
) -> "TreeVisitor[Any, ExecutionContext]":
|
|
138
192
|
"""Create a visitor that renames a typing alias to its built-in equivalent.
|
|
139
193
|
|
|
@@ -144,8 +198,8 @@ def _make_builtin_alias_editor(
|
|
|
144
198
|
- ``import typing [as alias]`` plus qualified ``typing.<old_name>``
|
|
145
199
|
attribute references
|
|
146
200
|
|
|
147
|
-
``
|
|
148
|
-
(see `
|
|
201
|
+
``type_positions_only`` confines the rename to type positions
|
|
202
|
+
(see `_in_type_position`).
|
|
149
203
|
|
|
150
204
|
Import removal is delegated to the SDK's `RemoveImport`, which only
|
|
151
205
|
removes imports that are no longer referenced and preserves comments.
|
|
@@ -190,7 +244,7 @@ def _make_builtin_alias_editor(
|
|
|
190
244
|
isinstance(field_access.target, Identifier)
|
|
191
245
|
and field_access.target.simple_name in self._module_refs
|
|
192
246
|
and field_access.name.simple_name == old_name
|
|
193
|
-
and (not
|
|
247
|
+
and (not type_positions_only or _in_type_position(self.cursor))
|
|
194
248
|
):
|
|
195
249
|
self._rewrote_qualified = True
|
|
196
250
|
return field_access.name.replace(_simple_name=new_name).replace(
|
|
@@ -200,7 +254,7 @@ def _make_builtin_alias_editor(
|
|
|
200
254
|
|
|
201
255
|
def visit_identifier(self, ident: Identifier, p: ExecutionContext) -> J:
|
|
202
256
|
ident = cast(Identifier, super().visit_identifier(ident, p))
|
|
203
|
-
if self._bare_ref is None or
|
|
257
|
+
if self._bare_ref is None or self._bare_ref not in referenced_names(ident):
|
|
204
258
|
return ident
|
|
205
259
|
|
|
206
260
|
# Skip identifiers that are part of import statements
|
|
@@ -221,9 +275,12 @@ def _make_builtin_alias_editor(
|
|
|
221
275
|
# A name bound by an enclosing scope is that local, not the import.
|
|
222
276
|
if self._local_bindings.is_bound(self.cursor, self._bare_ref):
|
|
223
277
|
return ident
|
|
224
|
-
if
|
|
278
|
+
if type_positions_only and not _in_type_position(self.cursor):
|
|
225
279
|
return ident
|
|
226
280
|
|
|
281
|
+
if ident.markers.find_first(Quoted) is not None:
|
|
282
|
+
renamed = _rename_in_quoted_body(ident.simple_name, self._bare_ref, new_name)
|
|
283
|
+
return ident if renamed is None else ident.replace(_simple_name=renamed)
|
|
227
284
|
return ident.replace(_simple_name=new_name)
|
|
228
285
|
|
|
229
286
|
return BuiltinAliasVisitor()
|
|
@@ -235,7 +292,7 @@ class _ReplaceTypingAliasRecipe(Recipe):
|
|
|
235
292
|
old_name: ClassVar[str]
|
|
236
293
|
new_name: ClassVar[str]
|
|
237
294
|
# False only where the alias *is* the built-in, so any position is safe.
|
|
238
|
-
|
|
295
|
+
type_positions_only: ClassVar[bool] = True
|
|
239
296
|
|
|
240
297
|
@property
|
|
241
298
|
def name(self) -> str:
|
|
@@ -252,17 +309,18 @@ class _ReplaceTypingAliasRecipe(Recipe):
|
|
|
252
309
|
def description(self) -> str:
|
|
253
310
|
return (
|
|
254
311
|
f"PEP 585 deprecated `typing.{self.old_name}` in Python 3.9. "
|
|
255
|
-
f"Replace with the built-in `{self.new_name}` type
|
|
312
|
+
f"Replace it with the built-in `{self.new_name}` wherever a type is expected, "
|
|
313
|
+
f"including class base lists, where either spelling subclasses `{self.new_name}`. "
|
|
256
314
|
"Applies inside `if TYPE_CHECKING:` blocks as well; the built-in generic is "
|
|
257
315
|
"valid at runtime from Python 3.9 on, so no `from __future__ import "
|
|
258
316
|
"annotations` is needed. "
|
|
259
|
-
f"References
|
|
317
|
+
f"References in a value position are left alone: `typing.{self.old_name}` "
|
|
260
318
|
f"and `{self.new_name}` are distinct objects, so substituting one for the "
|
|
261
319
|
"other where the name is used as a value would change behaviour."
|
|
262
320
|
)
|
|
263
321
|
|
|
264
322
|
def editor(self) -> TreeVisitor[Any, ExecutionContext]:
|
|
265
|
-
return _make_builtin_alias_editor(self.old_name, self.new_name, self.
|
|
323
|
+
return _make_builtin_alias_editor(self.old_name, self.new_name, self.type_positions_only)
|
|
266
324
|
|
|
267
325
|
|
|
268
326
|
@categorize(_Python39)
|
|
@@ -392,7 +450,7 @@ class ReplaceTypingText(_ReplaceTypingAliasRecipe):
|
|
|
392
450
|
|
|
393
451
|
old_name = "Text"
|
|
394
452
|
new_name = "str"
|
|
395
|
-
|
|
453
|
+
type_positions_only = False
|
|
396
454
|
|
|
397
455
|
@property
|
|
398
456
|
def name(self) -> str:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrewrite-migrate-python
|
|
3
|
-
Version: 0.14.0.
|
|
3
|
+
Version: 0.14.0.dev20260909112655
|
|
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
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""Tests for typing deprecation migration recipes."""
|
|
2
2
|
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
3
6
|
from rewrite.test import RecipeSpec, python
|
|
4
7
|
from openrewrite_migrate_python.migrate.typing_deprecations import (
|
|
5
8
|
ReplaceTypingDictWithDict,
|
|
@@ -410,26 +413,6 @@ class TestPep585CornerCases:
|
|
|
410
413
|
)
|
|
411
414
|
)
|
|
412
415
|
|
|
413
|
-
def test_keeps_import_used_by_string_annotation(self):
|
|
414
|
-
"""The import stays while a string annotation still references it."""
|
|
415
|
-
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
416
|
-
spec.rewrite_run(
|
|
417
|
-
python(
|
|
418
|
-
"""
|
|
419
|
-
from typing import List
|
|
420
|
-
x: List[int] = []
|
|
421
|
-
def f() -> "List[int]":
|
|
422
|
-
return x
|
|
423
|
-
""",
|
|
424
|
-
"""
|
|
425
|
-
from typing import List
|
|
426
|
-
x: list[int] = []
|
|
427
|
-
def f() -> "List[int]":
|
|
428
|
-
return x
|
|
429
|
-
""",
|
|
430
|
-
)
|
|
431
|
-
)
|
|
432
|
-
|
|
433
416
|
def test_removes_import_when_only_a_docstring_mentions_the_name(self):
|
|
434
417
|
"""Prose that happens to spell the name is not a reference to it."""
|
|
435
418
|
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
@@ -457,35 +440,59 @@ class TestPep585CornerCases:
|
|
|
457
440
|
)
|
|
458
441
|
)
|
|
459
442
|
|
|
460
|
-
def
|
|
461
|
-
"""A quoted annotation
|
|
443
|
+
def test_renames_inside_quoted_annotations(self):
|
|
444
|
+
"""A quoted annotation holds an expression; every lookup of the alias in it is renamed."""
|
|
462
445
|
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
463
446
|
spec.rewrite_run(
|
|
464
447
|
python(
|
|
465
448
|
"""
|
|
466
|
-
from typing import List
|
|
467
|
-
|
|
468
|
-
|
|
449
|
+
from typing import Dict, List
|
|
450
|
+
a: "List" = []
|
|
451
|
+
b: "List[int]" = []
|
|
452
|
+
c: "Dict[str, List[int]]" = {}
|
|
453
|
+
d: " List[int] " = []
|
|
454
|
+
e: "dict[Café, List[int]]" = {}
|
|
469
455
|
""",
|
|
470
456
|
"""
|
|
471
|
-
from typing import
|
|
472
|
-
|
|
473
|
-
|
|
457
|
+
from typing import Dict
|
|
458
|
+
a: "list" = []
|
|
459
|
+
b: "list[int]" = []
|
|
460
|
+
c: "Dict[str, list[int]]" = {}
|
|
461
|
+
d: " list[int] " = []
|
|
462
|
+
e: "dict[Café, list[int]]" = {}
|
|
474
463
|
""",
|
|
475
464
|
)
|
|
476
465
|
)
|
|
477
466
|
|
|
478
|
-
def
|
|
479
|
-
"""
|
|
467
|
+
def test_leaves_quoted_names_that_are_not_a_lookup_alone(self):
|
|
468
|
+
"""In a quoted body only an `ast.Name` is a lookup of the alias."""
|
|
480
469
|
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
481
470
|
spec.rewrite_run(
|
|
482
471
|
python(
|
|
483
472
|
"""
|
|
484
|
-
from typing import List
|
|
485
|
-
|
|
473
|
+
from typing import List, Literal
|
|
474
|
+
|
|
475
|
+
alias = List
|
|
476
|
+
a: "MyList" = []
|
|
477
|
+
b: "ListLike[int]" = []
|
|
478
|
+
c: "mod.List[int]" = []
|
|
479
|
+
d: "Literal['List', 'Tuple']" = "List"
|
|
480
|
+
"""
|
|
481
|
+
)
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
def test_leaves_quoted_annotated_metadata_alone(self):
|
|
485
|
+
"""The parser quotes `Annotated` metadata like a type; only its first argument is one."""
|
|
486
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
487
|
+
spec.rewrite_run(
|
|
488
|
+
python(
|
|
489
|
+
"""
|
|
490
|
+
from typing import Annotated, List
|
|
491
|
+
x: Annotated["List[int]", "List"] = []
|
|
486
492
|
""",
|
|
487
493
|
"""
|
|
488
|
-
|
|
494
|
+
from typing import Annotated, List
|
|
495
|
+
x: Annotated["list[int]", "List"] = []
|
|
489
496
|
""",
|
|
490
497
|
)
|
|
491
498
|
)
|
|
@@ -583,6 +590,118 @@ class TestPep585CornerCases:
|
|
|
583
590
|
)
|
|
584
591
|
)
|
|
585
592
|
|
|
593
|
+
def test_rewrites_pep695_type_parameter_bounds(self):
|
|
594
|
+
"""A PEP 695 bound stands where a type does, on a function and on a class."""
|
|
595
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
596
|
+
spec.rewrite_run(
|
|
597
|
+
python(
|
|
598
|
+
"""
|
|
599
|
+
from typing import List
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
def f[U: List](x: U) -> U: ...
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
class C[U: List]: pass
|
|
606
|
+
""",
|
|
607
|
+
"""
|
|
608
|
+
def f[U: list](x: U) -> U: ...
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
class C[U: list]: pass
|
|
612
|
+
""",
|
|
613
|
+
)
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
@pytest.mark.skipif(
|
|
617
|
+
sys.version_info < (3, 13), reason="PEP 696 type parameter defaults are 3.13+ syntax"
|
|
618
|
+
)
|
|
619
|
+
def test_rewrites_a_pep696_type_parameter_default(self):
|
|
620
|
+
"""A default is a second `bounds` entry, behind an `Empty` placeholder bound."""
|
|
621
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
622
|
+
spec.rewrite_run(
|
|
623
|
+
python(
|
|
624
|
+
"""
|
|
625
|
+
from typing import List
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
def h[W = List](x: W) -> W: ...
|
|
629
|
+
""",
|
|
630
|
+
"""
|
|
631
|
+
def h[W = list](x: W) -> W: ...
|
|
632
|
+
""",
|
|
633
|
+
)
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
def test_leaves_a_type_parameter_name_alone(self):
|
|
637
|
+
"""`def f[List: int]` declares a type parameter; the name is not the import."""
|
|
638
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
639
|
+
spec.rewrite_run(
|
|
640
|
+
python(
|
|
641
|
+
"""
|
|
642
|
+
from typing import List
|
|
643
|
+
|
|
644
|
+
x: List[int] = []
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
def f[List: int](y: int) -> int: ...
|
|
648
|
+
""",
|
|
649
|
+
"""
|
|
650
|
+
x: list[int] = []
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
def f[List: int](y: int) -> int: ...
|
|
654
|
+
""",
|
|
655
|
+
)
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
def test_rewrites_class_bases(self):
|
|
659
|
+
"""A base list is a type position: either spelling subclasses `list`."""
|
|
660
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
661
|
+
spec.rewrite_run(
|
|
662
|
+
python(
|
|
663
|
+
"""
|
|
664
|
+
from typing import List
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
class C(List[int]): pass
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
class D(List): pass
|
|
671
|
+
""",
|
|
672
|
+
"""
|
|
673
|
+
class C(list[int]): pass
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
class D(list): pass
|
|
677
|
+
""",
|
|
678
|
+
)
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
def test_leaves_a_class_keyword_argument_alone(self):
|
|
682
|
+
"""`metaclass=List` passes the alias as a value, not as a base."""
|
|
683
|
+
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
684
|
+
spec.rewrite_run(
|
|
685
|
+
python(
|
|
686
|
+
"""
|
|
687
|
+
from typing import List
|
|
688
|
+
|
|
689
|
+
x: List[int] = []
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
class C(object, metaclass=List): pass
|
|
693
|
+
""",
|
|
694
|
+
"""
|
|
695
|
+
from typing import List
|
|
696
|
+
|
|
697
|
+
x: list[int] = []
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
class C(object, metaclass=List): pass
|
|
701
|
+
""",
|
|
702
|
+
)
|
|
703
|
+
)
|
|
704
|
+
|
|
586
705
|
def test_preserves_comment_on_removed_import(self):
|
|
587
706
|
spec = RecipeSpec(recipe=ReplaceTypingListWithList())
|
|
588
707
|
spec.rewrite_run(
|
|
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
|
|
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
|