This repository was archived by the owner on Nov 3, 2023. It is now read-only.
File tree Expand file tree Collapse file tree 5 files changed +41
-30
lines changed Expand file tree Collapse file tree 5 files changed +41
-30
lines changed Original file line number Diff line number Diff line change 2626from .utils import (
2727 common_prefix_length ,
2828 is_blank ,
29- is_fstring ,
3029 log ,
3130 pairwise ,
32- safe_literal_eval ,
3331 strip_non_alphanumeric ,
3432)
3533from .wordlists import IMPERATIVE_BLACKLIST , IMPERATIVE_VERBS , stem
@@ -46,6 +44,27 @@ def decorator(f):
4644 return decorator
4745
4846
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+
4968class ConventionChecker :
5069 """Checker for PEP 257, NumPy and Google conventions.
5170
Original file line number Diff line number Diff line change 3030class ParseError (Exception ):
3131 """An error parsing contents of a Python file."""
3232
33+ def __init__ (self , info = "" ):
34+ """Initialize the error with a more specific message."""
35+ self .info = info
36+
3337 def __str__ (self ):
34- return "Cannot parse file."
38+ return f "Cannot parse file. { self . info } " . strip ()
3539
3640
3741class UnexpectedTokenError (ParseError ):
Original file line number Diff line number Diff line change 11"""General shared utilities."""
2- import ast
32import logging
43import re
54from itertools import tee , zip_longest
@@ -47,24 +46,3 @@ def common_prefix_length(a: str, b: str) -> int:
4746def strip_non_alphanumeric (string : str ) -> str :
4847 """Strip string from any non-alphanumeric characters."""
4948 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):
5050@D303
5151def fstring_with_blank_doc_string ():
5252 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():
571571 assert code == 0
572572
573573
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+
574589def test_empty_select_with_added_error (env ):
575590 """Test excluding all errors but one."""
576591 with env .open ('example.py' , 'wt' ) as example :
You can’t perform that action at this time.
0 commit comments