33"""
44import os
55import re
6+ import typing as t
7+ from collections .abc import Callable , Sequence
68
79from click .testing import CliRunner
10+ from click .testing import Result as ClickTestResult
11+ from stevedore import named
812
9- from code_annotations .base import BaseSearch , VerboseEcho
13+ from code_annotations .base import AnnotationConfig , BaseSearch
1014from code_annotations .cli import entry_point
15+ from code_annotations .helpers import VerboseEcho
16+
17+ # Re-export Result for convenience
18+ Result = ClickTestResult
1119
1220EXIT_CODE_SUCCESS = 0
1321EXIT_CODE_FAILURE = 1
3442""" .format (DEFAULT_FAKE_SAFELIST_PATH )
3543
3644
37- class FakeConfig :
45+ class FakeConfig ( AnnotationConfig ) :
3846 """
3947 Simple config for testing without reading a config file.
4048 """
4149
42- annotations : dict [str , str ] = {}
43- annotation_regexes : list [str ] = []
44- annotation_tokens : list [str ] = []
45- groups : list [str ] = []
46- echo = VerboseEcho ()
50+ # annotations: dict[str, t.Any] = {}
51+ # annotation_regexes: list[str] = []
52+ # annotation_tokens: list[str] = []
53+ # groups: t.Union[list[str], dict[str, list[str]]] = []
54+ # echo = VerboseEcho()
55+
56+ def __init__ (self ) -> None : # pylint: disable=super-init-not-called
57+ """
58+ Override the base __init__ to skip reading and parsing the config.
59+ """
60+ self .groups : dict [str , list [str ]] = {}
61+ self .choices : dict [str , list [str ]] = {}
62+ self .optional_groups : list [str ] = []
63+ self .annotation_tokens : list [str ] = []
64+ self .annotation_regexes : list [str ] = []
65+ self .mgr : named .NamedExtensionManager | None = None
66+ self .coverage_target : float | None = None
67+ self .echo = VerboseEcho ()
68+
4769
4870
4971class FakeSearch (BaseSearch ):
5072 """
5173 Simple test class for directly testing BaseSearch since it's abstract.
5274 """
5375
54- def search (self ):
76+ def search (self ) -> dict [ str , list [ dict [ str , t . Any ]]] :
5577 """
5678 Override for abstract base method.
79+
80+ Returns:
81+ Empty dict to satisfy the abstract method requirement
5782 """
83+ return {}
5884
5985
60- def delete_report_files (file_extension ) :
86+ def delete_report_files (file_extension : str ) -> None :
6187 """
6288 Delete all files with the given extension from the test_reports directory.
6389
@@ -76,7 +102,7 @@ def delete_report_files(file_extension):
76102 pass
77103
78104
79- def call_script (args_list , delete_test_reports = True , delete_test_docs = True ):
105+ def call_script (args_list : Sequence [ str ] , delete_test_reports : bool = True , delete_test_docs : bool = True ) -> Result :
80106 """
81107 Call the code_annotations script with the given params and a generic config file.
82108
@@ -108,11 +134,11 @@ def call_script(args_list, delete_test_reports=True, delete_test_docs=True):
108134
109135
110136def call_script_isolated (
111- args_list ,
112- test_filesystem_cb = None ,
113- test_filesystem_report_cb = None ,
114- fake_safelist_data = "{}"
115- ):
137+ args_list : list [ str ] ,
138+ test_filesystem_cb : Callable [[], None ] | None = None ,
139+ test_filesystem_report_cb : Callable [[ str ], None ] | None = None ,
140+ fake_safelist_data : str = "{}"
141+ ) -> Result :
116142 """
117143 Call the code_annotations script with the given params and a generic config file.
118144
@@ -123,8 +149,6 @@ def call_script_isolated(
123149 test_filesystem_report_cb: Callback function, called after the command is run, before the temp filesystem
124150 is cleared. Callback is called with the raw text contents of the report file.
125151 fake_safelist_data: Raw text to write to the safelist file before the command is called.
126- safelist_path: File path to write the safelist to. Used when writing a fake safelist, but not automatically
127- passed to the command.
128152
129153 Returns:
130154 click.testing.Result: Result from the `CliRunner.invoke()` call.
@@ -151,7 +175,9 @@ def call_script_isolated(
151175
152176 if test_filesystem_report_cb :
153177 try :
154- report_file = re .search (r'Generating report to (.*)' , result .output ).groups ()[0 ]
178+ report_match = re .search (r'Generating report to (.*)' , result .output )
179+ assert report_match is not None
180+ report_file = report_match .groups ()[0 ]
155181 with open (report_file ) as f :
156182 report_contents = f .read ()
157183
@@ -163,7 +189,7 @@ def call_script_isolated(
163189 return result
164190
165191
166- def get_report_filename_from_output (output ) :
192+ def get_report_filename_from_output (output : str ) -> str | None :
167193 """
168194 Find the report filename in a find_static or find_django output and return it.
169195
@@ -172,9 +198,10 @@ def get_report_filename_from_output(output):
172198
173199 Returns:
174200 Filename of the found report, or None of no name is found
175-
176201 """
202+ match = re .search (r'Generating report to (.*)' , output )
203+ assert match is not None
177204 try :
178- return re . search ( r'Generating report to (.*)' , output ) .groups ()[0 ]
205+ return match .groups ()[0 ]
179206 except IndexError :
180207 return None
0 commit comments