From 61532e8aad0608918cce8375e9409d848215305e Mon Sep 17 00:00:00 2001 From: Konrad Listwan-Ciesielski Date: Mon, 7 Aug 2023 08:21:14 +0700 Subject: [PATCH] Add `DTZ003` and `DTZ004` docs (#6223) Changes: - Fixes typo and repeated phrase in `DTZ002` - Adds docs for `DTZ003` - Adds docs for `DTZ004` - Adds example for <=Python3.10 in `DTZ001` Related to: https://github.com/astral-sh/ruff/issues/2646 --- .../rules/call_datetime_today.rs | 5 +- .../rules/call_datetime_utcfromtimestamp.rs | 46 +++++++++++++++---- .../rules/call_datetime_utcnow.rs | 44 ++++++++++++++---- .../rules/call_datetime_without_tzinfo.rs | 7 +++ 4 files changed, 82 insertions(+), 20 deletions(-) diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs index 97db9e874c763..d1b89c794d0de 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_today.rs @@ -18,9 +18,8 @@ use super::helpers; /// `datetime` objects are preferred, as they represent a specific moment in /// time, unlike "naive" objects. /// -/// `datetime.datetime.today()` crates a "naive" object; instead, use -/// instead, use `datetime.datetime.now(tz=)` to create a timezone-aware -/// object. +/// `datetime.datetime.today()` creates a "naive" object; instead, use +/// `datetime.datetime.now(tz=)` to create a timezone-aware object. /// /// ## Example /// ```python diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs index 6c060dd1bde08..26536d3c5cff7 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcfromtimestamp.rs @@ -8,6 +8,43 @@ use crate::checkers::ast::Checker; use super::helpers; +/// ## What it does +/// Checks for usage of `datetime.datetime.utcfromtimestamp()`. +/// +/// ## Why is this bad? +/// Python datetime objects can be naive or timezone-aware. While an aware +/// object represents a specific moment in time, a naive object does not +/// contain enough information to unambiguously locate itself relative to other +/// datetime objects. Since this can lead to errors, it is recommended to +/// always use timezone-aware objects. +/// +/// `datetime.datetime.utcfromtimestamp()` returns a naive datetime object; +/// instead, use `datetime.datetime.fromtimestamp(ts, tz=)` to return a +/// timezone-aware object. +/// +/// ## Example +/// ```python +/// import datetime +/// +/// datetime.datetime.utcfromtimestamp() +/// ``` +/// +/// Use instead: +/// ```python +/// import datetime +/// +/// datetime.datetime.fromtimestamp(946684800, tz=datetime.timezone.utc) +/// ``` +/// +/// Or, for Python 3.11 and later: +/// ```python +/// import datetime +/// +/// datetime.datetime.fromtimestamp(946684800, tz=datetime.UTC) +/// ``` +/// +/// ## References +/// - [Python documentation: Aware and Naive Objects](https://docs.python.org/3/library/datetime.html#aware-and-naive-objects) #[violation] pub struct CallDatetimeUtcfromtimestamp; @@ -21,15 +58,6 @@ impl Violation for CallDatetimeUtcfromtimestamp { } } -/// Checks for `datetime.datetime.utcfromtimestamp()`. (DTZ004) -/// -/// ## Why is this bad? -/// -/// Because naive `datetime` objects are treated by many `datetime` methods as -/// local times, it is preferred to use aware datetimes to represent times in -/// UTC. As such, the recommended way to create an object representing a -/// specific timestamp in UTC is by calling `datetime.fromtimestamp(timestamp, -/// tz=timezone.utc)`. pub(crate) fn call_datetime_utcfromtimestamp( checker: &mut Checker, func: &Expr, diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs index 0ea5136b7f0c3..e9ff0dd363180 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_utcnow.rs @@ -8,6 +8,42 @@ use crate::checkers::ast::Checker; use super::helpers; +/// ## What it does +/// Checks for usage of `datetime.datetime.utcnow()`. +/// +/// ## Why is this bad? +/// Python datetime objects can be naive or timezone-aware. While an aware +/// object represents a specific moment in time, a naive object does not +/// contain enough information to unambiguously locate itself relative to other +/// datetime objects. Since this can lead to errors, it is recommended to +/// always use timezone-aware objects. +/// +/// `datetime.datetime.utcnow()` returns a naive datetime object; instead, use +/// `datetime.datetime.now(tz=)` to return a timezone-aware object. +/// +/// ## Example +/// ```python +/// import datetime +/// +/// datetime.datetime.utcnow() +/// ``` +/// +/// Use instead: +/// ```python +/// import datetime +/// +/// datetime.datetime.now(tz=datetime.timezone.utc) +/// ``` +/// +/// Or, for Python 3.11 and later: +/// ```python +/// import datetime +/// +/// datetime.datetime.now(tz=datetime.UTC) +/// ``` +/// +/// ## References +/// - [Python documentation: Aware and Naive Objects](https://docs.python.org/3/library/datetime.html#aware-and-naive-objects) #[violation] pub struct CallDatetimeUtcnow; @@ -21,14 +57,6 @@ impl Violation for CallDatetimeUtcnow { } } -/// Checks for `datetime.datetime.today()`. (DTZ003) -/// -/// ## Why is this bad? -/// -/// Because naive `datetime` objects are treated by many `datetime` methods as -/// local times, it is preferred to use aware datetimes to represent times in -/// UTC. As such, the recommended way to create an object representing the -/// current time in UTC is by calling `datetime.now(timezone.utc)`. pub(crate) fn call_datetime_utcnow(checker: &mut Checker, func: &Expr, location: TextRange) { if !checker .semantic() diff --git a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs index 0c0f6b36f44d8..cc0cb486a23f2 100644 --- a/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs +++ b/crates/ruff/src/rules/flake8_datetimez/rules/call_datetime_without_tzinfo.rs @@ -31,6 +31,13 @@ use super::helpers; /// ```python /// import datetime /// +/// datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc) +/// ``` +/// +/// Or, for Python 3.11 and later: +/// ```python +/// import datetime +/// /// datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=datetime.UTC) /// ``` #[violation]