Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite django.utils.timezone.utc to datetime.timezone.utc #169

Merged
merged 2 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
History
=======

* Support Django 4.1 as a target version.

* Add Django 4.1+ fixer to rewrite imports of ``utc`` from ``django.utils.timezone`` to use
``datetime.timezone``.

Thanks to Hasan Ramezani in `PR #140 <https://github.com/adamchainz/django-upgrade/pull/140>`__.

1.7.0 (2022-05-11)
------------------

Expand Down
15 changes: 15 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -435,3 +435,18 @@ Django 4.0

There are no fixers for Django 4.0 at current.
Most of its deprecations don’t seem automatically fixable.

Django 4.1
----------

`Release Notes <https://docs.djangoproject.com/en/4.1/releases/4.1/#features-deprecated-in-4-1>`__

``django.utils.timezone.utc`` deprecations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Rewrites imports of ``utc`` from ``django.utils.timezone`` to use ``datetime.timezone``.

.. code-block:: diff

-from django.utils.timezone import utc
+from datetime.timezone import utc
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ classifiers =
Framework :: Django :: 3.1
Framework :: Django :: 3.2
Framework :: Django :: 4.0
Framework :: Django :: 4.1
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Natural Language :: English
Expand Down
43 changes: 43 additions & 0 deletions src/django_upgrade/fixers/utils_timezone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Replace django.utils.timezone.utc with datetime.timezone.utc
https://docs.djangoproject.com/en/4.1/releases/4.1/#id2
"""
from __future__ import annotations

import ast
from functools import partial
from typing import Iterable

from tokenize_rt import Offset

from django_upgrade.ast import ast_start_offset, is_rewritable_import_from
from django_upgrade.data import Fixer, State, TokenFunc
from django_upgrade.tokens import update_import_modules

fixer = Fixer(
__name__,
min_version=(4, 1),
)

MODULE = "django.utils.timezone"
MODULE_REWRITES = {
"utc": "datetime.timezone",
}


@fixer.register(ast.ImportFrom)
def visit_ImportFrom(
state: State,
node: ast.ImportFrom,
parent: ast.AST,
) -> Iterable[tuple[Offset, TokenFunc]]:
if (
node.module == MODULE
and is_rewritable_import_from(node)
and any(alias.name == "utc" for alias in node.names)
):
yield ast_start_offset(node), partial(
update_import_modules,
node=node,
module_rewrites=MODULE_REWRITES,
)
1 change: 1 addition & 0 deletions src/django_upgrade/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def main(argv: Sequence[str] | None = None) -> int:
"3.1",
"3.2",
"4.0",
"4.1",
],
)
parser.add_argument(
Expand Down
48 changes: 48 additions & 0 deletions tests/fixers/test_utils_timezone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from __future__ import annotations

from django_upgrade.data import Settings
from tests.fixers.tools import check_noop, check_transformed

settings = Settings(target_version=(4, 1))


def test_unmatched_import():
check_noop(
"""\
from datetime.timezone import utc
""",
settings,
)


def test_unmatched_import_name():
check_noop(
"""\
from django.utils.timezone import now
""",
settings,
)


def test_unrecognized_import_format():
check_noop(
"""\
from django.utils import timezone

def foo():
print(timezone.utc)
""",
settings,
)


def test_fixed():
check_transformed(
"""\
from django.utils.timezone import utc
""",
"""\
from datetime.timezone import utc
""",
settings,
)