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

[DTZ] Improve docs for call-datetime-without-tzinfo (DTZ005) #10590

Closed
wants to merge 4 commits into from

Conversation

cclauss
Copy link
Contributor

@cclauss cclauss commented Mar 25, 2024

Copy link
Contributor

github-actions bot commented Mar 25, 2024

ruff-ecosystem results

Linter (stable)

ℹ️ ecosystem check detected linter changes. (+109 -109 violations, +0 -0 fixes in 2 projects; 42 projects unchanged)

apache/airflow (+100 -100 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --no-preview --select ALL

- airflow/providers/amazon/aws/hooks/s3.py:699:34: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/hooks/s3.py:699:34: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/hooks/s3.py:714:38: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/hooks/s3.py:714:38: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/hooks/s3.py:738:34: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/hooks/s3.py:738:34: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:291:39: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:291:39: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:301:43: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:301:43: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:319:44: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:319:44: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:322:39: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:322:39: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:300:25: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:300:25: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:307:25: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:307:25: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/fab/auth_manager/security_manager/override.py:1641:31: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/fab/auth_manager/security_manager/override.py:1641:31: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/google/cloud/hooks/bigquery.py:1554:14: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/google/cloud/hooks/bigquery.py:1554:14: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/google/cloud/sensors/gcs.py:383:12: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/google/cloud/sensors/gcs.py:383:12: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/google/cloud/triggers/gcs.py:385:16: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/google/cloud/triggers/gcs.py:385:16: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/openlineage/plugins/listener.py:110:84: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/openlineage/plugins/listener.py:110:84: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/openlineage/plugins/listener.py:178:78: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/openlineage/plugins/listener.py:178:78: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/openlineage/plugins/listener.py:233:78: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/openlineage/plugins/listener.py:233:78: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/timetables/interval.py:215:15: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/timetables/interval.py:215:15: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2036:96: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2036:96: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2046:28: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2046:28: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2058:72: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2058:72: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/testing_commands.py:223:24: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/testing_commands.py:223:24: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/params/common_build_params.py:131:15: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/params/common_build_params.py:131:15: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/perf/dags/elastic_dag.py:155:14: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
... 155 additional changes omitted for project

bokeh/bokeh (+9 -9 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --no-preview --select ALL

- docs/bokeh/source/docs/first_steps/examples/first_steps_4_datetime_axis.py:8:11: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ docs/bokeh/source/docs/first_steps/examples/first_steps_4_datetime_axis.py:8:11: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- examples/basic/data/server_sent_events_source.py:55:17: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ examples/basic/data/server_sent_events_source.py:55:17: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- examples/server/app/faces/main.py:53:6: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ examples/server/app/faces/main.py:53:6: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- examples/server/app/faces/main.py:82:16: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ examples/server/app/faces/main.py:82:16: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- src/bokeh/events.py:242:26: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ src/bokeh/events.py:242:26: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
... 8 additional changes omitted for project

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
DTZ005 218 109 109 0 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+109 -109 violations, +0 -0 fixes in 2 projects; 42 projects unchanged)

apache/airflow (+100 -100 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- airflow/providers/amazon/aws/hooks/s3.py:699:34: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/hooks/s3.py:699:34: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/hooks/s3.py:714:38: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/hooks/s3.py:714:38: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/hooks/s3.py:738:34: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/hooks/s3.py:738:34: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:291:39: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:291:39: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:301:43: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:301:43: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:319:44: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:319:44: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/amazon/aws/sensors/s3.py:322:39: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/amazon/aws/sensors/s3.py:322:39: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:300:25: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:300:25: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:307:25: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py:307:25: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/fab/auth_manager/security_manager/override.py:1641:31: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/fab/auth_manager/security_manager/override.py:1641:31: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/google/cloud/hooks/bigquery.py:1554:14: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/google/cloud/hooks/bigquery.py:1554:14: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/google/cloud/sensors/gcs.py:383:12: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/google/cloud/sensors/gcs.py:383:12: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/google/cloud/triggers/gcs.py:385:16: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/google/cloud/triggers/gcs.py:385:16: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/openlineage/plugins/listener.py:110:84: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/openlineage/plugins/listener.py:110:84: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/openlineage/plugins/listener.py:178:78: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/openlineage/plugins/listener.py:178:78: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/providers/openlineage/plugins/listener.py:233:78: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/providers/openlineage/plugins/listener.py:233:78: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- airflow/timetables/interval.py:215:15: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ airflow/timetables/interval.py:215:15: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2036:96: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2036:96: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2046:28: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2046:28: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2058:72: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/release_management_commands.py:2058:72: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/commands/testing_commands.py:223:24: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/commands/testing_commands.py:223:24: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/breeze/src/airflow_breeze/params/common_build_params.py:131:15: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ dev/breeze/src/airflow_breeze/params/common_build_params.py:131:15: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- dev/perf/dags/elastic_dag.py:155:14: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
... 155 additional changes omitted for project

bokeh/bokeh (+9 -9 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- docs/bokeh/source/docs/first_steps/examples/first_steps_4_datetime_axis.py:8:11: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ docs/bokeh/source/docs/first_steps/examples/first_steps_4_datetime_axis.py:8:11: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- examples/basic/data/server_sent_events_source.py:55:17: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ examples/basic/data/server_sent_events_source.py:55:17: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- examples/server/app/faces/main.py:53:6: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ examples/server/app/faces/main.py:53:6: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- examples/server/app/faces/main.py:82:16: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ examples/server/app/faces/main.py:82:16: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
- src/bokeh/events.py:242:26: DTZ005 The use of `datetime.datetime.now()` without `tz` argument is not allowed
+ src/bokeh/events.py:242:26: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
... 8 additional changes omitted for project

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
DTZ005 218 109 109 0 0

@cclauss cclauss changed the title Update call_datetime_now_without_tzinfo.rs [DTZ] Update call_datetime_now_without_tzinfo.rs DTZ005 Mar 26, 2024
@MichaReiser MichaReiser added the documentation Improvements or additions to documentation label Mar 26, 2024
@AlexWaygood
Copy link
Member

AlexWaygood commented Mar 26, 2024

Hmm, I'm not sure about just adding a paragraph at the bottom. Possibly you could argue that the first sentence of the documentation for this rule is wrong:

Checks for usage of datetime.datetime.now() without a tz argument.

In reality, it does more than that, since it also emits an error if you explicitly pass tz=None. Probably it would be more accurate to say:

Checks for usages of datetime.datetime.now() that do not specify a timezone.

Then we could explain in the body of the rule's documentation why tz=None is, from the perspective of this rule, the same antipattern as failing to pass a tz= argument at all.

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Could you also change the error message? It's currently

"The use of datetime.datetime.now() without tz argument is not allowed"

It should be

"Using datetime.datetime.now() without specifying a timezone is not allowed"

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@AlexWaygood AlexWaygood changed the title [DTZ] Update call_datetime_now_without_tzinfo.rs DTZ005 [DTZ] Improve docs for call-datetime-without-tzinfo (DTZ005) Mar 26, 2024
@AlexWaygood AlexWaygood enabled auto-merge (squash) March 26, 2024 12:37
@cclauss
Copy link
Contributor Author

cclauss commented Mar 26, 2024

We have lost this helpful hint from the original commit...

For a timezone-aware datetime for the machine's timezone, use:
datetime.datetime.now(tz=datetime.timezone.utc).astimezone()

@AlexWaygood
Copy link
Member

We have lost this helpful hint from the original commit...

For a timezone-aware datetime for the machine's timezone, use:
datetime.datetime.now(tz=datetime.timezone.utc).astimezone()

Right. I think that could be worked into the docs somewhere; I agree that it's useful.

I'm also wondering if we could tailor the error message to the specific thing that the user is doing wrong. Something like this?

--- a/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs
+++ b/crates/ruff_linter/src/rules/flake8_datetimez/rules/call_datetime_now_without_tzinfo.rs
@@ -1,3 +1,5 @@
+use std::fmt;
+
 use ruff_diagnostics::{Diagnostic, Violation};
 use ruff_macros::{derive_message_formats, violation};
 
@@ -6,7 +8,6 @@ use ruff_python_semantic::Modules;
 use ruff_text_size::Ranged;
 
 use crate::checkers::ast::Checker;
-use crate::rules::flake8_datetimez::rules::helpers::has_non_none_keyword;
 
 use super::helpers;
 
@@ -48,12 +49,28 @@ use super::helpers;
 /// ## References
 /// - [Python documentation: Aware and Naive Objects](https://docs.python.org/3/library/datetime.html#aware-and-naive-objects)
 #[violation]
-pub struct CallDatetimeNowWithoutTzinfo;
+pub struct CallDatetimeNowWithoutTzinfo(DatetimeNowAntipattern);
 
 impl Violation for CallDatetimeNowWithoutTzinfo {
     #[derive_message_formats]
     fn message(&self) -> String {
-        format!("Using `datetime.datetime.now()` without specifying a timezone is not allowed")
+        let CallDatetimeNowWithoutTzinfo(antipattern) = self;
+        format!("{antipattern} is not allowed")
+    }
+}
+
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
+enum DatetimeNowAntipattern {
+    NoTzArgumentPassed,
+    NonePassedToTzArgument,
+}
+
+impl fmt::Display for DatetimeNowAntipattern {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(match self {
+            Self::NoTzArgumentPassed => "Using `datetime.datetime.now()` without a `tz=` argument",
+            Self::NonePassedToTzArgument => "Passing `tz=None` to `datetime.datetime.now()`",
+        })
     }
 }
 
@@ -78,9 +95,10 @@ pub(crate) fn call_datetime_now_without_tzinfo(checker: &mut Checker, call: &ast
 
     // no args / no args unqualified
     if call.arguments.args.is_empty() && call.arguments.keywords.is_empty() {
-        checker
-            .diagnostics
-            .push(Diagnostic::new(CallDatetimeNowWithoutTzinfo, call.range()));
+        checker.diagnostics.push(Diagnostic::new(
+            CallDatetimeNowWithoutTzinfo(DatetimeNowAntipattern::NoTzArgumentPassed),
+            call.range(),
+        ));
         return;
     }
 
@@ -91,16 +109,24 @@ pub(crate) fn call_datetime_now_without_tzinfo(checker: &mut Checker, call: &ast
         .first()
         .is_some_and(Expr::is_none_literal_expr)
     {
-        checker
-            .diagnostics
-            .push(Diagnostic::new(CallDatetimeNowWithoutTzinfo, call.range()));
+        checker.diagnostics.push(Diagnostic::new(
+            CallDatetimeNowWithoutTzinfo(DatetimeNowAntipattern::NonePassedToTzArgument),
+            call.range(),
+        ));
         return;
     }
 
-    // wrong keywords / none keyword
-    if !call.arguments.keywords.is_empty() && !has_non_none_keyword(&call.arguments, "tz") {
-        checker
-            .diagnostics
-            .push(Diagnostic::new(CallDatetimeNowWithoutTzinfo, call.range()));
+    if let Some(keyword_argument) = call.arguments.find_keyword("tz") {
+        if keyword_argument.value.is_none_literal_expr() {
+            checker.diagnostics.push(Diagnostic::new(
+                CallDatetimeNowWithoutTzinfo(DatetimeNowAntipattern::NonePassedToTzArgument),
+                call.range(),
+            ));
+        }
+    } else {
+        checker.diagnostics.push(Diagnostic::new(
+            CallDatetimeNowWithoutTzinfo(DatetimeNowAntipattern::NoTzArgumentPassed),
+            call.range(),
+        ));
     }
 }
diff --git a/crates/ruff_linter/src/rules/flake8_datetimez/snapshots/ruff_linter__rules__flake8_datetimez__tests__DTZ005_DTZ005.py.snap b/crates/ruff_linter/src/rules/flake8_datetimez/snapshots/ruff_linter__rules__flake8_datetimez__tests__DTZ005_DTZ005.py.snap
index 2f24cc4dc..d79264aad 100644
--- a/crates/ruff_linter/src/rules/flake8_datetimez/snapshots/ruff_linter__rules__flake8_datetimez__tests__DTZ005_DTZ005.py.snap
+++ b/crates/ruff_linter/src/rules/flake8_datetimez/snapshots/ruff_linter__rules__flake8_datetimez__tests__DTZ005_DTZ005.py.snap
@@ -1,7 +1,7 @@
 ---
 source: crates/ruff_linter/src/rules/flake8_datetimez/mod.rs
 ---
-DTZ005.py:4:1: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
+DTZ005.py:4:1: DTZ005 Using `datetime.datetime.now()` without a `tz=` argument is not allowed
   |
 3 | # no args
 4 | datetime.datetime.now()
@@ -10,7 +10,7 @@ DTZ005.py:4:1: DTZ005 Using `datetime.datetime.now()` without specifying a timez
 6 | # wrong keywords
   |
 
-DTZ005.py:7:1: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
+DTZ005.py:7:1: DTZ005 Using `datetime.datetime.now()` without a `tz=` argument is not allowed
   |
 6 | # wrong keywords
 7 | datetime.datetime.now(bad=datetime.timezone.utc)
@@ -19,7 +19,7 @@ DTZ005.py:7:1: DTZ005 Using `datetime.datetime.now()` without specifying a timez
 9 | # none args
   |
 
-DTZ005.py:10:1: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
+DTZ005.py:10:1: DTZ005 Passing `tz=None` to `datetime.datetime.now()` is not allowed
    |
  9 | # none args
 10 | datetime.datetime.now(None)
@@ -28,7 +28,7 @@ DTZ005.py:10:1: DTZ005 Using `datetime.datetime.now()` without specifying a time
 12 | # none keywords
    |
 
-DTZ005.py:13:1: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
+DTZ005.py:13:1: DTZ005 Passing `tz=None` to `datetime.datetime.now()` is not allowed
    |
 12 | # none keywords
 13 | datetime.datetime.now(tz=None)
@@ -37,7 +37,7 @@ DTZ005.py:13:1: DTZ005 Using `datetime.datetime.now()` without specifying a time
 15 | from datetime import datetime
    |
 
-DTZ005.py:18:1: DTZ005 Using `datetime.datetime.now()` without specifying a timezone is not allowed
+DTZ005.py:18:1: DTZ005 Using `datetime.datetime.now()` without a `tz=` argument is not allowed
    |
 17 | # no args unqualified
 18 | datetime.now()

(I'm happy to push that straight to your branch if you like it, since I've already tried it out locally!)

@charliermarsh
Copy link
Member

I'm gonna defer to Alex on the actual copy, but I'll note that similar changes may need to be applied to the other DTZ rules which enforce the ~same thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DTZ005 false postitive for tz=None
4 participants