Skip to content

Commit

Permalink
Allow f-strings with %z for DTZ007 (#10651)
Browse files Browse the repository at this point in the history
## Summary

This PR fixes the bug for `DTZ007` rule where it didn't consider to
check for the presence of `%z` in f-strings. It also considers the
string parts of an implicitly concatenated f-strings for which I want to
find a better solution (#10308).

fixes: #10601 

## Test Plan

Add test cases and update the snapshots.
  • Loading branch information
dhruvmanila committed Mar 29, 2024
1 parent a0263ab commit 1bcdfe2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@

# no replace orastimezone unqualified
datetime.strptime("something", "something")

# F-strings
datetime.strptime("something", f"%Y-%m-%dT%H:%M:%S{('.%f' if millis else '')}%z")
datetime.strptime("something", f"%Y-%m-%d %H:%M:%S%z")
# F-string is implicitly concatenated to another string
datetime.strptime("something", f"%Y-%m-%dT%H:%M:%S{('.%f' if millis else '')}" "%z")
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,30 @@ pub(crate) fn call_datetime_strptime_without_zone(checker: &mut Checker, call: &
}

// Does the `strptime` call contain a format string with a timezone specifier?
if let Some(Expr::StringLiteral(ast::ExprStringLiteral { value: format, .. })) =
call.arguments.args.get(1).as_ref()
{
if format.to_str().contains("%z") {
return;
if let Some(expr) = call.arguments.args.get(1) {
match expr {
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => {
if value.to_str().contains("%z") {
return;
}
}
Expr::FString(ast::ExprFString { value, .. }) => {
for f_string_part in value {
match f_string_part {
ast::FStringPart::Literal(string) => {
if string.contains("%z") {
return;
}
}
ast::FStringPart::FString(f_string) => {
if f_string.literals().any(|literal| literal.contains("%z")) {
return;
}
}
}
}
}
_ => {}
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,7 @@ DTZ007.py:35:1: DTZ007 Naive datetime constructed using `datetime.datetime.strpt
34 | # no replace orastimezone unqualified
35 | datetime.strptime("something", "something")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DTZ007
36 |
37 | # F-strings
|
= help: Call `.replace(tzinfo=<timezone>)` or `.astimezone()` to convert to an aware datetime

0 comments on commit 1bcdfe2

Please sign in to comment.