openrewrite-migrate-python 0.13.2__py3-none-any.whl → 0.14.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/migrate/_markers.py +9 -4
- openrewrite_migrate_python/migrate/array_deprecations.py +9 -3
- openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +2 -2
- openrewrite_migrate_python/migrate/configparser_deprecations.py +38 -19
- openrewrite_migrate_python/migrate/distutils_migrations.py +16 -16
- openrewrite_migrate_python/migrate/functools_deprecations.py +1 -1
- openrewrite_migrate_python/migrate/html_parser_deprecations.py +1 -1
- openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +1 -1
- openrewrite_migrate_python/migrate/os_deprecations.py +1 -1
- openrewrite_migrate_python/migrate/pathlib_deprecations.py +10 -6
- openrewrite_migrate_python/migrate/re_deprecations.py +1 -1
- openrewrite_migrate_python/migrate/shutil_deprecations.py +29 -17
- openrewrite_migrate_python/migrate/socket_deprecations.py +7 -11
- openrewrite_migrate_python/migrate/tarfile_deprecations.py +1 -1
- openrewrite_migrate_python/migrate/tempfile_deprecations.py +1 -1
- openrewrite_migrate_python/migrate/threading_deprecations.py +11 -5
- openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +5 -2
- openrewrite_migrate_python/migrate/typing_deprecations.py +73 -15
- openrewrite_migrate_python/migrate/typing_union_to_pipe.py +3 -0
- openrewrite_migrate_python/migrate/urllib_deprecations.py +12 -13
- openrewrite_migrate_python/migrate/xml_deprecations.py +2 -2
- {openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/METADATA +2 -2
- {openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/RECORD +26 -26
- {openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/WHEEL +0 -0
- {openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/entry_points.txt +0 -0
- {openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/top_level.txt +0 -0
|
@@ -15,8 +15,13 @@ def mark_deprecated(tree: Any, message: str, detail: Optional[str] = None) -> An
|
|
|
15
15
|
output but surfaces as a warning diagnostic in the tooling.
|
|
16
16
|
"""
|
|
17
17
|
full_message = f"{message}: {detail}" if detail else message
|
|
18
|
-
warn_marker = MarkupWarn(random_id(), full_message)
|
|
19
18
|
current_markers = tree.markers
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
# A run re-applies the recipe to its own output until nothing changes, so a tree already
|
|
20
|
+
# carrying this warning has to come back unchanged for the run to converge.
|
|
21
|
+
if any(
|
|
22
|
+
isinstance(m, MarkupWarn) and m.message == full_message
|
|
23
|
+
for m in current_markers.markers
|
|
24
|
+
):
|
|
25
|
+
return tree
|
|
26
|
+
new_markers_list = list(current_markers.markers) + [MarkupWarn(random_id(), full_message)]
|
|
27
|
+
return tree.replace(_markers=Markers(current_markers.id, new_markers_list))
|
|
@@ -14,7 +14,7 @@ from rewrite import ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
|
14
14
|
from rewrite.category import CategoryDescriptor
|
|
15
15
|
from rewrite.decorators import categorize
|
|
16
16
|
from rewrite.marketplace import Python
|
|
17
|
-
from rewrite.python.preconditions import uses_method
|
|
17
|
+
from rewrite.python.preconditions import uses_import, uses_method
|
|
18
18
|
from rewrite.python.visitor import PythonVisitor
|
|
19
19
|
from rewrite.java.tree import Identifier, MethodInvocation
|
|
20
20
|
|
|
@@ -81,7 +81,10 @@ class ReplaceArrayTostring(Recipe):
|
|
|
81
81
|
new_name = method.name.replace(_simple_name="tobytes")
|
|
82
82
|
return method.replace(_name=new_name)
|
|
83
83
|
|
|
84
|
-
return Preconditions.check(
|
|
84
|
+
return Preconditions.check(
|
|
85
|
+
Preconditions.and_(uses_import("array"), uses_method("*..* tostring(..)")),
|
|
86
|
+
Visitor(),
|
|
87
|
+
)
|
|
85
88
|
|
|
86
89
|
|
|
87
90
|
@categorize(_Python314)
|
|
@@ -137,4 +140,7 @@ class ReplaceArrayFromstring(Recipe):
|
|
|
137
140
|
new_name = method.name.replace(_simple_name="frombytes")
|
|
138
141
|
return method.replace(_name=new_name)
|
|
139
142
|
|
|
140
|
-
return Preconditions.check(
|
|
143
|
+
return Preconditions.check(
|
|
144
|
+
Preconditions.and_(uses_import("array"), uses_method("*..* fromstring(..)")),
|
|
145
|
+
Visitor(),
|
|
146
|
+
)
|
|
@@ -136,7 +136,7 @@ class ReplaceCgiParseQs(Recipe):
|
|
|
136
136
|
new_padded = old_padded.replace(_element=new_select)
|
|
137
137
|
return method.padding.replace(_select=new_padded)
|
|
138
138
|
|
|
139
|
-
return Preconditions.check(uses_method("
|
|
139
|
+
return Preconditions.check(uses_method("cgi parse_qs(..)"), Visitor())
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
@categorize(_Python38)
|
|
@@ -202,4 +202,4 @@ class ReplaceCgiParseQsl(Recipe):
|
|
|
202
202
|
new_padded = old_padded.replace(_element=new_select)
|
|
203
203
|
return method.padding.replace(_select=new_padded)
|
|
204
204
|
|
|
205
|
-
return Preconditions.check(uses_method("
|
|
205
|
+
return Preconditions.check(uses_method("cgi parse_qsl(..)"), Visitor())
|
|
@@ -12,12 +12,15 @@ See: https://docs.python.org/3/library/configparser.html
|
|
|
12
12
|
|
|
13
13
|
from typing import Any, Optional
|
|
14
14
|
|
|
15
|
-
from rewrite import ExecutionContext, Recipe, TreeVisitor
|
|
15
|
+
from rewrite import Cursor, ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
16
16
|
from rewrite.category import CategoryDescriptor
|
|
17
17
|
from rewrite.decorators import categorize
|
|
18
18
|
from rewrite.marketplace import Python
|
|
19
|
+
from rewrite.python.preconditions import uses_import, uses_method
|
|
20
|
+
from rewrite.python.scope_utils import LocalBindings
|
|
19
21
|
from rewrite.python.visitor import PythonVisitor
|
|
20
|
-
from rewrite.
|
|
22
|
+
from rewrite.python.tree import CompilationUnit
|
|
23
|
+
from rewrite.java.tree import Identifier, FieldAccess, J, MethodInvocation
|
|
21
24
|
|
|
22
25
|
# Define category path: Python > Migrate > Python 3.12
|
|
23
26
|
_Python312 = [
|
|
@@ -34,7 +37,18 @@ _Python313 = [
|
|
|
34
37
|
]
|
|
35
38
|
|
|
36
39
|
|
|
37
|
-
def
|
|
40
|
+
def _names_the_module(node: Any, locals_: LocalBindings, cursor: Cursor) -> bool:
|
|
41
|
+
"""Whether ``node`` is the `configparser` module rather than something else holding the name."""
|
|
42
|
+
return (
|
|
43
|
+
isinstance(node, Identifier)
|
|
44
|
+
and node.simple_name == "configparser"
|
|
45
|
+
and not locals_.is_bound(cursor, "configparser")
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _is_configparser_attribute(
|
|
50
|
+
field_access: FieldAccess, attr_name: str, locals_: LocalBindings, cursor: Cursor
|
|
51
|
+
) -> bool:
|
|
38
52
|
"""
|
|
39
53
|
Check if this is a configparser.attr_name access.
|
|
40
54
|
|
|
@@ -47,12 +61,7 @@ def _is_configparser_attribute(field_access: FieldAccess, attr_name: str) -> boo
|
|
|
47
61
|
if field_access.name.simple_name != attr_name:
|
|
48
62
|
return False
|
|
49
63
|
|
|
50
|
-
|
|
51
|
-
target = field_access.target
|
|
52
|
-
if isinstance(target, Identifier) and target.simple_name == "configparser":
|
|
53
|
-
return True
|
|
54
|
-
|
|
55
|
-
return False
|
|
64
|
+
return _names_the_module(field_access.target, locals_, cursor)
|
|
56
65
|
|
|
57
66
|
|
|
58
67
|
def _replace_configparser_attribute(field_access: FieldAccess, new_name: str) -> FieldAccess:
|
|
@@ -99,7 +108,9 @@ def _rename_method(method: MethodInvocation, new_name: str) -> MethodInvocation:
|
|
|
99
108
|
return method.replace(_name=new_identifier)
|
|
100
109
|
|
|
101
110
|
|
|
102
|
-
def _is_configparser_constructor(
|
|
111
|
+
def _is_configparser_constructor(
|
|
112
|
+
method: MethodInvocation, class_name: str, locals_: LocalBindings, cursor: Cursor
|
|
113
|
+
) -> bool:
|
|
103
114
|
"""
|
|
104
115
|
Check if this is a configparser.ClassName() constructor call.
|
|
105
116
|
|
|
@@ -112,11 +123,7 @@ def _is_configparser_constructor(method: MethodInvocation, class_name: str) -> b
|
|
|
112
123
|
if method.name.simple_name != class_name:
|
|
113
124
|
return False
|
|
114
125
|
|
|
115
|
-
|
|
116
|
-
select = method.select
|
|
117
|
-
if select is None:
|
|
118
|
-
return False
|
|
119
|
-
if isinstance(select, Identifier) and select.simple_name == "configparser":
|
|
126
|
+
if _names_the_module(method.select, locals_, cursor):
|
|
120
127
|
return True
|
|
121
128
|
|
|
122
129
|
return False
|
|
@@ -158,13 +165,23 @@ class ReplaceConfigparserSafeConfigParser(Recipe):
|
|
|
158
165
|
|
|
159
166
|
def editor(self) -> TreeVisitor[Any, ExecutionContext]:
|
|
160
167
|
class Visitor(PythonVisitor[ExecutionContext]):
|
|
168
|
+
def __init__(self) -> None:
|
|
169
|
+
super().__init__()
|
|
170
|
+
self._locals = LocalBindings()
|
|
171
|
+
|
|
172
|
+
def visit_compilation_unit(self, cu: CompilationUnit, p: ExecutionContext) -> J:
|
|
173
|
+
self._locals = LocalBindings()
|
|
174
|
+
return super().visit_compilation_unit(cu, p)
|
|
175
|
+
|
|
161
176
|
def visit_method_invocation(
|
|
162
177
|
self, method: MethodInvocation, p: ExecutionContext
|
|
163
178
|
) -> Optional[MethodInvocation]:
|
|
164
179
|
method = super().visit_method_invocation(method, p)
|
|
165
180
|
|
|
166
181
|
# Handle configparser.SafeConfigParser() constructor calls
|
|
167
|
-
if _is_configparser_constructor(
|
|
182
|
+
if _is_configparser_constructor(
|
|
183
|
+
method, "SafeConfigParser", self._locals, self.cursor
|
|
184
|
+
):
|
|
168
185
|
return _rename_method(method, "ConfigParser")
|
|
169
186
|
|
|
170
187
|
return method
|
|
@@ -175,12 +192,14 @@ class ReplaceConfigparserSafeConfigParser(Recipe):
|
|
|
175
192
|
field_access = super().visit_field_access(field_access, p)
|
|
176
193
|
|
|
177
194
|
# Handle configparser.SafeConfigParser as a value (without calling)
|
|
178
|
-
if _is_configparser_attribute(
|
|
195
|
+
if _is_configparser_attribute(
|
|
196
|
+
field_access, "SafeConfigParser", self._locals, self.cursor
|
|
197
|
+
):
|
|
179
198
|
return _replace_configparser_attribute(field_access, "ConfigParser")
|
|
180
199
|
|
|
181
200
|
return field_access
|
|
182
201
|
|
|
183
|
-
return Visitor()
|
|
202
|
+
return Preconditions.check(uses_import("configparser"), Visitor())
|
|
184
203
|
|
|
185
204
|
|
|
186
205
|
@categorize(_Python313)
|
|
@@ -232,4 +251,4 @@ class ReplaceConfigparserReadfp(Recipe):
|
|
|
232
251
|
|
|
233
252
|
return method
|
|
234
253
|
|
|
235
|
-
return Visitor()
|
|
254
|
+
return Preconditions.check(uses_method("configparser.*ConfigParser readfp(..)"), Visitor())
|
|
@@ -24,10 +24,13 @@ from rewrite.python.preconditions import uses_import
|
|
|
24
24
|
from rewrite.category import CategoryDescriptor
|
|
25
25
|
from rewrite.decorators import categorize
|
|
26
26
|
from rewrite.marketplace import Python
|
|
27
|
+
from rewrite.python.import_utils import get_name_string, get_qualid_name
|
|
27
28
|
from rewrite.python.visitor import PythonVisitor
|
|
28
29
|
from rewrite.python.tree import MultiImport
|
|
29
30
|
from ._markers import mark_deprecated
|
|
30
31
|
|
|
32
|
+
_DEPRECATED_CLASSES = frozenset({"LooseVersion", "StrictVersion"})
|
|
33
|
+
|
|
31
34
|
# Define category path: Python > Migrate > Python 3.12
|
|
32
35
|
_Python312 = [
|
|
33
36
|
*Python,
|
|
@@ -95,21 +98,18 @@ class ReplaceDistutilsVersion(Recipe):
|
|
|
95
98
|
) -> Optional[MultiImport]:
|
|
96
99
|
multi = super().visit_multi_import(multi, p)
|
|
97
100
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
return multi
|
|
101
|
+
if multi.from_ is None or get_name_string(multi.from_) != "distutils.version":
|
|
102
|
+
return multi
|
|
103
|
+
if not any(
|
|
104
|
+
get_qualid_name(imp.qualid) in _DEPRECATED_CLASSES for imp in multi.names
|
|
105
|
+
):
|
|
106
|
+
return multi
|
|
107
|
+
|
|
108
|
+
return mark_deprecated(
|
|
109
|
+
multi,
|
|
110
|
+
"distutils.version is deprecated",
|
|
111
|
+
"Migrate to packaging.version.Version (removed in Python 3.12). "
|
|
112
|
+
"Note: packaging.version.Version is not a drop-in replacement."
|
|
113
|
+
)
|
|
114
114
|
|
|
115
115
|
return Preconditions.check(uses_import("distutils"), Visitor())
|
|
@@ -13,11 +13,15 @@ from rewrite import ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
|
13
13
|
from rewrite.category import CategoryDescriptor
|
|
14
14
|
from rewrite.decorators import categorize
|
|
15
15
|
from rewrite.marketplace import Python
|
|
16
|
+
from rewrite.python.method_matcher import MethodMatcher
|
|
16
17
|
from rewrite.python.preconditions import uses_method
|
|
17
18
|
from rewrite.python.visitor import PythonVisitor
|
|
18
|
-
from rewrite.java.tree import
|
|
19
|
+
from rewrite.java.tree import MethodInvocation
|
|
19
20
|
from ._markers import mark_deprecated
|
|
20
21
|
|
|
22
|
+
_LINK_TO = "pathlib.Path link_to(..)"
|
|
23
|
+
_LINK_TO_MATCHER = MethodMatcher.create(_LINK_TO)
|
|
24
|
+
|
|
21
25
|
# Define category path: Python > Migrate > Python 3.12
|
|
22
26
|
_Python312 = [
|
|
23
27
|
*Python,
|
|
@@ -61,7 +65,9 @@ class FindPathlibLinkTo(Recipe):
|
|
|
61
65
|
def description(self) -> str:
|
|
62
66
|
return (
|
|
63
67
|
"Find usage of `Path.link_to()` which was deprecated in Python 3.10 "
|
|
64
|
-
"and removed in 3.12. Use `hardlink_to()` instead (note: argument order is reversed)."
|
|
68
|
+
"and removed in 3.12. Use `hardlink_to()` instead (note: argument order is reversed). "
|
|
69
|
+
"`link_to` is not a name reserved to `pathlib`, so this only reports calls whose "
|
|
70
|
+
"receiver resolves to a `Path`; a parse without type attribution reports nothing."
|
|
65
71
|
)
|
|
66
72
|
|
|
67
73
|
@property
|
|
@@ -75,9 +81,7 @@ class FindPathlibLinkTo(Recipe):
|
|
|
75
81
|
) -> Optional[MethodInvocation]:
|
|
76
82
|
method = super().visit_method_invocation(method, p)
|
|
77
83
|
|
|
78
|
-
if not
|
|
79
|
-
return method
|
|
80
|
-
if method.name.simple_name != "link_to":
|
|
84
|
+
if not _LINK_TO_MATCHER.matches(method):
|
|
81
85
|
return method
|
|
82
86
|
|
|
83
87
|
return mark_deprecated(
|
|
@@ -86,4 +90,4 @@ class FindPathlibLinkTo(Recipe):
|
|
|
86
90
|
"Use hardlink_to() instead (note: argument order is reversed)."
|
|
87
91
|
)
|
|
88
92
|
|
|
89
|
-
return Preconditions.check(uses_method(
|
|
93
|
+
return Preconditions.check(uses_method(_LINK_TO), Visitor())
|
|
@@ -13,11 +13,36 @@ from rewrite import ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
|
13
13
|
from rewrite.category import CategoryDescriptor
|
|
14
14
|
from rewrite.decorators import categorize
|
|
15
15
|
from rewrite.marketplace import Python
|
|
16
|
+
from rewrite.python.method_matcher import MethodMatcher
|
|
16
17
|
from rewrite.python.preconditions import uses_method
|
|
17
18
|
from rewrite.python.visitor import PythonVisitor
|
|
18
|
-
from rewrite.java.tree import Identifier, MethodInvocation
|
|
19
|
+
from rewrite.java.tree import Identifier, Literal, MethodInvocation
|
|
20
|
+
from rewrite.python.tree import NamedArgument
|
|
19
21
|
from ._markers import mark_deprecated
|
|
20
22
|
|
|
23
|
+
_RMTREE = "shutil rmtree(..)"
|
|
24
|
+
_RMTREE_MATCHER = MethodMatcher.create(_RMTREE)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _supplies_onerror(method: MethodInvocation) -> bool:
|
|
28
|
+
"""Whether the call passes a callback for `onerror`, by keyword or in its position.
|
|
29
|
+
|
|
30
|
+
`rmtree(path, ignore_errors, onerror)` puts `onerror` third, and an explicit `None`
|
|
31
|
+
there means the same as omitting it.
|
|
32
|
+
"""
|
|
33
|
+
def is_none(expr: Any) -> bool:
|
|
34
|
+
return isinstance(expr, (Identifier, Literal)) and str(
|
|
35
|
+
getattr(expr, "simple_name", None) or getattr(expr, "value_source", None)
|
|
36
|
+
) == "None"
|
|
37
|
+
|
|
38
|
+
for index, arg in enumerate(method.arguments):
|
|
39
|
+
if isinstance(arg, NamedArgument):
|
|
40
|
+
if isinstance(arg.name, Identifier) and arg.name.simple_name == "onerror":
|
|
41
|
+
return not is_none(arg.value)
|
|
42
|
+
elif index == 2:
|
|
43
|
+
return not is_none(arg)
|
|
44
|
+
return False
|
|
45
|
+
|
|
21
46
|
# Define category path: Python > Migrate > Python 3.12
|
|
22
47
|
_Python312 = [
|
|
23
48
|
*Python,
|
|
@@ -75,23 +100,10 @@ class FindShutilRmtreeOnerror(Recipe):
|
|
|
75
100
|
) -> Optional[MethodInvocation]:
|
|
76
101
|
method = super().visit_method_invocation(method, p)
|
|
77
102
|
|
|
78
|
-
if not
|
|
79
|
-
return method
|
|
80
|
-
if method.name.simple_name != "rmtree":
|
|
81
|
-
return method
|
|
82
|
-
|
|
83
|
-
select = method.select
|
|
84
|
-
if not isinstance(select, Identifier):
|
|
85
|
-
return method
|
|
86
|
-
if select.simple_name != "shutil":
|
|
103
|
+
if not _RMTREE_MATCHER.matches(method):
|
|
87
104
|
return method
|
|
88
105
|
|
|
89
|
-
|
|
90
|
-
# We look at the string representation of arguments for keyword args
|
|
91
|
-
# Since we can't easily inspect keyword args at the AST level
|
|
92
|
-
# without type attribution, we mark all shutil.rmtree() calls
|
|
93
|
-
# as needing review if they have 3+ arguments (path, ignore_errors, onerror)
|
|
94
|
-
if len(method.arguments) >= 3:
|
|
106
|
+
if _supplies_onerror(method):
|
|
95
107
|
return mark_deprecated(
|
|
96
108
|
method,
|
|
97
109
|
"shutil.rmtree() `onerror` parameter was deprecated in Python 3.12. "
|
|
@@ -100,4 +112,4 @@ class FindShutilRmtreeOnerror(Recipe):
|
|
|
100
112
|
|
|
101
113
|
return method
|
|
102
114
|
|
|
103
|
-
return Preconditions.check(uses_method(
|
|
115
|
+
return Preconditions.check(uses_method(_RMTREE), Visitor())
|
|
@@ -15,11 +15,15 @@ from rewrite import ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
|
15
15
|
from rewrite.category import CategoryDescriptor
|
|
16
16
|
from rewrite.decorators import categorize
|
|
17
17
|
from rewrite.marketplace import Python
|
|
18
|
+
from rewrite.python.method_matcher import MethodMatcher
|
|
18
19
|
from rewrite.python.preconditions import uses_method
|
|
19
20
|
from rewrite.python.visitor import PythonVisitor
|
|
20
|
-
from rewrite.java.tree import
|
|
21
|
+
from rewrite.java.tree import MethodInvocation
|
|
21
22
|
from ._markers import mark_deprecated
|
|
22
23
|
|
|
24
|
+
_GETFQDN = "socket getfqdn(..)"
|
|
25
|
+
_GETFQDN_MATCHER = MethodMatcher.create(_GETFQDN)
|
|
26
|
+
|
|
23
27
|
# Define category path: Python > Migrate > Python 3.11
|
|
24
28
|
_Python311 = [
|
|
25
29
|
*Python,
|
|
@@ -67,15 +71,7 @@ class FindSocketGetFQDN(Recipe):
|
|
|
67
71
|
) -> Optional[MethodInvocation]:
|
|
68
72
|
method = super().visit_method_invocation(method, p)
|
|
69
73
|
|
|
70
|
-
if not
|
|
71
|
-
return method
|
|
72
|
-
if method.name.simple_name != "getfqdn":
|
|
73
|
-
return method
|
|
74
|
-
|
|
75
|
-
select = method.select
|
|
76
|
-
if not isinstance(select, Identifier):
|
|
77
|
-
return method
|
|
78
|
-
if select.simple_name != "socket":
|
|
74
|
+
if not _GETFQDN_MATCHER.matches(method):
|
|
79
75
|
return method
|
|
80
76
|
|
|
81
77
|
return mark_deprecated(
|
|
@@ -84,4 +80,4 @@ class FindSocketGetFQDN(Recipe):
|
|
|
84
80
|
"Consider using socket.gethostname() instead."
|
|
85
81
|
)
|
|
86
82
|
|
|
87
|
-
return Preconditions.check(uses_method(
|
|
83
|
+
return Preconditions.check(uses_method(_GETFQDN), Visitor())
|
|
@@ -21,7 +21,7 @@ from rewrite import ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
|
21
21
|
from rewrite.category import CategoryDescriptor
|
|
22
22
|
from rewrite.decorators import categorize
|
|
23
23
|
from rewrite.marketplace import Python
|
|
24
|
-
from rewrite.python.preconditions import uses_method
|
|
24
|
+
from rewrite.python.preconditions import uses_import, uses_method
|
|
25
25
|
from rewrite.python.visitor import PythonVisitor
|
|
26
26
|
from rewrite.python.template import pattern, template, capture
|
|
27
27
|
from rewrite.java.tree import Identifier, MethodInvocation
|
|
@@ -95,7 +95,7 @@ class ReplaceThreadingCurrentThread(Recipe):
|
|
|
95
95
|
new_name = method.name.replace(_simple_name="current_thread")
|
|
96
96
|
return method.replace(_name=new_name)
|
|
97
97
|
|
|
98
|
-
return Preconditions.check(uses_method("
|
|
98
|
+
return Preconditions.check(uses_method("threading currentThread(..)"), Visitor())
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
@categorize(_Python310)
|
|
@@ -157,7 +157,7 @@ class ReplaceThreadingActiveCount(Recipe):
|
|
|
157
157
|
new_name = method.name.replace(_simple_name="active_count")
|
|
158
158
|
return method.replace(_name=new_name)
|
|
159
159
|
|
|
160
|
-
return Preconditions.check(uses_method("
|
|
160
|
+
return Preconditions.check(uses_method("threading activeCount(..)"), Visitor())
|
|
161
161
|
|
|
162
162
|
|
|
163
163
|
@categorize(_Python310)
|
|
@@ -216,7 +216,10 @@ class ReplaceConditionNotifyAll(Recipe):
|
|
|
216
216
|
new_name = method.name.replace(_simple_name="notify_all")
|
|
217
217
|
return method.replace(_name=new_name)
|
|
218
218
|
|
|
219
|
-
return Preconditions.check(
|
|
219
|
+
return Preconditions.check(
|
|
220
|
+
Preconditions.and_(uses_import("threading"), uses_method("*..* notifyAll(..)")),
|
|
221
|
+
Visitor(),
|
|
222
|
+
)
|
|
220
223
|
|
|
221
224
|
|
|
222
225
|
# Pattern/template pairs for getter-to-property conversions
|
|
@@ -296,7 +299,10 @@ class ReplaceEventIsSet(Recipe):
|
|
|
296
299
|
new_name = method.name.replace(_simple_name="is_set")
|
|
297
300
|
return method.replace(_name=new_name)
|
|
298
301
|
|
|
299
|
-
return Preconditions.check(
|
|
302
|
+
return Preconditions.check(
|
|
303
|
+
Preconditions.and_(uses_import("threading"), uses_method("*..* isSet(..)")),
|
|
304
|
+
Visitor(),
|
|
305
|
+
)
|
|
300
306
|
|
|
301
307
|
|
|
302
308
|
@categorize(_Python310)
|
|
@@ -13,7 +13,7 @@ from rewrite import ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
|
13
13
|
from rewrite.category import CategoryDescriptor
|
|
14
14
|
from rewrite.decorators import categorize
|
|
15
15
|
from rewrite.marketplace import Python
|
|
16
|
-
from rewrite.python.preconditions import uses_method
|
|
16
|
+
from rewrite.python.preconditions import uses_import, uses_method
|
|
17
17
|
from rewrite.python.visitor import PythonVisitor
|
|
18
18
|
from rewrite.java.tree import Identifier, MethodInvocation
|
|
19
19
|
|
|
@@ -84,4 +84,7 @@ class ReplaceThreadIsAlive(Recipe):
|
|
|
84
84
|
new_name = method.name.replace(_simple_name="is_alive")
|
|
85
85
|
return method.replace(_name=new_name)
|
|
86
86
|
|
|
87
|
-
return Preconditions.check(
|
|
87
|
+
return Preconditions.check(
|
|
88
|
+
Preconditions.and_(uses_import("threading"), uses_method("*..* isAlive(..)")),
|
|
89
|
+
Visitor(),
|
|
90
|
+
)
|
|
@@ -20,12 +20,15 @@ handled with `ChangeImport` in `upgrade_to_python39`.
|
|
|
20
20
|
See: https://peps.python.org/pep-0585/
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
+
import ast
|
|
23
24
|
from typing import Any, ClassVar, Optional, Set, cast
|
|
24
25
|
|
|
25
26
|
from rewrite import ExecutionContext, Recipe, Tree, TreeVisitor
|
|
26
27
|
from rewrite.category import CategoryDescriptor
|
|
27
28
|
from rewrite.decorators import categorize
|
|
28
29
|
from rewrite.marketplace import Python
|
|
30
|
+
from rewrite.python.import_utils import referenced_names
|
|
31
|
+
from rewrite.python.markers import Quoted
|
|
29
32
|
from rewrite.python.scope_utils import LocalBindings
|
|
30
33
|
from rewrite.visitor import Cursor
|
|
31
34
|
|
|
@@ -37,6 +40,7 @@ from ._typing_imports import (
|
|
|
37
40
|
from rewrite.python.tree import (
|
|
38
41
|
CollectionLiteral,
|
|
39
42
|
CompilationUnit,
|
|
43
|
+
ExpressionTypeTree,
|
|
40
44
|
MultiImport,
|
|
41
45
|
NamedArgument,
|
|
42
46
|
TypeAlias,
|
|
@@ -47,11 +51,13 @@ from rewrite.python.visitor import PythonVisitor
|
|
|
47
51
|
from rewrite.java.tree import (
|
|
48
52
|
ArrayAccess,
|
|
49
53
|
Assignment,
|
|
54
|
+
ClassDeclaration,
|
|
50
55
|
FieldAccess,
|
|
51
56
|
Identifier,
|
|
52
57
|
Import,
|
|
53
58
|
J,
|
|
54
59
|
ParameterizedType,
|
|
60
|
+
TypeParameter,
|
|
55
61
|
VariableDeclarations,
|
|
56
62
|
)
|
|
57
63
|
|
|
@@ -102,12 +108,12 @@ def _annotated_type_argument(subscript: Tree) -> Optional[J]:
|
|
|
102
108
|
return arguments[0]
|
|
103
109
|
|
|
104
110
|
|
|
105
|
-
def
|
|
111
|
+
def _in_type_position(cursor: Cursor) -> bool:
|
|
106
112
|
"""True when the cursor's node stands where a type expression is expected.
|
|
107
113
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
A type position is the only one where a `typing` alias and its built-in are
|
|
115
|
+
interchangeable; elsewhere they are distinct objects, so a dict key or a
|
|
116
|
+
call argument spelling the alias must keep naming it.
|
|
111
117
|
"""
|
|
112
118
|
walked = [cursor.value]
|
|
113
119
|
parent_cursor = cursor.parent_tree_cursor()
|
|
@@ -122,6 +128,16 @@ def _in_annotation(cursor: Cursor) -> bool:
|
|
|
122
128
|
return parent.value is child
|
|
123
129
|
if isinstance(parent, Assignment):
|
|
124
130
|
return parent.assignment is child and _names_type_alias(parent.variable)
|
|
131
|
+
# A type parameter's bound, constraint tuple and PEP 696 default are
|
|
132
|
+
# types; its name is the type parameter being declared.
|
|
133
|
+
if isinstance(parent, TypeParameter):
|
|
134
|
+
return parent.name is not child
|
|
135
|
+
# `implements` holds the base list, where an `ExpressionTypeTree` wraps
|
|
136
|
+
# a keyword argument or a computed base rather than a type.
|
|
137
|
+
if isinstance(parent, ClassDeclaration):
|
|
138
|
+
return not isinstance(child, ExpressionTypeTree) and any(
|
|
139
|
+
base is child for base in (parent.implements or [])
|
|
140
|
+
)
|
|
125
141
|
# `Annotated` carries a type in its first argument and runtime metadata
|
|
126
142
|
# in the rest, which a tuple wraps a level below the subscript.
|
|
127
143
|
annotated_type = _annotated_type_argument(parent)
|
|
@@ -132,8 +148,46 @@ def _in_annotation(cursor: Cursor) -> bool:
|
|
|
132
148
|
return False
|
|
133
149
|
|
|
134
150
|
|
|
151
|
+
def _rename_in_quoted_body(body: str, old_name: str, new_name: str) -> Optional[str]:
|
|
152
|
+
"""`body` with each name lookup of `old_name` renamed, or None when it holds none.
|
|
153
|
+
|
|
154
|
+
A quoted annotation carries a whole expression in one identifier, so the
|
|
155
|
+
rename has to land on its `ast.Name` nodes. Only parsing separates those
|
|
156
|
+
from a string constant the body encloses, where the name is a value:
|
|
157
|
+
renaming in `Literal['Text', 'Binary']` would change the type.
|
|
158
|
+
"""
|
|
159
|
+
stripped = body.strip()
|
|
160
|
+
try:
|
|
161
|
+
expression = ast.parse(stripped, mode="eval")
|
|
162
|
+
except (SyntaxError, ValueError):
|
|
163
|
+
return None
|
|
164
|
+
matches = [
|
|
165
|
+
node
|
|
166
|
+
for node in ast.walk(expression)
|
|
167
|
+
if isinstance(node, ast.Name) and node.id == old_name
|
|
168
|
+
]
|
|
169
|
+
if not matches:
|
|
170
|
+
return None
|
|
171
|
+
|
|
172
|
+
# `col_offset` counts UTF-8 bytes, so the splice has to happen in bytes.
|
|
173
|
+
source = stripped.encode()
|
|
174
|
+
line_starts = [0]
|
|
175
|
+
for line in source.split(b"\n"):
|
|
176
|
+
line_starts.append(line_starts[-1] + len(line) + 1)
|
|
177
|
+
for node in sorted(matches, key=lambda n: (n.lineno, n.col_offset), reverse=True):
|
|
178
|
+
line = line_starts[node.lineno - 1]
|
|
179
|
+
source = (
|
|
180
|
+
source[: line + node.col_offset]
|
|
181
|
+
+ new_name.encode()
|
|
182
|
+
+ source[line + cast(int, node.end_col_offset) :]
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
leading = len(body) - len(body.lstrip())
|
|
186
|
+
return body[:leading] + source.decode() + body[leading + len(stripped) :]
|
|
187
|
+
|
|
188
|
+
|
|
135
189
|
def _make_builtin_alias_editor(
|
|
136
|
-
old_name: str, new_name: str,
|
|
190
|
+
old_name: str, new_name: str, type_positions_only: bool
|
|
137
191
|
) -> "TreeVisitor[Any, ExecutionContext]":
|
|
138
192
|
"""Create a visitor that renames a typing alias to its built-in equivalent.
|
|
139
193
|
|
|
@@ -144,8 +198,8 @@ def _make_builtin_alias_editor(
|
|
|
144
198
|
- ``import typing [as alias]`` plus qualified ``typing.<old_name>``
|
|
145
199
|
attribute references
|
|
146
200
|
|
|
147
|
-
``
|
|
148
|
-
(see `
|
|
201
|
+
``type_positions_only`` confines the rename to type positions
|
|
202
|
+
(see `_in_type_position`).
|
|
149
203
|
|
|
150
204
|
Import removal is delegated to the SDK's `RemoveImport`, which only
|
|
151
205
|
removes imports that are no longer referenced and preserves comments.
|
|
@@ -190,7 +244,7 @@ def _make_builtin_alias_editor(
|
|
|
190
244
|
isinstance(field_access.target, Identifier)
|
|
191
245
|
and field_access.target.simple_name in self._module_refs
|
|
192
246
|
and field_access.name.simple_name == old_name
|
|
193
|
-
and (not
|
|
247
|
+
and (not type_positions_only or _in_type_position(self.cursor))
|
|
194
248
|
):
|
|
195
249
|
self._rewrote_qualified = True
|
|
196
250
|
return field_access.name.replace(_simple_name=new_name).replace(
|
|
@@ -200,7 +254,7 @@ def _make_builtin_alias_editor(
|
|
|
200
254
|
|
|
201
255
|
def visit_identifier(self, ident: Identifier, p: ExecutionContext) -> J:
|
|
202
256
|
ident = cast(Identifier, super().visit_identifier(ident, p))
|
|
203
|
-
if self._bare_ref is None or
|
|
257
|
+
if self._bare_ref is None or self._bare_ref not in referenced_names(ident):
|
|
204
258
|
return ident
|
|
205
259
|
|
|
206
260
|
# Skip identifiers that are part of import statements
|
|
@@ -221,9 +275,12 @@ def _make_builtin_alias_editor(
|
|
|
221
275
|
# A name bound by an enclosing scope is that local, not the import.
|
|
222
276
|
if self._local_bindings.is_bound(self.cursor, self._bare_ref):
|
|
223
277
|
return ident
|
|
224
|
-
if
|
|
278
|
+
if type_positions_only and not _in_type_position(self.cursor):
|
|
225
279
|
return ident
|
|
226
280
|
|
|
281
|
+
if ident.markers.find_first(Quoted) is not None:
|
|
282
|
+
renamed = _rename_in_quoted_body(ident.simple_name, self._bare_ref, new_name)
|
|
283
|
+
return ident if renamed is None else ident.replace(_simple_name=renamed)
|
|
227
284
|
return ident.replace(_simple_name=new_name)
|
|
228
285
|
|
|
229
286
|
return BuiltinAliasVisitor()
|
|
@@ -235,7 +292,7 @@ class _ReplaceTypingAliasRecipe(Recipe):
|
|
|
235
292
|
old_name: ClassVar[str]
|
|
236
293
|
new_name: ClassVar[str]
|
|
237
294
|
# False only where the alias *is* the built-in, so any position is safe.
|
|
238
|
-
|
|
295
|
+
type_positions_only: ClassVar[bool] = True
|
|
239
296
|
|
|
240
297
|
@property
|
|
241
298
|
def name(self) -> str:
|
|
@@ -252,17 +309,18 @@ class _ReplaceTypingAliasRecipe(Recipe):
|
|
|
252
309
|
def description(self) -> str:
|
|
253
310
|
return (
|
|
254
311
|
f"PEP 585 deprecated `typing.{self.old_name}` in Python 3.9. "
|
|
255
|
-
f"Replace with the built-in `{self.new_name}` type
|
|
312
|
+
f"Replace it with the built-in `{self.new_name}` wherever a type is expected, "
|
|
313
|
+
f"including class base lists, where either spelling subclasses `{self.new_name}`. "
|
|
256
314
|
"Applies inside `if TYPE_CHECKING:` blocks as well; the built-in generic is "
|
|
257
315
|
"valid at runtime from Python 3.9 on, so no `from __future__ import "
|
|
258
316
|
"annotations` is needed. "
|
|
259
|
-
f"References
|
|
317
|
+
f"References in a value position are left alone: `typing.{self.old_name}` "
|
|
260
318
|
f"and `{self.new_name}` are distinct objects, so substituting one for the "
|
|
261
319
|
"other where the name is used as a value would change behaviour."
|
|
262
320
|
)
|
|
263
321
|
|
|
264
322
|
def editor(self) -> TreeVisitor[Any, ExecutionContext]:
|
|
265
|
-
return _make_builtin_alias_editor(self.old_name, self.new_name, self.
|
|
323
|
+
return _make_builtin_alias_editor(self.old_name, self.new_name, self.type_positions_only)
|
|
266
324
|
|
|
267
325
|
|
|
268
326
|
@categorize(_Python39)
|
|
@@ -392,7 +450,7 @@ class ReplaceTypingText(_ReplaceTypingAliasRecipe):
|
|
|
392
450
|
|
|
393
451
|
old_name = "Text"
|
|
394
452
|
new_name = "str"
|
|
395
|
-
|
|
453
|
+
type_positions_only = False
|
|
396
454
|
|
|
397
455
|
@property
|
|
398
456
|
def name(self) -> str:
|
|
@@ -222,6 +222,9 @@ class ReplaceTypingOptionalWithUnion(Recipe):
|
|
|
222
222
|
|
|
223
223
|
# Get the type argument from the dimension
|
|
224
224
|
index = array_access.dimension.index
|
|
225
|
+
# Several arguments arrive as a CollectionLiteral, and `Optional` takes one.
|
|
226
|
+
if isinstance(index, CollectionLiteral):
|
|
227
|
+
return array_access
|
|
225
228
|
if not self._can_transform_args([index]):
|
|
226
229
|
return array_access
|
|
227
230
|
|
|
@@ -23,6 +23,7 @@ from rewrite import ExecutionContext, Preconditions, Recipe, TreeVisitor
|
|
|
23
23
|
from rewrite.category import CategoryDescriptor
|
|
24
24
|
from rewrite.decorators import categorize
|
|
25
25
|
from rewrite.marketplace import Python
|
|
26
|
+
from rewrite.python.method_matcher import MethodMatcher
|
|
26
27
|
from rewrite.python.preconditions import uses_method
|
|
27
28
|
from rewrite.python.visitor import PythonVisitor
|
|
28
29
|
from rewrite.java.tree import Identifier, MethodInvocation, FieldAccess
|
|
@@ -139,6 +140,10 @@ class FindUrllibParseSplitFunctions(Recipe):
|
|
|
139
140
|
)
|
|
140
141
|
|
|
141
142
|
|
|
143
|
+
_TO_BYTES = "urllib.parse to_bytes(..)"
|
|
144
|
+
_TO_BYTES_MATCHER = MethodMatcher.create(_TO_BYTES)
|
|
145
|
+
|
|
146
|
+
|
|
142
147
|
@categorize(_Python314)
|
|
143
148
|
class FindUrllibParseToBytes(Recipe):
|
|
144
149
|
"""
|
|
@@ -182,19 +187,13 @@ class FindUrllibParseToBytes(Recipe):
|
|
|
182
187
|
) -> Optional[MethodInvocation]:
|
|
183
188
|
method = super().visit_method_invocation(method, p)
|
|
184
189
|
|
|
185
|
-
if not
|
|
186
|
-
return method
|
|
187
|
-
if method.name.simple_name != "to_bytes":
|
|
190
|
+
if not _TO_BYTES_MATCHER.matches(method):
|
|
188
191
|
return method
|
|
189
192
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
"Use str.encode() directly instead."
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
return method
|
|
193
|
+
return mark_deprecated(
|
|
194
|
+
method,
|
|
195
|
+
"urllib.parse.to_bytes() was removed in Python 3.14. "
|
|
196
|
+
"Use str.encode() directly instead."
|
|
197
|
+
)
|
|
199
198
|
|
|
200
|
-
return Preconditions.check(uses_method(
|
|
199
|
+
return Preconditions.check(uses_method(_TO_BYTES), Visitor())
|
|
@@ -115,7 +115,7 @@ class ReplaceElementGetchildren(Recipe):
|
|
|
115
115
|
|
|
116
116
|
return result
|
|
117
117
|
|
|
118
|
-
return Preconditions.check(uses_method("
|
|
118
|
+
return Preconditions.check(uses_method("xml.etree..* getchildren(..)"), Visitor())
|
|
119
119
|
|
|
120
120
|
|
|
121
121
|
@categorize(_Python39)
|
|
@@ -185,4 +185,4 @@ class ReplaceElementGetiterator(Recipe):
|
|
|
185
185
|
new_name = method.name.replace(_simple_name="iter")
|
|
186
186
|
return method.replace(_name=new_name)
|
|
187
187
|
|
|
188
|
-
return Preconditions.check(uses_method("
|
|
188
|
+
return Preconditions.check(uses_method("xml.etree..* getiterator(..)"), Visitor())
|
{openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrewrite-migrate-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14.0
|
|
4
4
|
Summary: OpenRewrite recipes for migrating Python codebases to newer Python versions.
|
|
5
5
|
Author-email: "Moderne Inc." <support@moderne.io>
|
|
6
6
|
License: Moderne Proprietary
|
|
@@ -21,7 +21,7 @@ Classifier: Typing :: Typed
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
Provides-Extra: dev
|
|
24
|
-
Requires-Dist: openrewrite>=8.91.
|
|
24
|
+
Requires-Dist: openrewrite>=8.91.6; extra == "dev"
|
|
25
25
|
Requires-Dist: pydantic>=2.11; extra == "dev"
|
|
26
26
|
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
27
27
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
{openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/RECORD
RENAMED
|
@@ -18,38 +18,38 @@ openrewrite_migrate_python/migrate/__init__.py,sha256=6sXcyfAHFzaCPzBwINC2GDhATh
|
|
|
18
18
|
openrewrite_migrate_python/migrate/_from_imports.py,sha256=9bBTNjuaQhiSOnvDJbG58wkraxRfEOkKyjsPucaO7b4,3018
|
|
19
19
|
openrewrite_migrate_python/migrate/_import_hygiene.py,sha256=pfDkAnT7NwTAFtDvEVED7UqjVajUuaOxcAaVH84nZfU,2200
|
|
20
20
|
openrewrite_migrate_python/migrate/_langchain_tables.py,sha256=TF2A2iwkULa5uybo1rBxp_o2weziCxAmn5NLUcSAXqs,55153
|
|
21
|
-
openrewrite_migrate_python/migrate/_markers.py,sha256=
|
|
21
|
+
openrewrite_migrate_python/migrate/_markers.py,sha256=dyuu_GaYY2T1pPgtbyjnOfwR-ran5TgtjLsYbaEFHhY,1231
|
|
22
22
|
openrewrite_migrate_python/migrate/_slots.py,sha256=WYiAMYa7_tZE3vI_r55kMBojHXdxE58CzvhyAOJSZ48,634
|
|
23
23
|
openrewrite_migrate_python/migrate/_typing_imports.py,sha256=MVdv1Gn9MERZ43WfBG96sBgB0Q9KfH5n1jA4kuus5cQ,2937
|
|
24
24
|
openrewrite_migrate_python/migrate/aifc_migrations.py,sha256=-zgYl57VQIEaKam_kQ6jmmYYm3H8xL2SBR1N33oklDo,18810
|
|
25
|
-
openrewrite_migrate_python/migrate/array_deprecations.py,sha256=
|
|
25
|
+
openrewrite_migrate_python/migrate/array_deprecations.py,sha256=l1xvLULsdLgR-9re3Ub-MbVCR2guSeB2LwjGW2dtC9Q,4890
|
|
26
26
|
openrewrite_migrate_python/migrate/ast_deprecations.py,sha256=psy9RlTJTECrFd3G8UXEd1ZGuekWOdWJUdlUgqKsdZk,10348
|
|
27
27
|
openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py,sha256=HkQCWCCJ-rpm6rf2BPe0gYo8mlgC9X5YTNfCw6cVKsQ,8108
|
|
28
28
|
openrewrite_migrate_python/migrate/asyncio_deprecations.py,sha256=KMwEoz825bRt_TufgefU2mw3Uuv9UGynp-uoDzHQKcg,3536
|
|
29
29
|
openrewrite_migrate_python/migrate/avro_migrations.py,sha256=kGGu9InH_uWZuEE94dO-GJTHNNf-Gx2TwFMEAzlRkV8,1908
|
|
30
30
|
openrewrite_migrate_python/migrate/calendar_deprecations.py,sha256=tZMcLwPgTUuX1NxuZx4HRCnU0JeyL5bUFqmQcfeDLEE,4288
|
|
31
31
|
openrewrite_migrate_python/migrate/cgi_migrations.py,sha256=hzBa5-Yp2EtPLg-S07hp5bp8Rsm0WS1pNudgeS-BMJ0,7673
|
|
32
|
-
openrewrite_migrate_python/migrate/cgi_parse_deprecations.py,sha256=
|
|
32
|
+
openrewrite_migrate_python/migrate/cgi_parse_deprecations.py,sha256=EcWLP7X1leg7BxpcPCDmkuQMUJbE7IxCSU29q_O-U-k,6731
|
|
33
33
|
openrewrite_migrate_python/migrate/collections_abc_migrations.py,sha256=L2Ja2A07UZw8fgQT7l37xNLXSd5Z4KKHu9_5wD7VjQc,2868
|
|
34
|
-
openrewrite_migrate_python/migrate/configparser_deprecations.py,sha256=
|
|
34
|
+
openrewrite_migrate_python/migrate/configparser_deprecations.py,sha256=_uYjllxQNhDiBoXZ4nn003vRgqAUb7Ejs7SdzRXL2Wk,8686
|
|
35
35
|
openrewrite_migrate_python/migrate/datetime_utc.py,sha256=kCcxJYk9DXXOOEG0GJBK-UKd9zuVfUYyzgWF2BqmDng,11119
|
|
36
36
|
openrewrite_migrate_python/migrate/distutils_deprecations.py,sha256=VMjlPzp6bVW3hytC2sXLhQsEpq6NCscU0nGz2z2KhJk,3408
|
|
37
|
-
openrewrite_migrate_python/migrate/distutils_migrations.py,sha256=
|
|
38
|
-
openrewrite_migrate_python/migrate/functools_deprecations.py,sha256=
|
|
37
|
+
openrewrite_migrate_python/migrate/distutils_migrations.py,sha256=KwSJ7kwyYZA4ZsFUXJ0siSmCB9jgtoytjYpo0iFChHk,4409
|
|
38
|
+
openrewrite_migrate_python/migrate/functools_deprecations.py,sha256=6ccTq5j5Goa_vRKq6trEAG72f4gWuPqybbrEmrX_5qw,3031
|
|
39
39
|
openrewrite_migrate_python/migrate/future_imports.py,sha256=LU_fjJA0EaiNieismWlzd79_SVjbWzBA2m33HUNpuGU,5643
|
|
40
40
|
openrewrite_migrate_python/migrate/gettext_deprecations.py,sha256=zMTygphHIRzlgqq3QfosDjLxFhJb1beXWXZ0Iv4_fGw,5460
|
|
41
|
-
openrewrite_migrate_python/migrate/html_parser_deprecations.py,sha256=
|
|
41
|
+
openrewrite_migrate_python/migrate/html_parser_deprecations.py,sha256=kVpYiNKghiHqEdbTXewGc9pxmNtwy1o07y9xGLFXe3U,3705
|
|
42
42
|
openrewrite_migrate_python/migrate/imp_migrations.py,sha256=zqQeNX42ykUPtSnGXJML-MnxCYB_kFOoketJaEsu3II,4547
|
|
43
43
|
openrewrite_migrate_python/migrate/langchain_classic_imports.py,sha256=dxBQ20mmPKldcACDREr0hGL1AGhaJp5IsifKRHu3MFg,12116
|
|
44
44
|
openrewrite_migrate_python/migrate/langchain_community_imports.py,sha256=y8kNFqYp8qlO8f1feVy7ybQ3zxjekU2KAe1jeKEHeAE,5978
|
|
45
45
|
openrewrite_migrate_python/migrate/langchain_provider_imports.py,sha256=U0zAsV3cRuCtRFSg4S0by_fzi_6frgygMHerV4KmXrk,9404
|
|
46
46
|
openrewrite_migrate_python/migrate/locale_deprecations.py,sha256=AlHtcirX3SUWoEAFWSBgIdcyt3LyukkfgodW_2ZoUQI,6932
|
|
47
|
-
openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py,sha256=
|
|
47
|
+
openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py,sha256=42NdYLbyNIc9b7X3GWlxuld8I-QoQSEZ00O_TireR7U,3243
|
|
48
48
|
openrewrite_migrate_python/migrate/macpath_deprecations.py,sha256=wihrM7Nd5-90dPgc-cVk1mP_13i1INp0bPYdQNRKBNw,3978
|
|
49
49
|
openrewrite_migrate_python/migrate/mailcap_migrations.py,sha256=ri5F7O0jG21tQcRF8yg5snWB6rLxQ3ll9O0KHTCIevw,4263
|
|
50
50
|
openrewrite_migrate_python/migrate/nntplib_migrations.py,sha256=D4NFwfaxOBImxwS7AczOs75CPef7JnZaG1S9yh0VwQM,4280
|
|
51
|
-
openrewrite_migrate_python/migrate/os_deprecations.py,sha256=
|
|
52
|
-
openrewrite_migrate_python/migrate/pathlib_deprecations.py,sha256=
|
|
51
|
+
openrewrite_migrate_python/migrate/os_deprecations.py,sha256=tNkywHA5izEgNjHQrV3Qasi3ZnbAVO_bE-ZyDAXSgXo,5321
|
|
52
|
+
openrewrite_migrate_python/migrate/pathlib_deprecations.py,sha256=R27EiQCgBwpd1UnEpt5-WpTxUGIpGqeQ2qQwGw58QXI,3290
|
|
53
53
|
openrewrite_migrate_python/migrate/pep594_system_migrations.py,sha256=2Ul1AzGNkwzXKjiRHHV5Wz0TGf9bjM33Nj1bclP7Hj0,15337
|
|
54
54
|
openrewrite_migrate_python/migrate/pipes_migrations.py,sha256=JpfWib0iAkQM0isNPL3x7h56i78FO7L0e1KHA4oO5Ro,4352
|
|
55
55
|
openrewrite_migrate_python/migrate/pkgutil_deprecations.py,sha256=CyJEXNKGtLLUcteUoSAmDdY479HPpbh3W0oEzY5PncM,5346
|
|
@@ -57,22 +57,22 @@ openrewrite_migrate_python/migrate/platform_deprecations.py,sha256=dHHaGjVSm1EDz
|
|
|
57
57
|
openrewrite_migrate_python/migrate/pydantic_deprecations.py,sha256=iSn8gTr_lahvddo5BtR4S3f_4ga-puZh4EDaaM5Z7e8,30149
|
|
58
58
|
openrewrite_migrate_python/migrate/pydantic_fields.py,sha256=HCNkRhZOFS6jIadYyDQS4ePIkF1pOVBQbuzyEjNZecQ,6568
|
|
59
59
|
openrewrite_migrate_python/migrate/pydantic_model_fields.py,sha256=BEU05lyjHKlDCGutysRR9clBLXcoRMtv-bYmiRbVqks,7274
|
|
60
|
-
openrewrite_migrate_python/migrate/re_deprecations.py,sha256=
|
|
60
|
+
openrewrite_migrate_python/migrate/re_deprecations.py,sha256=y0U5vIfcRYVihiLpQd2LxqsnahjiPjqLB4k_th3wF-Q,4396
|
|
61
61
|
openrewrite_migrate_python/migrate/removed_modules_312.py,sha256=EL0w7O1j0l6Gfrsj6M4xRhxnABRgjY1cIvI8-v50qb8,5170
|
|
62
|
-
openrewrite_migrate_python/migrate/shutil_deprecations.py,sha256=
|
|
63
|
-
openrewrite_migrate_python/migrate/socket_deprecations.py,sha256=
|
|
62
|
+
openrewrite_migrate_python/migrate/shutil_deprecations.py,sha256=a8KkBUHmdDOk0U6poDHNPFsTNbJH9ljJsK2_sKlMo4g,4050
|
|
63
|
+
openrewrite_migrate_python/migrate/socket_deprecations.py,sha256=h_5BV64_BICy1FpuWybti72le1xdEiPfu0gNL0MgWQE,2785
|
|
64
64
|
openrewrite_migrate_python/migrate/ssl_deprecations.py,sha256=BEYd8a00S2ysyfodFp-z8TqHFVI5o8TkAubZgU4G7II,4025
|
|
65
65
|
openrewrite_migrate_python/migrate/string_formatting.py,sha256=jTGJLdSthnnAkgHgupJ2kztft-ehaHVs2j9KQ2ztfMI,19323
|
|
66
66
|
openrewrite_migrate_python/migrate/sys_deprecations.py,sha256=bZ6vB0EA20bsfJ86mftgOKjOKasOGOIdHvJoVlSKseo,2961
|
|
67
67
|
openrewrite_migrate_python/migrate/sys_last_deprecations.py,sha256=6wwjxOWX6wCfk88OsApeMQn4E4SXByF2jvzIoCE3Quw,3643
|
|
68
|
-
openrewrite_migrate_python/migrate/tarfile_deprecations.py,sha256=
|
|
68
|
+
openrewrite_migrate_python/migrate/tarfile_deprecations.py,sha256=8YEMb35RtAYaTL3YhvRZqhKThqf9oTeEFO7hBiVU5fk,3838
|
|
69
69
|
openrewrite_migrate_python/migrate/telnetlib_migrations.py,sha256=E3obYMTjKoDbGKR_tmp3HXQWopv4b9l4X2Wa-UIUQnU,4575
|
|
70
|
-
openrewrite_migrate_python/migrate/tempfile_deprecations.py,sha256=
|
|
71
|
-
openrewrite_migrate_python/migrate/threading_deprecations.py,sha256=
|
|
72
|
-
openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py,sha256=
|
|
70
|
+
openrewrite_migrate_python/migrate/tempfile_deprecations.py,sha256=0SR6Qu_IuspaCByR7phAPghkCcQDArSg1tJT27Rnqfk,3466
|
|
71
|
+
openrewrite_migrate_python/migrate/threading_deprecations.py,sha256=UrHJvfhxkKrPx0TtHWQ6xsjfVTB2jbAy4W6bZOskkW0,17105
|
|
72
|
+
openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py,sha256=MS9tGOZNYp5xKybAfe0oMp1Tsh5O_kpc3LeI3vMPXII,2938
|
|
73
73
|
openrewrite_migrate_python/migrate/typing_callable.py,sha256=CNT3eLQ4cVjcK8wn9OW49xE1kTgXjSceLRHBJX_F31c,1914
|
|
74
|
-
openrewrite_migrate_python/migrate/typing_deprecations.py,sha256=
|
|
75
|
-
openrewrite_migrate_python/migrate/typing_union_to_pipe.py,sha256=
|
|
74
|
+
openrewrite_migrate_python/migrate/typing_deprecations.py,sha256=OkC7wNvQ50j2WbMVKRoi8YpuxEeKpFo_jIBXIMhUjMU,15735
|
|
75
|
+
openrewrite_migrate_python/migrate/typing_union_to_pipe.py,sha256=F2XpE3krxQMA5CwWx7yRf1RKIAALTwSB2AUIk9hvqu8,11912
|
|
76
76
|
openrewrite_migrate_python/migrate/unittest_deprecations.py,sha256=iQHg6uB6ZGatYPBMWURmhsFUHar7ZJ5UjK-dyKoWyhI,4925
|
|
77
77
|
openrewrite_migrate_python/migrate/upgrade_to_langchain02.py,sha256=Zifezmcewzy9JBLX2akyw7eJWI0Ztzra-Kd6kmPXTMc,1816
|
|
78
78
|
openrewrite_migrate_python/migrate/upgrade_to_langchain1.py,sha256=wMiPGM6EmL-3fc0NrxM_InErvFtXYrZFJAQgi3gKa1o,2140
|
|
@@ -84,12 +84,12 @@ openrewrite_migrate_python/migrate/upgrade_to_python313.py,sha256=5v7CvJNzLkYxv2
|
|
|
84
84
|
openrewrite_migrate_python/migrate/upgrade_to_python314.py,sha256=0KJsnDQxBk41FNYN06V1howRHAQ39dw1x01MOZgCEEk,3423
|
|
85
85
|
openrewrite_migrate_python/migrate/upgrade_to_python38.py,sha256=AYg5chkV0Glh3BCH1iW9gsmWTXHfjHzkusinSz3DFJY,4418
|
|
86
86
|
openrewrite_migrate_python/migrate/upgrade_to_python39.py,sha256=DnmvOJIO_eVsX2YAL1CTVWk7AJthymt9vRUX4LRjc1k,7083
|
|
87
|
-
openrewrite_migrate_python/migrate/urllib_deprecations.py,sha256=
|
|
87
|
+
openrewrite_migrate_python/migrate/urllib_deprecations.py,sha256=615XoOK_8brnc1Qr52pOrCJ2IZuwSUq6vQ-Afui6vcM,7173
|
|
88
88
|
openrewrite_migrate_python/migrate/uu_migrations.py,sha256=p4c83AxvBY2EGW_JNOCOpgafHYrCJQhHe_wIjgMdcSk,4242
|
|
89
89
|
openrewrite_migrate_python/migrate/xdrlib_migrations.py,sha256=UhFFzz2CRlHn4eZqh7F33HgIqBcy74LV9Nrg3XfWj8I,4273
|
|
90
|
-
openrewrite_migrate_python/migrate/xml_deprecations.py,sha256=
|
|
91
|
-
openrewrite_migrate_python-0.
|
|
92
|
-
openrewrite_migrate_python-0.
|
|
93
|
-
openrewrite_migrate_python-0.
|
|
94
|
-
openrewrite_migrate_python-0.
|
|
95
|
-
openrewrite_migrate_python-0.
|
|
90
|
+
openrewrite_migrate_python/migrate/xml_deprecations.py,sha256=BMpAmXE9JFVXP3pur4ySpJDaJxF-BSFgFeeFfJGaz9w,6757
|
|
91
|
+
openrewrite_migrate_python-0.14.0.dist-info/METADATA,sha256=0QG-6J0vAfbrSi3sV9fYcMaWQBcMMkWGGxbJVt820Mc,1510
|
|
92
|
+
openrewrite_migrate_python-0.14.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
93
|
+
openrewrite_migrate_python-0.14.0.dist-info/entry_points.txt,sha256=SuygzlMJiKIW19FYJVxx0hhRyzW6HTDCweY7584XpXw,138
|
|
94
|
+
openrewrite_migrate_python-0.14.0.dist-info/top_level.txt,sha256=y8dKeC9kb5GUzFraB-OhJGxjPemM3GaPdrAygz2RP0U,59
|
|
95
|
+
openrewrite_migrate_python-0.14.0.dist-info/RECORD,,
|
{openrewrite_migrate_python-0.13.2.dist-info → openrewrite_migrate_python-0.14.0.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|