Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-django-codemod for
openSUSE:Factory checked in at 2026-02-12 17:27:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-codemod (Old)
and /work/SRC/openSUSE:Factory/.python-django-codemod.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-codemod"
Thu Feb 12 17:27:13 2026 rev:8 rq:1332603 version:2.4.5
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-django-codemod/python-django-codemod.changes
2025-08-05 14:23:33.790942252 +0200
+++
/work/SRC/openSUSE:Factory/.python-django-codemod.new.1977/python-django-codemod.changes
2026-02-12 17:28:24.045921809 +0100
@@ -1,0 +2,13 @@
+Thu Feb 12 05:05:01 UTC 2026 - Steve Kowalik <[email protected]>
+
+- Update to 2.4.5:
+ * Update dependency pathspec to v1
+ * Update signature for codemodchoice.get_metavar
+ * Update dependency libcst to v1.8.6
+ * Update dependency click to <8.4
+ * Add support for python 3.14
+ * Drop support for python 3.9
+ * Use spdx expression for license
+- Drop patch support-click-8.2.patch, no longer required.
+
+-------------------------------------------------------------------
Old:
----
django_codemod-2.3.5.tar.gz
support-click-8.2.patch
New:
----
django_codemod-2.4.5.tar.gz
----------(Old B)----------
Old: * Use spdx expression for license
- Drop patch support-click-8.2.patch, no longer required.
----------(Old E)----------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-django-codemod.spec ++++++
--- /var/tmp/diff_new_pack.O4U8IH/_old 2026-02-12 17:28:24.869956768 +0100
+++ /var/tmp/diff_new_pack.O4U8IH/_new 2026-02-12 17:28:24.873956937 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-django-codemod
#
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,18 +17,16 @@
Name: python-django-codemod
-Version: 2.3.5
+Version: 2.4.5
Release: 0
Summary: Collections of libCST codemodders to upgrade Django
License: MIT
URL: https://github.com/browniebroke/django-codemod
Source:
https://files.pythonhosted.org/packages/source/d/django-codemod/django_codemod-%{version}.tar.gz
Source1: conftest.py
-# PATCH-FIX-OPENSUSE Support click 8.2+
-Patch0: support-click-8.2.patch
-BuildRequires: %{python_module base >= 3.9}
+BuildRequires: %{python_module base >= 3.10}
BuildRequires: %{python_module pip}
-BuildRequires: %{python_module poetry}
+BuildRequires: %{python_module setuptools >= 77}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-click
@@ -36,7 +34,6 @@
Requires: python-pathspec
Requires: python-rich
Requires: python-rich-click
-Recommends: python-setuptools
Requires(post): update-alternatives
Requires(postun): update-alternatives
BuildArch: noarch
@@ -46,7 +43,9 @@
BuildRequires: %{python_module libcst}
BuildRequires: %{python_module parameterized}
BuildRequires: %{python_module pathspec}
+BuildRequires: %{python_module pytest-cov}
BuildRequires: %{python_module pytest-mock}
+BuildRequires: %{python_module pytest}
BuildRequires: %{python_module rich-click}
# /SECTION
%python_subpackages
@@ -57,8 +56,6 @@
%prep
%autosetup -p1 -n django_codemod-%{version}
cp %{SOURCE1} .
-sed -i 's/rich = ".*"/rich = "*"/' pyproject.toml
-sed -i '/addopts/d' pyproject.toml
%build
%pyproject_wheel
++++++ django_codemod-2.3.5.tar.gz -> django_codemod-2.4.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django_codemod-2.3.5/PKG-INFO
new/django_codemod-2.4.5/PKG-INFO
--- old/django_codemod-2.3.5/PKG-INFO 2025-06-14 03:17:33.843341600 +0200
+++ new/django_codemod-2.4.5/PKG-INFO 2026-01-07 11:04:18.436555100 +0100
@@ -1,9 +1,9 @@
Metadata-Version: 2.4
Name: django-codemod
-Version: 2.3.5
+Version: 2.4.5
Summary: A command line tool to automatically fix Django deprecations.
Author-email: Bruno Alla <[email protected]>
-License: MIT
+License-Expression: MIT
Project-URL: Bug Tracker, https://github.com/browniebroke/django-codemod/issues
Project-URL: Changelog,
https://django-codemod.readthedocs.io/en/stable/changelog.html
Project-URL: documentation, https://django-codemod.readthedocs.io
@@ -16,18 +16,18 @@
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
-Requires-Python: >=3.9
+Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
-Requires-Dist: click<9
-Requires-Dist: libcst==1.8.2
-Requires-Dist: pathspec<1,>=0.6
+Requires-Dist: click<8.4
+Requires-Dist: libcst==1.8.6
+Requires-Dist: pathspec<2,>=0.6
Requires-Dist: rich>=10
Requires-Dist: rich-click>=1
Dynamic: license-file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django_codemod-2.3.5/pyproject.toml
new/django_codemod-2.4.5/pyproject.toml
--- old/django_codemod-2.3.5/pyproject.toml 2025-06-14 03:17:30.000000000
+0200
+++ new/django_codemod-2.4.5/pyproject.toml 2026-01-07 11:04:14.000000000
+0100
@@ -1,10 +1,10 @@
[build-system]
build-backend = "setuptools.build_meta"
-requires = [ "setuptools" ]
+requires = [ "setuptools>=77.0.3" ]
[project]
name = "django-codemod"
-version = "2.3.5"
+version = "2.4.5"
description = "A command line tool to automatically fix Django deprecations."
readme = "README.md"
keywords = [
@@ -12,29 +12,29 @@
"django",
"libCST",
]
-license = { text = "MIT" }
+license = "MIT"
authors = [
{ name = "Bruno Alla", email = "[email protected]" },
]
-requires-python = ">=3.9"
+requires-python = ">=3.10"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3 :: Only",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: Software Development :: Libraries",
]
dependencies = [
- "click<9",
- "libcst==1.8.2",
- "pathspec>=0.6,<1",
+ "click<8.4",
+ "libcst==1.8.6",
+ "pathspec>=0.6,<2",
"rich>=10",
"rich-click>=1",
]
@@ -49,8 +49,8 @@
[dependency-groups]
dev = [
"parameterized>=0.9,<1",
- "pytest>=8,<9",
- "pytest-cov>=6,<7",
+ "pytest>=9,<10",
+ "pytest-cov>=7,<8",
"pytest-mock>=3.3,<4",
]
docs = [
@@ -96,6 +96,9 @@
]
lint.isort.known-first-party = [ "django_codemod", "tests" ]
+[tool.pyproject-fmt]
+max_supported_python = "3.14"
+
[tool.pytest.ini_options]
addopts = "-v -Wdefault --cov=django_codemod
--cov-report=term-missing:skip-covered"
pythonpath = [ "src" ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django_codemod-2.3.5/src/django_codemod/__init__.py
new/django_codemod-2.4.5/src/django_codemod/__init__.py
--- old/django_codemod-2.3.5/src/django_codemod/__init__.py 2025-06-14
03:17:30.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/__init__.py 2026-01-07
11:04:14.000000000 +0100
@@ -1 +1 @@
-__version__ = "2.3.5"
+__version__ = "2.4.5"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django_codemod-2.3.5/src/django_codemod/cli.py
new/django_codemod-2.4.5/src/django_codemod/cli.py
--- old/django_codemod-2.3.5/src/django_codemod/cli.py 2025-06-14
03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/cli.py 2026-01-07
11:04:08.000000000 +0100
@@ -1,9 +1,8 @@
import inspect
from collections import defaultdict
-from collections.abc import Generator
+from collections.abc import Callable, Generator
from operator import attrgetter
from pathlib import Path
-from typing import Callable, Optional
import rich_click as click
from libcst.codemod import CodemodContext,
parallel_exec_transform_with_prettyprint
@@ -49,7 +48,7 @@
class CodemodChoice(click.Choice):
- def get_metavar(self, param: click.Parameter) -> str:
+ def get_metavar(self, *args, **kwargs) -> str:
return "(see `djcodemod list`)"
@@ -68,8 +67,8 @@
def convert( # type: ignore[return]
self,
value: str,
- param: Optional[click.Parameter],
- ctx: Optional[click.Context],
+ param: click.Parameter | None,
+ ctx: click.Context | None,
) -> tuple[int, int]:
"""Parse version to keep only major an minor digits."""
try:
@@ -84,8 +83,8 @@
def _parse_unsafe(
self,
value: str,
- param: Optional[click.Parameter],
- ctx: Optional[click.Context],
+ param: click.Parameter | None,
+ ctx: click.Context | None,
) -> tuple[int, int]:
"""Parse version and validate it's a supported one."""
parsed_version = self._split_digits(value, param, ctx)
@@ -104,8 +103,8 @@
def _split_digits(
self,
value: str,
- param: Optional[click.Parameter],
- ctx: Optional[click.Context],
+ param: click.Parameter | None,
+ ctx: click.Context | None,
) -> tuple[int, int]:
"""Split version into 2-tuple of digits, ignoring patch digit."""
values_parts = tuple(int(v) for v in value.split("."))
@@ -115,7 +114,7 @@
param,
ctx,
)
- major, minor, *patches = values_parts
+ major, minor, *_patches = values_parts
return major, minor
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod/path_utils.py
new/django_codemod-2.4.5/src/django_codemod/path_utils.py
--- old/django_codemod-2.3.5/src/django_codemod/path_utils.py 2025-06-14
03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/path_utils.py 2026-01-07
11:04:08.000000000 +0100
@@ -7,7 +7,6 @@
from collections.abc import Iterable, Iterator
from pathlib import Path
-from typing import Optional
from pathspec import PathSpec
@@ -113,7 +112,7 @@
yield child
-def normalize_path(path: Path, root: Path) -> Optional[str]:
+def normalize_path(path: Path, root: Path) -> str | None:
"""Normalize `path`. May return `None` if `path` was ignored."""
try:
abspath = path if path.is_absolute() else Path.cwd() / path
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod/utils/calls.py
new/django_codemod-2.4.5/src/django_codemod/utils/calls.py
--- old/django_codemod-2.3.5/src/django_codemod/utils/calls.py 2025-06-14
03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/utils/calls.py 2026-01-07
11:04:08.000000000 +0100
@@ -1,11 +1,10 @@
from collections.abc import Sequence
-from typing import Optional
from libcst import Arg, Call, FunctionDef, Param, parse_expression,
parse_statement
from libcst import matchers as m
-def find_keyword_arg(args: Sequence[Arg], keyword_name: str) -> Optional[Arg]:
+def find_keyword_arg(args: Sequence[Arg], keyword_name: str) -> Arg | None:
"""Find a kwarg among a sequence of arguments."""
matcher = m.Arg(keyword=m.Name(keyword_name))
return next((arg for arg in args if m.matches(arg, matcher)), None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod/visitors/admin.py
new/django_codemod-2.4.5/src/django_codemod/visitors/admin.py
--- old/django_codemod-2.3.5/src/django_codemod/visitors/admin.py
2025-06-14 03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/visitors/admin.py
2026-01-07 11:04:08.000000000 +0100
@@ -1,5 +1,3 @@
-from typing import Union
-
from libcst import (
BaseExpression,
BaseSmallStatement,
@@ -35,9 +33,7 @@
def leave_ImportFrom(
self, original_node: ImportFrom, updated_node: ImportFrom
- ) -> Union[
- BaseSmallStatement, FlattenSentinel[BaseSmallStatement],
RemovalSentinel
- ]:
+ ) -> BaseSmallStatement | FlattenSentinel[BaseSmallStatement] |
RemovalSentinel:
if isinstance(updated_node.names, ImportStar):
return super().leave_ImportFrom(original_node, updated_node)
base_cls_matcher = []
@@ -98,7 +94,7 @@
def leave_ClassDef(
self, original_node: ClassDef, updated_node: ClassDef
- ) -> Union[BaseStatement, FlattenSentinel[BaseStatement], RemovalSentinel]:
+ ) -> BaseStatement | FlattenSentinel[BaseStatement] | RemovalSentinel:
self.context.scratch.pop(self.ctx_key_visiting_subclass, None)
return super().leave_ClassDef(original_node, updated_node)
@@ -108,7 +104,7 @@
def leave_FunctionDef(
self, original_node: FunctionDef, updated_node: FunctionDef
- ) -> Union[BaseStatement, FlattenSentinel[BaseStatement], RemovalSentinel]:
+ ) -> BaseStatement | FlattenSentinel[BaseStatement] | RemovalSentinel:
if (
self.is_visiting_subclass
and m.matches(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod/visitors/base.py
new/django_codemod-2.4.5/src/django_codemod/visitors/base.py
--- old/django_codemod-2.3.5/src/django_codemod/visitors/base.py
2025-06-14 03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/visitors/base.py
2026-01-07 11:04:08.000000000 +0100
@@ -2,7 +2,6 @@
from abc import ABC
from collections.abc import Sequence
-from typing import Optional, Union
from libcst import (
Arg,
@@ -53,7 +52,7 @@
def module_matcher(
import_parts: Sequence[str],
-) -> Union[m.Attribute, m.Name]:
+) -> m.Attribute | m.Name:
"""Build matcher for a module given sequence of import parts."""
# If only one element, it is just a Name
if len(import_parts) == 1:
@@ -112,7 +111,7 @@
def leave_ImportFrom(
self, original_node: ImportFrom, updated_node: ImportFrom
- ) -> Union[BaseSmallStatement, RemovalSentinel]:
+ ) -> BaseSmallStatement | RemovalSentinel:
"""Update import statements for matching old module name."""
return (
self._check_import_from_exact(original_node, updated_node)
@@ -123,7 +122,7 @@
def _check_import_from_exact(
self, original_node: ImportFrom, updated_node: ImportFrom
- ) -> Optional[Union[BaseSmallStatement, RemovalSentinel]]:
+ ) -> BaseSmallStatement | RemovalSentinel | None:
"""
Check for when the thing to replace is imported exactly.
@@ -171,7 +170,7 @@
def _check_import_from_parent(
self, original_node: ImportFrom, updated_node: ImportFrom
- ) -> Optional[Union[BaseSmallStatement, RemovalSentinel]]:
+ ) -> BaseSmallStatement | RemovalSentinel | None:
"""
Check for when the parent module of thing to replace is imported.
@@ -200,7 +199,7 @@
value=m.Name(module_name_str),
attr=m.Name(self.old_name),
)
- new_as_name: Optional[str] = None
+ new_as_name: str | None = None
if import_alias.evaluated_alias:
# The import alias would be the same before and after
# Add a `_` to differentiate the old alias from the new
one.
@@ -214,7 +213,7 @@
if self.old_parent_module_parts !=
self.new_parent_module_parts:
# import statement might need updating: build arguments for
# AddImportsVisitor and RemoveImportsVisitor to update
imports
- add_import_module: Optional[str] = None
+ add_import_module: str | None = None
if self.new_parent_module_parts:
add_import_module =
".".join(self.new_parent_module_parts)
self.context.scratch[self.ctx_key_add_import_kwargs] = {
@@ -223,7 +222,7 @@
"obj": self.new_parent_name,
"asname": new_as_name,
}
- remove_import_module: Optional[str] = None
+ remove_import_module: str | None = None
if self.old_parent_module_parts:
remove_import_module =
".".join(self.old_parent_module_parts)
self.context.scratch[self.ctx_key_remove_import_kwargs] = {
@@ -236,7 +235,7 @@
def _check_import_from_child(
self, original_node: ImportFrom, updated_node: ImportFrom
- ) -> Optional[Union[BaseSmallStatement, RemovalSentinel]]:
+ ) -> BaseSmallStatement | RemovalSentinel | None:
"""
Check import of a member of the module being codemodded.
@@ -275,7 +274,7 @@
self.context.scratch[self.ctx_key_import_scope] = scope
@property
- def import_scope(self) -> Optional[Scope]:
+ def import_scope(self) -> Scope | None:
return self.context.scratch.get(self.ctx_key_import_scope, None)
def update_imports(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod/visitors/models.py
new/django_codemod-2.4.5/src/django_codemod/visitors/models.py
--- old/django_codemod-2.3.5/src/django_codemod/visitors/models.py
2025-06-14 03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/visitors/models.py
2026-01-07 11:04:08.000000000 +0100
@@ -1,5 +1,4 @@
from collections.abc import Sequence
-from typing import Optional, Union
from libcst import (
Arg,
@@ -47,9 +46,7 @@
def leave_ImportFrom(
self, original_node: ImportFrom, updated_node: ImportFrom
- ) -> Union[
- BaseSmallStatement, FlattenSentinel[BaseSmallStatement],
RemovalSentinel
- ]:
+ ) -> BaseSmallStatement | FlattenSentinel[BaseSmallStatement] |
RemovalSentinel:
if isinstance(updated_node.names, ImportStar):
return super().leave_ImportFrom(original_node, updated_node)
if m.matches(
@@ -105,7 +102,7 @@
return matchers_list[0]
return m.OneOf(*iter(matchers_list))
- def visit_FunctionDef(self, node: FunctionDef) -> Optional[bool]:
+ def visit_FunctionDef(self, node: FunctionDef) -> bool | None:
for decorator in node.decorators:
if m.matches(decorator, self.decorator_matcher):
self.context.scratch[self.ctx_key_inside_method] = True
@@ -113,7 +110,7 @@
def leave_FunctionDef(
self, original_node: FunctionDef, updated_node: FunctionDef
- ) -> Union[BaseStatement, FlattenSentinel[BaseStatement], RemovalSentinel]:
+ ) -> BaseStatement | FlattenSentinel[BaseStatement] | RemovalSentinel:
if self.visiting_permalink_method:
for decorator in updated_node.decorators:
if m.matches(decorator, self.decorator_matcher):
@@ -136,9 +133,7 @@
def leave_Return(
self, original_node: Return, updated_node: Return
- ) -> Union[
- BaseSmallStatement, FlattenSentinel[BaseSmallStatement],
RemovalSentinel
- ]:
+ ) -> BaseSmallStatement | FlattenSentinel[BaseSmallStatement] |
RemovalSentinel:
if self.visiting_permalink_method and m.matches(
updated_node.value,
m.Tuple(), # type: ignore
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod/visitors/signals.py
new/django_codemod-2.4.5/src/django_codemod/visitors/signals.py
--- old/django_codemod-2.3.5/src/django_codemod/visitors/signals.py
2025-06-14 03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/visitors/signals.py
2026-01-07 11:04:08.000000000 +0100
@@ -1,4 +1,4 @@
-from typing import ClassVar, Optional
+from typing import ClassVar
from libcst import BaseExpression, Call, ImportFrom, ImportStar,
MaybeSentinel, Module
from libcst import matchers as m
@@ -45,7 +45,7 @@
self.context.scratch.pop(self.ctx_key_call_matchers, None)
return super().leave_Module(original_node, updated_node)
- def visit_ImportFrom(self, node: ImportFrom) -> Optional[bool]:
+ def visit_ImportFrom(self, node: ImportFrom) -> bool | None:
"""Set the `Call` matcher depending on which signals are imported.."""
if not import_from_matches(
node, ["django", "db", "models", "signals"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod/visitors/template_tags.py
new/django_codemod-2.4.5/src/django_codemod/visitors/template_tags.py
--- old/django_codemod-2.3.5/src/django_codemod/visitors/template_tags.py
2025-06-14 03:17:24.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod/visitors/template_tags.py
2026-01-07 11:04:08.000000000 +0100
@@ -1,5 +1,4 @@
from collections.abc import Generator, Sequence
-from typing import Optional, Union
from libcst import (
Assign,
@@ -29,11 +28,11 @@
ctx_key_decorator_matcher = f"{ctx_key_prefix}-decorator_matcher"
@property
- def library_call_matcher(self) -> Optional[m.Call]:
+ def library_call_matcher(self) -> m.Call | None:
return self.context.scratch.get(self.ctx_key_library_call_matcher,
None)
@property
- def decorators_matcher(self) -> Optional[m.BaseMatcherNode]:
+ def decorators_matcher(self) -> m.BaseMatcherNode | None:
return self.context.scratch.get(self.ctx_key_decorator_matcher, None)
def leave_Module(self, original_node: Module, updated_node: Module) ->
Module:
@@ -42,7 +41,7 @@
self.context.scratch.pop(self.ctx_key_decorator_matcher, None)
return super().leave_Module(original_node, updated_node)
- def visit_ImportFrom(self, node: ImportFrom) -> Optional[bool]:
+ def visit_ImportFrom(self, node: ImportFrom) -> bool | None:
"""Record whether an interesting import is detected."""
import_matcher = (
# django.template
@@ -54,7 +53,7 @@
self.context.scratch[self.ctx_key_library_call_matcher] =
import_matcher
return None
- def _template_import_matcher(self, node: ImportFrom) -> Optional[m.Call]:
+ def _template_import_matcher(self, node: ImportFrom) -> m.Call | None:
"""Return matcher if django.template is imported."""
imported_name_str = self._get_imported_name(node, "django.template")
if not imported_name_str:
@@ -66,7 +65,7 @@
)
)
- def _library_import_matcher(self, node: ImportFrom) -> Optional[m.Call]:
+ def _library_import_matcher(self, node: ImportFrom) -> m.Call | None:
"""Return matcher if django.template.Library is imported."""
imported_name_str = self._get_imported_name(node,
"django.template.Library")
if not imported_name_str:
@@ -75,7 +74,7 @@
return m.Call(func=m.Name(imported_name_str))
@staticmethod
- def _get_imported_name(node: ImportFrom, import_path: str) ->
Optional[str]:
+ def _get_imported_name(node: ImportFrom, import_path: str) -> str | None:
"""Resolve the imported name if present."""
if isinstance(node.names, ImportStar):
return None
@@ -92,7 +91,7 @@
return imported_name_str
return None
- def visit_Assign(self, node: Assign) -> Optional[bool]:
+ def visit_Assign(self, node: Assign) -> bool | None:
"""Record variable name the `Library()` call is assigned to."""
if self.library_call_matcher and m.matches(
node,
@@ -127,7 +126,7 @@
def leave_Decorator(
self, original_node: Decorator, updated_node: Decorator
- ) -> Union[Decorator, FlattenSentinel[Decorator], RemovalSentinel]:
+ ) -> Decorator | FlattenSentinel[Decorator] | RemovalSentinel:
"""Update decorator call if all conditions are met."""
if self.decorators_matcher and m.matches(updated_node,
self.decorators_matcher):
# If we have a decorator matcher, and it matches,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod.egg-info/PKG-INFO
new/django_codemod-2.4.5/src/django_codemod.egg-info/PKG-INFO
--- old/django_codemod-2.3.5/src/django_codemod.egg-info/PKG-INFO
2025-06-14 03:17:33.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod.egg-info/PKG-INFO
2026-01-07 11:04:18.000000000 +0100
@@ -1,9 +1,9 @@
Metadata-Version: 2.4
Name: django-codemod
-Version: 2.3.5
+Version: 2.4.5
Summary: A command line tool to automatically fix Django deprecations.
Author-email: Bruno Alla <[email protected]>
-License: MIT
+License-Expression: MIT
Project-URL: Bug Tracker, https://github.com/browniebroke/django-codemod/issues
Project-URL: Changelog,
https://django-codemod.readthedocs.io/en/stable/changelog.html
Project-URL: documentation, https://django-codemod.readthedocs.io
@@ -16,18 +16,18 @@
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
-Requires-Python: >=3.9
+Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
-Requires-Dist: click<9
-Requires-Dist: libcst==1.8.2
-Requires-Dist: pathspec<1,>=0.6
+Requires-Dist: click<8.4
+Requires-Dist: libcst==1.8.6
+Requires-Dist: pathspec<2,>=0.6
Requires-Dist: rich>=10
Requires-Dist: rich-click>=1
Dynamic: license-file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django_codemod-2.3.5/src/django_codemod.egg-info/requires.txt
new/django_codemod-2.4.5/src/django_codemod.egg-info/requires.txt
--- old/django_codemod-2.3.5/src/django_codemod.egg-info/requires.txt
2025-06-14 03:17:33.000000000 +0200
+++ new/django_codemod-2.4.5/src/django_codemod.egg-info/requires.txt
2026-01-07 11:04:18.000000000 +0100
@@ -1,5 +1,5 @@
-click<9
-libcst==1.8.2
-pathspec<1,>=0.6
+click<8.4
+libcst==1.8.6
+pathspec<2,>=0.6
rich>=10
rich-click>=1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django_codemod-2.3.5/tests/test_cli.py
new/django_codemod-2.4.5/tests/test_cli.py
--- old/django_codemod-2.3.5/tests/test_cli.py 2025-06-14 03:17:24.000000000
+0200
+++ new/django_codemod-2.4.5/tests/test_cli.py 2026-01-07 11:04:08.000000000
+0100
@@ -95,7 +95,7 @@
)
assert result.exit_code == 0
- assert "djcodemod list" in result.output
+ assert "Automatically fixes deprecations" in result.output
@pytest.mark.parametrize(