codeshift 0.3.3__py3-none-any.whl → 0.3.5__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.
- codeshift/cli/commands/apply.py +24 -2
- codeshift/cli/package_manager.py +102 -0
- codeshift/knowledge/generator.py +11 -1
- codeshift/knowledge_base/libraries/aiohttp.yaml +186 -0
- codeshift/knowledge_base/libraries/attrs.yaml +181 -0
- codeshift/knowledge_base/libraries/celery.yaml +244 -0
- codeshift/knowledge_base/libraries/click.yaml +195 -0
- codeshift/knowledge_base/libraries/django.yaml +355 -0
- codeshift/knowledge_base/libraries/flask.yaml +270 -0
- codeshift/knowledge_base/libraries/httpx.yaml +183 -0
- codeshift/knowledge_base/libraries/marshmallow.yaml +238 -0
- codeshift/knowledge_base/libraries/numpy.yaml +429 -0
- codeshift/knowledge_base/libraries/pytest.yaml +192 -0
- codeshift/knowledge_base/libraries/sqlalchemy.yaml +2 -1
- codeshift/migrator/engine.py +60 -0
- codeshift/migrator/transforms/__init__.py +2 -0
- codeshift/migrator/transforms/aiohttp_transformer.py +608 -0
- codeshift/migrator/transforms/attrs_transformer.py +570 -0
- codeshift/migrator/transforms/celery_transformer.py +546 -0
- codeshift/migrator/transforms/click_transformer.py +526 -0
- codeshift/migrator/transforms/django_transformer.py +852 -0
- codeshift/migrator/transforms/fastapi_transformer.py +12 -7
- codeshift/migrator/transforms/flask_transformer.py +505 -0
- codeshift/migrator/transforms/httpx_transformer.py +419 -0
- codeshift/migrator/transforms/marshmallow_transformer.py +515 -0
- codeshift/migrator/transforms/numpy_transformer.py +413 -0
- codeshift/migrator/transforms/pydantic_v1_to_v2.py +53 -8
- codeshift/migrator/transforms/pytest_transformer.py +351 -0
- codeshift/migrator/transforms/requests_transformer.py +74 -1
- codeshift/migrator/transforms/sqlalchemy_transformer.py +692 -39
- {codeshift-0.3.3.dist-info → codeshift-0.3.5.dist-info}/METADATA +46 -4
- {codeshift-0.3.3.dist-info → codeshift-0.3.5.dist-info}/RECORD +36 -15
- {codeshift-0.3.3.dist-info → codeshift-0.3.5.dist-info}/WHEEL +0 -0
- {codeshift-0.3.3.dist-info → codeshift-0.3.5.dist-info}/entry_points.txt +0 -0
- {codeshift-0.3.3.dist-info → codeshift-0.3.5.dist-info}/licenses/LICENSE +0 -0
- {codeshift-0.3.3.dist-info → codeshift-0.3.5.dist-info}/top_level.txt +0 -0
codeshift/cli/commands/apply.py
CHANGED
|
@@ -10,6 +10,7 @@ from rich.panel import Panel
|
|
|
10
10
|
from rich.prompt import Confirm
|
|
11
11
|
|
|
12
12
|
from codeshift.cli.commands.upgrade import load_state, save_state
|
|
13
|
+
from codeshift.cli.package_manager import get_install_commands, get_sync_command
|
|
13
14
|
from codeshift.cli.quota import (
|
|
14
15
|
QuotaError,
|
|
15
16
|
check_quota,
|
|
@@ -226,11 +227,32 @@ def apply(
|
|
|
226
227
|
state_file.unlink()
|
|
227
228
|
console.print("\n[green]Migration complete![/]")
|
|
228
229
|
|
|
229
|
-
# Next steps
|
|
230
|
+
# Next steps - generate dynamic dependency sync command
|
|
230
231
|
console.print("\n[bold]Recommended next steps:[/]")
|
|
231
232
|
console.print(" 1. Review the changes in your editor")
|
|
232
233
|
console.print(" 2. Run your test suite: [cyan]pytest[/]")
|
|
233
|
-
|
|
234
|
+
|
|
235
|
+
# Generate dependency update commands based on library/libraries and package manager
|
|
236
|
+
sync_command = get_sync_command(project_path)
|
|
237
|
+
|
|
238
|
+
# Check if this is a multi-library migration (upgrade-all)
|
|
239
|
+
migrations = state.get("migrations", [])
|
|
240
|
+
if library == "multiple" and migrations:
|
|
241
|
+
# Multi-library case: show sync command and list all libraries
|
|
242
|
+
console.print(f" 3. Sync your dependencies: [cyan]{sync_command}[/]")
|
|
243
|
+
console.print("\n [dim]Upgraded libraries:[/]")
|
|
244
|
+
for migration in migrations:
|
|
245
|
+
lib_name = migration.get("library", "unknown")
|
|
246
|
+
to_version = migration.get("to_version", "unknown")
|
|
247
|
+
console.print(f" • {lib_name} → {to_version}")
|
|
248
|
+
else:
|
|
249
|
+
# Single library case: show sync command with specific library info
|
|
250
|
+
console.print(f" 3. Sync your dependencies: [cyan]{sync_command}[/]")
|
|
251
|
+
if library != "unknown" and target_version != "unknown":
|
|
252
|
+
libraries = [{"name": library, "version": target_version}]
|
|
253
|
+
install_commands = get_install_commands(project_path, libraries)
|
|
254
|
+
if install_commands:
|
|
255
|
+
console.print(f"\n [dim]Or install directly:[/] {install_commands[0]}")
|
|
234
256
|
|
|
235
257
|
|
|
236
258
|
@click.command()
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Package manager detection and sync command generation utilities."""
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
PackageManager = Literal["uv", "poetry", "pip"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def detect_package_manager(project_path: Path) -> PackageManager:
|
|
11
|
+
"""Detect the package manager used in a project.
|
|
12
|
+
|
|
13
|
+
Detection order:
|
|
14
|
+
1. uv.lock file presence → uv
|
|
15
|
+
2. poetry.lock file presence → poetry
|
|
16
|
+
3. Default → pip
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
project_path: Path to the project root directory.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
The detected package manager name.
|
|
23
|
+
"""
|
|
24
|
+
# Check for uv (uv.lock file)
|
|
25
|
+
if (project_path / "uv.lock").exists():
|
|
26
|
+
return "uv"
|
|
27
|
+
|
|
28
|
+
# Check for poetry (poetry.lock file)
|
|
29
|
+
if (project_path / "poetry.lock").exists():
|
|
30
|
+
return "poetry"
|
|
31
|
+
|
|
32
|
+
# Default to pip
|
|
33
|
+
return "pip"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_sync_command(project_path: Path) -> str:
|
|
37
|
+
"""Get the appropriate dependency sync command for the project.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
project_path: Path to the project root directory.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
The shell command to sync/install dependencies.
|
|
44
|
+
"""
|
|
45
|
+
manager = detect_package_manager(project_path)
|
|
46
|
+
|
|
47
|
+
if manager == "uv":
|
|
48
|
+
return "uv sync"
|
|
49
|
+
elif manager == "poetry":
|
|
50
|
+
return "poetry install"
|
|
51
|
+
else:
|
|
52
|
+
# pip - check what kind of project it is
|
|
53
|
+
if (project_path / "pyproject.toml").exists():
|
|
54
|
+
return "pip install -e ."
|
|
55
|
+
elif (project_path / "requirements.txt").exists():
|
|
56
|
+
return "pip install -r requirements.txt"
|
|
57
|
+
else:
|
|
58
|
+
return "pip install -e ."
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def is_package_manager_available(manager: PackageManager) -> bool:
|
|
62
|
+
"""Check if a package manager is available in the system.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
manager: The package manager to check.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
True if the package manager is available, False otherwise.
|
|
69
|
+
"""
|
|
70
|
+
return shutil.which(manager) is not None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_install_commands(
|
|
74
|
+
project_path: Path,
|
|
75
|
+
libraries: list[dict[str, str]],
|
|
76
|
+
) -> list[str]:
|
|
77
|
+
"""Generate install commands for the upgraded libraries.
|
|
78
|
+
|
|
79
|
+
This is a fallback for when users want to install specific packages
|
|
80
|
+
rather than sync the entire project.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
project_path: Path to the project root directory.
|
|
84
|
+
libraries: List of dicts with 'name' and 'version' keys.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
List of install commands for each library.
|
|
88
|
+
"""
|
|
89
|
+
manager = detect_package_manager(project_path)
|
|
90
|
+
|
|
91
|
+
commands = []
|
|
92
|
+
for lib in libraries:
|
|
93
|
+
name = lib["name"]
|
|
94
|
+
version = lib["version"]
|
|
95
|
+
if manager == "uv":
|
|
96
|
+
commands.append(f"uv add {name}>={version}")
|
|
97
|
+
elif manager == "poetry":
|
|
98
|
+
commands.append(f"poetry add {name}>={version}")
|
|
99
|
+
else:
|
|
100
|
+
commands.append(f"pip install {name}>={version}")
|
|
101
|
+
|
|
102
|
+
return commands
|
codeshift/knowledge/generator.py
CHANGED
|
@@ -162,7 +162,17 @@ class KnowledgeGenerator:
|
|
|
162
162
|
|
|
163
163
|
|
|
164
164
|
# Tier 1 libraries with deterministic AST transforms
|
|
165
|
-
TIER_1_LIBRARIES = {
|
|
165
|
+
TIER_1_LIBRARIES = {
|
|
166
|
+
"pydantic",
|
|
167
|
+
"fastapi",
|
|
168
|
+
"sqlalchemy",
|
|
169
|
+
"pandas",
|
|
170
|
+
"requests",
|
|
171
|
+
"numpy",
|
|
172
|
+
"pytest",
|
|
173
|
+
"marshmallow",
|
|
174
|
+
"flask",
|
|
175
|
+
}
|
|
166
176
|
|
|
167
177
|
|
|
168
178
|
def is_tier_1_library(library: str) -> bool:
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# aiohttp Knowledge Base
|
|
2
|
+
# Breaking changes from v3.7 to v3.9+
|
|
3
|
+
|
|
4
|
+
name: aiohttp
|
|
5
|
+
display_name: aiohttp
|
|
6
|
+
description: Async HTTP client/server framework for asyncio
|
|
7
|
+
migration_guide_url: https://docs.aiohttp.org/en/stable/changes.html
|
|
8
|
+
|
|
9
|
+
supported_migrations:
|
|
10
|
+
- from: "3.7"
|
|
11
|
+
to: "3.9"
|
|
12
|
+
|
|
13
|
+
breaking_changes:
|
|
14
|
+
# Loop parameter removal - ClientSession
|
|
15
|
+
- symbol: "ClientSession(loop=...)"
|
|
16
|
+
change_type: removed
|
|
17
|
+
severity: high
|
|
18
|
+
from_version: "3.7"
|
|
19
|
+
to_version: "3.8"
|
|
20
|
+
description: "loop parameter removed from ClientSession constructor"
|
|
21
|
+
replacement: "ClientSession()"
|
|
22
|
+
has_deterministic_transform: true
|
|
23
|
+
transform_name: remove_loop_param_client_session
|
|
24
|
+
notes: "Event loop is now obtained automatically via asyncio.get_event_loop()"
|
|
25
|
+
|
|
26
|
+
# Loop parameter removal - TCPConnector
|
|
27
|
+
- symbol: "TCPConnector(loop=...)"
|
|
28
|
+
change_type: removed
|
|
29
|
+
severity: high
|
|
30
|
+
from_version: "3.7"
|
|
31
|
+
to_version: "3.8"
|
|
32
|
+
description: "loop parameter removed from TCPConnector constructor"
|
|
33
|
+
replacement: "TCPConnector()"
|
|
34
|
+
has_deterministic_transform: true
|
|
35
|
+
transform_name: remove_loop_param_tcp_connector
|
|
36
|
+
|
|
37
|
+
# Loop parameter removal - UnixConnector
|
|
38
|
+
- symbol: "UnixConnector(loop=...)"
|
|
39
|
+
change_type: removed
|
|
40
|
+
severity: medium
|
|
41
|
+
from_version: "3.7"
|
|
42
|
+
to_version: "3.8"
|
|
43
|
+
description: "loop parameter removed from UnixConnector constructor"
|
|
44
|
+
replacement: "UnixConnector()"
|
|
45
|
+
has_deterministic_transform: true
|
|
46
|
+
transform_name: remove_loop_param_unix_connector
|
|
47
|
+
|
|
48
|
+
# Loop parameter removal - web.Application
|
|
49
|
+
- symbol: "web.Application(loop=...)"
|
|
50
|
+
change_type: removed
|
|
51
|
+
severity: high
|
|
52
|
+
from_version: "3.7"
|
|
53
|
+
to_version: "3.8"
|
|
54
|
+
description: "loop parameter removed from web.Application constructor"
|
|
55
|
+
replacement: "web.Application()"
|
|
56
|
+
has_deterministic_transform: true
|
|
57
|
+
transform_name: remove_loop_param_web_application
|
|
58
|
+
|
|
59
|
+
# Loop parameter removal - ClientTimeout
|
|
60
|
+
- symbol: "ClientTimeout(loop=...)"
|
|
61
|
+
change_type: removed
|
|
62
|
+
severity: medium
|
|
63
|
+
from_version: "3.7"
|
|
64
|
+
to_version: "3.8"
|
|
65
|
+
description: "loop parameter removed from ClientTimeout constructor"
|
|
66
|
+
replacement: "ClientTimeout()"
|
|
67
|
+
has_deterministic_transform: true
|
|
68
|
+
transform_name: remove_loop_param_client_timeout
|
|
69
|
+
|
|
70
|
+
# connector_owner default change
|
|
71
|
+
- symbol: "ClientSession(connector=..., connector_owner=None)"
|
|
72
|
+
change_type: behavior_change
|
|
73
|
+
severity: medium
|
|
74
|
+
from_version: "3.7"
|
|
75
|
+
to_version: "3.9"
|
|
76
|
+
description: "connector_owner now defaults to True; explicitly set to False if connector is shared"
|
|
77
|
+
replacement: "ClientSession(connector=..., connector_owner=False)"
|
|
78
|
+
has_deterministic_transform: false
|
|
79
|
+
notes: "Manual review needed - depends on whether connector is shared across sessions"
|
|
80
|
+
|
|
81
|
+
# BasicAuth.encode() removal
|
|
82
|
+
- symbol: "BasicAuth.encode()"
|
|
83
|
+
change_type: removed
|
|
84
|
+
severity: medium
|
|
85
|
+
from_version: "3.7"
|
|
86
|
+
to_version: "3.9"
|
|
87
|
+
description: "BasicAuth.encode() method removed"
|
|
88
|
+
replacement: "str(BasicAuth(...))"
|
|
89
|
+
has_deterministic_transform: true
|
|
90
|
+
transform_name: basicauth_encode_to_str
|
|
91
|
+
|
|
92
|
+
# Deprecated timeout parameters
|
|
93
|
+
- symbol: "ClientSession(read_timeout=...)"
|
|
94
|
+
change_type: removed
|
|
95
|
+
severity: medium
|
|
96
|
+
from_version: "3.7"
|
|
97
|
+
to_version: "3.8"
|
|
98
|
+
description: "read_timeout parameter deprecated, use ClientTimeout instead"
|
|
99
|
+
replacement: "ClientSession(timeout=ClientTimeout(total=...))"
|
|
100
|
+
has_deterministic_transform: true
|
|
101
|
+
transform_name: read_timeout_to_client_timeout
|
|
102
|
+
|
|
103
|
+
- symbol: "ClientSession(conn_timeout=...)"
|
|
104
|
+
change_type: removed
|
|
105
|
+
severity: medium
|
|
106
|
+
from_version: "3.7"
|
|
107
|
+
to_version: "3.8"
|
|
108
|
+
description: "conn_timeout parameter deprecated, use ClientTimeout instead"
|
|
109
|
+
replacement: "ClientSession(timeout=ClientTimeout(connect=...))"
|
|
110
|
+
has_deterministic_transform: true
|
|
111
|
+
transform_name: conn_timeout_to_client_timeout
|
|
112
|
+
|
|
113
|
+
# app.loop, request.loop, client.loop deprecation
|
|
114
|
+
- symbol: "app.loop"
|
|
115
|
+
change_type: deprecated
|
|
116
|
+
severity: medium
|
|
117
|
+
from_version: "3.7"
|
|
118
|
+
to_version: "3.8"
|
|
119
|
+
description: "app.loop property deprecated"
|
|
120
|
+
replacement: "asyncio.get_event_loop()"
|
|
121
|
+
has_deterministic_transform: true
|
|
122
|
+
transform_name: app_loop_to_get_event_loop
|
|
123
|
+
|
|
124
|
+
- symbol: "request.app.loop"
|
|
125
|
+
change_type: deprecated
|
|
126
|
+
severity: medium
|
|
127
|
+
from_version: "3.7"
|
|
128
|
+
to_version: "3.8"
|
|
129
|
+
description: "request.app.loop property deprecated"
|
|
130
|
+
replacement: "asyncio.get_event_loop()"
|
|
131
|
+
has_deterministic_transform: true
|
|
132
|
+
transform_name: request_loop_to_get_event_loop
|
|
133
|
+
|
|
134
|
+
# Middleware signature changes (old-style to new-style)
|
|
135
|
+
- symbol: "@middleware"
|
|
136
|
+
change_type: signature_change
|
|
137
|
+
severity: high
|
|
138
|
+
from_version: "3.7"
|
|
139
|
+
to_version: "3.9"
|
|
140
|
+
description: "Old-style middleware decorator deprecated; use @web.middleware with async def(request, handler)"
|
|
141
|
+
replacement: "@web.middleware async def middleware(request, handler)"
|
|
142
|
+
has_deterministic_transform: false
|
|
143
|
+
notes: "Middleware function signature changed; manual review recommended"
|
|
144
|
+
|
|
145
|
+
# ws_connect timeout deprecation
|
|
146
|
+
- symbol: "ws_connect(timeout=...)"
|
|
147
|
+
change_type: deprecated
|
|
148
|
+
severity: low
|
|
149
|
+
from_version: "3.7"
|
|
150
|
+
to_version: "3.9"
|
|
151
|
+
description: "timeout parameter in ws_connect deprecated"
|
|
152
|
+
replacement: "ws_connect(receive_timeout=...)"
|
|
153
|
+
has_deterministic_transform: true
|
|
154
|
+
transform_name: ws_connect_timeout_rename
|
|
155
|
+
|
|
156
|
+
- symbol: "ws_connect(receive_timeout=...)"
|
|
157
|
+
change_type: behavior_change
|
|
158
|
+
severity: low
|
|
159
|
+
from_version: "3.7"
|
|
160
|
+
to_version: "3.9"
|
|
161
|
+
description: "Default websocket receive_timeout changed from None to 10.0 seconds"
|
|
162
|
+
replacement: "ws_connect(receive_timeout=None)"
|
|
163
|
+
has_deterministic_transform: false
|
|
164
|
+
notes: "Set receive_timeout=None explicitly if you want no timeout"
|
|
165
|
+
|
|
166
|
+
# Response URL attribute change
|
|
167
|
+
- symbol: "response.url_obj"
|
|
168
|
+
change_type: renamed
|
|
169
|
+
severity: low
|
|
170
|
+
from_version: "3.7"
|
|
171
|
+
to_version: "3.9"
|
|
172
|
+
description: "url_obj attribute renamed to url (now returns yarl.URL)"
|
|
173
|
+
replacement: "response.url"
|
|
174
|
+
has_deterministic_transform: true
|
|
175
|
+
transform_name: url_obj_to_url
|
|
176
|
+
|
|
177
|
+
# WebSocket protocol attribute rename
|
|
178
|
+
- symbol: "ws_response.protocol"
|
|
179
|
+
change_type: renamed
|
|
180
|
+
severity: low
|
|
181
|
+
from_version: "3.7"
|
|
182
|
+
to_version: "3.9"
|
|
183
|
+
description: "WebSocketResponse.protocol renamed to ws_protocol"
|
|
184
|
+
replacement: "ws_response.ws_protocol"
|
|
185
|
+
has_deterministic_transform: true
|
|
186
|
+
transform_name: ws_protocol_rename
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# attrs Knowledge Base
|
|
2
|
+
# Breaking changes from 21.x to 23.x+
|
|
3
|
+
|
|
4
|
+
name: attrs
|
|
5
|
+
display_name: attrs
|
|
6
|
+
description: Python Classes Without Boilerplate - declarative classes with validation
|
|
7
|
+
migration_guide_url: https://www.attrs.org/en/stable/changelog.html
|
|
8
|
+
|
|
9
|
+
supported_migrations:
|
|
10
|
+
- from: "21.0"
|
|
11
|
+
to: "23.0"
|
|
12
|
+
|
|
13
|
+
breaking_changes:
|
|
14
|
+
# Decorator changes - attr.s to attrs.define
|
|
15
|
+
- symbol: "@attr.s"
|
|
16
|
+
change_type: renamed
|
|
17
|
+
severity: high
|
|
18
|
+
from_version: "21.0"
|
|
19
|
+
to_version: "23.0"
|
|
20
|
+
description: "@attr.s decorator replaced with @attrs.define (modern API)"
|
|
21
|
+
replacement: "@attrs.define"
|
|
22
|
+
has_deterministic_transform: true
|
|
23
|
+
transform_name: attr_s_to_attrs_define
|
|
24
|
+
notes: "The modern API has slots=True and auto_attribs=True as defaults"
|
|
25
|
+
|
|
26
|
+
- symbol: "@attr.attrs"
|
|
27
|
+
change_type: renamed
|
|
28
|
+
severity: high
|
|
29
|
+
from_version: "21.0"
|
|
30
|
+
to_version: "23.0"
|
|
31
|
+
description: "@attr.attrs decorator replaced with @attrs.define"
|
|
32
|
+
replacement: "@attrs.define"
|
|
33
|
+
has_deterministic_transform: true
|
|
34
|
+
transform_name: attr_attrs_to_attrs_define
|
|
35
|
+
|
|
36
|
+
- symbol: "@attr.s(auto_attribs=True)"
|
|
37
|
+
change_type: renamed
|
|
38
|
+
severity: high
|
|
39
|
+
from_version: "21.0"
|
|
40
|
+
to_version: "23.0"
|
|
41
|
+
description: "@attr.s with auto_attribs=True becomes @attrs.define (auto_attribs is default)"
|
|
42
|
+
replacement: "@attrs.define"
|
|
43
|
+
has_deterministic_transform: true
|
|
44
|
+
transform_name: attr_s_auto_attribs_to_define
|
|
45
|
+
notes: "auto_attribs=True is the default in @attrs.define"
|
|
46
|
+
|
|
47
|
+
- symbol: "@attr.s(slots=True)"
|
|
48
|
+
change_type: renamed
|
|
49
|
+
severity: medium
|
|
50
|
+
from_version: "21.0"
|
|
51
|
+
to_version: "23.0"
|
|
52
|
+
description: "@attr.s with slots=True becomes @attrs.define (slots is default)"
|
|
53
|
+
replacement: "@attrs.define"
|
|
54
|
+
has_deterministic_transform: true
|
|
55
|
+
transform_name: attr_s_slots_to_define
|
|
56
|
+
notes: "slots=True is the default in @attrs.define"
|
|
57
|
+
|
|
58
|
+
- symbol: "@attr.s(frozen=True)"
|
|
59
|
+
change_type: renamed
|
|
60
|
+
severity: medium
|
|
61
|
+
from_version: "21.0"
|
|
62
|
+
to_version: "23.0"
|
|
63
|
+
description: "@attr.s with frozen=True becomes @attrs.frozen"
|
|
64
|
+
replacement: "@attrs.frozen"
|
|
65
|
+
has_deterministic_transform: true
|
|
66
|
+
transform_name: attr_s_frozen_to_attrs_frozen
|
|
67
|
+
|
|
68
|
+
# Field/attribute definition changes
|
|
69
|
+
- symbol: "attr.ib()"
|
|
70
|
+
change_type: renamed
|
|
71
|
+
severity: high
|
|
72
|
+
from_version: "21.0"
|
|
73
|
+
to_version: "23.0"
|
|
74
|
+
description: "attr.ib() replaced with attrs.field()"
|
|
75
|
+
replacement: "attrs.field()"
|
|
76
|
+
has_deterministic_transform: true
|
|
77
|
+
transform_name: attr_ib_to_attrs_field
|
|
78
|
+
|
|
79
|
+
- symbol: "attr.attrib()"
|
|
80
|
+
change_type: renamed
|
|
81
|
+
severity: high
|
|
82
|
+
from_version: "21.0"
|
|
83
|
+
to_version: "23.0"
|
|
84
|
+
description: "attr.attrib() replaced with attrs.field()"
|
|
85
|
+
replacement: "attrs.field()"
|
|
86
|
+
has_deterministic_transform: true
|
|
87
|
+
transform_name: attr_attrib_to_attrs_field
|
|
88
|
+
|
|
89
|
+
- symbol: "attr.Factory"
|
|
90
|
+
change_type: renamed
|
|
91
|
+
severity: medium
|
|
92
|
+
from_version: "21.0"
|
|
93
|
+
to_version: "23.0"
|
|
94
|
+
description: "attr.Factory replaced with attrs.Factory"
|
|
95
|
+
replacement: "attrs.Factory"
|
|
96
|
+
has_deterministic_transform: true
|
|
97
|
+
transform_name: attr_factory_to_attrs_factory
|
|
98
|
+
|
|
99
|
+
# Function changes
|
|
100
|
+
- symbol: "attr.asdict()"
|
|
101
|
+
change_type: renamed
|
|
102
|
+
severity: medium
|
|
103
|
+
from_version: "21.0"
|
|
104
|
+
to_version: "23.0"
|
|
105
|
+
description: "attr.asdict() replaced with attrs.asdict()"
|
|
106
|
+
replacement: "attrs.asdict()"
|
|
107
|
+
has_deterministic_transform: true
|
|
108
|
+
transform_name: attr_asdict_to_attrs_asdict
|
|
109
|
+
|
|
110
|
+
- symbol: "attr.astuple()"
|
|
111
|
+
change_type: renamed
|
|
112
|
+
severity: medium
|
|
113
|
+
from_version: "21.0"
|
|
114
|
+
to_version: "23.0"
|
|
115
|
+
description: "attr.astuple() replaced with attrs.astuple()"
|
|
116
|
+
replacement: "attrs.astuple()"
|
|
117
|
+
has_deterministic_transform: true
|
|
118
|
+
transform_name: attr_astuple_to_attrs_astuple
|
|
119
|
+
|
|
120
|
+
- symbol: "attr.fields()"
|
|
121
|
+
change_type: renamed
|
|
122
|
+
severity: low
|
|
123
|
+
from_version: "21.0"
|
|
124
|
+
to_version: "23.0"
|
|
125
|
+
description: "attr.fields() replaced with attrs.fields()"
|
|
126
|
+
replacement: "attrs.fields()"
|
|
127
|
+
has_deterministic_transform: true
|
|
128
|
+
transform_name: attr_fields_to_attrs_fields
|
|
129
|
+
|
|
130
|
+
- symbol: "attr.has()"
|
|
131
|
+
change_type: renamed
|
|
132
|
+
severity: low
|
|
133
|
+
from_version: "21.0"
|
|
134
|
+
to_version: "23.0"
|
|
135
|
+
description: "attr.has() replaced with attrs.has()"
|
|
136
|
+
replacement: "attrs.has()"
|
|
137
|
+
has_deterministic_transform: true
|
|
138
|
+
transform_name: attr_has_to_attrs_has
|
|
139
|
+
|
|
140
|
+
- symbol: "attr.evolve()"
|
|
141
|
+
change_type: renamed
|
|
142
|
+
severity: medium
|
|
143
|
+
from_version: "21.0"
|
|
144
|
+
to_version: "23.0"
|
|
145
|
+
description: "attr.evolve() replaced with attrs.evolve()"
|
|
146
|
+
replacement: "attrs.evolve()"
|
|
147
|
+
has_deterministic_transform: true
|
|
148
|
+
transform_name: attr_evolve_to_attrs_evolve
|
|
149
|
+
|
|
150
|
+
# Parameter deprecations
|
|
151
|
+
- symbol: "cmp"
|
|
152
|
+
change_type: removed
|
|
153
|
+
severity: high
|
|
154
|
+
from_version: "21.0"
|
|
155
|
+
to_version: "22.1"
|
|
156
|
+
description: "cmp parameter removed from @attr.s and attr.ib(), use eq and order instead"
|
|
157
|
+
replacement: "eq=..., order=..."
|
|
158
|
+
has_deterministic_transform: true
|
|
159
|
+
transform_name: cmp_to_eq_order
|
|
160
|
+
notes: "cmp=True becomes eq=True, order=True; cmp=False becomes eq=False, order=False"
|
|
161
|
+
|
|
162
|
+
# Import path changes for validators and converters
|
|
163
|
+
- symbol: "attr.validators"
|
|
164
|
+
change_type: renamed
|
|
165
|
+
severity: medium
|
|
166
|
+
from_version: "21.0"
|
|
167
|
+
to_version: "23.0"
|
|
168
|
+
description: "attr.validators module replaced with attrs.validators"
|
|
169
|
+
replacement: "attrs.validators"
|
|
170
|
+
has_deterministic_transform: true
|
|
171
|
+
transform_name: attr_validators_to_attrs_validators
|
|
172
|
+
|
|
173
|
+
- symbol: "attr.converters"
|
|
174
|
+
change_type: renamed
|
|
175
|
+
severity: medium
|
|
176
|
+
from_version: "21.0"
|
|
177
|
+
to_version: "23.0"
|
|
178
|
+
description: "attr.converters module replaced with attrs.converters"
|
|
179
|
+
replacement: "attrs.converters"
|
|
180
|
+
has_deterministic_transform: true
|
|
181
|
+
transform_name: attr_converters_to_attrs_converters
|