openrewrite-migrate-python 0.17.0.dev20261021175539__tar.gz → 0.17.0.dev20261022150922__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.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/PKG-INFO +1 -1
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/pyproject.toml +1 -1
- openrewrite_migrate_python-0.17.0.dev20261022150922/src/openrewrite_migrate_python/migrate/cgi_escape_deprecations.py +186 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +1 -1
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/string_formatting.py +12 -2
- openrewrite_migrate_python-0.17.0.dev20261022150922/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +227 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +7 -6
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python.egg-info/PKG-INFO +1 -1
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +2 -0
- openrewrite_migrate_python-0.17.0.dev20261022150922/tests/test_cgi_escape_deprecations.py +236 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_change_import_recipes.py +0 -12
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_string_formatting.py +75 -8
- openrewrite_migrate_python-0.17.0.dev20261022150922/tests/test_sys_last_deprecations.py +286 -0
- openrewrite_migrate_python-0.17.0.dev20261021175539/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +0 -141
- openrewrite_migrate_python-0.17.0.dev20261021175539/tests/test_sys_last_deprecations.py +0 -142
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/setup.cfg +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/__init__.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/_literals.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/_negation.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/assign_return.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/attr_access.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/boolean_simplification.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/collection_literals.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/comparison_simplification.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/complex_transforms.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/comprehension_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/conditionals.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/datetime_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/dict_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/exception_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/expression_simplification.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/logger_warn.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/loop_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/merge_nested_with.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/merge_startswith_endswith.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/naming_conventions.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/negated_operators.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/none_and_identity.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/object_inheritance.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/pandas_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/python_best_practices.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/range_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/redundant_code.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/remove_trailing_return_none.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/string_cleanup.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/unreachable_code.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/use_items.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/use_list_clear.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/cleanup/yoda_conditions.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/__init__.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/_reindent.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/_semantically_equal.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/_side_effects.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/_trivia.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/_truth_value.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/all_branches_identical.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/boolean_checks_not_inverted.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/code_quality.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/collapsible_if_statements.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/find_suspicious_chained_comparison.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/merge_identical_branches.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/remove_duplicate_conditions.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/remove_unconditional_value_overwrite.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/simplify_boolean_literal.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_code_quality_python/codequality/simplify_redundant_logical_expression.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/__init__.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/_decorators.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/_langchain_tables.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/_markers.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/_method_renames.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/_module_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/_slots.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/backoff_to_tenacity.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/future_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/glob_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/importlib_resources_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/inspect_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/module_cached_attribute.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/platform_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/typing_callable.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/typing_functional_syntax.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_pandas.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python315.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/uu_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python.egg-info/requires.txt +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_asyncio_coroutine_to_async.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_avro_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_backoff_to_tenacity.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_cgi_parse_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_configparser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_datetime_utc.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_distutils_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_functools_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_future_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_gettext_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_glob_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_html_parser_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_importlib_resources_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_inspect_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_langchain_classic_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_langchain_community_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_locale_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_mailcap_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_markers.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_module_cached_attribute.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_pathlib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_pep594_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_pkgutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_platform_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_pydantic_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_pydantic_fields.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_pydantic_model_fields.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_re_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_socket_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_ssl_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_tarfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_tempfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_threading_extended.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_typing_alias_moves.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_typing_callable.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_typing_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_typing_functional_syntax.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_upgrade_recipes.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_upgrade_to_pydantic.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_urllib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/tests/test_xdrlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.17.0.dev20261021175539 → openrewrite_migrate_python-0.17.0.dev20261022150922}/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.17.0.
|
|
3
|
+
Version: 0.17.0.dev20261022150922
|
|
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.17.0.
|
|
8
|
+
version = "0.17.0.dev20261022150922" # 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"
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Recipe for replacing the removed cgi.escape() with html.escape().
|
|
3
|
+
|
|
4
|
+
cgi.escape() was deprecated in Python 3.2 and removed in Python 3.8. Its
|
|
5
|
+
replacement html.escape() escapes quotes by default, where cgi.escape() did
|
|
6
|
+
not, so a call that relied on the default passes quote=False. A reference the
|
|
7
|
+
recipe cannot carry the default over for is marked instead.
|
|
8
|
+
|
|
9
|
+
See: https://docs.python.org/3/whatsnew/3.8.html#api-and-feature-removals
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Any, List, Set
|
|
13
|
+
|
|
14
|
+
from rewrite import Cursor, ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
15
|
+
from rewrite.category import CategoryDescriptor
|
|
16
|
+
from rewrite.decorators import categorize
|
|
17
|
+
from rewrite.marketplace import Python
|
|
18
|
+
from rewrite.python.binding import maybe_rebind
|
|
19
|
+
from rewrite.python.binding_utils import import_bindings
|
|
20
|
+
from rewrite.python.method_matcher import MethodMatcher
|
|
21
|
+
from rewrite.python.preconditions import uses_method
|
|
22
|
+
from rewrite.python.template import template
|
|
23
|
+
from rewrite.python.tree import CompilationUnit, ExpressionStatement, NamedArgument, Star
|
|
24
|
+
from rewrite.python.visitor import PythonVisitor
|
|
25
|
+
from rewrite.java.support_types import JRightPadded, Space
|
|
26
|
+
from rewrite.java.tree import FieldAccess, Identifier, J, MethodInvocation
|
|
27
|
+
|
|
28
|
+
from ._markers import mark_deprecated
|
|
29
|
+
|
|
30
|
+
# Define category path: Python > Migrate > Python 3.8
|
|
31
|
+
_Python38 = [
|
|
32
|
+
*Python,
|
|
33
|
+
CategoryDescriptor(display_name="Migrate"),
|
|
34
|
+
CategoryDescriptor(display_name="Python 3.8"),
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
_ESCAPE_PATTERN = "cgi escape(..)"
|
|
38
|
+
_ESCAPE = MethodMatcher.create(_ESCAPE_PATTERN)
|
|
39
|
+
_QUOTE_FALSE = template("escape(s, quote=False)")
|
|
40
|
+
_MANUAL = (
|
|
41
|
+
"`cgi.escape()` was removed in Python 3.8. Replace it with `html.escape()`, "
|
|
42
|
+
"passing `quote=False` unless quotes should now be escaped too"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@categorize(_Python38)
|
|
47
|
+
class ReplaceCgiEscape(Recipe):
|
|
48
|
+
"""
|
|
49
|
+
Replace ``cgi.escape()`` with ``html.escape()``, keeping quotes unescaped.
|
|
50
|
+
|
|
51
|
+
``cgi.escape(s)`` left quotes alone unless called with ``quote=True``, while
|
|
52
|
+
``html.escape(s)`` escapes them by default. A call without a ``quote``
|
|
53
|
+
argument therefore gains ``quote=False``.
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
Before:
|
|
57
|
+
import cgi
|
|
58
|
+
safe = cgi.escape(text)
|
|
59
|
+
attr = cgi.escape(text, True)
|
|
60
|
+
|
|
61
|
+
After:
|
|
62
|
+
import html
|
|
63
|
+
safe = html.escape(text, quote=False)
|
|
64
|
+
attr = html.escape(text, True)
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def name(self) -> str:
|
|
69
|
+
return "org.openrewrite.python.migrate.ReplaceCgiEscape"
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def display_name(self) -> str:
|
|
73
|
+
return "Replace `cgi.escape()` with `html.escape()`"
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def description(self) -> str:
|
|
77
|
+
return (
|
|
78
|
+
"`cgi.escape()` was removed in Python 3.8. Replace it with `html.escape()`, "
|
|
79
|
+
"passing `quote=False` where the call gave no `quote` argument, since "
|
|
80
|
+
"`html.escape()` escapes quotes by default and `cgi.escape()` did not. An explicit "
|
|
81
|
+
"`quote` argument is kept as it is. A file that also refers to `cgi.escape` other than "
|
|
82
|
+
"by calling it, or calls it with unpacked `*args` or `**kwargs`, is left as it is, with "
|
|
83
|
+
"those references marked for a manual change. A file that never calls it is not visited."
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def tags(self) -> List[str]:
|
|
88
|
+
return ["python", "migration", "3.8", "cgi"]
|
|
89
|
+
|
|
90
|
+
def editor(self) -> TreeVisitor[Any, ExecutionContext]:
|
|
91
|
+
class Visitor(PythonVisitor[ExecutionContext]):
|
|
92
|
+
unsafe: Set[Any] = set()
|
|
93
|
+
|
|
94
|
+
def visit_compilation_unit(self, cu: CompilationUnit, p: ExecutionContext) -> J:
|
|
95
|
+
finder = _EscapeReferences()
|
|
96
|
+
finder.visit(cu, p)
|
|
97
|
+
self.unsafe = finder.unsafe
|
|
98
|
+
visited = super().visit_compilation_unit(cu, p)
|
|
99
|
+
if finder.found and not finder.unsafe:
|
|
100
|
+
maybe_rebind(self, "cgi", "html", from_member="escape")
|
|
101
|
+
return visited
|
|
102
|
+
|
|
103
|
+
def visit_method_invocation(self, method: MethodInvocation, p: ExecutionContext) -> J:
|
|
104
|
+
m = super().visit_method_invocation(method, p)
|
|
105
|
+
if not isinstance(m, MethodInvocation):
|
|
106
|
+
return m
|
|
107
|
+
if self.unsafe:
|
|
108
|
+
return mark_deprecated(m, _MANUAL) if m.id in self.unsafe else m
|
|
109
|
+
if not _ESCAPE.matches(m, cursor=self.cursor) or not _relies_on_default_quote(m):
|
|
110
|
+
return m
|
|
111
|
+
quote = _quote_false(self.cursor)
|
|
112
|
+
if quote is None:
|
|
113
|
+
return m
|
|
114
|
+
arguments = m.padding.arguments
|
|
115
|
+
last = arguments.padding.elements[-1]
|
|
116
|
+
elements = [
|
|
117
|
+
last.replace(_after=Space.EMPTY, _markers=quote.markers),
|
|
118
|
+
quote.replace(_after=last.after, _markers=last.markers),
|
|
119
|
+
]
|
|
120
|
+
return m.padding.replace(_arguments=arguments.padding.replace(elements=elements))
|
|
121
|
+
|
|
122
|
+
def visit_field_access(self, field_access: FieldAccess, p: ExecutionContext) -> J:
|
|
123
|
+
fa = super().visit_field_access(field_access, p)
|
|
124
|
+
return mark_deprecated(fa, _MANUAL) if fa.id in self.unsafe else fa
|
|
125
|
+
|
|
126
|
+
def visit_identifier(self, ident: Identifier, p: ExecutionContext) -> J:
|
|
127
|
+
i = super().visit_identifier(ident, p)
|
|
128
|
+
return mark_deprecated(i, _MANUAL) if i.id in self.unsafe else i
|
|
129
|
+
|
|
130
|
+
return Preconditions.check(uses_method(_ESCAPE_PATTERN), Visitor())
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class _EscapeReferences(PythonVisitor[ExecutionContext]):
|
|
134
|
+
"""Finds the file's references to ``cgi.escape``, and those whose meaning the move would change."""
|
|
135
|
+
|
|
136
|
+
def __init__(self) -> None:
|
|
137
|
+
super().__init__()
|
|
138
|
+
self.found = False
|
|
139
|
+
self.unsafe: Set[Any] = set()
|
|
140
|
+
|
|
141
|
+
def visit_method_invocation(self, method: MethodInvocation, p: ExecutionContext) -> J:
|
|
142
|
+
if _ESCAPE.matches(method, cursor=self.cursor):
|
|
143
|
+
self.found = True
|
|
144
|
+
if not method.arguments or any(isinstance(arg, Star) for arg in method.arguments):
|
|
145
|
+
self.unsafe.add(method.id)
|
|
146
|
+
return super().visit_method_invocation(method, p)
|
|
147
|
+
|
|
148
|
+
def visit_field_access(self, field_access: FieldAccess, p: ExecutionContext) -> J:
|
|
149
|
+
# A call is a MethodInvocation, so `cgi.escape` as a FieldAccess is passed around, not called.
|
|
150
|
+
target = field_access.target
|
|
151
|
+
if field_access.name.simple_name == "escape" and isinstance(target, Identifier):
|
|
152
|
+
binding = import_bindings(self).reference(Cursor(self.cursor, target), target)
|
|
153
|
+
if binding is not None and binding.module == "cgi" and binding.member is None:
|
|
154
|
+
self.found = True
|
|
155
|
+
self.unsafe.add(field_access.id)
|
|
156
|
+
return super().visit_field_access(field_access, p)
|
|
157
|
+
|
|
158
|
+
def visit_identifier(self, ident: Identifier, p: ExecutionContext) -> J:
|
|
159
|
+
binding = import_bindings(self).reference(self.cursor, ident)
|
|
160
|
+
if binding is not None and binding.module == "cgi" and binding.member == "escape":
|
|
161
|
+
parent = self.cursor.parent_tree_cursor().value
|
|
162
|
+
if not (isinstance(parent, MethodInvocation) and parent.name is ident):
|
|
163
|
+
self.found = True
|
|
164
|
+
self.unsafe.add(ident.id)
|
|
165
|
+
return super().visit_identifier(ident, p)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _relies_on_default_quote(call: MethodInvocation) -> bool:
|
|
169
|
+
"""Whether ``call`` passes only the string, by position or as ``s=``."""
|
|
170
|
+
if len(call.arguments) != 1:
|
|
171
|
+
return False
|
|
172
|
+
only = call.arguments[0]
|
|
173
|
+
if isinstance(only, NamedArgument):
|
|
174
|
+
return only.name.simple_name == "s"
|
|
175
|
+
return not isinstance(only, Star)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _quote_false(cursor: Cursor) -> JRightPadded | None:
|
|
179
|
+
"""A ``quote=False`` argument as a parse gives it, padded to follow a comma."""
|
|
180
|
+
call = _QUOTE_FALSE.apply(cursor, format=False)
|
|
181
|
+
if isinstance(call, ExpressionStatement):
|
|
182
|
+
call = call.expression
|
|
183
|
+
if not isinstance(call, MethodInvocation):
|
|
184
|
+
return None
|
|
185
|
+
quote = call.padding.arguments.padding.elements[-1]
|
|
186
|
+
return quote.replace(_element=quote.element.replace(prefix=Space.SINGLE_SPACE))
|
|
@@ -6,7 +6,7 @@ The following functions were deprecated in Python 3.2 and removed in Python 3.8:
|
|
|
6
6
|
- cgi.parse_qs() -> urllib.parse.parse_qs()
|
|
7
7
|
- cgi.parse_qsl() -> urllib.parse.parse_qsl()
|
|
8
8
|
|
|
9
|
-
Note: cgi.escape() -> html.escape() is handled in
|
|
9
|
+
Note: cgi.escape() -> html.escape() is handled in cgi_escape_deprecations.py.
|
|
10
10
|
|
|
11
11
|
See: https://docs.python.org/3/whatsnew/3.8.html#api-and-feature-removals
|
|
12
12
|
"""
|
|
@@ -35,6 +35,7 @@ from rewrite.utils import random_id
|
|
|
35
35
|
|
|
36
36
|
from openrewrite_code_quality_python.cleanup._literals import is_string_literal
|
|
37
37
|
from openrewrite_code_quality_python.codequality._side_effects import is_side_effect_free
|
|
38
|
+
from openrewrite_code_quality_python.codequality._trivia import has_comments
|
|
38
39
|
|
|
39
40
|
from ._slots import as_slot_of
|
|
40
41
|
|
|
@@ -173,6 +174,10 @@ def _convert_format_to_fstring(method: MethodInvocation) -> FormattedString | No
|
|
|
173
174
|
if not isinstance(select, Literal):
|
|
174
175
|
return None
|
|
175
176
|
|
|
177
|
+
# The f-string is rebuilt from the parts, which drops every comment inside the call
|
|
178
|
+
if has_comments(method.replace(prefix=Space.EMPTY)):
|
|
179
|
+
return None
|
|
180
|
+
|
|
176
181
|
value_source = select.value_source
|
|
177
182
|
if not value_source:
|
|
178
183
|
return None
|
|
@@ -366,7 +371,7 @@ class ReplaceStrFormatWithFString(Recipe):
|
|
|
366
371
|
"conversion is safe. A format string with a backslash escape, a raw or bytes prefix, "
|
|
367
372
|
"or a field reading an attribute or index is left alone. So is a call with an unpacked "
|
|
368
373
|
"argument, a string literal argument, or an argument that has side effects and is "
|
|
369
|
-
"used more than once."
|
|
374
|
+
"used more than once, and a call with a comment inside it, which the f-string would drop."
|
|
370
375
|
)
|
|
371
376
|
|
|
372
377
|
@property
|
|
@@ -449,6 +454,10 @@ def _convert_percent_to_fstring(binary: Binary) -> FormattedString | None:
|
|
|
449
454
|
if not isinstance(left, Literal):
|
|
450
455
|
return None
|
|
451
456
|
|
|
457
|
+
# The f-string is rebuilt from the parts, which drops every comment inside the expression
|
|
458
|
+
if has_comments(binary.replace(prefix=Space.EMPTY)):
|
|
459
|
+
return None
|
|
460
|
+
|
|
452
461
|
value_source = left.value_source
|
|
453
462
|
if not value_source:
|
|
454
463
|
return None
|
|
@@ -581,7 +590,8 @@ class ReplacePercentFormatWithFString(Recipe):
|
|
|
581
590
|
"Only converts `%s` and `%r` specifiers where the format string is "
|
|
582
591
|
"a literal and the conversion is safe. A single operand that is not a "
|
|
583
592
|
"tuple literal must have a type that resolves to a non-tuple, such as "
|
|
584
|
-
"`str` or `int`, since a tuple would be spread over the specifiers."
|
|
593
|
+
"`str` or `int`, since a tuple would be spread over the specifiers. "
|
|
594
|
+
"An expression with a comment inside it is left alone, since the f-string would drop it."
|
|
585
595
|
)
|
|
586
596
|
|
|
587
597
|
@property
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Recipe for replacing deprecated sys.last_type/last_value/last_traceback
|
|
3
|
+
with sys.last_exc equivalents.
|
|
4
|
+
|
|
5
|
+
sys.last_type, sys.last_value, and sys.last_traceback were deprecated in
|
|
6
|
+
Python 3.12 in favor of sys.last_exc:
|
|
7
|
+
|
|
8
|
+
- sys.last_value -> sys.last_exc
|
|
9
|
+
- sys.last_type -> type(sys.last_exc)
|
|
10
|
+
- sys.last_traceback -> sys.last_exc.__traceback__
|
|
11
|
+
|
|
12
|
+
See: https://docs.python.org/3/whatsnew/3.12.html#deprecated
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import Any, List
|
|
16
|
+
|
|
17
|
+
from rewrite import Cursor, ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
18
|
+
from rewrite.category import CategoryDescriptor
|
|
19
|
+
from rewrite.decorators import categorize
|
|
20
|
+
from rewrite.marketplace import Python
|
|
21
|
+
from rewrite.python.binding_utils import import_bindings
|
|
22
|
+
from rewrite.python.method_matcher import MethodMatcher
|
|
23
|
+
from rewrite.python.preconditions import uses_import
|
|
24
|
+
from rewrite.python.remove_import import RemoveImportOptions, maybe_remove_import
|
|
25
|
+
from rewrite.python.scope_utils import scope_of
|
|
26
|
+
from rewrite.python.template import template
|
|
27
|
+
from rewrite.python.visitor import PythonVisitor
|
|
28
|
+
from rewrite.python.tree import (
|
|
29
|
+
ChainedAssignment,
|
|
30
|
+
CollectionLiteral,
|
|
31
|
+
CompilationUnit,
|
|
32
|
+
ComprehensionExpression,
|
|
33
|
+
Del,
|
|
34
|
+
ExpressionStatement,
|
|
35
|
+
Star,
|
|
36
|
+
TypeHintedExpression,
|
|
37
|
+
)
|
|
38
|
+
from rewrite.java.tree import (
|
|
39
|
+
Assignment,
|
|
40
|
+
AssignmentOperation,
|
|
41
|
+
FieldAccess,
|
|
42
|
+
ForEachLoop,
|
|
43
|
+
Identifier,
|
|
44
|
+
J,
|
|
45
|
+
Literal,
|
|
46
|
+
MethodInvocation,
|
|
47
|
+
Parentheses,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Define category path: Python > Migrate > Python 3.12
|
|
51
|
+
_Python312 = [
|
|
52
|
+
*Python,
|
|
53
|
+
CategoryDescriptor(display_name="Migrate"),
|
|
54
|
+
CategoryDescriptor(display_name="Python 3.12"),
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
_REPLACEMENTS = {
|
|
58
|
+
attribute: template(replacement, context=["import sys"])
|
|
59
|
+
for attribute, replacement in (
|
|
60
|
+
("last_value", "sys.last_exc"),
|
|
61
|
+
("last_type", "type(sys.last_exc)"),
|
|
62
|
+
("last_traceback", "sys.last_exc.__traceback__"),
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_HASATTR = MethodMatcher.create("builtins hasattr(..)")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@categorize(_Python312)
|
|
70
|
+
class ReplaceSysLastExcInfo(Recipe):
|
|
71
|
+
"""
|
|
72
|
+
Replace ``sys.last_type``, ``sys.last_value``, and ``sys.last_traceback`` with
|
|
73
|
+
their ``sys.last_exc``-based equivalents.
|
|
74
|
+
|
|
75
|
+
These attributes were deprecated in Python 3.12 in favor of ``sys.last_exc``
|
|
76
|
+
which provides the exception object directly.
|
|
77
|
+
|
|
78
|
+
Example:
|
|
79
|
+
Before:
|
|
80
|
+
import sys
|
|
81
|
+
if hasattr(sys, "last_type"):
|
|
82
|
+
exc_type = sys.last_type
|
|
83
|
+
exc_value = sys.last_value
|
|
84
|
+
exc_tb = sys.last_traceback
|
|
85
|
+
|
|
86
|
+
After:
|
|
87
|
+
import sys
|
|
88
|
+
if hasattr(sys, "last_exc"):
|
|
89
|
+
exc_type = type(sys.last_exc)
|
|
90
|
+
exc_value = sys.last_exc
|
|
91
|
+
exc_tb = sys.last_exc.__traceback__
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def name(self) -> str:
|
|
96
|
+
return "org.openrewrite.python.migrate.ReplaceSysLastExcInfo"
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def display_name(self) -> str:
|
|
100
|
+
return "Replace `sys.last_type` / `sys.last_value` / `sys.last_traceback` with `sys.last_exc`"
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def description(self) -> str:
|
|
104
|
+
return (
|
|
105
|
+
"`sys.last_type`, `sys.last_value`, and `sys.last_traceback` were "
|
|
106
|
+
"deprecated in Python 3.12. "
|
|
107
|
+
"Replace reads of them with their `sys.last_exc`-based equivalents: "
|
|
108
|
+
"`type(sys.last_exc)`, `sys.last_exc`, and `sys.last_exc.__traceback__` "
|
|
109
|
+
"respectively, and a `hasattr(sys, \"last_type\")` guard with "
|
|
110
|
+
"`hasattr(sys, \"last_exc\")`. Assignment, `del`, `for` and `with` targets "
|
|
111
|
+
"are left alone, and so is every read in a file that assigns or deletes "
|
|
112
|
+
"one of the attributes, since `sys.last_exc` would not hold what it set. "
|
|
113
|
+
"`sys.last_type` is left alone where `type` is shadowed."
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def tags(self) -> List[str]:
|
|
118
|
+
return ["python", "migration", "3.12", "sys"]
|
|
119
|
+
|
|
120
|
+
def editor(self) -> TreeVisitor[Any, ExecutionContext]:
|
|
121
|
+
class Visitor(PythonVisitor[ExecutionContext]):
|
|
122
|
+
def visit_compilation_unit(self, cu: CompilationUnit, p: ExecutionContext) -> J:
|
|
123
|
+
finder = _WriteFinder()
|
|
124
|
+
finder.visit(cu, p)
|
|
125
|
+
if finder.found:
|
|
126
|
+
return cu
|
|
127
|
+
return super().visit_compilation_unit(cu, p)
|
|
128
|
+
|
|
129
|
+
def visit_field_access(self, field_access: FieldAccess, p: ExecutionContext) -> J:
|
|
130
|
+
fa = super().visit_field_access(field_access, p)
|
|
131
|
+
if not isinstance(fa, FieldAccess):
|
|
132
|
+
return fa
|
|
133
|
+
member = _sys_attribute(self, fa)
|
|
134
|
+
return fa if member is None else self._replace(fa, member)
|
|
135
|
+
|
|
136
|
+
def visit_identifier(self, ident: Identifier, p: ExecutionContext) -> J:
|
|
137
|
+
i = super().visit_identifier(ident, p)
|
|
138
|
+
if not isinstance(i, Identifier):
|
|
139
|
+
return i
|
|
140
|
+
binding = import_bindings(self).reference(self.cursor, i)
|
|
141
|
+
if binding is None or binding.module != "sys" or binding.member not in _REPLACEMENTS:
|
|
142
|
+
return i
|
|
143
|
+
if _is_written(self.cursor):
|
|
144
|
+
return i
|
|
145
|
+
replaced = self._replace(i, binding.member)
|
|
146
|
+
if replaced is not i:
|
|
147
|
+
maybe_remove_import(self, RemoveImportOptions(module="sys", name=binding.member))
|
|
148
|
+
return replaced
|
|
149
|
+
|
|
150
|
+
def visit_method_invocation(self, method: MethodInvocation, p: ExecutionContext) -> J:
|
|
151
|
+
m = super().visit_method_invocation(method, p)
|
|
152
|
+
if not isinstance(m, MethodInvocation) or not _HASATTR.matches(m, cursor=self.cursor):
|
|
153
|
+
return m
|
|
154
|
+
if len(m.arguments) != 2:
|
|
155
|
+
return m
|
|
156
|
+
receiver, attribute = m.arguments
|
|
157
|
+
if not isinstance(receiver, Identifier) or not isinstance(attribute, Literal):
|
|
158
|
+
return m
|
|
159
|
+
binding = import_bindings(self).reference(Cursor(self.cursor, receiver), receiver)
|
|
160
|
+
if binding is None or binding.module != "sys" or binding.member is not None:
|
|
161
|
+
return m
|
|
162
|
+
if attribute.value not in _REPLACEMENTS or attribute.value_source is None:
|
|
163
|
+
return m
|
|
164
|
+
guard = attribute.replace(
|
|
165
|
+
value="last_exc",
|
|
166
|
+
value_source=attribute.value_source.replace(str(attribute.value), "last_exc"),
|
|
167
|
+
)
|
|
168
|
+
arguments = m.padding.arguments
|
|
169
|
+
padded = arguments.padding.elements
|
|
170
|
+
padded = [padded[0], padded[1].replace(_element=guard)]
|
|
171
|
+
return m.padding.replace(_arguments=arguments.padding.replace(elements=padded))
|
|
172
|
+
|
|
173
|
+
def _replace(self, tree: J, member: str) -> J:
|
|
174
|
+
if member == "last_type" and scope_of(self.cursor).declares("type"):
|
|
175
|
+
return tree
|
|
176
|
+
try:
|
|
177
|
+
return _REPLACEMENTS[member].apply(self.cursor, visitor=self) or tree
|
|
178
|
+
except ValueError:
|
|
179
|
+
# The template refuses a file where `sys` is bound to something else.
|
|
180
|
+
return tree
|
|
181
|
+
|
|
182
|
+
return Preconditions.check(uses_import("sys"), Visitor())
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class _WriteFinder(PythonVisitor[ExecutionContext]):
|
|
186
|
+
"""Finds an assignment to or ``del`` of one of the deprecated ``sys`` attributes."""
|
|
187
|
+
|
|
188
|
+
found = False
|
|
189
|
+
|
|
190
|
+
def visit_field_access(self, field_access: FieldAccess, p: ExecutionContext) -> J:
|
|
191
|
+
if not self.found and _sys_attribute(self, field_access) is not None and _is_written(self.cursor):
|
|
192
|
+
self.found = True
|
|
193
|
+
return super().visit_field_access(field_access, p)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _sys_attribute(visitor: PythonVisitor, field_access: FieldAccess) -> str | None:
|
|
197
|
+
"""The deprecated attribute ``field_access`` names on the ``sys`` module, if it does."""
|
|
198
|
+
if not isinstance(field_access.target, Identifier) or field_access.name.simple_name not in _REPLACEMENTS:
|
|
199
|
+
return None
|
|
200
|
+
binding = import_bindings(visitor).reference(visitor.cursor, field_access.target)
|
|
201
|
+
if binding is None or binding.module != "sys" or binding.member is not None:
|
|
202
|
+
return None
|
|
203
|
+
return field_access.name.simple_name
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _is_written(cursor: Cursor) -> bool:
|
|
207
|
+
"""Whether the expression at ``cursor`` is assigned or deleted rather than read."""
|
|
208
|
+
node = cursor.value
|
|
209
|
+
parent = cursor.parent_tree_cursor()
|
|
210
|
+
while True:
|
|
211
|
+
holder = parent.value
|
|
212
|
+
if isinstance(holder, TypeHintedExpression):
|
|
213
|
+
return holder.expression is node
|
|
214
|
+
if not isinstance(holder, (Parentheses, Star, CollectionLiteral, ExpressionStatement)):
|
|
215
|
+
break
|
|
216
|
+
node = holder
|
|
217
|
+
parent = parent.parent_tree_cursor()
|
|
218
|
+
target = parent.value
|
|
219
|
+
if isinstance(target, (Assignment, AssignmentOperation)):
|
|
220
|
+
return target.variable is node
|
|
221
|
+
if isinstance(target, ChainedAssignment):
|
|
222
|
+
return any(variable is node for variable in target.variables)
|
|
223
|
+
if isinstance(target, ForEachLoop.Control):
|
|
224
|
+
return target.variable is node
|
|
225
|
+
if isinstance(target, ComprehensionExpression.Clause):
|
|
226
|
+
return target.iterator_variable is node
|
|
227
|
+
return isinstance(target, Del)
|
|
@@ -22,8 +22,8 @@ class UpgradeToPython38(Recipe):
|
|
|
22
22
|
|
|
23
23
|
Key changes:
|
|
24
24
|
- Replace ``time.clock()`` with ``time.perf_counter()``
|
|
25
|
-
- Replace ``cgi.escape()`` with ``html.escape()``,
|
|
26
|
-
|
|
25
|
+
- Replace ``cgi.escape()`` with ``html.escape()``, passing ``quote=False`` where the
|
|
26
|
+
call relied on ``cgi.escape()`` leaving quotes alone
|
|
27
27
|
- Replace ``cgi.parse_qs()`` / ``cgi.parse_qsl()`` with ``urllib.parse`` equivalents
|
|
28
28
|
- Replace ``platform.popen()`` with ``subprocess.check_output()``
|
|
29
29
|
- Replace ``tarfile.filemode`` with ``stat.filemode``
|
|
@@ -48,8 +48,8 @@ class UpgradeToPython38(Recipe):
|
|
|
48
48
|
def description(self) -> str:
|
|
49
49
|
return (
|
|
50
50
|
"Migrate deprecated APIs and detect legacy patterns for Python 3.8 compatibility. "
|
|
51
|
-
"`cgi.escape()` becomes `html.escape()`,
|
|
52
|
-
"
|
|
51
|
+
"`cgi.escape()` becomes `html.escape()`, with `quote=False` where the call relied "
|
|
52
|
+
"on `cgi.escape()` leaving quotes alone."
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
@property
|
|
@@ -58,6 +58,7 @@ class UpgradeToPython38(Recipe):
|
|
|
58
58
|
|
|
59
59
|
def recipe_list(self) -> List[Recipe]:
|
|
60
60
|
"""Return the list of recipes to apply for Python 3.8 upgrade."""
|
|
61
|
+
from .cgi_escape_deprecations import ReplaceCgiEscape
|
|
61
62
|
from .cgi_parse_deprecations import ReplaceCgiParseQs, ReplaceCgiParseQsl
|
|
62
63
|
from .functools_deprecations import FindFunctoolsCmpToKey
|
|
63
64
|
from .future_imports import RemoveFutureImports
|
|
@@ -69,8 +70,8 @@ class UpgradeToPython38(Recipe):
|
|
|
69
70
|
return [
|
|
70
71
|
# Auto-fix: time.clock() -> time.perf_counter()
|
|
71
72
|
ChangeImport(old_module="time", old_name="clock", new_module="time", new_name="perf_counter"),
|
|
72
|
-
# Auto-fix: cgi.escape() -> html.escape()
|
|
73
|
-
|
|
73
|
+
# Auto-fix: cgi.escape() -> html.escape(..., quote=False)
|
|
74
|
+
ReplaceCgiEscape(),
|
|
74
75
|
# Auto-fix: cgi.parse_qs() / cgi.parse_qsl() -> urllib.parse
|
|
75
76
|
ReplaceCgiParseQs(),
|
|
76
77
|
ReplaceCgiParseQsl(),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrewrite-migrate-python
|
|
3
|
-
Version: 0.17.0.
|
|
3
|
+
Version: 0.17.0.dev20261022150922
|
|
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
|
|
@@ -72,6 +72,7 @@ src/openrewrite_migrate_python/migrate/asyncio_deprecations.py
|
|
|
72
72
|
src/openrewrite_migrate_python/migrate/avro_migrations.py
|
|
73
73
|
src/openrewrite_migrate_python/migrate/backoff_to_tenacity.py
|
|
74
74
|
src/openrewrite_migrate_python/migrate/calendar_deprecations.py
|
|
75
|
+
src/openrewrite_migrate_python/migrate/cgi_escape_deprecations.py
|
|
75
76
|
src/openrewrite_migrate_python/migrate/cgi_migrations.py
|
|
76
77
|
src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py
|
|
77
78
|
src/openrewrite_migrate_python/migrate/collections_abc_migrations.py
|
|
@@ -147,6 +148,7 @@ tests/test_asyncio_deprecations.py
|
|
|
147
148
|
tests/test_avro_migrations.py
|
|
148
149
|
tests/test_backoff_to_tenacity.py
|
|
149
150
|
tests/test_calendar_deprecations.py
|
|
151
|
+
tests/test_cgi_escape_deprecations.py
|
|
150
152
|
tests/test_cgi_parse_deprecations.py
|
|
151
153
|
tests/test_change_import_recipes.py
|
|
152
154
|
tests/test_collections_abc_migrations.py
|