openrewrite-migrate-python 0.1.0__py3-none-any.whl
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/__init__.py +35 -0
- openrewrite_migrate_python/migrate/__init__.py +219 -0
- openrewrite_migrate_python/migrate/aifc_migrations.py +517 -0
- openrewrite_migrate_python/migrate/array_deprecations.py +133 -0
- openrewrite_migrate_python/migrate/ast_deprecations.py +322 -0
- openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +225 -0
- openrewrite_migrate_python/migrate/asyncio_deprecations.py +117 -0
- openrewrite_migrate_python/migrate/calendar_deprecations.py +134 -0
- openrewrite_migrate_python/migrate/cgi_migrations.py +213 -0
- openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +170 -0
- openrewrite_migrate_python/migrate/collections_abc_migrations.py +207 -0
- openrewrite_migrate_python/migrate/configparser_deprecations.py +252 -0
- openrewrite_migrate_python/migrate/datetime_utc.py +136 -0
- openrewrite_migrate_python/migrate/distutils_deprecations.py +107 -0
- openrewrite_migrate_python/migrate/distutils_migrations.py +125 -0
- openrewrite_migrate_python/migrate/functools_deprecations.py +98 -0
- openrewrite_migrate_python/migrate/gettext_deprecations.py +139 -0
- openrewrite_migrate_python/migrate/html_parser_deprecations.py +110 -0
- openrewrite_migrate_python/migrate/imp_migrations.py +135 -0
- openrewrite_migrate_python/migrate/langchain_classic_imports.py +308 -0
- openrewrite_migrate_python/migrate/langchain_community_imports.py +154 -0
- openrewrite_migrate_python/migrate/langchain_provider_imports.py +240 -0
- openrewrite_migrate_python/migrate/locale_deprecations.py +177 -0
- openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +103 -0
- openrewrite_migrate_python/migrate/macpath_deprecations.py +125 -0
- openrewrite_migrate_python/migrate/mailcap_migrations.py +129 -0
- openrewrite_migrate_python/migrate/nntplib_migrations.py +127 -0
- openrewrite_migrate_python/migrate/os_deprecations.py +158 -0
- openrewrite_migrate_python/migrate/pathlib_deprecations.py +98 -0
- openrewrite_migrate_python/migrate/pep594_system_migrations.py +429 -0
- openrewrite_migrate_python/migrate/pipes_migrations.py +130 -0
- openrewrite_migrate_python/migrate/pkgutil_deprecations.py +180 -0
- openrewrite_migrate_python/migrate/platform_deprecations.py +99 -0
- openrewrite_migrate_python/migrate/re_deprecations.py +122 -0
- openrewrite_migrate_python/migrate/removed_modules_312.py +139 -0
- openrewrite_migrate_python/migrate/shutil_deprecations.py +112 -0
- openrewrite_migrate_python/migrate/socket_deprecations.py +96 -0
- openrewrite_migrate_python/migrate/ssl_deprecations.py +121 -0
- openrewrite_migrate_python/migrate/string_formatting.py +526 -0
- openrewrite_migrate_python/migrate/sys_deprecations.py +97 -0
- openrewrite_migrate_python/migrate/sys_last_deprecations.py +104 -0
- openrewrite_migrate_python/migrate/tarfile_deprecations.py +120 -0
- openrewrite_migrate_python/migrate/telnetlib_migrations.py +132 -0
- openrewrite_migrate_python/migrate/tempfile_deprecations.py +113 -0
- openrewrite_migrate_python/migrate/threading_deprecations.py +488 -0
- openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +82 -0
- openrewrite_migrate_python/migrate/typing_callable.py +153 -0
- openrewrite_migrate_python/migrate/typing_deprecations.py +337 -0
- openrewrite_migrate_python/migrate/typing_union_to_pipe.py +272 -0
- openrewrite_migrate_python/migrate/unittest_deprecations.py +140 -0
- openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +56 -0
- openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +66 -0
- openrewrite_migrate_python/migrate/upgrade_to_python310.py +91 -0
- openrewrite_migrate_python/migrate/upgrade_to_python311.py +92 -0
- openrewrite_migrate_python/migrate/upgrade_to_python312.py +101 -0
- openrewrite_migrate_python/migrate/upgrade_to_python313.py +109 -0
- openrewrite_migrate_python/migrate/upgrade_to_python314.py +87 -0
- openrewrite_migrate_python/migrate/upgrade_to_python38.py +85 -0
- openrewrite_migrate_python/migrate/upgrade_to_python39.py +125 -0
- openrewrite_migrate_python/migrate/urllib_deprecations.py +204 -0
- openrewrite_migrate_python/migrate/uu_migrations.py +129 -0
- openrewrite_migrate_python/migrate/xdrlib_migrations.py +129 -0
- openrewrite_migrate_python/migrate/xml_deprecations.py +154 -0
- openrewrite_migrate_python-0.1.0.dist-info/METADATA +31 -0
- openrewrite_migrate_python-0.1.0.dist-info/RECORD +68 -0
- openrewrite_migrate_python-0.1.0.dist-info/WHEEL +5 -0
- openrewrite_migrate_python-0.1.0.dist-info/entry_points.txt +2 -0
- openrewrite_migrate_python-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""Composite recipe for upgrading from Python 3.10 to Python 3.11."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from rewrite import Recipe
|
|
6
|
+
from rewrite.category import CategoryDescriptor
|
|
7
|
+
from rewrite.decorators import categorize
|
|
8
|
+
from rewrite.marketplace import Python
|
|
9
|
+
from rewrite.python.recipes import ChangeImport
|
|
10
|
+
|
|
11
|
+
# Define category path: Python > Migrate
|
|
12
|
+
_Migrate = [*Python, CategoryDescriptor(display_name="Migrate")]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@categorize(_Migrate)
|
|
16
|
+
class UpgradeToPython311(Recipe):
|
|
17
|
+
"""
|
|
18
|
+
Migrate deprecated and removed APIs for Python 3.11 compatibility.
|
|
19
|
+
|
|
20
|
+
This composite recipe applies all necessary migrations for code
|
|
21
|
+
running on Python 3.10 to be compatible with Python 3.11.
|
|
22
|
+
|
|
23
|
+
Key changes in Python 3.11:
|
|
24
|
+
- The `@asyncio.coroutine` decorator is removed (use `async def` instead)
|
|
25
|
+
- `inspect.getargspec()` is removed (use `inspect.getfullargspec()`)
|
|
26
|
+
- `gettext.lgettext()` and related functions removed
|
|
27
|
+
|
|
28
|
+
See: https://docs.python.org/3/whatsnew/3.11.html
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def name(self) -> str:
|
|
33
|
+
return "org.openrewrite.python.migrate.UpgradeToPython311"
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def display_name(self) -> str:
|
|
37
|
+
return "Upgrade to Python 3.11"
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def description(self) -> str:
|
|
41
|
+
return (
|
|
42
|
+
"Migrate deprecated and removed APIs for Python 3.11 compatibility. "
|
|
43
|
+
"This includes handling removed modules, deprecated functions, and "
|
|
44
|
+
"API changes between Python 3.10 and 3.11."
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def tags(self) -> List[str]:
|
|
49
|
+
return ["python", "migration", "3.11"]
|
|
50
|
+
|
|
51
|
+
def recipe_list(self) -> List[Recipe]:
|
|
52
|
+
"""Return the list of recipes to apply for Python 3.11 upgrade."""
|
|
53
|
+
# Import here to avoid circular imports
|
|
54
|
+
from .asyncio_coroutine_to_async import MigrateAsyncioCoroutine
|
|
55
|
+
from .asyncio_deprecations import FindAsyncioCoroutineDecorator
|
|
56
|
+
from .locale_getdefaultlocale_deprecation import FindLocaleGetdefaultlocale
|
|
57
|
+
from .re_deprecations import FindReTemplate
|
|
58
|
+
from .configparser_deprecations import (
|
|
59
|
+
ReplaceConfigparserReadfp,
|
|
60
|
+
ReplaceConfigparserSafeConfigParser,
|
|
61
|
+
)
|
|
62
|
+
from .gettext_deprecations import ReplaceGettextDeprecations
|
|
63
|
+
from .socket_deprecations import FindSocketGetFQDN
|
|
64
|
+
from .unittest_deprecations import ReplaceUnittestDeprecatedAliases
|
|
65
|
+
from .upgrade_to_python310 import UpgradeToPython310
|
|
66
|
+
|
|
67
|
+
return [
|
|
68
|
+
# First apply all Python 3.10 upgrades
|
|
69
|
+
UpgradeToPython310(),
|
|
70
|
+
# inspect.getargspec() was deprecated in 3.0 and removed in 3.11
|
|
71
|
+
ChangeImport(old_module="inspect", old_name="getargspec", new_module="inspect", new_name="getfullargspec"),
|
|
72
|
+
# configparser.SafeConfigParser deprecated in 3.2, removed in 3.12
|
|
73
|
+
ReplaceConfigparserSafeConfigParser(),
|
|
74
|
+
# configparser.readfp() deprecated in 3.2, removed in 3.13
|
|
75
|
+
ReplaceConfigparserReadfp(),
|
|
76
|
+
# gettext.lgettext() etc. deprecated in 3.8, removed in 3.11
|
|
77
|
+
ReplaceGettextDeprecations(),
|
|
78
|
+
# logging.warn() deprecated in 3.3 (still works but not recommended)
|
|
79
|
+
ChangeImport(old_module="logging", old_name="warn", new_module="logging", new_name="warning"),
|
|
80
|
+
# unittest method aliases (assertEquals, etc.) removed in 3.11/3.12
|
|
81
|
+
ReplaceUnittestDeprecatedAliases(),
|
|
82
|
+
# @asyncio.coroutine + yield from -> async def + await (removed in 3.11)
|
|
83
|
+
MigrateAsyncioCoroutine(),
|
|
84
|
+
# Detect @asyncio.coroutine usage that can't be auto-migrated
|
|
85
|
+
FindAsyncioCoroutineDecorator(),
|
|
86
|
+
# socket.getfqdn() deprecated in 3.11
|
|
87
|
+
FindSocketGetFQDN(),
|
|
88
|
+
# locale.getdefaultlocale() deprecated in 3.11
|
|
89
|
+
FindLocaleGetdefaultlocale(),
|
|
90
|
+
# re.template() / re.TEMPLATE deprecated in 3.11
|
|
91
|
+
FindReTemplate(),
|
|
92
|
+
]
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Composite recipe for upgrading from Python 3.11 to Python 3.12."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from rewrite import Recipe
|
|
6
|
+
from rewrite.category import CategoryDescriptor
|
|
7
|
+
from rewrite.decorators import categorize
|
|
8
|
+
from rewrite.marketplace import Python
|
|
9
|
+
from rewrite.python.recipes import ChangeImport
|
|
10
|
+
|
|
11
|
+
# Define category path: Python > Migrate
|
|
12
|
+
_Migrate = [*Python, CategoryDescriptor(display_name="Migrate")]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@categorize(_Migrate)
|
|
16
|
+
class UpgradeToPython312(Recipe):
|
|
17
|
+
"""
|
|
18
|
+
Migrate deprecated and removed APIs for Python 3.12 compatibility.
|
|
19
|
+
|
|
20
|
+
This composite recipe applies all necessary migrations for code
|
|
21
|
+
running on Python 3.11 to be compatible with Python 3.12.
|
|
22
|
+
|
|
23
|
+
Key changes in Python 3.12:
|
|
24
|
+
- `datetime.utcnow()` and `utcfromtimestamp()` deprecated
|
|
25
|
+
- The `imp` module is removed (use `importlib` instead)
|
|
26
|
+
- `asynchat`, `asyncore`, and `smtpd` modules removed
|
|
27
|
+
- `distutils` is fully removed (use `setuptools` or `packaging`)
|
|
28
|
+
- `configparser.SafeConfigParser` is removed (use `ConfigParser`)
|
|
29
|
+
- `Path.link_to()` removed (use `hardlink_to()` with reversed args)
|
|
30
|
+
|
|
31
|
+
See: https://docs.python.org/3/whatsnew/3.12.html
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def name(self) -> str:
|
|
36
|
+
return "org.openrewrite.python.migrate.UpgradeToPython312"
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def display_name(self) -> str:
|
|
40
|
+
return "Upgrade to Python 3.12"
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def description(self) -> str:
|
|
44
|
+
return (
|
|
45
|
+
"Migrate deprecated and removed APIs for Python 3.12 compatibility. "
|
|
46
|
+
"This includes detecting usage of the removed `imp` module and other "
|
|
47
|
+
"legacy modules that were removed in Python 3.12."
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def tags(self) -> List[str]:
|
|
52
|
+
return ["python", "migration", "3.12"]
|
|
53
|
+
|
|
54
|
+
def recipe_list(self) -> List[Recipe]:
|
|
55
|
+
"""Return the list of recipes to apply for Python 3.12 upgrade."""
|
|
56
|
+
# Import here to avoid circular imports
|
|
57
|
+
from .calendar_deprecations import ReplaceCalendarConstants
|
|
58
|
+
from .datetime_utc import ReplaceDatetimeUtcFromTimestamp, ReplaceDatetimeUtcNow
|
|
59
|
+
from .shutil_deprecations import FindShutilRmtreeOnerror
|
|
60
|
+
from .sys_last_deprecations import FindSysLastExcInfo
|
|
61
|
+
from .distutils_deprecations import FindDistutilsUsage
|
|
62
|
+
from .distutils_migrations import ReplaceDistutilsVersion
|
|
63
|
+
from .imp_migrations import FindImpUsage
|
|
64
|
+
from .os_deprecations import FindOsPopen, FindOsSpawn
|
|
65
|
+
from .pathlib_deprecations import FindPathlibLinkTo
|
|
66
|
+
from .pkgutil_deprecations import ReplacePkgutilFindLoader, ReplacePkgutilGetLoader
|
|
67
|
+
from .removed_modules_312 import FindRemovedModules312
|
|
68
|
+
from .ssl_deprecations import FindSslMatchHostname
|
|
69
|
+
from .upgrade_to_python311 import UpgradeToPython311
|
|
70
|
+
|
|
71
|
+
return [
|
|
72
|
+
# First apply all Python 3.11 upgrades (which includes 3.10 upgrades)
|
|
73
|
+
UpgradeToPython311(),
|
|
74
|
+
# datetime.utcnow() / utcfromtimestamp() deprecated in 3.12
|
|
75
|
+
ReplaceDatetimeUtcNow(),
|
|
76
|
+
ReplaceDatetimeUtcFromTimestamp(),
|
|
77
|
+
# calendar mixed-case constants deprecated in Python 3.12
|
|
78
|
+
ReplaceCalendarConstants(),
|
|
79
|
+
# imp module was removed in Python 3.12 - auto-fix where possible
|
|
80
|
+
ChangeImport(old_module="imp", old_name="reload", new_module="importlib"), # imp.reload() -> importlib.reload()
|
|
81
|
+
FindImpUsage(), # Flag any remaining imp usage
|
|
82
|
+
# distutils removed in 3.12 (detection only)
|
|
83
|
+
ReplaceDistutilsVersion(),
|
|
84
|
+
FindDistutilsUsage(),
|
|
85
|
+
# pkgutil.find_loader/get_loader deprecated in 3.12 (detection only)
|
|
86
|
+
ReplacePkgutilFindLoader(),
|
|
87
|
+
ReplacePkgutilGetLoader(),
|
|
88
|
+
# Path.link_to() removed in 3.12
|
|
89
|
+
FindPathlibLinkTo(),
|
|
90
|
+
# Detect imports of modules removed in 3.12
|
|
91
|
+
FindRemovedModules312(),
|
|
92
|
+
# ssl.match_hostname() removed in 3.12
|
|
93
|
+
FindSslMatchHostname(),
|
|
94
|
+
# os.popen/os.spawn* deprecated (use subprocess)
|
|
95
|
+
FindOsPopen(),
|
|
96
|
+
FindOsSpawn(),
|
|
97
|
+
# shutil.rmtree(onerror=) deprecated in 3.12
|
|
98
|
+
FindShutilRmtreeOnerror(),
|
|
99
|
+
# sys.last_type/last_value/last_traceback deprecated in 3.12
|
|
100
|
+
FindSysLastExcInfo(),
|
|
101
|
+
]
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Composite recipe for upgrading from Python 3.12 to Python 3.13."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from rewrite import Recipe
|
|
6
|
+
from rewrite.category import CategoryDescriptor
|
|
7
|
+
from rewrite.decorators import categorize
|
|
8
|
+
from rewrite.marketplace import Python
|
|
9
|
+
|
|
10
|
+
# Define category path: Python > Migrate
|
|
11
|
+
_Migrate = [*Python, CategoryDescriptor(display_name="Migrate")]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@categorize(_Migrate)
|
|
15
|
+
class UpgradeToPython313(Recipe):
|
|
16
|
+
"""
|
|
17
|
+
Migrate deprecated and removed APIs for Python 3.13 compatibility.
|
|
18
|
+
|
|
19
|
+
This composite recipe applies all necessary migrations for code
|
|
20
|
+
running on Python 3.12 to be compatible with Python 3.13.
|
|
21
|
+
|
|
22
|
+
Key changes in Python 3.13 (PEP 594 "dead batteries" removals):
|
|
23
|
+
- `cgi` and `cgitb` modules removed
|
|
24
|
+
- `telnetlib` module removed
|
|
25
|
+
- `nntplib` module removed
|
|
26
|
+
- `pipes` module removed
|
|
27
|
+
- `uu` module removed
|
|
28
|
+
- Many other legacy modules removed (aifc, audioop, chunk, crypt,
|
|
29
|
+
imghdr, mailcap, msilib, nis, ossaudiodev, sndhdr, spwd, sunau, xdrlib)
|
|
30
|
+
- `configparser.readfp()` removed (deprecated since 3.2)
|
|
31
|
+
|
|
32
|
+
See: https://docs.python.org/3/whatsnew/3.13.html
|
|
33
|
+
See: https://peps.python.org/pep-0594/
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def name(self) -> str:
|
|
38
|
+
return "org.openrewrite.python.migrate.UpgradeToPython313"
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def display_name(self) -> str:
|
|
42
|
+
return "Upgrade to Python 3.13"
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def description(self) -> str:
|
|
46
|
+
return (
|
|
47
|
+
"Migrate deprecated and removed APIs for Python 3.13 compatibility. "
|
|
48
|
+
"This includes detecting usage of modules removed in PEP 594 "
|
|
49
|
+
"('dead batteries') and other API changes between Python 3.12 and 3.13."
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def tags(self) -> List[str]:
|
|
54
|
+
return ["python", "migration", "3.13"]
|
|
55
|
+
|
|
56
|
+
def recipe_list(self) -> List[Recipe]:
|
|
57
|
+
"""Return the list of recipes to apply for Python 3.13 upgrade."""
|
|
58
|
+
# Import here to avoid circular imports
|
|
59
|
+
from .aifc_migrations import (
|
|
60
|
+
FindAifcModule,
|
|
61
|
+
FindAudioopModule,
|
|
62
|
+
FindChunkModule,
|
|
63
|
+
FindImghdrModule,
|
|
64
|
+
FindSndhdrModule,
|
|
65
|
+
FindSunauModule,
|
|
66
|
+
)
|
|
67
|
+
from .cgi_migrations import FindCgiModule, FindCgitbModule
|
|
68
|
+
from .locale_deprecations import ReplaceLocaleResetlocale
|
|
69
|
+
from .mailcap_migrations import FindMailcapModule
|
|
70
|
+
from .nntplib_migrations import FindNntplibModule
|
|
71
|
+
from .pep594_system_migrations import (
|
|
72
|
+
FindCryptModule,
|
|
73
|
+
FindMsilibModule,
|
|
74
|
+
FindNisModule,
|
|
75
|
+
FindOssaudiodevModule,
|
|
76
|
+
FindSpwdModule,
|
|
77
|
+
)
|
|
78
|
+
from .pipes_migrations import FindPipesModule
|
|
79
|
+
from .telnetlib_migrations import FindTelnetlibModule
|
|
80
|
+
from .upgrade_to_python312 import UpgradeToPython312
|
|
81
|
+
from .uu_migrations import FindUuModule
|
|
82
|
+
from .xdrlib_migrations import FindXdrlibModule
|
|
83
|
+
|
|
84
|
+
return [
|
|
85
|
+
# First apply all Python 3.12 upgrades (which includes 3.11 and 3.10)
|
|
86
|
+
UpgradeToPython312(),
|
|
87
|
+
# locale.resetlocale() removed in 3.13 (deprecated in 3.11)
|
|
88
|
+
ReplaceLocaleResetlocale(),
|
|
89
|
+
# PEP 594 "dead batteries" - removed modules (detection only)
|
|
90
|
+
FindAifcModule(),
|
|
91
|
+
FindAudioopModule(),
|
|
92
|
+
FindCgiModule(),
|
|
93
|
+
FindCgitbModule(),
|
|
94
|
+
FindChunkModule(),
|
|
95
|
+
FindCryptModule(),
|
|
96
|
+
FindImghdrModule(),
|
|
97
|
+
FindMailcapModule(),
|
|
98
|
+
FindMsilibModule(),
|
|
99
|
+
FindNisModule(),
|
|
100
|
+
FindNntplibModule(),
|
|
101
|
+
FindOssaudiodevModule(),
|
|
102
|
+
FindPipesModule(),
|
|
103
|
+
FindSndhdrModule(),
|
|
104
|
+
FindSpwdModule(),
|
|
105
|
+
FindSunauModule(),
|
|
106
|
+
FindTelnetlibModule(),
|
|
107
|
+
FindUuModule(),
|
|
108
|
+
FindXdrlibModule(),
|
|
109
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Composite recipe for upgrading from Python 3.13 to Python 3.14."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from rewrite import Recipe
|
|
6
|
+
from rewrite.category import CategoryDescriptor
|
|
7
|
+
from rewrite.decorators import categorize
|
|
8
|
+
from rewrite.marketplace import Python
|
|
9
|
+
|
|
10
|
+
# Define category path: Python > Migrate
|
|
11
|
+
_Migrate = [*Python, CategoryDescriptor(display_name="Migrate")]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@categorize(_Migrate)
|
|
15
|
+
class UpgradeToPython314(Recipe):
|
|
16
|
+
"""
|
|
17
|
+
Migrate deprecated and removed APIs for Python 3.14 compatibility.
|
|
18
|
+
|
|
19
|
+
This composite recipe applies all necessary migrations for code
|
|
20
|
+
running on Python 3.13 to be compatible with Python 3.14.
|
|
21
|
+
|
|
22
|
+
Key changes in Python 3.14:
|
|
23
|
+
- `ast.Num`, `ast.Str`, `ast.Bytes`, `ast.NameConstant`, `ast.Ellipsis`
|
|
24
|
+
removed (deprecated since 3.8, use `ast.Constant` instead)
|
|
25
|
+
- `array.tostring()` / `fromstring()` removed (use tobytes/frombytes)
|
|
26
|
+
- `tempfile.mktemp()` removed (security issue, use mkstemp)
|
|
27
|
+
- Various urllib.parse split functions removed
|
|
28
|
+
|
|
29
|
+
See: https://docs.python.org/3/whatsnew/3.14.html
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def name(self) -> str:
|
|
34
|
+
return "org.openrewrite.python.migrate.UpgradeToPython314"
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def display_name(self) -> str:
|
|
38
|
+
return "Upgrade to Python 3.14"
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def description(self) -> str:
|
|
42
|
+
return (
|
|
43
|
+
"Migrate deprecated and removed APIs for Python 3.14 compatibility. "
|
|
44
|
+
"This includes replacing deprecated AST node types with `ast.Constant` "
|
|
45
|
+
"and other API changes between Python 3.13 and 3.14."
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def tags(self) -> List[str]:
|
|
50
|
+
return ["python", "migration", "3.14"]
|
|
51
|
+
|
|
52
|
+
def recipe_list(self) -> List[Recipe]:
|
|
53
|
+
"""Return the list of recipes to apply for Python 3.14 upgrade."""
|
|
54
|
+
# Import here to avoid circular imports
|
|
55
|
+
from .array_deprecations import ReplaceArrayFromstring, ReplaceArrayTostring
|
|
56
|
+
from .ast_deprecations import (
|
|
57
|
+
ReplaceAstBytes,
|
|
58
|
+
ReplaceAstEllipsis,
|
|
59
|
+
ReplaceAstNameConstant,
|
|
60
|
+
ReplaceAstNum,
|
|
61
|
+
ReplaceAstStr,
|
|
62
|
+
)
|
|
63
|
+
from .tempfile_deprecations import FindTempfileMktemp
|
|
64
|
+
from .upgrade_to_python313 import UpgradeToPython313
|
|
65
|
+
from .urllib_deprecations import (
|
|
66
|
+
FindUrllibParseSplitFunctions,
|
|
67
|
+
FindUrllibParseToBytes,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return [
|
|
71
|
+
# First apply all Python 3.13 upgrades (which includes 3.12, 3.11, 3.10)
|
|
72
|
+
UpgradeToPython313(),
|
|
73
|
+
# Array methods removed in 3.14 (deprecated since 3.2)
|
|
74
|
+
ReplaceArrayTostring(), # tostring() -> tobytes()
|
|
75
|
+
ReplaceArrayFromstring(), # fromstring() -> frombytes()
|
|
76
|
+
# ast.Num, ast.Str, etc. removed in 3.14 (deprecated since 3.8)
|
|
77
|
+
ReplaceAstNum(),
|
|
78
|
+
ReplaceAstStr(),
|
|
79
|
+
ReplaceAstBytes(),
|
|
80
|
+
ReplaceAstNameConstant(),
|
|
81
|
+
ReplaceAstEllipsis(),
|
|
82
|
+
# tempfile.mktemp() removed (security issue)
|
|
83
|
+
FindTempfileMktemp(),
|
|
84
|
+
# urllib.parse split functions removed
|
|
85
|
+
FindUrllibParseSplitFunctions(),
|
|
86
|
+
FindUrllibParseToBytes(),
|
|
87
|
+
]
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Composite recipe for upgrading to Python 3.8."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from rewrite import Recipe
|
|
6
|
+
from rewrite.category import CategoryDescriptor
|
|
7
|
+
from rewrite.decorators import categorize
|
|
8
|
+
from rewrite.marketplace import Python
|
|
9
|
+
from rewrite.python.recipes import ChangeImport
|
|
10
|
+
|
|
11
|
+
# Define category path: Python > Migrate
|
|
12
|
+
_Migrate = [*Python, CategoryDescriptor(display_name="Migrate")]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@categorize(_Migrate)
|
|
16
|
+
class UpgradeToPython38(Recipe):
|
|
17
|
+
"""
|
|
18
|
+
Migrate deprecated APIs and detect legacy patterns for Python 3.8 compatibility.
|
|
19
|
+
|
|
20
|
+
This composite recipe applies migrations for code targeting Python 3.8.
|
|
21
|
+
|
|
22
|
+
Key changes:
|
|
23
|
+
- Replace `time.clock()` with `time.perf_counter()`
|
|
24
|
+
- Replace `cgi.escape()` with `html.escape()`
|
|
25
|
+
- Detect removed `cgi.parse_qs()` / `cgi.parse_qsl()` usage
|
|
26
|
+
- Detect removed `platform.popen()` usage
|
|
27
|
+
- Detect removed `macpath` module usage
|
|
28
|
+
- Detect removed `tarfile.filemode` usage
|
|
29
|
+
- Detect removed `sys.set_coroutine_wrapper()` / `sys.get_coroutine_wrapper()`
|
|
30
|
+
- Detect legacy string formatting (% formatting, str.format())
|
|
31
|
+
- Detect deprecated `functools.cmp_to_key()` usage
|
|
32
|
+
|
|
33
|
+
See: https://docs.python.org/3/whatsnew/3.8.html
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def name(self) -> str:
|
|
38
|
+
return "org.openrewrite.python.migrate.UpgradeToPython38"
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def display_name(self) -> str:
|
|
42
|
+
return "Upgrade to Python 3.8"
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def description(self) -> str:
|
|
46
|
+
return (
|
|
47
|
+
"Migrate deprecated APIs and detect legacy patterns for Python 3.8 compatibility."
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def tags(self) -> List[str]:
|
|
52
|
+
return ["python", "migration", "3.8"]
|
|
53
|
+
|
|
54
|
+
def recipe_list(self) -> List[Recipe]:
|
|
55
|
+
"""Return the list of recipes to apply for Python 3.8 upgrade."""
|
|
56
|
+
from .cgi_parse_deprecations import FindCgiParseQs, FindCgiParseQsl
|
|
57
|
+
from .functools_deprecations import FindFunctoolsCmpToKey
|
|
58
|
+
from .macpath_deprecations import FindMacpathModule
|
|
59
|
+
from .platform_deprecations import FindPlatformPopen
|
|
60
|
+
from .string_formatting import ReplacePercentFormatWithFString, ReplaceStrFormatWithFString
|
|
61
|
+
from .sys_deprecations import FindSysCoroutineWrapper
|
|
62
|
+
from .tarfile_deprecations import FindTarfileFilemode
|
|
63
|
+
return [
|
|
64
|
+
# Auto-fix: time.clock() -> time.perf_counter()
|
|
65
|
+
ChangeImport(old_module="time", old_name="clock", new_module="time", new_name="perf_counter"),
|
|
66
|
+
# Auto-fix: cgi.escape() -> html.escape()
|
|
67
|
+
ChangeImport(old_module="cgi", old_name="escape", new_module="html"),
|
|
68
|
+
# Detect removed cgi.parse_qs() / cgi.parse_qsl()
|
|
69
|
+
FindCgiParseQs(),
|
|
70
|
+
FindCgiParseQsl(),
|
|
71
|
+
# Detect removed platform.popen()
|
|
72
|
+
FindPlatformPopen(),
|
|
73
|
+
# Detect removed macpath module
|
|
74
|
+
FindMacpathModule(),
|
|
75
|
+
# Detect removed tarfile.filemode
|
|
76
|
+
FindTarfileFilemode(),
|
|
77
|
+
# Detect removed sys.set_coroutine_wrapper()/get_coroutine_wrapper()
|
|
78
|
+
FindSysCoroutineWrapper(),
|
|
79
|
+
|
|
80
|
+
# String formatting migrations
|
|
81
|
+
ReplaceStrFormatWithFString(),
|
|
82
|
+
ReplacePercentFormatWithFString(),
|
|
83
|
+
# functools.cmp_to_key deprecated
|
|
84
|
+
FindFunctoolsCmpToKey(),
|
|
85
|
+
]
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""Composite recipe for upgrading from Python 3.8 to Python 3.9."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from rewrite import Recipe
|
|
6
|
+
from rewrite.category import CategoryDescriptor
|
|
7
|
+
from rewrite.decorators import categorize
|
|
8
|
+
from rewrite.marketplace import Python
|
|
9
|
+
from rewrite.python.recipes import ChangeImport
|
|
10
|
+
|
|
11
|
+
# Define category path: Python > Migrate
|
|
12
|
+
_Migrate = [*Python, CategoryDescriptor(display_name="Migrate")]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@categorize(_Migrate)
|
|
16
|
+
class UpgradeToPython39(Recipe):
|
|
17
|
+
"""
|
|
18
|
+
Migrate deprecated APIs for Python 3.9 compatibility.
|
|
19
|
+
|
|
20
|
+
This composite recipe applies all necessary migrations for code
|
|
21
|
+
running on Python 3.8 to be compatible with Python 3.9.
|
|
22
|
+
|
|
23
|
+
Key changes in Python 3.9:
|
|
24
|
+
- PEP 585: Built-in generics (`list[int]` instead of `typing.List[int]`)
|
|
25
|
+
- `base64.encodestring()` / `decodestring()` removed
|
|
26
|
+
- `Element.getiterator()` deprecated (use `iter()`)
|
|
27
|
+
- `Element.getchildren()` deprecated (use `list(element)`)
|
|
28
|
+
- `typing.Callable` deprecated in favor of `collections.abc.Callable`
|
|
29
|
+
|
|
30
|
+
See: https://docs.python.org/3/whatsnew/3.9.html
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def name(self) -> str:
|
|
35
|
+
return "org.openrewrite.python.migrate.UpgradeToPython39"
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def display_name(self) -> str:
|
|
39
|
+
return "Upgrade to Python 3.9"
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def description(self) -> str:
|
|
43
|
+
return (
|
|
44
|
+
"Migrate deprecated APIs for Python 3.9 compatibility. "
|
|
45
|
+
"This includes PEP 585 built-in generics, removed base64 functions, "
|
|
46
|
+
"and deprecated XML Element methods."
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def tags(self) -> List[str]:
|
|
51
|
+
return ["python", "migration", "3.9"]
|
|
52
|
+
|
|
53
|
+
def recipe_list(self) -> List[Recipe]:
|
|
54
|
+
"""Return the list of recipes to apply for Python 3.9 upgrade."""
|
|
55
|
+
from .html_parser_deprecations import FindHtmlParserUnescape
|
|
56
|
+
from .threading_is_alive_deprecation import ReplaceThreadIsAlive
|
|
57
|
+
from .typing_callable import ReplaceTypingCallableWithCollectionsAbcCallable
|
|
58
|
+
from .upgrade_to_python38 import UpgradeToPython38
|
|
59
|
+
from .xml_deprecations import FindElementGetchildren, ReplaceElementGetiterator
|
|
60
|
+
|
|
61
|
+
return [
|
|
62
|
+
# First apply all Python 3.8 upgrades
|
|
63
|
+
UpgradeToPython38(),
|
|
64
|
+
# base64 encodestring/decodestring removed in Python 3.9
|
|
65
|
+
ChangeImport(old_module="base64", old_name="encodestring", new_module="base64", new_name="encodebytes"),
|
|
66
|
+
ChangeImport(old_module="base64", old_name="decodestring", new_module="base64", new_name="decodebytes"),
|
|
67
|
+
# PEP 585: Replace typing.List[X] with list[X], etc. (Python 3.9+)
|
|
68
|
+
ChangeImport(old_module="typing", old_name="List", new_module="builtins", new_name="list"),
|
|
69
|
+
ChangeImport(old_module="typing", old_name="Dict", new_module="builtins", new_name="dict"),
|
|
70
|
+
ChangeImport(old_module="typing", old_name="Set", new_module="builtins", new_name="set"),
|
|
71
|
+
ChangeImport(old_module="typing", old_name="FrozenSet", new_module="builtins", new_name="frozenset"),
|
|
72
|
+
ChangeImport(old_module="typing", old_name="Tuple", new_module="builtins", new_name="tuple"),
|
|
73
|
+
ChangeImport(old_module="typing", old_name="Type", new_module="builtins", new_name="type"),
|
|
74
|
+
# typing.Callable -> collections.abc.Callable (PEP 585)
|
|
75
|
+
ReplaceTypingCallableWithCollectionsAbcCallable(),
|
|
76
|
+
# PEP 585: typing -> collections replacements
|
|
77
|
+
ChangeImport(old_module="typing", old_name="Deque", new_module="collections", new_name="deque"),
|
|
78
|
+
ChangeImport(old_module="typing", old_name="DefaultDict", new_module="collections", new_name="defaultdict"),
|
|
79
|
+
ChangeImport(old_module="typing", old_name="OrderedDict", new_module="collections"),
|
|
80
|
+
ChangeImport(old_module="typing", old_name="Counter", new_module="collections"),
|
|
81
|
+
ChangeImport(old_module="typing", old_name="ChainMap", new_module="collections"),
|
|
82
|
+
# PEP 585: typing -> re replacements
|
|
83
|
+
ChangeImport(old_module="typing", old_name="Pattern", new_module="re"),
|
|
84
|
+
ChangeImport(old_module="typing", old_name="Match", new_module="re"),
|
|
85
|
+
# PEP 585: typing -> contextlib replacements
|
|
86
|
+
ChangeImport(old_module="typing", old_name="ContextManager", new_module="contextlib", new_name="AbstractContextManager"),
|
|
87
|
+
ChangeImport(old_module="typing", old_name="AsyncContextManager", new_module="contextlib", new_name="AbstractAsyncContextManager"),
|
|
88
|
+
# PEP 585: typing -> collections.abc replacements
|
|
89
|
+
ChangeImport(old_module="typing", old_name="Iterable", new_module="collections.abc"),
|
|
90
|
+
ChangeImport(old_module="typing", old_name="Iterator", new_module="collections.abc"),
|
|
91
|
+
ChangeImport(old_module="typing", old_name="Generator", new_module="collections.abc"),
|
|
92
|
+
ChangeImport(old_module="typing", old_name="Sequence", new_module="collections.abc"),
|
|
93
|
+
ChangeImport(old_module="typing", old_name="MutableSequence", new_module="collections.abc"),
|
|
94
|
+
ChangeImport(old_module="typing", old_name="Mapping", new_module="collections.abc"),
|
|
95
|
+
ChangeImport(old_module="typing", old_name="MutableMapping", new_module="collections.abc"),
|
|
96
|
+
ChangeImport(old_module="typing", old_name="AbstractSet", new_module="collections.abc", new_name="Set"),
|
|
97
|
+
ChangeImport(old_module="typing", old_name="MutableSet", new_module="collections.abc"),
|
|
98
|
+
ChangeImport(old_module="typing", old_name="Awaitable", new_module="collections.abc"),
|
|
99
|
+
ChangeImport(old_module="typing", old_name="Coroutine", new_module="collections.abc"),
|
|
100
|
+
ChangeImport(old_module="typing", old_name="AsyncIterable", new_module="collections.abc"),
|
|
101
|
+
ChangeImport(old_module="typing", old_name="AsyncIterator", new_module="collections.abc"),
|
|
102
|
+
ChangeImport(old_module="typing", old_name="AsyncGenerator", new_module="collections.abc"),
|
|
103
|
+
ChangeImport(old_module="typing", old_name="Reversible", new_module="collections.abc"),
|
|
104
|
+
ChangeImport(old_module="typing", old_name="Container", new_module="collections.abc"),
|
|
105
|
+
ChangeImport(old_module="typing", old_name="Collection", new_module="collections.abc"),
|
|
106
|
+
ChangeImport(old_module="typing", old_name="MappingView", new_module="collections.abc"),
|
|
107
|
+
ChangeImport(old_module="typing", old_name="KeysView", new_module="collections.abc"),
|
|
108
|
+
ChangeImport(old_module="typing", old_name="ItemsView", new_module="collections.abc"),
|
|
109
|
+
ChangeImport(old_module="typing", old_name="ValuesView", new_module="collections.abc"),
|
|
110
|
+
ChangeImport(old_module="typing", old_name="Hashable", new_module="collections.abc"),
|
|
111
|
+
ChangeImport(old_module="typing", old_name="Sized", new_module="collections.abc"),
|
|
112
|
+
# XML Element.getiterator() deprecated in 3.9, use iter()
|
|
113
|
+
ReplaceElementGetiterator(),
|
|
114
|
+
# XML Element.getchildren() deprecated in 3.9 (detection only)
|
|
115
|
+
FindElementGetchildren(),
|
|
116
|
+
# fractions.gcd() removed in 3.9, use math.gcd()
|
|
117
|
+
ChangeImport(old_module="fractions", old_name="gcd", new_module="math"),
|
|
118
|
+
# sys.getcheckinterval/setcheckinterval removed in 3.9
|
|
119
|
+
ChangeImport(old_module="sys", old_name="getcheckinterval", new_module="sys", new_name="getswitchinterval"),
|
|
120
|
+
ChangeImport(old_module="sys", old_name="setcheckinterval", new_module="sys", new_name="setswitchinterval"),
|
|
121
|
+
# Thread.isAlive() removed in 3.9
|
|
122
|
+
ReplaceThreadIsAlive(),
|
|
123
|
+
# HTMLParser.unescape() removed in 3.9
|
|
124
|
+
FindHtmlParserUnescape(),
|
|
125
|
+
]
|