Skip to content

Commit a77f0c1

Browse files
Respect py-version for inconsistent-quotes inside f-strings (#9152) (#9155)
* [inconsistent-quotes] Emit for f-strings for 3.12 only * Add docs for inconsistent-quotes with f-strings Despite ``sys.version`` check, pylint raises the warning with Python 3.11 (cherry picked from commit 1c0bc70) Co-authored-by: theirix <[email protected]>
1 parent a9d9dc3 commit a77f0c1

9 files changed

+54
-0
lines changed

doc/whatsnew/fragments/9113.bugfix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Emit ``inconsistent-quotes`` for f-strings with 3.12 interpreter only if targeting pre-3.12 versions.
2+
3+
Closes #9113

pylint/checkers/strings.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import collections
1010
import re
11+
import sys
1112
import tokenize
1213
from collections import Counter
1314
from collections.abc import Iterable, Sequence
@@ -834,8 +835,22 @@ def check_for_consistent_string_delimiters(
834835
"""
835836
string_delimiters: Counter[str] = collections.Counter()
836837

838+
inside_fstring = False # whether token is inside f-string (since 3.12)
839+
target_py312 = self.linter.config.py_version >= (3, 12)
840+
837841
# First, figure out which quote character predominates in the module
838842
for tok_type, token, _, _, _ in tokens:
843+
if sys.version_info[:2] >= (3, 12):
844+
# pylint: disable=no-member,useless-suppression
845+
if tok_type == tokenize.FSTRING_START:
846+
inside_fstring = True
847+
elif tok_type == tokenize.FSTRING_END:
848+
inside_fstring = False
849+
850+
if inside_fstring and not target_py312:
851+
# skip analysis of f-string contents
852+
continue
853+
839854
if tok_type == tokenize.STRING and _is_quote_delimiter_chosen_freely(token):
840855
string_delimiters[_get_quote_delimiter(token)] += 1
841856

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# pylint: disable=missing-module-docstring
2+
3+
dictionary = {'0': 0}
4+
f_string = f'{dictionary["0"]}'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[STRING]
2+
check-quote-consistency=yes
3+
4+
[testoptions]
5+
max_pyver=3.12
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# pylint: disable=missing-module-docstring
2+
3+
dictionary = {'0': 0}
4+
# quotes are inconsistent when targetting Python 3.12 (use single quotes)
5+
f_string = f'{dictionary["0"]}' # [inconsistent-quotes]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[STRING]
2+
check-quote-consistency=yes
3+
4+
[main]
5+
py-version=3.12
6+
7+
[testoptions]
8+
min_pyver=3.12
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
inconsistent-quotes:5:0:None:None::"Quote delimiter "" is inconsistent with the rest of the file":UNDEFINED
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# pylint: disable=missing-module-docstring
2+
3+
dictionary = {'0': 0}
4+
# quotes are consistent when targetting 3.11 and earlier (cannot use single quotes here)
5+
f_string = f'{dictionary["0"]}'
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[STRING]
2+
check-quote-consistency=yes
3+
4+
[main]
5+
py-version=3.11
6+
7+
[testoptions]
8+
min_pyver=3.12

0 commit comments

Comments
 (0)