mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:53 +00:00
Allow f-strings with %z
for DTZ007
(#10651)
## 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.
This commit is contained in:
parent
a0263ab472
commit
1bcdfe268d
3 changed files with 32 additions and 5 deletions
|
@ -33,3 +33,9 @@ from datetime import datetime
|
||||||
|
|
||||||
# no replace orastimezone unqualified
|
# no replace orastimezone unqualified
|
||||||
datetime.strptime("something", "something")
|
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")
|
||||||
|
|
|
@ -102,12 +102,31 @@ pub(crate) fn call_datetime_strptime_without_zone(checker: &mut Checker, call: &
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the `strptime` call contain a format string with a timezone specifier?
|
// Does the `strptime` call contain a format string with a timezone specifier?
|
||||||
if let Some(Expr::StringLiteral(ast::ExprStringLiteral { value: format, .. })) =
|
if let Some(expr) = call.arguments.args.get(1) {
|
||||||
call.arguments.args.get(1).as_ref()
|
match expr {
|
||||||
{
|
Expr::StringLiteral(ast::ExprStringLiteral { value, .. }) => {
|
||||||
if format.to_str().contains("%z") {
|
if value.to_str().contains("%z") {
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let semantic = checker.semantic();
|
let semantic = checker.semantic();
|
||||||
|
|
|
@ -46,5 +46,7 @@ DTZ007.py:35:1: DTZ007 Naive datetime constructed using `datetime.datetime.strpt
|
||||||
34 | # no replace orastimezone unqualified
|
34 | # no replace orastimezone unqualified
|
||||||
35 | datetime.strptime("something", "something")
|
35 | datetime.strptime("something", "something")
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DTZ007
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DTZ007
|
||||||
|
36 |
|
||||||
|
37 | # F-strings
|
||||||
|
|
|
|
||||||
= help: Call `.replace(tzinfo=<timezone>)` or `.astimezone()` to convert to an aware datetime
|
= help: Call `.replace(tzinfo=<timezone>)` or `.astimezone()` to convert to an aware datetime
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue