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 ()
4768
4869
4970class FakeSearch (BaseSearch ):
5071 """
5172 Simple test class for directly testing BaseSearch since it's abstract.
5273 """
5374
54- def search (self ):
75+ def search (self ) -> dict [ str , list [ dict [ str , t . Any ]]] :
5576 """
5677 Override for abstract base method.
78+
79+ Returns:
80+ Empty dict to satisfy the abstract method requirement
5781 """
82+ return {}
5883
5984
60- def delete_report_files (file_extension ) :
85+ def delete_report_files (file_extension : str ) -> None :
6186 """
6287 Delete all files with the given extension from the test_reports directory.
6388
@@ -76,7 +101,7 @@ def delete_report_files(file_extension):
76101 pass
77102
78103
79- def call_script (args_list , delete_test_reports = True , delete_test_docs = True ):
104+ def call_script (args_list : Sequence [ str ] , delete_test_reports : bool = True , delete_test_docs : bool = True ) -> Result :
80105 """
81106 Call the code_annotations script with the given params and a generic config file.
82107
@@ -108,11 +133,11 @@ def call_script(args_list, delete_test_reports=True, delete_test_docs=True):
108133
109134
110135def call_script_isolated (
111- args_list ,
112- test_filesystem_cb = None ,
113- test_filesystem_report_cb = None ,
114- fake_safelist_data = "{}"
115- ):
136+ args_list : list [ str ] ,
137+ test_filesystem_cb : Callable [[], None ] | None = None ,
138+ test_filesystem_report_cb : Callable [[ str ], None ] | None = None ,
139+ fake_safelist_data : str = "{}"
140+ ) -> Result :
116141 """
117142 Call the code_annotations script with the given params and a generic config file.
118143
@@ -123,8 +148,6 @@ def call_script_isolated(
123148 test_filesystem_report_cb: Callback function, called after the command is run, before the temp filesystem
124149 is cleared. Callback is called with the raw text contents of the report file.
125150 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.
128151
129152 Returns:
130153 click.testing.Result: Result from the `CliRunner.invoke()` call.
@@ -151,7 +174,9 @@ def call_script_isolated(
151174
152175 if test_filesystem_report_cb :
153176 try :
154- report_file = re .search (r'Generating report to (.*)' , result .output ).groups ()[0 ]
177+ report_match = re .search (r'Generating report to (.*)' , result .output )
178+ assert report_match is not None
179+ report_file = report_match .groups ()[0 ]
155180 with open (report_file ) as f :
156181 report_contents = f .read ()
157182
@@ -163,7 +188,7 @@ def call_script_isolated(
163188 return result
164189
165190
166- def get_report_filename_from_output (output ) :
191+ def get_report_filename_from_output (output : str ) -> str | None :
167192 """
168193 Find the report filename in a find_static or find_django output and return it.
169194
@@ -172,9 +197,10 @@ def get_report_filename_from_output(output):
172197
173198 Returns:
174199 Filename of the found report, or None of no name is found
175-
176200 """
201+ match = re .search (r'Generating report to (.*)' , output )
202+ assert match is not None
177203 try :
178- return re . search ( r'Generating report to (.*)' , output ) .groups ()[0 ]
204+ return match .groups ()[0 ]
179205 except IndexError :
180206 return None
0 commit comments