django-codemod 2.3.7__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_codemod-2.3.7/src/django_codemod.egg-info → django_codemod-2.4.0}/PKG-INFO +4 -4
- {django_codemod-2.3.7 → django_codemod-2.4.0}/pyproject.toml +7 -4
- django_codemod-2.4.0/src/django_codemod/__init__.py +1 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/cli.py +8 -9
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/path_utils.py +1 -2
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/utils/calls.py +1 -2
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/admin.py +3 -7
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/base.py +9 -10
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/models.py +4 -9
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/signals.py +2 -2
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/template_tags.py +8 -9
- {django_codemod-2.3.7 → django_codemod-2.4.0/src/django_codemod.egg-info}/PKG-INFO +4 -4
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod.egg-info/requires.txt +1 -1
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/test_cli.py +2 -2
- django_codemod-2.3.7/src/django_codemod/__init__.py +0 -1
- {django_codemod-2.3.7 → django_codemod-2.4.0}/LICENSE +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/MANIFEST.in +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/README.md +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/docs/Makefile +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/docs/conf.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/docs/make.bat +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/setup.cfg +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/commands.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/constants.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/feature_flags.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/utils/__init__.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/__init__.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/core.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/crypto.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/decorators.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/encoding.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/exceptions.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/forms.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/html.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/http.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/lru_cache.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/os_utils.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/paginator.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/postgres_fields.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/shortcuts.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/template_context.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/timezone.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/translations.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/urls.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod.egg-info/SOURCES.txt +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod.egg-info/dependency_links.txt +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod.egg-info/entry_points.txt +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod.egg-info/top_level.txt +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/__init__.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/test_e2e.sh +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/test_path_utils.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/__init__.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/base.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_admin.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_base.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_core.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_crypto.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_decorators.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_encoding.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_exceptions.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_forms.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_html.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_http.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_lru_cache.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_models.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_os_utils.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_paginator.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_postgres_fields.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_shortcuts.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_signals.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_template_context.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_template_tags.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_timezone.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_translations.py +0 -0
- {django_codemod-2.3.7 → django_codemod-2.4.0}/tests/visitors/test_urls.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-codemod
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: A command line tool to automatically fix Django deprecations.
|
|
5
5
|
Author-email: Bruno Alla <alla.brunoo@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -16,16 +16,16 @@ Classifier: Intended Audience :: Developers
|
|
|
16
16
|
Classifier: Natural Language :: English
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
24
|
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
|
-
Requires-Dist: click<8.
|
|
28
|
+
Requires-Dist: click<8.3
|
|
29
29
|
Requires-Dist: libcst==1.8.4
|
|
30
30
|
Requires-Dist: pathspec<1,>=0.6
|
|
31
31
|
Requires-Dist: rich>=10
|
|
@@ -4,7 +4,7 @@ requires = [ "setuptools>=77.0.3" ]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "django-codemod"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.4.0"
|
|
8
8
|
description = "A command line tool to automatically fix Django deprecations."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [
|
|
@@ -16,23 +16,23 @@ license = "MIT"
|
|
|
16
16
|
authors = [
|
|
17
17
|
{ name = "Bruno Alla", email = "alla.brunoo@gmail.com" },
|
|
18
18
|
]
|
|
19
|
-
requires-python = ">=3.
|
|
19
|
+
requires-python = ">=3.10"
|
|
20
20
|
classifiers = [
|
|
21
21
|
"Development Status :: 5 - Production/Stable",
|
|
22
22
|
"Intended Audience :: Developers",
|
|
23
23
|
"Natural Language :: English",
|
|
24
24
|
"Operating System :: OS Independent",
|
|
25
25
|
"Programming Language :: Python :: 3 :: Only",
|
|
26
|
-
"Programming Language :: Python :: 3.9",
|
|
27
26
|
"Programming Language :: Python :: 3.10",
|
|
28
27
|
"Programming Language :: Python :: 3.11",
|
|
29
28
|
"Programming Language :: Python :: 3.12",
|
|
30
29
|
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
31
31
|
"Topic :: Software Development :: Libraries",
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
dependencies = [
|
|
35
|
-
"click<8.
|
|
35
|
+
"click<8.3",
|
|
36
36
|
"libcst==1.8.4",
|
|
37
37
|
"pathspec>=0.6,<1",
|
|
38
38
|
"rich>=10",
|
|
@@ -96,6 +96,9 @@ lint.per-file-ignores."tests/**/*" = [
|
|
|
96
96
|
]
|
|
97
97
|
lint.isort.known-first-party = [ "django_codemod", "tests" ]
|
|
98
98
|
|
|
99
|
+
[tool.pyproject-fmt]
|
|
100
|
+
max_supported_python = "3.14"
|
|
101
|
+
|
|
99
102
|
[tool.pytest.ini_options]
|
|
100
103
|
addopts = "-v -Wdefault --cov=django_codemod --cov-report=term-missing:skip-covered"
|
|
101
104
|
pythonpath = [ "src" ]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.4.0"
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
from collections import defaultdict
|
|
3
|
-
from collections.abc import Generator
|
|
3
|
+
from collections.abc import Callable, Generator
|
|
4
4
|
from operator import attrgetter
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import Callable, Optional
|
|
7
6
|
|
|
8
7
|
import rich_click as click
|
|
9
8
|
from libcst.codemod import CodemodContext, parallel_exec_transform_with_prettyprint
|
|
@@ -68,8 +67,8 @@ class VersionParamType(click.ParamType):
|
|
|
68
67
|
def convert( # type: ignore[return]
|
|
69
68
|
self,
|
|
70
69
|
value: str,
|
|
71
|
-
param:
|
|
72
|
-
ctx:
|
|
70
|
+
param: click.Parameter | None,
|
|
71
|
+
ctx: click.Context | None,
|
|
73
72
|
) -> tuple[int, int]:
|
|
74
73
|
"""Parse version to keep only major an minor digits."""
|
|
75
74
|
try:
|
|
@@ -84,8 +83,8 @@ class VersionParamType(click.ParamType):
|
|
|
84
83
|
def _parse_unsafe(
|
|
85
84
|
self,
|
|
86
85
|
value: str,
|
|
87
|
-
param:
|
|
88
|
-
ctx:
|
|
86
|
+
param: click.Parameter | None,
|
|
87
|
+
ctx: click.Context | None,
|
|
89
88
|
) -> tuple[int, int]:
|
|
90
89
|
"""Parse version and validate it's a supported one."""
|
|
91
90
|
parsed_version = self._split_digits(value, param, ctx)
|
|
@@ -104,8 +103,8 @@ class VersionParamType(click.ParamType):
|
|
|
104
103
|
def _split_digits(
|
|
105
104
|
self,
|
|
106
105
|
value: str,
|
|
107
|
-
param:
|
|
108
|
-
ctx:
|
|
106
|
+
param: click.Parameter | None,
|
|
107
|
+
ctx: click.Context | None,
|
|
109
108
|
) -> tuple[int, int]:
|
|
110
109
|
"""Split version into 2-tuple of digits, ignoring patch digit."""
|
|
111
110
|
values_parts = tuple(int(v) for v in value.split("."))
|
|
@@ -115,7 +114,7 @@ class VersionParamType(click.ParamType):
|
|
|
115
114
|
param,
|
|
116
115
|
ctx,
|
|
117
116
|
)
|
|
118
|
-
major, minor, *
|
|
117
|
+
major, minor, *_patches = values_parts
|
|
119
118
|
return major, minor
|
|
120
119
|
|
|
121
120
|
|
|
@@ -7,7 +7,6 @@ https://github.com/psf/black
|
|
|
7
7
|
|
|
8
8
|
from collections.abc import Iterable, Iterator
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Optional
|
|
11
10
|
|
|
12
11
|
from pathspec import PathSpec
|
|
13
12
|
|
|
@@ -113,7 +112,7 @@ def gen_python_files(
|
|
|
113
112
|
yield child
|
|
114
113
|
|
|
115
114
|
|
|
116
|
-
def normalize_path(path: Path, root: Path) ->
|
|
115
|
+
def normalize_path(path: Path, root: Path) -> str | None:
|
|
117
116
|
"""Normalize `path`. May return `None` if `path` was ignored."""
|
|
118
117
|
try:
|
|
119
118
|
abspath = path if path.is_absolute() else Path.cwd() / path
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from collections.abc import Sequence
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
from libcst import Arg, Call, FunctionDef, Param, parse_expression, parse_statement
|
|
5
4
|
from libcst import matchers as m
|
|
6
5
|
|
|
7
6
|
|
|
8
|
-
def find_keyword_arg(args: Sequence[Arg], keyword_name: str) ->
|
|
7
|
+
def find_keyword_arg(args: Sequence[Arg], keyword_name: str) -> Arg | None:
|
|
9
8
|
"""Find a kwarg among a sequence of arguments."""
|
|
10
9
|
matcher = m.Arg(keyword=m.Name(keyword_name))
|
|
11
10
|
return next((arg for arg in args if m.matches(arg, matcher)), None)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Union
|
|
2
|
-
|
|
3
1
|
from libcst import (
|
|
4
2
|
BaseExpression,
|
|
5
3
|
BaseSmallStatement,
|
|
@@ -35,9 +33,7 @@ class InlineHasAddPermissionsTransformer(BaseDjCodemodTransformer):
|
|
|
35
33
|
|
|
36
34
|
def leave_ImportFrom(
|
|
37
35
|
self, original_node: ImportFrom, updated_node: ImportFrom
|
|
38
|
-
) ->
|
|
39
|
-
BaseSmallStatement, FlattenSentinel[BaseSmallStatement], RemovalSentinel
|
|
40
|
-
]:
|
|
36
|
+
) -> BaseSmallStatement | FlattenSentinel[BaseSmallStatement] | RemovalSentinel:
|
|
41
37
|
if isinstance(updated_node.names, ImportStar):
|
|
42
38
|
return super().leave_ImportFrom(original_node, updated_node)
|
|
43
39
|
base_cls_matcher = []
|
|
@@ -98,7 +94,7 @@ class InlineHasAddPermissionsTransformer(BaseDjCodemodTransformer):
|
|
|
98
94
|
|
|
99
95
|
def leave_ClassDef(
|
|
100
96
|
self, original_node: ClassDef, updated_node: ClassDef
|
|
101
|
-
) ->
|
|
97
|
+
) -> BaseStatement | FlattenSentinel[BaseStatement] | RemovalSentinel:
|
|
102
98
|
self.context.scratch.pop(self.ctx_key_visiting_subclass, None)
|
|
103
99
|
return super().leave_ClassDef(original_node, updated_node)
|
|
104
100
|
|
|
@@ -108,7 +104,7 @@ class InlineHasAddPermissionsTransformer(BaseDjCodemodTransformer):
|
|
|
108
104
|
|
|
109
105
|
def leave_FunctionDef(
|
|
110
106
|
self, original_node: FunctionDef, updated_node: FunctionDef
|
|
111
|
-
) ->
|
|
107
|
+
) -> BaseStatement | FlattenSentinel[BaseStatement] | RemovalSentinel:
|
|
112
108
|
if (
|
|
113
109
|
self.is_visiting_subclass
|
|
114
110
|
and m.matches(
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from abc import ABC
|
|
4
4
|
from collections.abc import Sequence
|
|
5
|
-
from typing import Optional, Union
|
|
6
5
|
|
|
7
6
|
from libcst import (
|
|
8
7
|
Arg,
|
|
@@ -53,7 +52,7 @@ class BaseDjCodemodTransformer(ContextAwareTransformer, ABC):
|
|
|
53
52
|
|
|
54
53
|
def module_matcher(
|
|
55
54
|
import_parts: Sequence[str],
|
|
56
|
-
) ->
|
|
55
|
+
) -> m.Attribute | m.Name:
|
|
57
56
|
"""Build matcher for a module given sequence of import parts."""
|
|
58
57
|
# If only one element, it is just a Name
|
|
59
58
|
if len(import_parts) == 1:
|
|
@@ -112,7 +111,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
112
111
|
|
|
113
112
|
def leave_ImportFrom(
|
|
114
113
|
self, original_node: ImportFrom, updated_node: ImportFrom
|
|
115
|
-
) ->
|
|
114
|
+
) -> BaseSmallStatement | RemovalSentinel:
|
|
116
115
|
"""Update import statements for matching old module name."""
|
|
117
116
|
return (
|
|
118
117
|
self._check_import_from_exact(original_node, updated_node)
|
|
@@ -123,7 +122,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
123
122
|
|
|
124
123
|
def _check_import_from_exact(
|
|
125
124
|
self, original_node: ImportFrom, updated_node: ImportFrom
|
|
126
|
-
) ->
|
|
125
|
+
) -> BaseSmallStatement | RemovalSentinel | None:
|
|
127
126
|
"""
|
|
128
127
|
Check for when the thing to replace is imported exactly.
|
|
129
128
|
|
|
@@ -171,7 +170,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
171
170
|
|
|
172
171
|
def _check_import_from_parent(
|
|
173
172
|
self, original_node: ImportFrom, updated_node: ImportFrom
|
|
174
|
-
) ->
|
|
173
|
+
) -> BaseSmallStatement | RemovalSentinel | None:
|
|
175
174
|
"""
|
|
176
175
|
Check for when the parent module of thing to replace is imported.
|
|
177
176
|
|
|
@@ -200,7 +199,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
200
199
|
value=m.Name(module_name_str),
|
|
201
200
|
attr=m.Name(self.old_name),
|
|
202
201
|
)
|
|
203
|
-
new_as_name:
|
|
202
|
+
new_as_name: str | None = None
|
|
204
203
|
if import_alias.evaluated_alias:
|
|
205
204
|
# The import alias would be the same before and after
|
|
206
205
|
# Add a `_` to differentiate the old alias from the new one.
|
|
@@ -214,7 +213,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
214
213
|
if self.old_parent_module_parts != self.new_parent_module_parts:
|
|
215
214
|
# import statement might need updating: build arguments for
|
|
216
215
|
# AddImportsVisitor and RemoveImportsVisitor to update imports
|
|
217
|
-
add_import_module:
|
|
216
|
+
add_import_module: str | None = None
|
|
218
217
|
if self.new_parent_module_parts:
|
|
219
218
|
add_import_module = ".".join(self.new_parent_module_parts)
|
|
220
219
|
self.context.scratch[self.ctx_key_add_import_kwargs] = {
|
|
@@ -223,7 +222,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
223
222
|
"obj": self.new_parent_name,
|
|
224
223
|
"asname": new_as_name,
|
|
225
224
|
}
|
|
226
|
-
remove_import_module:
|
|
225
|
+
remove_import_module: str | None = None
|
|
227
226
|
if self.old_parent_module_parts:
|
|
228
227
|
remove_import_module = ".".join(self.old_parent_module_parts)
|
|
229
228
|
self.context.scratch[self.ctx_key_remove_import_kwargs] = {
|
|
@@ -236,7 +235,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
236
235
|
|
|
237
236
|
def _check_import_from_child(
|
|
238
237
|
self, original_node: ImportFrom, updated_node: ImportFrom
|
|
239
|
-
) ->
|
|
238
|
+
) -> BaseSmallStatement | RemovalSentinel | None:
|
|
240
239
|
"""
|
|
241
240
|
Check import of a member of the module being codemodded.
|
|
242
241
|
|
|
@@ -275,7 +274,7 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
275
274
|
self.context.scratch[self.ctx_key_import_scope] = scope
|
|
276
275
|
|
|
277
276
|
@property
|
|
278
|
-
def import_scope(self) ->
|
|
277
|
+
def import_scope(self) -> Scope | None:
|
|
279
278
|
return self.context.scratch.get(self.ctx_key_import_scope, None)
|
|
280
279
|
|
|
281
280
|
def update_imports(self):
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from collections.abc import Sequence
|
|
2
|
-
from typing import Optional, Union
|
|
3
2
|
|
|
4
3
|
from libcst import (
|
|
5
4
|
Arg,
|
|
@@ -47,9 +46,7 @@ class ModelsPermalinkTransformer(BaseDjCodemodTransformer):
|
|
|
47
46
|
|
|
48
47
|
def leave_ImportFrom(
|
|
49
48
|
self, original_node: ImportFrom, updated_node: ImportFrom
|
|
50
|
-
) ->
|
|
51
|
-
BaseSmallStatement, FlattenSentinel[BaseSmallStatement], RemovalSentinel
|
|
52
|
-
]:
|
|
49
|
+
) -> BaseSmallStatement | FlattenSentinel[BaseSmallStatement] | RemovalSentinel:
|
|
53
50
|
if isinstance(updated_node.names, ImportStar):
|
|
54
51
|
return super().leave_ImportFrom(original_node, updated_node)
|
|
55
52
|
if m.matches(
|
|
@@ -105,7 +102,7 @@ class ModelsPermalinkTransformer(BaseDjCodemodTransformer):
|
|
|
105
102
|
return matchers_list[0]
|
|
106
103
|
return m.OneOf(*iter(matchers_list))
|
|
107
104
|
|
|
108
|
-
def visit_FunctionDef(self, node: FunctionDef) ->
|
|
105
|
+
def visit_FunctionDef(self, node: FunctionDef) -> bool | None:
|
|
109
106
|
for decorator in node.decorators:
|
|
110
107
|
if m.matches(decorator, self.decorator_matcher):
|
|
111
108
|
self.context.scratch[self.ctx_key_inside_method] = True
|
|
@@ -113,7 +110,7 @@ class ModelsPermalinkTransformer(BaseDjCodemodTransformer):
|
|
|
113
110
|
|
|
114
111
|
def leave_FunctionDef(
|
|
115
112
|
self, original_node: FunctionDef, updated_node: FunctionDef
|
|
116
|
-
) ->
|
|
113
|
+
) -> BaseStatement | FlattenSentinel[BaseStatement] | RemovalSentinel:
|
|
117
114
|
if self.visiting_permalink_method:
|
|
118
115
|
for decorator in updated_node.decorators:
|
|
119
116
|
if m.matches(decorator, self.decorator_matcher):
|
|
@@ -136,9 +133,7 @@ class ModelsPermalinkTransformer(BaseDjCodemodTransformer):
|
|
|
136
133
|
|
|
137
134
|
def leave_Return(
|
|
138
135
|
self, original_node: Return, updated_node: Return
|
|
139
|
-
) ->
|
|
140
|
-
BaseSmallStatement, FlattenSentinel[BaseSmallStatement], RemovalSentinel
|
|
141
|
-
]:
|
|
136
|
+
) -> BaseSmallStatement | FlattenSentinel[BaseSmallStatement] | RemovalSentinel:
|
|
142
137
|
if self.visiting_permalink_method and m.matches(
|
|
143
138
|
updated_node.value,
|
|
144
139
|
m.Tuple(), # type: ignore
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import ClassVar
|
|
1
|
+
from typing import ClassVar
|
|
2
2
|
|
|
3
3
|
from libcst import BaseExpression, Call, ImportFrom, ImportStar, MaybeSentinel, Module
|
|
4
4
|
from libcst import matchers as m
|
|
@@ -45,7 +45,7 @@ class SignalDisconnectWeakTransformer(BaseDjCodemodTransformer):
|
|
|
45
45
|
self.context.scratch.pop(self.ctx_key_call_matchers, None)
|
|
46
46
|
return super().leave_Module(original_node, updated_node)
|
|
47
47
|
|
|
48
|
-
def visit_ImportFrom(self, node: ImportFrom) ->
|
|
48
|
+
def visit_ImportFrom(self, node: ImportFrom) -> bool | None:
|
|
49
49
|
"""Set the `Call` matcher depending on which signals are imported.."""
|
|
50
50
|
if not import_from_matches(
|
|
51
51
|
node, ["django", "db", "models", "signals"]
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from collections.abc import Generator, Sequence
|
|
2
|
-
from typing import Optional, Union
|
|
3
2
|
|
|
4
3
|
from libcst import (
|
|
5
4
|
Assign,
|
|
@@ -29,11 +28,11 @@ class AssignmentTagTransformer(BaseDjCodemodTransformer):
|
|
|
29
28
|
ctx_key_decorator_matcher = f"{ctx_key_prefix}-decorator_matcher"
|
|
30
29
|
|
|
31
30
|
@property
|
|
32
|
-
def library_call_matcher(self) ->
|
|
31
|
+
def library_call_matcher(self) -> m.Call | None:
|
|
33
32
|
return self.context.scratch.get(self.ctx_key_library_call_matcher, None)
|
|
34
33
|
|
|
35
34
|
@property
|
|
36
|
-
def decorators_matcher(self) ->
|
|
35
|
+
def decorators_matcher(self) -> m.BaseMatcherNode | None:
|
|
37
36
|
return self.context.scratch.get(self.ctx_key_decorator_matcher, None)
|
|
38
37
|
|
|
39
38
|
def leave_Module(self, original_node: Module, updated_node: Module) -> Module:
|
|
@@ -42,7 +41,7 @@ class AssignmentTagTransformer(BaseDjCodemodTransformer):
|
|
|
42
41
|
self.context.scratch.pop(self.ctx_key_decorator_matcher, None)
|
|
43
42
|
return super().leave_Module(original_node, updated_node)
|
|
44
43
|
|
|
45
|
-
def visit_ImportFrom(self, node: ImportFrom) ->
|
|
44
|
+
def visit_ImportFrom(self, node: ImportFrom) -> bool | None:
|
|
46
45
|
"""Record whether an interesting import is detected."""
|
|
47
46
|
import_matcher = (
|
|
48
47
|
# django.template
|
|
@@ -54,7 +53,7 @@ class AssignmentTagTransformer(BaseDjCodemodTransformer):
|
|
|
54
53
|
self.context.scratch[self.ctx_key_library_call_matcher] = import_matcher
|
|
55
54
|
return None
|
|
56
55
|
|
|
57
|
-
def _template_import_matcher(self, node: ImportFrom) ->
|
|
56
|
+
def _template_import_matcher(self, node: ImportFrom) -> m.Call | None:
|
|
58
57
|
"""Return matcher if django.template is imported."""
|
|
59
58
|
imported_name_str = self._get_imported_name(node, "django.template")
|
|
60
59
|
if not imported_name_str:
|
|
@@ -66,7 +65,7 @@ class AssignmentTagTransformer(BaseDjCodemodTransformer):
|
|
|
66
65
|
)
|
|
67
66
|
)
|
|
68
67
|
|
|
69
|
-
def _library_import_matcher(self, node: ImportFrom) ->
|
|
68
|
+
def _library_import_matcher(self, node: ImportFrom) -> m.Call | None:
|
|
70
69
|
"""Return matcher if django.template.Library is imported."""
|
|
71
70
|
imported_name_str = self._get_imported_name(node, "django.template.Library")
|
|
72
71
|
if not imported_name_str:
|
|
@@ -75,7 +74,7 @@ class AssignmentTagTransformer(BaseDjCodemodTransformer):
|
|
|
75
74
|
return m.Call(func=m.Name(imported_name_str))
|
|
76
75
|
|
|
77
76
|
@staticmethod
|
|
78
|
-
def _get_imported_name(node: ImportFrom, import_path: str) ->
|
|
77
|
+
def _get_imported_name(node: ImportFrom, import_path: str) -> str | None:
|
|
79
78
|
"""Resolve the imported name if present."""
|
|
80
79
|
if isinstance(node.names, ImportStar):
|
|
81
80
|
return None
|
|
@@ -92,7 +91,7 @@ class AssignmentTagTransformer(BaseDjCodemodTransformer):
|
|
|
92
91
|
return imported_name_str
|
|
93
92
|
return None
|
|
94
93
|
|
|
95
|
-
def visit_Assign(self, node: Assign) ->
|
|
94
|
+
def visit_Assign(self, node: Assign) -> bool | None:
|
|
96
95
|
"""Record variable name the `Library()` call is assigned to."""
|
|
97
96
|
if self.library_call_matcher and m.matches(
|
|
98
97
|
node,
|
|
@@ -127,7 +126,7 @@ class AssignmentTagTransformer(BaseDjCodemodTransformer):
|
|
|
127
126
|
|
|
128
127
|
def leave_Decorator(
|
|
129
128
|
self, original_node: Decorator, updated_node: Decorator
|
|
130
|
-
) ->
|
|
129
|
+
) -> Decorator | FlattenSentinel[Decorator] | RemovalSentinel:
|
|
131
130
|
"""Update decorator call if all conditions are met."""
|
|
132
131
|
if self.decorators_matcher and m.matches(updated_node, self.decorators_matcher):
|
|
133
132
|
# If we have a decorator matcher, and it matches,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-codemod
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: A command line tool to automatically fix Django deprecations.
|
|
5
5
|
Author-email: Bruno Alla <alla.brunoo@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -16,16 +16,16 @@ Classifier: Intended Audience :: Developers
|
|
|
16
16
|
Classifier: Natural Language :: English
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
24
|
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
|
-
Requires-Dist: click<8.
|
|
28
|
+
Requires-Dist: click<8.3
|
|
29
29
|
Requires-Dist: libcst==1.8.4
|
|
30
30
|
Requires-Dist: pathspec<1,>=0.6
|
|
31
31
|
Requires-Dist: rich>=10
|
|
@@ -94,8 +94,8 @@ def test_run_help(cli_runner):
|
|
|
94
94
|
["run", "--help"],
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
assert result.exit_code ==
|
|
98
|
-
assert "
|
|
97
|
+
assert result.exit_code == 1
|
|
98
|
+
assert "Automatically fixes deprecations" in result.output
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
@pytest.mark.parametrize(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.3.7"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/postgres_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod/visitors/template_context.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_codemod-2.3.7 → django_codemod-2.4.0}/src/django_codemod.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|