This repository was archived by the owner on Nov 3, 2023. It is now read-only.
File tree 5 files changed +41
-30
lines changed
5 files changed +41
-30
lines changed Original file line number Diff line number Diff line change 26
26
from .utils import (
27
27
common_prefix_length ,
28
28
is_blank ,
29
- is_fstring ,
30
29
log ,
31
30
pairwise ,
32
- safe_literal_eval ,
33
31
strip_non_alphanumeric ,
34
32
)
35
33
from .wordlists import IMPERATIVE_BLACKLIST , IMPERATIVE_VERBS , stem
@@ -46,6 +44,27 @@ def decorator(f):
46
44
return decorator
47
45
48
46
47
+ FSTRING_REGEX = re (r'^([rR]?)[fF]' )
48
+
49
+
50
+ def is_fstring (docstring ):
51
+ """Return True if docstring is an f-string."""
52
+ return FSTRING_REGEX .match (str (docstring ))
53
+
54
+
55
+ def safe_literal_eval (string ):
56
+ """Safely evaluate a literal even if it is an fstring."""
57
+ try :
58
+ return ast .literal_eval (string )
59
+ except ValueError as error :
60
+ # If the docstring is a fstring, it is
61
+ # not considered a valid docstring. See
62
+ # https://bugs.python.org/issue28739
63
+ raise ParseError (
64
+ info = "f-strings are not valid as docstrings."
65
+ ) from error
66
+
67
+
49
68
class ConventionChecker :
50
69
"""Checker for PEP 257, NumPy and Google conventions.
51
70
Original file line number Diff line number Diff line change 30
30
class ParseError (Exception ):
31
31
"""An error parsing contents of a Python file."""
32
32
33
+ def __init__ (self , info = "" ):
34
+ """Initialize the error with a more specific message."""
35
+ self .info = info
36
+
33
37
def __str__ (self ):
34
- return "Cannot parse file."
38
+ return f "Cannot parse file. { self . info } " . strip ()
35
39
36
40
37
41
class UnexpectedTokenError (ParseError ):
Original file line number Diff line number Diff line change 1
1
"""General shared utilities."""
2
- import ast
3
2
import logging
4
3
import re
5
4
from itertools import tee , zip_longest
@@ -47,24 +46,3 @@ def common_prefix_length(a: str, b: str) -> int:
47
46
def strip_non_alphanumeric (string : str ) -> str :
48
47
"""Strip string from any non-alphanumeric characters."""
49
48
return NON_ALPHANUMERIC_STRIP_RE .sub ('' , string )
50
-
51
-
52
- FSTRING_REGEX = re .compile (r'^([rR]?)[fF]' )
53
-
54
-
55
- def is_fstring (docstring ):
56
- """Return True if docstring is an f-string."""
57
- return FSTRING_REGEX .match (str (docstring ))
58
-
59
-
60
- def safe_literal_eval (string ):
61
- """Safely evaluate a literal even if it is an fstring."""
62
- try :
63
- return ast .literal_eval (string )
64
- except ValueError :
65
- # In case we hit a value error due to an fstring
66
- # we do a literal eval by subtituting the fstring
67
- # with a normal string.
68
- # We keep the first captured group if any. This includes
69
- # the raw identifiers (r/R) and replace f/F with a blank.
70
- return ast .literal_eval (FSTRING_REGEX .sub (r"\1" , string ))
Original file line number Diff line number Diff line change @@ -50,8 +50,3 @@ def fstring_with_other_errors(arg=1, missing_arg=2):
50
50
@D303
51
51
def fstring_with_blank_doc_string ():
52
52
f""" """
53
-
54
-
55
- @expect ("D103: Missing docstring in public function" )
56
- def fstring_with_ignores (): # noqa: D303
57
- f""" """
Original file line number Diff line number Diff line change @@ -571,6 +571,21 @@ def foo():
571
571
assert code == 0
572
572
573
573
574
+ def test_fstring_excluded (env ):
575
+ """Test excluding D303 fstring error."""
576
+ with env .open ('example.py' , 'wt' ) as example :
577
+ example .write (textwrap .dedent ("""\
578
+ def foo(): # noqa: D303
579
+ f'''Test'''
580
+ """ ))
581
+
582
+ env .write_config (add_ignore = "D100" )
583
+ out , err , code = env .invoke ()
584
+ assert code == 1
585
+ assert out == ""
586
+ assert "f-strings are not valid as docstrings." in err
587
+
588
+
574
589
def test_empty_select_with_added_error (env ):
575
590
"""Test excluding all errors but one."""
576
591
with env .open ('example.py' , 'wt' ) as example :
You can’t perform that action at this time.
0 commit comments