openrewrite-migrate-python 0.2.0.dev20260304105122__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/PKG-INFO +1 -1
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/pyproject.toml +1 -1
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/__init__.py +17 -15
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +73 -29
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +7 -24
- openrewrite_migrate_python-0.3.0/src/openrewrite_migrate_python/migrate/future_imports.py +153 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +7 -21
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +25 -20
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +7 -22
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +7 -22
- openrewrite_migrate_python-0.3.0/src/openrewrite_migrate_python/migrate/platform_deprecations.py +138 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/re_deprecations.py +18 -12
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +7 -16
- openrewrite_migrate_python-0.3.0/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +121 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +15 -19
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +3 -3
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +3 -3
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +23 -13
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +6 -6
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +57 -14
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python.egg-info/PKG-INFO +1 -1
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +2 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_aifc_migrations.py +0 -14
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_array_deprecations.py +0 -4
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_ast_deprecations.py +0 -11
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_asyncio_coroutine_to_async.py +0 -2
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_asyncio_deprecations.py +0 -3
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_calendar_deprecations.py +0 -3
- openrewrite_migrate_python-0.3.0/tests/test_cgi_parse_deprecations.py +77 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_collections_abc_migrations.py +0 -2
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_configparser_deprecations.py +0 -4
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_datetime_utc.py +0 -4
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_distutils_deprecations.py +0 -3
- openrewrite_migrate_python-0.3.0/tests/test_future_imports.py +117 -0
- openrewrite_migrate_python-0.3.0/tests/test_html_parser_deprecations.py +84 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_imp_migrations.py +0 -4
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_langchain_classic_imports.py +0 -8
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_langchain_community_imports.py +0 -2
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_langchain_provider_imports.py +0 -3
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_locale_deprecations.py +0 -2
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_pep594_system_migrations.py +0 -13
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_pkgutil_deprecations.py +0 -5
- openrewrite_migrate_python-0.3.0/tests/test_platform_deprecations.py +45 -0
- openrewrite_migrate_python-0.3.0/tests/test_re_deprecations.py +70 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_removed_modules_312.py +0 -6
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_ssl_deprecations.py +0 -3
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_string_formatting.py +0 -24
- openrewrite_migrate_python-0.3.0/tests/test_sys_last_deprecations.py +75 -0
- openrewrite_migrate_python-0.3.0/tests/test_tarfile_deprecations.py +55 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_threading_deprecations.py +0 -5
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_typing_deprecations.py +0 -2
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_upgrade_recipes.py +0 -3
- openrewrite_migrate_python-0.3.0/tests/test_xml_deprecations.py +106 -0
- openrewrite_migrate_python-0.2.0.dev20260304105122/src/openrewrite_migrate_python/migrate/platform_deprecations.py +0 -89
- openrewrite_migrate_python-0.2.0.dev20260304105122/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +0 -94
- openrewrite_migrate_python-0.2.0.dev20260304105122/tests/test_cgi_parse_deprecations.py +0 -46
- openrewrite_migrate_python-0.2.0.dev20260304105122/tests/test_html_parser_deprecations.py +0 -26
- openrewrite_migrate_python-0.2.0.dev20260304105122/tests/test_platform_deprecations.py +0 -24
- openrewrite_migrate_python-0.2.0.dev20260304105122/tests/test_re_deprecations.py +0 -33
- openrewrite_migrate_python-0.2.0.dev20260304105122/tests/test_sys_last_deprecations.py +0 -35
- openrewrite_migrate_python-0.2.0.dev20260304105122/tests/test_tarfile_deprecations.py +0 -24
- openrewrite_migrate_python-0.2.0.dev20260304105122/tests/test_xml_deprecations.py +0 -60
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/setup.cfg +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/__init__.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/_markers.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/imp_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/string_formatting.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/typing_callable.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/uu_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python.egg-info/requires.txt +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_change_import_recipes.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_gettext_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_locale_getdefaultlocale_deprecation.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_macpath_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_os_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_pep594_migrations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_shutil_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_sys_deprecations.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_threading_extended.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_threading_is_alive_deprecation.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_typing_callable.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_typing_union_to_pipe.py +0 -0
- {openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/tests/test_unittest_deprecations.py +0 -0
{openrewrite_migrate_python-0.2.0.dev20260304105122 → openrewrite_migrate_python-0.3.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrewrite-migrate-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: OpenRewrite recipes for migrating Python codebases to newer Python versions.
|
|
5
5
|
Author-email: "Moderne Inc." <support@moderne.io>
|
|
6
6
|
License: Moderne Proprietary
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openrewrite-migrate-python"
|
|
7
7
|
description = "OpenRewrite recipes for migrating Python codebases to newer Python versions."
|
|
8
|
-
version = "0.
|
|
8
|
+
version = "0.3.0" # Updated dynamically during release
|
|
9
9
|
authors = [{ name = "Moderne Inc.", email = "support@moderne.io" }]
|
|
10
10
|
license = { text = "Moderne Proprietary" }
|
|
11
11
|
readme = "README.md"
|
|
@@ -32,7 +32,7 @@ from .asyncio_coroutine_to_async import MigrateAsyncioCoroutine
|
|
|
32
32
|
from .asyncio_deprecations import FindAsyncioCoroutineDecorator
|
|
33
33
|
from .calendar_deprecations import ReplaceCalendarConstants
|
|
34
34
|
from .cgi_migrations import FindCgiModule, FindCgitbModule
|
|
35
|
-
from .cgi_parse_deprecations import
|
|
35
|
+
from .cgi_parse_deprecations import ReplaceCgiParseQs, ReplaceCgiParseQsl
|
|
36
36
|
from .collections_abc_migrations import ReplaceCollectionsAbcImports
|
|
37
37
|
from .configparser_deprecations import (
|
|
38
38
|
ReplaceConfigparserReadfp,
|
|
@@ -42,8 +42,9 @@ from .datetime_utc import ReplaceDatetimeUtcFromTimestamp, ReplaceDatetimeUtcNow
|
|
|
42
42
|
from .distutils_deprecations import FindDistutilsUsage
|
|
43
43
|
from .distutils_migrations import ReplaceDistutilsVersion
|
|
44
44
|
from .functools_deprecations import FindFunctoolsCmpToKey
|
|
45
|
+
from .future_imports import RemoveFutureImports
|
|
45
46
|
from .gettext_deprecations import ReplaceGettextDeprecations
|
|
46
|
-
from .html_parser_deprecations import
|
|
47
|
+
from .html_parser_deprecations import ReplaceHtmlParserUnescape
|
|
47
48
|
from .imp_migrations import FindImpUsage
|
|
48
49
|
from .locale_deprecations import ReplaceLocaleResetlocale
|
|
49
50
|
from .locale_getdefaultlocale_deprecation import FindLocaleGetdefaultlocale
|
|
@@ -52,7 +53,7 @@ from .mailcap_migrations import FindMailcapModule
|
|
|
52
53
|
from .nntplib_migrations import FindNntplibModule
|
|
53
54
|
from .os_deprecations import FindOsPopen, FindOsSpawn
|
|
54
55
|
from .pathlib_deprecations import FindPathlibLinkTo
|
|
55
|
-
from .platform_deprecations import
|
|
56
|
+
from .platform_deprecations import ReplacePlatformPopen
|
|
56
57
|
from .pep594_system_migrations import (
|
|
57
58
|
FindCryptModule,
|
|
58
59
|
FindMsilibModule,
|
|
@@ -62,15 +63,15 @@ from .pep594_system_migrations import (
|
|
|
62
63
|
)
|
|
63
64
|
from .pipes_migrations import FindPipesModule
|
|
64
65
|
from .pkgutil_deprecations import ReplacePkgutilFindLoader, ReplacePkgutilGetLoader
|
|
65
|
-
from .re_deprecations import
|
|
66
|
+
from .re_deprecations import ReplaceReTemplate
|
|
66
67
|
from .removed_modules_312 import FindRemovedModules312
|
|
67
68
|
from .shutil_deprecations import FindShutilRmtreeOnerror
|
|
68
69
|
from .socket_deprecations import FindSocketGetFQDN
|
|
69
70
|
from .ssl_deprecations import FindSslMatchHostname
|
|
70
71
|
from .string_formatting import ReplacePercentFormatWithFString, ReplaceStrFormatWithFString
|
|
71
72
|
from .sys_deprecations import FindSysCoroutineWrapper
|
|
72
|
-
from .sys_last_deprecations import
|
|
73
|
-
from .tarfile_deprecations import
|
|
73
|
+
from .sys_last_deprecations import ReplaceSysLastExcInfo
|
|
74
|
+
from .tarfile_deprecations import ReplaceTarfileFilemode
|
|
74
75
|
from .telnetlib_migrations import FindTelnetlibModule
|
|
75
76
|
from .tempfile_deprecations import FindTempfileMktemp
|
|
76
77
|
from .threading_is_alive_deprecation import ReplaceThreadIsAlive
|
|
@@ -100,7 +101,7 @@ from .upgrade_to_python314 import UpgradeToPython314
|
|
|
100
101
|
from .urllib_deprecations import FindUrllibParseSplitFunctions, FindUrllibParseToBytes
|
|
101
102
|
from .uu_migrations import FindUuModule
|
|
102
103
|
from .xdrlib_migrations import FindXdrlibModule
|
|
103
|
-
from .xml_deprecations import
|
|
104
|
+
from .xml_deprecations import ReplaceElementGetchildren, ReplaceElementGetiterator
|
|
104
105
|
|
|
105
106
|
__all__ = [
|
|
106
107
|
# String formatting auto-fix recipes
|
|
@@ -110,15 +111,16 @@ __all__ = [
|
|
|
110
111
|
"FindAsyncioCoroutineDecorator",
|
|
111
112
|
"FindAudioopModule",
|
|
112
113
|
"FindCgiModule",
|
|
113
|
-
"
|
|
114
|
-
"
|
|
114
|
+
"ReplaceCgiParseQs",
|
|
115
|
+
"ReplaceCgiParseQsl",
|
|
115
116
|
"FindCgitbModule",
|
|
116
117
|
"FindChunkModule",
|
|
117
118
|
"FindCryptModule",
|
|
118
119
|
"FindDistutilsUsage",
|
|
119
|
-
"
|
|
120
|
+
"ReplaceElementGetchildren",
|
|
120
121
|
"FindFunctoolsCmpToKey",
|
|
121
|
-
"
|
|
122
|
+
"RemoveFutureImports",
|
|
123
|
+
"ReplaceHtmlParserUnescape",
|
|
122
124
|
"FindImghdrModule",
|
|
123
125
|
"FindImpUsage",
|
|
124
126
|
"FindMacpathModule",
|
|
@@ -132,18 +134,18 @@ __all__ = [
|
|
|
132
134
|
"FindOssaudiodevModule",
|
|
133
135
|
"FindPathlibLinkTo",
|
|
134
136
|
"FindPipesModule",
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
+
"ReplacePlatformPopen",
|
|
138
|
+
"ReplaceReTemplate",
|
|
137
139
|
"FindRemovedModules312",
|
|
138
140
|
"FindShutilRmtreeOnerror",
|
|
139
141
|
"FindSndhdrModule",
|
|
140
142
|
"FindSocketGetFQDN",
|
|
141
143
|
"FindSpwdModule",
|
|
142
144
|
"FindSslMatchHostname",
|
|
143
|
-
"
|
|
145
|
+
"ReplaceSysLastExcInfo",
|
|
144
146
|
"FindSunauModule",
|
|
145
147
|
"FindSysCoroutineWrapper",
|
|
146
|
-
"
|
|
148
|
+
"ReplaceTarfileFilemode",
|
|
147
149
|
"FindTelnetlibModule",
|
|
148
150
|
"FindTempfileMktemp",
|
|
149
151
|
"ReplaceThreadGetName",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Recipes for
|
|
2
|
+
Recipes for replacing deprecated cgi.parse_qs/parse_qsl with
|
|
3
|
+
urllib.parse.parse_qs/parse_qsl.
|
|
3
4
|
|
|
4
5
|
The following functions were deprecated in Python 3.2 and removed in Python 3.8:
|
|
5
6
|
- cgi.parse_qs() -> urllib.parse.parse_qs()
|
|
@@ -16,9 +17,11 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
|
|
|
16
17
|
from rewrite.category import CategoryDescriptor
|
|
17
18
|
from rewrite.decorators import categorize
|
|
18
19
|
from rewrite.marketplace import Python
|
|
20
|
+
from rewrite.markers import Markers
|
|
19
21
|
from rewrite.python.visitor import PythonVisitor
|
|
20
|
-
from rewrite.java.
|
|
21
|
-
from .
|
|
22
|
+
from rewrite.java.support_types import JLeftPadded, Space
|
|
23
|
+
from rewrite.java.tree import FieldAccess, Identifier, MethodInvocation
|
|
24
|
+
from rewrite.utils import random_id
|
|
22
25
|
|
|
23
26
|
# Define category path: Python > Migrate > Python 3.8
|
|
24
27
|
_Python38 = [
|
|
@@ -28,10 +31,51 @@ _Python38 = [
|
|
|
28
31
|
]
|
|
29
32
|
|
|
30
33
|
|
|
34
|
+
def _create_urllib_parse_select(original_select: Identifier) -> FieldAccess:
|
|
35
|
+
"""Create a FieldAccess node representing 'urllib.parse'.
|
|
36
|
+
|
|
37
|
+
Preserves the prefix/whitespace from the original select.
|
|
38
|
+
"""
|
|
39
|
+
parse_identifier = Identifier(
|
|
40
|
+
_id=random_id(),
|
|
41
|
+
_prefix=Space.EMPTY,
|
|
42
|
+
_markers=Markers.EMPTY,
|
|
43
|
+
_annotations=[],
|
|
44
|
+
_simple_name="parse",
|
|
45
|
+
_type=None,
|
|
46
|
+
_field_type=None,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
padded_parse = JLeftPadded(
|
|
50
|
+
_before=Space.EMPTY,
|
|
51
|
+
_element=parse_identifier,
|
|
52
|
+
_markers=Markers.EMPTY,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
urllib_identifier = Identifier(
|
|
56
|
+
_id=random_id(),
|
|
57
|
+
_prefix=original_select.prefix,
|
|
58
|
+
_markers=Markers.EMPTY,
|
|
59
|
+
_annotations=[],
|
|
60
|
+
_simple_name="urllib",
|
|
61
|
+
_type=None,
|
|
62
|
+
_field_type=None,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return FieldAccess(
|
|
66
|
+
_id=random_id(),
|
|
67
|
+
_prefix=Space.EMPTY,
|
|
68
|
+
_markers=Markers.EMPTY,
|
|
69
|
+
_target=urllib_identifier,
|
|
70
|
+
_name=padded_parse,
|
|
71
|
+
_type=None,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
31
75
|
@categorize(_Python38)
|
|
32
|
-
class
|
|
76
|
+
class ReplaceCgiParseQs(Recipe):
|
|
33
77
|
"""
|
|
34
|
-
|
|
78
|
+
Replace `cgi.parse_qs()` with `urllib.parse.parse_qs()`.
|
|
35
79
|
|
|
36
80
|
`cgi.parse_qs()` was deprecated in Python 3.2 and removed in Python 3.8.
|
|
37
81
|
Use `urllib.parse.parse_qs()` instead.
|
|
@@ -43,24 +87,24 @@ class FindCgiParseQs(Recipe):
|
|
|
43
87
|
|
|
44
88
|
After:
|
|
45
89
|
from urllib.parse import parse_qs
|
|
46
|
-
params = parse_qs(query_string)
|
|
47
|
-
|
|
48
|
-
Note: This is a search recipe because the import change is non-trivial.
|
|
90
|
+
params = urllib.parse.parse_qs(query_string)
|
|
49
91
|
"""
|
|
50
92
|
|
|
51
93
|
@property
|
|
52
94
|
def name(self) -> str:
|
|
53
|
-
return "org.openrewrite.python.migrate.
|
|
95
|
+
return "org.openrewrite.python.migrate.ReplaceCgiParseQs"
|
|
54
96
|
|
|
55
97
|
@property
|
|
56
98
|
def display_name(self) -> str:
|
|
57
|
-
return "
|
|
99
|
+
return "Replace `cgi.parse_qs()` with `urllib.parse.parse_qs()`"
|
|
58
100
|
|
|
59
101
|
@property
|
|
60
102
|
def description(self) -> str:
|
|
61
103
|
return (
|
|
62
104
|
"`cgi.parse_qs()` was removed in Python 3.8. "
|
|
63
|
-
"Use `urllib.parse.parse_qs()` instead."
|
|
105
|
+
"Use `urllib.parse.parse_qs()` instead. "
|
|
106
|
+
"Note: this rewrites call sites but does not manage imports. "
|
|
107
|
+
"Use with `ChangeImport` in a composite recipe to update `from` imports."
|
|
64
108
|
)
|
|
65
109
|
|
|
66
110
|
@property
|
|
@@ -85,19 +129,19 @@ class FindCgiParseQs(Recipe):
|
|
|
85
129
|
if select.simple_name != "cgi":
|
|
86
130
|
return method
|
|
87
131
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
)
|
|
132
|
+
# Replace cgi with urllib.parse
|
|
133
|
+
new_select = _create_urllib_parse_select(select)
|
|
134
|
+
old_padded = method.padding.select
|
|
135
|
+
new_padded = old_padded.replace(_element=new_select)
|
|
136
|
+
return method.padding.replace(_select=new_padded)
|
|
93
137
|
|
|
94
138
|
return Visitor()
|
|
95
139
|
|
|
96
140
|
|
|
97
141
|
@categorize(_Python38)
|
|
98
|
-
class
|
|
142
|
+
class ReplaceCgiParseQsl(Recipe):
|
|
99
143
|
"""
|
|
100
|
-
|
|
144
|
+
Replace `cgi.parse_qsl()` with `urllib.parse.parse_qsl()`.
|
|
101
145
|
|
|
102
146
|
`cgi.parse_qsl()` was deprecated in Python 3.2 and removed in Python 3.8.
|
|
103
147
|
Use `urllib.parse.parse_qsl()` instead.
|
|
@@ -109,24 +153,24 @@ class FindCgiParseQsl(Recipe):
|
|
|
109
153
|
|
|
110
154
|
After:
|
|
111
155
|
from urllib.parse import parse_qsl
|
|
112
|
-
params = parse_qsl(query_string)
|
|
113
|
-
|
|
114
|
-
Note: This is a search recipe because the import change is non-trivial.
|
|
156
|
+
params = urllib.parse.parse_qsl(query_string)
|
|
115
157
|
"""
|
|
116
158
|
|
|
117
159
|
@property
|
|
118
160
|
def name(self) -> str:
|
|
119
|
-
return "org.openrewrite.python.migrate.
|
|
161
|
+
return "org.openrewrite.python.migrate.ReplaceCgiParseQsl"
|
|
120
162
|
|
|
121
163
|
@property
|
|
122
164
|
def display_name(self) -> str:
|
|
123
|
-
return "
|
|
165
|
+
return "Replace `cgi.parse_qsl()` with `urllib.parse.parse_qsl()`"
|
|
124
166
|
|
|
125
167
|
@property
|
|
126
168
|
def description(self) -> str:
|
|
127
169
|
return (
|
|
128
170
|
"`cgi.parse_qsl()` was removed in Python 3.8. "
|
|
129
|
-
"Use `urllib.parse.parse_qsl()` instead."
|
|
171
|
+
"Use `urllib.parse.parse_qsl()` instead. "
|
|
172
|
+
"Note: this rewrites call sites but does not manage imports. "
|
|
173
|
+
"Use with `ChangeImport` in a composite recipe to update `from` imports."
|
|
130
174
|
)
|
|
131
175
|
|
|
132
176
|
@property
|
|
@@ -151,10 +195,10 @@ class FindCgiParseQsl(Recipe):
|
|
|
151
195
|
if select.simple_name != "cgi":
|
|
152
196
|
return method
|
|
153
197
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
)
|
|
198
|
+
# Replace cgi with urllib.parse
|
|
199
|
+
new_select = _create_urllib_parse_select(select)
|
|
200
|
+
old_padded = method.padding.select
|
|
201
|
+
new_padded = old_padded.replace(_element=new_select)
|
|
202
|
+
return method.padding.replace(_select=new_padded)
|
|
159
203
|
|
|
160
204
|
return Visitor()
|
|
@@ -73,37 +73,20 @@ def _replace_configparser_attribute(field_access: FieldAccess, new_name: str) ->
|
|
|
73
73
|
|
|
74
74
|
def _is_configparser_method(method: MethodInvocation, method_name: str) -> bool:
|
|
75
75
|
"""
|
|
76
|
-
Check if this is a method call on a ConfigParser instance.
|
|
77
|
-
|
|
78
|
-
Since we can't always determine the type of the receiver, we check:
|
|
79
|
-
1. Method name matches
|
|
80
|
-
2. Type attribution if available
|
|
81
|
-
3. Common variable names like 'config', 'parser', 'cfg', 'cp'
|
|
76
|
+
Check if this is a method call on a ConfigParser instance using type attribution.
|
|
82
77
|
"""
|
|
83
78
|
if not isinstance(method.name, Identifier):
|
|
84
79
|
return False
|
|
85
80
|
if method.name.simple_name != method_name:
|
|
86
81
|
return False
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
if method.method_type and method.method_type.declaring_type:
|
|
90
|
-
dt = method.method_type.declaring_type
|
|
91
|
-
if hasattr(dt, '_fully_qualified_name'):
|
|
92
|
-
fqn = str(dt._fully_qualified_name)
|
|
93
|
-
if 'configparser' in fqn.lower() or 'ConfigParser' in fqn:
|
|
94
|
-
return True
|
|
95
|
-
|
|
96
|
-
# Fallback: Check for common ConfigParser variable names
|
|
97
|
-
select = method.select
|
|
98
|
-
if select is None:
|
|
83
|
+
if not method.method_type or not method.method_type.declaring_type:
|
|
99
84
|
return False
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return False
|
|
85
|
+
dt = method.method_type.declaring_type
|
|
86
|
+
if not hasattr(dt, '_fully_qualified_name'):
|
|
87
|
+
return False
|
|
88
|
+
fqn = str(dt._fully_qualified_name)
|
|
89
|
+
return 'configparser' in fqn.lower() or 'ConfigParser' in fqn
|
|
107
90
|
|
|
108
91
|
|
|
109
92
|
def _rename_method(method: MethodInvocation, new_name: str) -> MethodInvocation:
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Recipe for removing obsolete __future__ imports.
|
|
3
|
+
|
|
4
|
+
In Python 3, many __future__ imports are no longer needed because their
|
|
5
|
+
features are enabled by default:
|
|
6
|
+
- print_function (default since Python 3.0)
|
|
7
|
+
- division (default since Python 3.0)
|
|
8
|
+
- unicode_literals (default since Python 3.0)
|
|
9
|
+
- absolute_import (default since Python 3.0)
|
|
10
|
+
- generators (default since Python 2.3)
|
|
11
|
+
- nested_scopes (default since Python 2.2)
|
|
12
|
+
- with_statement (default since Python 2.6)
|
|
13
|
+
|
|
14
|
+
The `annotations` import (PEP 563) is kept because it still has meaning
|
|
15
|
+
in Python 3.10+ (postponed evaluation of annotations).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from typing import Any, List, Optional
|
|
19
|
+
|
|
20
|
+
from rewrite import ExecutionContext, Recipe, TreeVisitor
|
|
21
|
+
from rewrite.category import CategoryDescriptor
|
|
22
|
+
from rewrite.decorators import categorize
|
|
23
|
+
from rewrite.marketplace import Python
|
|
24
|
+
from rewrite.python.visitor import PythonVisitor
|
|
25
|
+
from rewrite.python.tree import MultiImport
|
|
26
|
+
from rewrite.java.tree import FieldAccess, Identifier
|
|
27
|
+
|
|
28
|
+
# Define category path: Python > Migrate
|
|
29
|
+
_Migrate = [
|
|
30
|
+
*Python,
|
|
31
|
+
CategoryDescriptor(display_name="Migrate"),
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
# __future__ imports that are obsolete in Python 3 and can be safely removed
|
|
35
|
+
OBSOLETE_FUTURE_IMPORTS = {
|
|
36
|
+
"print_function",
|
|
37
|
+
"division",
|
|
38
|
+
"unicode_literals",
|
|
39
|
+
"absolute_import",
|
|
40
|
+
"generators",
|
|
41
|
+
"nested_scopes",
|
|
42
|
+
"with_statement",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _get_import_name(import_node: Any) -> Optional[str]:
|
|
47
|
+
"""Extract the imported name from an import node's qualid."""
|
|
48
|
+
qualid = import_node.qualid
|
|
49
|
+
if isinstance(qualid, FieldAccess):
|
|
50
|
+
if isinstance(qualid.name, Identifier):
|
|
51
|
+
return qualid.name.simple_name
|
|
52
|
+
elif isinstance(qualid, Identifier):
|
|
53
|
+
return qualid.simple_name
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@categorize(_Migrate)
|
|
58
|
+
class RemoveFutureImports(Recipe):
|
|
59
|
+
"""
|
|
60
|
+
Remove obsolete `from __future__ import ...` statements.
|
|
61
|
+
|
|
62
|
+
In Python 3, many `__future__` imports are enabled by default and
|
|
63
|
+
no longer needed. This recipe removes imports that are obsolete:
|
|
64
|
+
- `print_function` (default since 3.0)
|
|
65
|
+
- `division` (default since 3.0)
|
|
66
|
+
- `unicode_literals` (default since 3.0)
|
|
67
|
+
- `absolute_import` (default since 3.0)
|
|
68
|
+
- `generators` (default since 2.3)
|
|
69
|
+
- `nested_scopes` (default since 2.2)
|
|
70
|
+
- `with_statement` (default since 2.6)
|
|
71
|
+
|
|
72
|
+
The `annotations` import (PEP 563) is preserved.
|
|
73
|
+
|
|
74
|
+
Example:
|
|
75
|
+
Before:
|
|
76
|
+
from __future__ import print_function, division, annotations
|
|
77
|
+
|
|
78
|
+
After:
|
|
79
|
+
from __future__ import annotations
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def name(self) -> str:
|
|
84
|
+
return "org.openrewrite.python.migrate.RemoveFutureImports"
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def display_name(self) -> str:
|
|
88
|
+
return "Remove obsolete `__future__` imports"
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def description(self) -> str:
|
|
92
|
+
return (
|
|
93
|
+
"Remove `from __future__ import ...` statements for features that "
|
|
94
|
+
"are enabled by default in Python 3."
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def tags(self) -> List[str]:
|
|
99
|
+
return ["python", "migration", "future"]
|
|
100
|
+
|
|
101
|
+
def editor(self) -> TreeVisitor[Any, ExecutionContext]:
|
|
102
|
+
class Visitor(PythonVisitor[ExecutionContext]):
|
|
103
|
+
def visit_multi_import(
|
|
104
|
+
self, multi: MultiImport, p: ExecutionContext
|
|
105
|
+
) -> Optional[MultiImport]:
|
|
106
|
+
multi = super().visit_multi_import(multi, p)
|
|
107
|
+
|
|
108
|
+
# Check if this is a 'from __future__ import ...' statement
|
|
109
|
+
from_part = multi.from_
|
|
110
|
+
if from_part is None:
|
|
111
|
+
return multi
|
|
112
|
+
if not isinstance(from_part, Identifier):
|
|
113
|
+
return multi
|
|
114
|
+
if from_part.simple_name != "__future__":
|
|
115
|
+
return multi
|
|
116
|
+
|
|
117
|
+
# Collect imported names and categorize them
|
|
118
|
+
names = multi.names
|
|
119
|
+
keep_indices = []
|
|
120
|
+
for i, import_node in enumerate(names):
|
|
121
|
+
imported_name = _get_import_name(import_node)
|
|
122
|
+
if imported_name is not None and imported_name not in OBSOLETE_FUTURE_IMPORTS:
|
|
123
|
+
keep_indices.append(i)
|
|
124
|
+
|
|
125
|
+
# If all names should be kept, no change
|
|
126
|
+
if len(keep_indices) == len(names):
|
|
127
|
+
return multi
|
|
128
|
+
|
|
129
|
+
# If all names should be removed, remove the entire statement
|
|
130
|
+
if len(keep_indices) == 0:
|
|
131
|
+
# noinspection PyTypeChecker
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
# Partial removal: keep only non-obsolete names
|
|
135
|
+
old_container = multi.padding.names
|
|
136
|
+
old_elements = list(old_container.padding.elements)
|
|
137
|
+
new_elements = [old_elements[i] for i in keep_indices]
|
|
138
|
+
|
|
139
|
+
# Fix spacing: if the first remaining element had extra prefix
|
|
140
|
+
# from being after a comma, use the prefix of the original first element
|
|
141
|
+
if new_elements and keep_indices[0] != 0:
|
|
142
|
+
original_first = old_elements[0]
|
|
143
|
+
first = new_elements[0]
|
|
144
|
+
# Copy the prefix from original first element
|
|
145
|
+
new_first_elem = first.element.replace(
|
|
146
|
+
_prefix=original_first.element.prefix
|
|
147
|
+
)
|
|
148
|
+
new_elements[0] = first.replace(_element=new_first_elem)
|
|
149
|
+
|
|
150
|
+
new_container = old_container.replace(_elements=new_elements)
|
|
151
|
+
return multi.replace(_names=new_container)
|
|
152
|
+
|
|
153
|
+
return Visitor()
|
|
@@ -49,34 +49,20 @@ def _rename_method(method: MethodInvocation, new_name: str) -> MethodInvocation:
|
|
|
49
49
|
|
|
50
50
|
def _is_gettext_method(method: MethodInvocation, method_name: str) -> bool:
|
|
51
51
|
"""
|
|
52
|
-
Check if this is a gettext.method_name() call.
|
|
53
|
-
|
|
54
|
-
Uses multiple strategies to identify the method:
|
|
55
|
-
1. Check method name matches
|
|
56
|
-
2. Check type attribution if available
|
|
57
|
-
3. Check simple name on select is 'gettext'
|
|
52
|
+
Check if this is a gettext.method_name() call using type attribution.
|
|
58
53
|
"""
|
|
59
54
|
if not isinstance(method.name, Identifier):
|
|
60
55
|
return False
|
|
61
56
|
if method.name.simple_name != method_name:
|
|
62
57
|
return False
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
if method.method_type and method.method_type.declaring_type:
|
|
66
|
-
dt = method.method_type.declaring_type
|
|
67
|
-
if hasattr(dt, '_fully_qualified_name'):
|
|
68
|
-
fqn = str(dt._fully_qualified_name)
|
|
69
|
-
if 'gettext' in fqn:
|
|
70
|
-
return True
|
|
71
|
-
|
|
72
|
-
# Fallback: Check simple name on select
|
|
73
|
-
select = method.select
|
|
74
|
-
if select is None:
|
|
59
|
+
if not method.method_type or not method.method_type.declaring_type:
|
|
75
60
|
return False
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
dt = method.method_type.declaring_type
|
|
62
|
+
if not hasattr(dt, '_fully_qualified_name'):
|
|
63
|
+
return False
|
|
64
|
+
fqn = str(dt._fully_qualified_name)
|
|
65
|
+
return 'gettext' in fqn
|
|
80
66
|
|
|
81
67
|
|
|
82
68
|
@categorize(_Python311)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Recipe for
|
|
2
|
+
Recipe for replacing deprecated HTMLParser.unescape() with html.unescape().
|
|
3
3
|
|
|
4
4
|
HTMLParser.unescape() was deprecated in Python 3.4 and removed in Python 3.9.
|
|
5
5
|
Use html.unescape() instead.
|
|
@@ -15,7 +15,6 @@ from rewrite.decorators import categorize
|
|
|
15
15
|
from rewrite.marketplace import Python
|
|
16
16
|
from rewrite.python.visitor import PythonVisitor
|
|
17
17
|
from rewrite.java.tree import Identifier, MethodInvocation
|
|
18
|
-
from ._markers import mark_deprecated
|
|
19
18
|
|
|
20
19
|
# Define category path: Python > Migrate > Python 3.9
|
|
21
20
|
_Python39 = [
|
|
@@ -26,9 +25,9 @@ _Python39 = [
|
|
|
26
25
|
|
|
27
26
|
|
|
28
27
|
@categorize(_Python39)
|
|
29
|
-
class
|
|
28
|
+
class ReplaceHtmlParserUnescape(Recipe):
|
|
30
29
|
"""
|
|
31
|
-
|
|
30
|
+
Replace `HTMLParser.unescape()` with `html.unescape()`.
|
|
32
31
|
|
|
33
32
|
`HTMLParser.unescape()` was deprecated in Python 3.4 and removed in Python 3.9.
|
|
34
33
|
Use `html.unescape()` instead.
|
|
@@ -42,18 +41,15 @@ class FindHtmlParserUnescape(Recipe):
|
|
|
42
41
|
After:
|
|
43
42
|
import html
|
|
44
43
|
text = html.unescape(html_text)
|
|
45
|
-
|
|
46
|
-
Note: This is a search recipe because the transformation requires
|
|
47
|
-
changing from an instance method to a module function.
|
|
48
44
|
"""
|
|
49
45
|
|
|
50
46
|
@property
|
|
51
47
|
def name(self) -> str:
|
|
52
|
-
return "org.openrewrite.python.migrate.
|
|
48
|
+
return "org.openrewrite.python.migrate.ReplaceHtmlParserUnescape"
|
|
53
49
|
|
|
54
50
|
@property
|
|
55
51
|
def display_name(self) -> str:
|
|
56
|
-
return "
|
|
52
|
+
return "Replace `HTMLParser.unescape()` with `html.unescape()`"
|
|
57
53
|
|
|
58
54
|
@property
|
|
59
55
|
def description(self) -> str:
|
|
@@ -78,23 +74,32 @@ class FindHtmlParserUnescape(Recipe):
|
|
|
78
74
|
if method.name.simple_name != "unescape":
|
|
79
75
|
return method
|
|
80
76
|
|
|
81
|
-
#
|
|
82
|
-
# .unescape() calls without type information, so we mark all
|
|
83
|
-
# .unescape() calls on non-module selects as potential matches
|
|
84
|
-
# when the select is not a known module name like "html"
|
|
77
|
+
# Already using html.unescape(), no change needed
|
|
85
78
|
select = method.select
|
|
86
79
|
if isinstance(select, Identifier) and select.simple_name == "html":
|
|
87
|
-
# Already using html.unescape(), no change needed
|
|
88
80
|
return method
|
|
89
81
|
|
|
90
82
|
# Skip if no select (bare function call)
|
|
91
|
-
if
|
|
83
|
+
if select is None:
|
|
84
|
+
return method
|
|
85
|
+
|
|
86
|
+
# Require type info to confirm HTMLParser
|
|
87
|
+
if not method.method_type or not method.method_type.declaring_type:
|
|
92
88
|
return method
|
|
89
|
+
dt = method.method_type.declaring_type
|
|
90
|
+
if not hasattr(dt, '_fully_qualified_name'):
|
|
91
|
+
return method
|
|
92
|
+
fqn = str(dt._fully_qualified_name)
|
|
93
|
+
if 'html.parser' not in fqn:
|
|
94
|
+
return method
|
|
95
|
+
|
|
96
|
+
# Replace select with html identifier
|
|
97
|
+
if isinstance(select, Identifier):
|
|
98
|
+
new_select = select.replace(_simple_name="html")
|
|
99
|
+
old_padded = method.padding.select
|
|
100
|
+
new_padded = old_padded.replace(_element=new_select)
|
|
101
|
+
return method.padding.replace(_select=new_padded)
|
|
93
102
|
|
|
94
|
-
return
|
|
95
|
-
method,
|
|
96
|
-
"HTMLParser.unescape() was removed in Python 3.9. "
|
|
97
|
-
"Use html.unescape() instead."
|
|
98
|
-
)
|
|
103
|
+
return method
|
|
99
104
|
|
|
100
105
|
return Visitor()
|
|
@@ -29,35 +29,20 @@ _Python311 = [
|
|
|
29
29
|
|
|
30
30
|
def _is_locale_method(method: MethodInvocation, method_name: str) -> bool:
|
|
31
31
|
"""
|
|
32
|
-
Check if this is a locale.method_name() call.
|
|
33
|
-
|
|
34
|
-
Uses multiple strategies to identify the method:
|
|
35
|
-
1. Check method name matches
|
|
36
|
-
2. Check type attribution if available (FQN contains 'locale')
|
|
37
|
-
3. Check simple name on select is 'locale'
|
|
32
|
+
Check if this is a locale.method_name() call using type attribution.
|
|
38
33
|
"""
|
|
39
|
-
# Check method name first
|
|
40
34
|
if not isinstance(method.name, Identifier):
|
|
41
35
|
return False
|
|
42
36
|
if method.name.simple_name != method_name:
|
|
43
37
|
return False
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
if method.method_type and method.method_type.declaring_type:
|
|
47
|
-
dt = method.method_type.declaring_type
|
|
48
|
-
if hasattr(dt, '_fully_qualified_name'):
|
|
49
|
-
fqn = str(dt._fully_qualified_name)
|
|
50
|
-
if 'locale' in fqn:
|
|
51
|
-
return True
|
|
52
|
-
|
|
53
|
-
# Fallback: Check simple name on select
|
|
54
|
-
select = method.select
|
|
55
|
-
if select is None:
|
|
39
|
+
if not method.method_type or not method.method_type.declaring_type:
|
|
56
40
|
return False
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
41
|
+
dt = method.method_type.declaring_type
|
|
42
|
+
if not hasattr(dt, '_fully_qualified_name'):
|
|
43
|
+
return False
|
|
44
|
+
fqn = str(dt._fully_qualified_name)
|
|
45
|
+
return 'locale' in fqn
|
|
61
46
|
|
|
62
47
|
|
|
63
48
|
def _rename_method(method: MethodInvocation, new_name: str) -> MethodInvocation:
|