django-codemod 2.1.10__tar.gz → 2.2.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.1.10 → django_codemod-2.2.0}/PKG-INFO +6 -6
- {django_codemod-2.1.10 → django_codemod-2.2.0}/README.md +3 -3
- {django_codemod-2.1.10 → django_codemod-2.2.0}/pyproject.toml +77 -78
- django_codemod-2.2.0/src/django_codemod/__init__.py +1 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/cli.py +17 -16
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/commands.py +1 -2
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/path_utils.py +5 -4
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/utils/calls.py +2 -1
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/base.py +6 -5
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/crypto.py +1 -1
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/models.py +4 -2
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/shortcuts.py +1 -1
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/signals.py +3 -3
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/template_tags.py +2 -1
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/timezone.py +1 -1
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/urls.py +2 -2
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/base.py +1 -3
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_admin.py +3 -9
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_base.py +6 -18
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_http.py +3 -9
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_models.py +3 -9
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_paginator.py +1 -3
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_postgres_fields.py +3 -9
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_signals.py +2 -6
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_template_tags.py +4 -12
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_timezone.py +2 -6
- django_codemod-2.1.10/src/django_codemod/__init__.py +0 -1
- {django_codemod-2.1.10 → django_codemod-2.2.0}/LICENSE +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/constants.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/feature_flags.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/utils/__init__.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/__init__.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/admin.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/core.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/decorators.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/encoding.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/exceptions.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/forms.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/html.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/http.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/lru_cache.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/os_utils.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/paginator.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/postgres_fields.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/template_context.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/translations.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/__init__.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/test_cli.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/test_e2e.sh +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/test_path_utils.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/__init__.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_core.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_crypto.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_decorators.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_encoding.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_exceptions.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_forms.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_html.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_lru_cache.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_os_utils.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_shortcuts.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_template_context.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_translations.py +0 -0
- {django_codemod-2.1.10 → django_codemod-2.2.0}/tests/visitors/test_urls.py +0 -0
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-codemod
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: A command line tool to automatically fix Django deprecations.
|
|
5
5
|
Home-page: https://github.com/browniebroke/django-codemod
|
|
6
6
|
License: MIT
|
|
7
7
|
Keywords: django,codemod,libCST
|
|
8
8
|
Author: Bruno Alla
|
|
9
9
|
Author-email: alla.brunoo@gmail.com
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.9,<4.0
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Natural Language :: English
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries
|
|
23
23
|
Requires-Dist: click (<9)
|
|
24
24
|
Requires-Dist: libcst (==1.1.0)
|
|
@@ -53,10 +53,10 @@ Description-Content-Type: text/markdown
|
|
|
53
53
|
</p>
|
|
54
54
|
<p align="center">
|
|
55
55
|
<a href="https://python-poetry.org/">
|
|
56
|
-
<img src="https://img.shields.io/
|
|
56
|
+
<img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Poetry">
|
|
57
57
|
</a>
|
|
58
|
-
<a href="https://github.com/
|
|
59
|
-
<img src="https://img.shields.io/badge/
|
|
58
|
+
<a href="https://github.com/astral-sh/ruff">
|
|
59
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
60
60
|
</a>
|
|
61
61
|
<a href="https://github.com/pre-commit/pre-commit">
|
|
62
62
|
<img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
</p>
|
|
19
19
|
<p align="center">
|
|
20
20
|
<a href="https://python-poetry.org/">
|
|
21
|
-
<img src="https://img.shields.io/
|
|
21
|
+
<img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Poetry">
|
|
22
22
|
</a>
|
|
23
|
-
<a href="https://github.com/
|
|
24
|
-
<img src="https://img.shields.io/badge/
|
|
23
|
+
<a href="https://github.com/astral-sh/ruff">
|
|
24
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
25
25
|
</a>
|
|
26
26
|
<a href="https://github.com/pre-commit/pre-commit">
|
|
27
27
|
<img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "poetry.core.masonry.api"
|
|
3
|
+
requires = [ "poetry-core>=1" ]
|
|
4
|
+
|
|
1
5
|
[tool.poetry]
|
|
2
6
|
name = "django-codemod"
|
|
3
|
-
version = "2.
|
|
7
|
+
version = "2.2.0"
|
|
4
8
|
description = "A command line tool to automatically fix Django deprecations."
|
|
5
|
-
authors = ["Bruno Alla <alla.brunoo@gmail.com>"]
|
|
9
|
+
authors = [ "Bruno Alla <alla.brunoo@gmail.com>" ]
|
|
6
10
|
license = "MIT"
|
|
7
11
|
readme = "README.md"
|
|
8
|
-
keywords = ["django", "codemod", "libCST"]
|
|
12
|
+
keywords = [ "django", "codemod", "libCST" ]
|
|
9
13
|
repository = "https://github.com/browniebroke/django-codemod"
|
|
10
14
|
documentation = "https://django-codemod.readthedocs.io"
|
|
11
15
|
classifiers = [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
"Development Status :: 5 - Production/Stable",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Natural Language :: English",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Topic :: Software Development :: Libraries",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
18
22
|
]
|
|
19
23
|
packages = [
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
{ include = "django_codemod", from = "src" },
|
|
25
|
+
{ include = "tests", format = "sdist" },
|
|
22
26
|
]
|
|
23
27
|
|
|
24
28
|
[tool.poetry.urls]
|
|
@@ -31,7 +35,7 @@ packages = [
|
|
|
31
35
|
djcodemod = "django_codemod.cli:djcodemod"
|
|
32
36
|
|
|
33
37
|
[tool.poetry.dependencies]
|
|
34
|
-
python = "^3.
|
|
38
|
+
python = "^3.9"
|
|
35
39
|
click = "<9"
|
|
36
40
|
libcst = "==1.1.0"
|
|
37
41
|
pathspec = ">=0.6,<1"
|
|
@@ -52,81 +56,56 @@ myst-parser = { version = ">=0.16", python = ">=3.11" }
|
|
|
52
56
|
sphinx = { version = ">=4.0", python = ">=3.11" }
|
|
53
57
|
furo = { version = ">=2023.5.20", python = ">=3.11" }
|
|
54
58
|
|
|
55
|
-
[tool.semantic_release]
|
|
56
|
-
version_toml = ["pyproject.toml:tool.poetry.version"]
|
|
57
|
-
version_variables = [
|
|
58
|
-
"src/django_codemod/__init__.py:__version__",
|
|
59
|
-
]
|
|
60
|
-
build_command = "pip install poetry && poetry build"
|
|
61
|
-
|
|
62
|
-
[tool.semantic_release.changelog]
|
|
63
|
-
exclude_commit_patterns = [
|
|
64
|
-
"chore*",
|
|
65
|
-
"ci*",
|
|
66
|
-
]
|
|
67
|
-
|
|
68
|
-
[tool.semantic_release.changelog.environment]
|
|
69
|
-
keep_trailing_newline = true
|
|
70
|
-
|
|
71
|
-
[tool.semantic_release.branches.main]
|
|
72
|
-
match = "main"
|
|
73
|
-
|
|
74
|
-
[tool.semantic_release.branches.noop]
|
|
75
|
-
match = "(?!main$)"
|
|
76
|
-
prerelease = true
|
|
77
|
-
|
|
78
|
-
[tool.pytest.ini_options]
|
|
79
|
-
addopts = "-v -Wdefault --cov=django_codemod --cov-report=term-missing:skip-covered"
|
|
80
|
-
pythonpath = ["src"]
|
|
81
|
-
|
|
82
59
|
[tool.ruff]
|
|
83
|
-
target-version = "
|
|
60
|
+
target-version = "py39"
|
|
84
61
|
line-length = 88
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
62
|
+
|
|
63
|
+
lint.select = [
|
|
64
|
+
"B", # flake8-bugbear
|
|
65
|
+
"C4", # flake8-comprehensions
|
|
66
|
+
"D", # flake8-docstrings
|
|
67
|
+
"E", # pycodestyle
|
|
68
|
+
"F", # pyflake
|
|
69
|
+
"I", # isort
|
|
70
|
+
"RUF", # ruff specific
|
|
71
|
+
"S", # flake8-bandit
|
|
72
|
+
"UP", # pyupgrade
|
|
73
|
+
"W", # pycodestyle
|
|
94
74
|
]
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
"I", # isort
|
|
105
|
-
"RUF", # ruff specific
|
|
75
|
+
lint.ignore = [
|
|
76
|
+
"D100", # Missing docstring in public module
|
|
77
|
+
"D101", # Missing docstring in public class
|
|
78
|
+
"D102", # Missing docstring in public method
|
|
79
|
+
"D104", # Missing docstring in public package
|
|
80
|
+
"D107", # Missing docstring in `__init__`
|
|
81
|
+
"D203", # 1 blank line required before class docstring
|
|
82
|
+
"D212", # Multi-line docstring summary should start at the first line
|
|
83
|
+
"D401", # First line of docstring should be in imperative mood
|
|
106
84
|
]
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
85
|
+
lint.per-file-ignores."conftest.py" = [ "D100" ]
|
|
86
|
+
lint.per-file-ignores."docs/conf.py" = [ "D100" ]
|
|
87
|
+
lint.per-file-ignores."tests/**/*" = [
|
|
88
|
+
"D100",
|
|
89
|
+
"D101",
|
|
90
|
+
"D102",
|
|
91
|
+
"D103",
|
|
92
|
+
"D104",
|
|
93
|
+
"S101",
|
|
115
94
|
]
|
|
116
|
-
|
|
117
|
-
"docs/conf.py" = ["D100"]
|
|
95
|
+
lint.isort.known-first-party = [ "django_codemod", "tests" ]
|
|
118
96
|
|
|
119
|
-
[tool.
|
|
120
|
-
|
|
97
|
+
[tool.pytest.ini_options]
|
|
98
|
+
addopts = "-v -Wdefault --cov=django_codemod --cov-report=term-missing:skip-covered"
|
|
99
|
+
pythonpath = [ "src" ]
|
|
121
100
|
|
|
122
101
|
[tool.coverage.run]
|
|
123
102
|
branch = true
|
|
124
103
|
|
|
125
104
|
[tool.coverage.report]
|
|
126
105
|
exclude_lines = [
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
106
|
+
"pragma: no cover",
|
|
107
|
+
"raise AssertionError",
|
|
108
|
+
"raise NotImplementedError",
|
|
130
109
|
]
|
|
131
110
|
|
|
132
111
|
[tool.mypy]
|
|
@@ -140,6 +119,26 @@ warn_no_return = true
|
|
|
140
119
|
|
|
141
120
|
show_error_codes = true
|
|
142
121
|
|
|
143
|
-
[
|
|
144
|
-
|
|
145
|
-
|
|
122
|
+
[tool.semantic_release]
|
|
123
|
+
version_toml = [ "pyproject.toml:tool.poetry.version" ]
|
|
124
|
+
version_variables = [
|
|
125
|
+
"src/django_codemod/__init__.py:__version__",
|
|
126
|
+
]
|
|
127
|
+
build_command = "pip install poetry && poetry build"
|
|
128
|
+
|
|
129
|
+
[tool.semantic_release.changelog]
|
|
130
|
+
exclude_commit_patterns = [
|
|
131
|
+
"chore.*",
|
|
132
|
+
"ci.*",
|
|
133
|
+
"Merge pull request .*",
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
[tool.semantic_release.changelog.environment]
|
|
137
|
+
keep_trailing_newline = true
|
|
138
|
+
|
|
139
|
+
[tool.semantic_release.branches.main]
|
|
140
|
+
match = "main"
|
|
141
|
+
|
|
142
|
+
[tool.semantic_release.branches.noop]
|
|
143
|
+
match = "(?!main$)"
|
|
144
|
+
prerelease = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.0"
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
from collections import defaultdict
|
|
3
|
+
from collections.abc import Generator
|
|
3
4
|
from operator import attrgetter
|
|
4
5
|
from pathlib import Path
|
|
5
|
-
from typing import Callable,
|
|
6
|
+
from typing import Callable, Optional
|
|
6
7
|
|
|
7
8
|
import rich_click as click
|
|
8
9
|
from libcst.codemod import CodemodContext, parallel_exec_transform_with_prettyprint
|
|
@@ -16,7 +17,7 @@ from django_codemod.path_utils import get_sources
|
|
|
16
17
|
from django_codemod.visitors.base import BaseDjCodemodTransformer
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
def index_codemodders(version_getter: Callable) ->
|
|
20
|
+
def index_codemodders(version_getter: Callable) -> dict[tuple[int, int], list]:
|
|
20
21
|
"""
|
|
21
22
|
Index codemodders by version.
|
|
22
23
|
|
|
@@ -29,7 +30,7 @@ def index_codemodders(version_getter: Callable) -> Dict[Tuple[int, int], List]:
|
|
|
29
30
|
return dict(codemodders_index)
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
def iter_codemodders() -> Generator[
|
|
33
|
+
def iter_codemodders() -> Generator[type[BaseDjCodemodTransformer], None, None]:
|
|
33
34
|
"""Iterator of all the codemodders classes."""
|
|
34
35
|
for object_name in dir(visitors):
|
|
35
36
|
try:
|
|
@@ -61,15 +62,15 @@ class VersionParamType(click.ParamType):
|
|
|
61
62
|
" e.g. '2.2' or '2.2.10'"
|
|
62
63
|
)
|
|
63
64
|
|
|
64
|
-
def __init__(self, version_index:
|
|
65
|
-
self.valid_versions:
|
|
65
|
+
def __init__(self, version_index: dict[tuple[int, int], list]) -> None:
|
|
66
|
+
self.valid_versions: list[tuple[int, int]] = list(version_index.keys())
|
|
66
67
|
|
|
67
68
|
def convert( # type: ignore[return]
|
|
68
69
|
self,
|
|
69
70
|
value: str,
|
|
70
71
|
param: Optional[click.Parameter],
|
|
71
72
|
ctx: Optional[click.Context],
|
|
72
|
-
) ->
|
|
73
|
+
) -> tuple[int, int]:
|
|
73
74
|
"""Parse version to keep only major an minor digits."""
|
|
74
75
|
try:
|
|
75
76
|
return self._parse_unsafe(value, param, ctx)
|
|
@@ -85,7 +86,7 @@ class VersionParamType(click.ParamType):
|
|
|
85
86
|
value: str,
|
|
86
87
|
param: Optional[click.Parameter],
|
|
87
88
|
ctx: Optional[click.Context],
|
|
88
|
-
) ->
|
|
89
|
+
) -> tuple[int, int]:
|
|
89
90
|
"""Parse version and validate it's a supported one."""
|
|
90
91
|
parsed_version = self._split_digits(value, param, ctx)
|
|
91
92
|
if parsed_version not in self.valid_versions:
|
|
@@ -106,7 +107,7 @@ class VersionParamType(click.ParamType):
|
|
|
106
107
|
value: str,
|
|
107
108
|
param: Optional[click.Parameter],
|
|
108
109
|
ctx: Optional[click.Context],
|
|
109
|
-
) ->
|
|
110
|
+
) -> tuple[int, int]:
|
|
110
111
|
"""Split version into 2-tuple of digits, ignoring patch digit."""
|
|
111
112
|
values_parts = tuple(int(v) for v in value.split("."))
|
|
112
113
|
if len(values_parts) < 2:
|
|
@@ -155,10 +156,10 @@ def djcodemod():
|
|
|
155
156
|
multiple=True,
|
|
156
157
|
)
|
|
157
158
|
def run(
|
|
158
|
-
removed_in:
|
|
159
|
-
deprecated_in:
|
|
160
|
-
codemod:
|
|
161
|
-
src:
|
|
159
|
+
removed_in: list[tuple[int, int]],
|
|
160
|
+
deprecated_in: list[tuple[int, int]],
|
|
161
|
+
codemod: list[str],
|
|
162
|
+
src: tuple[str, ...],
|
|
162
163
|
) -> None:
|
|
163
164
|
"""
|
|
164
165
|
Automatically fixes deprecations removed Django deprecations.
|
|
@@ -185,7 +186,7 @@ def run(
|
|
|
185
186
|
call_command(command_instance, files)
|
|
186
187
|
|
|
187
188
|
|
|
188
|
-
def call_command(command_instance: BaseCodemodCommand, files:
|
|
189
|
+
def call_command(command_instance: BaseCodemodCommand, files: list[Path]):
|
|
189
190
|
"""Call libCST with our customized command."""
|
|
190
191
|
try:
|
|
191
192
|
# Super simplified call
|
|
@@ -228,7 +229,7 @@ def list_() -> None:
|
|
|
228
229
|
console.print(table)
|
|
229
230
|
|
|
230
231
|
|
|
231
|
-
def generate_rows() -> Generator[
|
|
232
|
+
def generate_rows() -> Generator[tuple[str, str, str, str], None, None]:
|
|
232
233
|
"""Build up the rows for the table of codemodders."""
|
|
233
234
|
codemodders_list = sorted(
|
|
234
235
|
iter_codemodders(), key=lambda obj: (obj.deprecated_in, obj.removed_in)
|
|
@@ -242,7 +243,7 @@ def generate_rows() -> Generator[Tuple[str, str, str, str], None, None]:
|
|
|
242
243
|
)
|
|
243
244
|
|
|
244
245
|
|
|
245
|
-
def get_short_description(codemodder:
|
|
246
|
+
def get_short_description(codemodder: type[BaseDjCodemodTransformer]) -> str:
|
|
246
247
|
"""Get a one line description of the codemodder from its docstring."""
|
|
247
248
|
if codemodder.__doc__ is None:
|
|
248
249
|
return ""
|
|
@@ -252,6 +253,6 @@ def get_short_description(codemodder: Type[BaseDjCodemodTransformer]) -> str:
|
|
|
252
253
|
return ""
|
|
253
254
|
|
|
254
255
|
|
|
255
|
-
def version_str(version_parts:
|
|
256
|
+
def version_str(version_parts: tuple[int, int]) -> str:
|
|
256
257
|
"""Format the version tuple as string."""
|
|
257
258
|
return ".".join(str(d) for d in version_parts)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from abc import ABC
|
|
2
|
-
from typing import List, Type
|
|
3
2
|
|
|
4
3
|
import libcst as cst
|
|
5
4
|
from libcst.codemod import (
|
|
@@ -12,7 +11,7 @@ from libcst.codemod import (
|
|
|
12
11
|
class BaseCodemodCommand(VisitorBasedCodemodCommand, ABC):
|
|
13
12
|
"""Base class for our commands."""
|
|
14
13
|
|
|
15
|
-
transformers:
|
|
14
|
+
transformers: list[type[ContextAwareTransformer]]
|
|
16
15
|
|
|
17
16
|
def __init__(self, transformers, context: CodemodContext) -> None:
|
|
18
17
|
self.transformers = transformers
|
|
@@ -5,13 +5,14 @@ Inspired or taken from black:
|
|
|
5
5
|
https://github.com/psf/black
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from collections.abc import Iterable, Iterator
|
|
8
9
|
from pathlib import Path
|
|
9
|
-
from typing import
|
|
10
|
+
from typing import Optional
|
|
10
11
|
|
|
11
12
|
from pathspec import PathSpec
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
def get_sources(src: Iterable[str]) ->
|
|
15
|
+
def get_sources(src: Iterable[str]) -> list[Path]:
|
|
15
16
|
"""
|
|
16
17
|
Return a list of sources to codemod.
|
|
17
18
|
|
|
@@ -20,7 +21,7 @@ def get_sources(src: Iterable[str]) -> List[Path]:
|
|
|
20
21
|
"""
|
|
21
22
|
root = find_project_root(src)
|
|
22
23
|
gitignore = get_gitignore(root)
|
|
23
|
-
sources:
|
|
24
|
+
sources: set[Path] = set()
|
|
24
25
|
for s in src:
|
|
25
26
|
p = Path(s)
|
|
26
27
|
paths: Iterable[Path] = []
|
|
@@ -75,7 +76,7 @@ def find_project_root(sources: Iterable[str]) -> Path:
|
|
|
75
76
|
def get_gitignore(root: Path) -> PathSpec:
|
|
76
77
|
"""Return a PathSpec matching gitignore content if present."""
|
|
77
78
|
gitignore = root / ".gitignore"
|
|
78
|
-
lines:
|
|
79
|
+
lines: list[str] = []
|
|
79
80
|
if gitignore.is_file():
|
|
80
81
|
with gitignore.open() as gf:
|
|
81
82
|
lines = gf.readlines()
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""Module to implement base functionality."""
|
|
2
2
|
|
|
3
3
|
from abc import ABC
|
|
4
|
-
from
|
|
4
|
+
from collections.abc import Sequence
|
|
5
|
+
from typing import Optional, Union
|
|
5
6
|
|
|
6
7
|
from libcst import (
|
|
7
8
|
Arg,
|
|
@@ -46,8 +47,8 @@ class IsTryImportProvider(BatchableMetadataProvider[bool]):
|
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
class BaseDjCodemodTransformer(ContextAwareTransformer, ABC):
|
|
49
|
-
deprecated_in:
|
|
50
|
-
removed_in:
|
|
50
|
+
deprecated_in: tuple[int, int]
|
|
51
|
+
removed_in: tuple[int, int]
|
|
51
52
|
|
|
52
53
|
|
|
53
54
|
def module_matcher(
|
|
@@ -334,8 +335,8 @@ class BaseRenameTransformer(BaseDjCodemodTransformer, ABC):
|
|
|
334
335
|
|
|
335
336
|
|
|
336
337
|
def clean_new_import_aliases(
|
|
337
|
-
import_aliases:
|
|
338
|
-
) ->
|
|
338
|
+
import_aliases: list[ImportAlias],
|
|
339
|
+
) -> list[ImportAlias]:
|
|
339
340
|
"""Clean up a list of import aliases."""
|
|
340
341
|
# Sort them
|
|
341
342
|
cleaned_import_aliases = sorted(import_aliases, key=lambda n: n.evaluated_name)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Sequence
|
|
2
|
+
from typing import Optional, Union
|
|
2
3
|
|
|
3
4
|
from libcst import (
|
|
4
5
|
Arg,
|
|
@@ -139,7 +140,8 @@ class ModelsPermalinkTransformer(BaseDjCodemodTransformer):
|
|
|
139
140
|
BaseSmallStatement, FlattenSentinel[BaseSmallStatement], RemovalSentinel
|
|
140
141
|
]:
|
|
141
142
|
if self.visiting_permalink_method and m.matches(
|
|
142
|
-
updated_node.value,
|
|
143
|
+
updated_node.value,
|
|
144
|
+
m.Tuple(), # type: ignore
|
|
143
145
|
):
|
|
144
146
|
elem_0, *elem_1_3 = updated_node.value.elements[:3] # type: ignore
|
|
145
147
|
args = (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import ClassVar,
|
|
1
|
+
from typing import ClassVar, Optional
|
|
2
2
|
|
|
3
3
|
from libcst import BaseExpression, Call, ImportFrom, ImportStar, MaybeSentinel, Module
|
|
4
4
|
from libcst import matchers as m
|
|
@@ -15,7 +15,7 @@ class SignalDisconnectWeakTransformer(BaseDjCodemodTransformer):
|
|
|
15
15
|
|
|
16
16
|
ctx_key_prefix = "SignalDisconnectWeakTransformer"
|
|
17
17
|
ctx_key_call_matchers = f"{ctx_key_prefix}-call_matchers"
|
|
18
|
-
builtin_signals: ClassVar[
|
|
18
|
+
builtin_signals: ClassVar[list[str]] = [
|
|
19
19
|
"pre_init",
|
|
20
20
|
"post_init",
|
|
21
21
|
"pre_save",
|
|
@@ -31,7 +31,7 @@ class SignalDisconnectWeakTransformer(BaseDjCodemodTransformer):
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
@property
|
|
34
|
-
def disconnect_call_matchers(self) ->
|
|
34
|
+
def disconnect_call_matchers(self) -> list[m.Call]:
|
|
35
35
|
return self.context.scratch.get(self.ctx_key_call_matchers, [])
|
|
36
36
|
|
|
37
37
|
def add_disconnect_call_matcher(self, call_matcher: m.Call) -> None:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Sequence
|
|
2
2
|
|
|
3
3
|
from libcst import Arg, BaseExpression, Call, Name, SimpleString
|
|
4
4
|
from libcst import matchers as m
|
|
@@ -85,7 +85,7 @@ class URLTransformer(BaseFuncRenameTransformer):
|
|
|
85
85
|
return route
|
|
86
86
|
|
|
87
87
|
@staticmethod
|
|
88
|
-
def parse_next_group(left_to_parse: str) ->
|
|
88
|
+
def parse_next_group(left_to_parse: str) -> tuple[str, str]:
|
|
89
89
|
"""Extract captured group info."""
|
|
90
90
|
prefix, rest = left_to_parse.split("(?P<", 1)
|
|
91
91
|
group, left_to_parse = rest.split(")", 1)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Type
|
|
2
|
-
|
|
3
1
|
from libcst.codemod import CodemodTest
|
|
4
2
|
|
|
5
3
|
from django_codemod.commands import BaseCodemodCommand
|
|
@@ -9,7 +7,7 @@ from django_codemod.visitors.base import BaseDjCodemodTransformer
|
|
|
9
7
|
class BaseVisitorTest(CodemodTest):
|
|
10
8
|
"""Base test to use in all visitors tests."""
|
|
11
9
|
|
|
12
|
-
transformer:
|
|
10
|
+
transformer: type[BaseDjCodemodTransformer]
|
|
13
11
|
|
|
14
12
|
def TRANSFORM(self, context):
|
|
15
13
|
"""Create a command for the transformer under test."""
|
|
@@ -19,9 +19,7 @@ class TestInlineHasAddPermissionsTransformer(BaseVisitorTest):
|
|
|
19
19
|
]
|
|
20
20
|
)
|
|
21
21
|
def test_noop_import_star(self, import_line: str, base_class: str) -> None:
|
|
22
|
-
before =
|
|
23
|
-
after
|
|
24
|
-
) = f"""
|
|
22
|
+
before = after = f"""
|
|
25
23
|
{import_line}
|
|
26
24
|
|
|
27
25
|
class MyInlineInline(InlineMixin, {base_class}):
|
|
@@ -35,9 +33,7 @@ class TestInlineHasAddPermissionsTransformer(BaseVisitorTest):
|
|
|
35
33
|
|
|
36
34
|
def test_model_admin_base_class(self) -> None:
|
|
37
35
|
"""Doesn't modify if base class doesn't match."""
|
|
38
|
-
before =
|
|
39
|
-
after
|
|
40
|
-
) = """
|
|
36
|
+
before = after = """
|
|
41
37
|
from django.contrib import admin
|
|
42
38
|
|
|
43
39
|
class MyAdmin(admin.ModelAdmin):
|
|
@@ -51,9 +47,7 @@ class TestInlineHasAddPermissionsTransformer(BaseVisitorTest):
|
|
|
51
47
|
|
|
52
48
|
def test_no_base_class(self) -> None:
|
|
53
49
|
"""Doesn't modify if there is no base class."""
|
|
54
|
-
before =
|
|
55
|
-
after
|
|
56
|
-
) = """
|
|
50
|
+
before = after = """
|
|
57
51
|
from django.contrib import admin
|
|
58
52
|
|
|
59
53
|
class MyCustomStuff:
|
|
@@ -278,9 +278,7 @@ class TestFuncRenameTransformer(BaseVisitorTest):
|
|
|
278
278
|
self.assertCodemod(before, after)
|
|
279
279
|
|
|
280
280
|
def test_avoid_try_import(self) -> None:
|
|
281
|
-
before =
|
|
282
|
-
after
|
|
283
|
-
) = """
|
|
281
|
+
before = after = """
|
|
284
282
|
try:
|
|
285
283
|
from django.dummy.module import func
|
|
286
284
|
except:
|
|
@@ -293,9 +291,7 @@ class TestFuncRenameTransformer(BaseVisitorTest):
|
|
|
293
291
|
|
|
294
292
|
@pytest.mark.usefixtures("parent_module_import_enabled")
|
|
295
293
|
def test_avoid_try_import_parent(self) -> None:
|
|
296
|
-
before =
|
|
297
|
-
after
|
|
298
|
-
) = """
|
|
294
|
+
before = after = """
|
|
299
295
|
try:
|
|
300
296
|
from django.dummy import module
|
|
301
297
|
except:
|
|
@@ -308,9 +304,7 @@ class TestFuncRenameTransformer(BaseVisitorTest):
|
|
|
308
304
|
|
|
309
305
|
@pytest.mark.usefixtures("parent_module_import_enabled")
|
|
310
306
|
def test_parent_import_star(self) -> None:
|
|
311
|
-
before =
|
|
312
|
-
after
|
|
313
|
-
) = """
|
|
307
|
+
before = after = """
|
|
314
308
|
from django.dummy import *
|
|
315
309
|
|
|
316
310
|
result = module.func()
|
|
@@ -319,9 +313,7 @@ class TestFuncRenameTransformer(BaseVisitorTest):
|
|
|
319
313
|
|
|
320
314
|
@pytest.mark.usefixtures("parent_module_import_enabled")
|
|
321
315
|
def test_parent_import_not_matches(self) -> None:
|
|
322
|
-
before =
|
|
323
|
-
after
|
|
324
|
-
) = """
|
|
316
|
+
before = after = """
|
|
325
317
|
from django.ymmud import other_module
|
|
326
318
|
|
|
327
319
|
result = other_module.other_func()
|
|
@@ -415,9 +407,7 @@ class TestOtherModuleFuncRenameTransformer(BaseVisitorTest):
|
|
|
415
407
|
@pytest.mark.usefixtures("parent_module_import_enabled")
|
|
416
408
|
def test_parent_module_noop(self) -> None:
|
|
417
409
|
"""Parent module imported, but other function used."""
|
|
418
|
-
before =
|
|
419
|
-
after
|
|
420
|
-
) = """
|
|
410
|
+
before = after = """
|
|
421
411
|
from django.dummy import module
|
|
422
412
|
|
|
423
413
|
result = module.other_func()
|
|
@@ -476,9 +466,7 @@ class TestModuleRenameTransformer(BaseVisitorTest):
|
|
|
476
466
|
self.assertCodemod(before, after)
|
|
477
467
|
|
|
478
468
|
def test_avoid_try_import(self) -> None:
|
|
479
|
-
before =
|
|
480
|
-
after
|
|
481
|
-
) = """
|
|
469
|
+
before = after = """
|
|
482
470
|
try:
|
|
483
471
|
from django.dummy.module import func
|
|
484
472
|
except:
|
|
@@ -102,9 +102,7 @@ class TestHttpRequestXReadLinesTransformer(BaseVisitorTest):
|
|
|
102
102
|
|
|
103
103
|
def test_noop_wrong_name(self) -> None:
|
|
104
104
|
"""Don't replace calls for name other than `request` or `req`."""
|
|
105
|
-
before =
|
|
106
|
-
after
|
|
107
|
-
) = """
|
|
105
|
+
before = after = """
|
|
108
106
|
for line in r.xreadlines():
|
|
109
107
|
print(line)
|
|
110
108
|
"""
|
|
@@ -112,9 +110,7 @@ class TestHttpRequestXReadLinesTransformer(BaseVisitorTest):
|
|
|
112
110
|
|
|
113
111
|
def test_noop_function_call(self) -> None:
|
|
114
112
|
"""Don't replace calls for name other than `request` or `req`."""
|
|
115
|
-
before =
|
|
116
|
-
after
|
|
117
|
-
) = """
|
|
113
|
+
before = after = """
|
|
118
114
|
for line in xreadlines(r):
|
|
119
115
|
print(line)
|
|
120
116
|
"""
|
|
@@ -173,9 +169,7 @@ class TestCookieDateTransformer(BaseVisitorTest):
|
|
|
173
169
|
transformer = CookieDateTransformer
|
|
174
170
|
|
|
175
171
|
def test_noop(self):
|
|
176
|
-
before =
|
|
177
|
-
after
|
|
178
|
-
) = """
|
|
172
|
+
before = after = """
|
|
179
173
|
from django.utils.http import http_date
|
|
180
174
|
|
|
181
175
|
http_date(12345)
|
|
@@ -218,9 +218,7 @@ class TestAvailableAttrsTransformer(BaseVisitorTest):
|
|
|
218
218
|
)
|
|
219
219
|
def test_noop_import_star(self, import_str: str) -> None:
|
|
220
220
|
"""Should not try to replace if import star is used."""
|
|
221
|
-
before =
|
|
222
|
-
after
|
|
223
|
-
) = f"""
|
|
221
|
+
before = after = f"""
|
|
224
222
|
{import_str}
|
|
225
223
|
|
|
226
224
|
class MyModel(models.Model):
|
|
@@ -352,9 +350,7 @@ class TestNullBooleanFieldTransformer(BaseVisitorTest):
|
|
|
352
350
|
transformer = NullBooleanFieldTransformer
|
|
353
351
|
|
|
354
352
|
def test_noop_models(self) -> None:
|
|
355
|
-
before =
|
|
356
|
-
after
|
|
357
|
-
) = """
|
|
353
|
+
before = after = """
|
|
358
354
|
from django.db import models
|
|
359
355
|
|
|
360
356
|
class MyThing(models.Model):
|
|
@@ -363,9 +359,7 @@ class TestNullBooleanFieldTransformer(BaseVisitorTest):
|
|
|
363
359
|
self.assertCodemod(before, after)
|
|
364
360
|
|
|
365
361
|
def test_noop_fields(self) -> None:
|
|
366
|
-
before =
|
|
367
|
-
after
|
|
368
|
-
) = """
|
|
362
|
+
before = after = """
|
|
369
363
|
from django.db.models import BooleanField, Model
|
|
370
364
|
|
|
371
365
|
class MyThing(Model):
|
|
@@ -7,9 +7,7 @@ class TestQuerySetPaginatorTransformer(BaseVisitorTest):
|
|
|
7
7
|
|
|
8
8
|
def test_noop(self) -> None:
|
|
9
9
|
"""Test when nothing should change."""
|
|
10
|
-
before =
|
|
11
|
-
after
|
|
12
|
-
) = """
|
|
10
|
+
before = after = """
|
|
13
11
|
from django.core.paginator import Paginator
|
|
14
12
|
|
|
15
13
|
paginator_instance = Paginator([], 5)
|
|
@@ -11,9 +11,7 @@ class TestFloatRangeModelFieldTransformer(BaseVisitorTest):
|
|
|
11
11
|
|
|
12
12
|
def test_noop(self) -> None:
|
|
13
13
|
"""Test when nothing should change."""
|
|
14
|
-
before =
|
|
15
|
-
after
|
|
16
|
-
) = """
|
|
14
|
+
before = after = """
|
|
17
15
|
from django.contrib.postgres.fields import DecimalRangeField
|
|
18
16
|
|
|
19
17
|
some_range = DecimalRangeField()
|
|
@@ -42,9 +40,7 @@ class TestFloatRangeFormFieldTransformer(BaseVisitorTest):
|
|
|
42
40
|
|
|
43
41
|
def test_noop(self) -> None:
|
|
44
42
|
"""Test when nothing should change."""
|
|
45
|
-
before =
|
|
46
|
-
after
|
|
47
|
-
) = """
|
|
43
|
+
before = after = """
|
|
48
44
|
from django.contrib.postgres.forms import DecimalRangeField
|
|
49
45
|
|
|
50
46
|
some_range = DecimalRangeField()
|
|
@@ -73,9 +69,7 @@ class TestJSONModelFieldTransformer(BaseVisitorTest):
|
|
|
73
69
|
|
|
74
70
|
def test_noop(self) -> None:
|
|
75
71
|
"""Test when nothing should change."""
|
|
76
|
-
before =
|
|
77
|
-
after
|
|
78
|
-
) = """
|
|
72
|
+
before = after = """
|
|
79
73
|
from django.db.models import JSONField
|
|
80
74
|
|
|
81
75
|
field = JSONField()
|
|
@@ -24,9 +24,7 @@ class TestSignalDisconnectWeakTransformer(BaseVisitorTest):
|
|
|
24
24
|
|
|
25
25
|
@parameterized.expand(DJANGO_SIGNAL_NAMES)
|
|
26
26
|
def test_noop(self, signal_name):
|
|
27
|
-
before =
|
|
28
|
-
after
|
|
29
|
-
) = f"""
|
|
27
|
+
before = after = f"""
|
|
30
28
|
from django.db.models.signals import {signal_name}
|
|
31
29
|
|
|
32
30
|
{signal_name}.disconnect(
|
|
@@ -40,9 +38,7 @@ class TestSignalDisconnectWeakTransformer(BaseVisitorTest):
|
|
|
40
38
|
|
|
41
39
|
@parameterized.expand(DJANGO_SIGNAL_NAMES)
|
|
42
40
|
def test_noop_import_star(self, signal_name):
|
|
43
|
-
before =
|
|
44
|
-
after
|
|
45
|
-
) = f"""
|
|
41
|
+
before = after = f"""
|
|
46
42
|
from django.db.models.signals import *
|
|
47
43
|
|
|
48
44
|
{signal_name}.disconnect(receiver=some_handler, sender=MyModel, weak=True)
|
|
@@ -9,9 +9,7 @@ class TestAssignmentTagTransformer(BaseVisitorTest):
|
|
|
9
9
|
|
|
10
10
|
def test_noop(self) -> None:
|
|
11
11
|
"""Test when nothing should change."""
|
|
12
|
-
before =
|
|
13
|
-
after
|
|
14
|
-
) = """
|
|
12
|
+
before = after = """
|
|
15
13
|
from django import template
|
|
16
14
|
|
|
17
15
|
register = template.Library()
|
|
@@ -32,9 +30,7 @@ class TestAssignmentTagTransformer(BaseVisitorTest):
|
|
|
32
30
|
)
|
|
33
31
|
def test_noop_not_imported(self, import_line: str) -> None:
|
|
34
32
|
"""Test when import is missing."""
|
|
35
|
-
before =
|
|
36
|
-
after
|
|
37
|
-
) = f"""
|
|
33
|
+
before = after = f"""
|
|
38
34
|
{import_line}
|
|
39
35
|
|
|
40
36
|
@register.assignment_tag
|
|
@@ -46,9 +42,7 @@ class TestAssignmentTagTransformer(BaseVisitorTest):
|
|
|
46
42
|
|
|
47
43
|
def test_noop_import_star(self) -> None:
|
|
48
44
|
"""Test when imported as star import."""
|
|
49
|
-
before =
|
|
50
|
-
after
|
|
51
|
-
) = """
|
|
45
|
+
before = after = """
|
|
52
46
|
from django import *
|
|
53
47
|
|
|
54
48
|
register = template.Library()
|
|
@@ -138,9 +132,7 @@ class TestAssignmentTagTransformer(BaseVisitorTest):
|
|
|
138
132
|
|
|
139
133
|
def test_noop_content_star_import(self) -> None:
|
|
140
134
|
"""Test when Library class is imported as star import."""
|
|
141
|
-
before =
|
|
142
|
-
after
|
|
143
|
-
) = """
|
|
135
|
+
before = after = """
|
|
144
136
|
from django.template import *
|
|
145
137
|
|
|
146
138
|
register = Library()
|
|
@@ -7,9 +7,7 @@ class TestFixedOffsetTransformer(BaseVisitorTest):
|
|
|
7
7
|
|
|
8
8
|
def test_noop(self) -> None:
|
|
9
9
|
"""Test when nothing should change."""
|
|
10
|
-
before =
|
|
11
|
-
after
|
|
12
|
-
) = """
|
|
10
|
+
before = after = """
|
|
13
11
|
from datetime import timedelta, timezone
|
|
14
12
|
|
|
15
13
|
timezone(offset=timedelta(minutes=60))
|
|
@@ -78,9 +76,7 @@ class TestFixedOffsetTransformer(BaseVisitorTest):
|
|
|
78
76
|
self.assertCodemod(before, after)
|
|
79
77
|
|
|
80
78
|
def test_issue_421(self) -> None:
|
|
81
|
-
before =
|
|
82
|
-
after
|
|
83
|
-
) = """
|
|
79
|
+
before = after = """
|
|
84
80
|
from django.utils import timezone
|
|
85
81
|
|
|
86
82
|
now = timezone.now()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.1.10"
|
|
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.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/postgres_fields.py
RENAMED
|
File without changes
|
{django_codemod-2.1.10 → django_codemod-2.2.0}/src/django_codemod/visitors/template_context.py
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
|