Skip to content

Commit c7a006c

Browse files
committed
fix: resolve Black formatting issues and improve CI check script
FORMATTING FIXES: - Fixed Black code formatting issues in 32 files - Applied isort import sorting - All syntax and formatting checks now pass CI SCRIPT IMPROVEMENTS: - Updated dev-tools/scripts/ci_check.py to write output to temp files - Prevents context window overflow when running CI checks - Added --output-file option for custom output location - Maintains console output for immediate feedback - Detailed findings written to temp file for later analysis VALIDATION: - All 463 Python files pass syntax compilation - Black formatting: PASS - isort import sorting: PASS - flake8 style guide: PASS (for syntax/formatting) - mypy type checking: Expected failures (type annotations, not syntax) This resolves the CI formatting failures and provides better tooling for local development and debugging.
1 parent fd46504 commit c7a006c

34 files changed

Lines changed: 577 additions & 339 deletions

bandit-report.json

Lines changed: 50 additions & 50 deletions
Large diffs are not rendered by default.

dev-tools/scripts/ci_check.py

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import configparser
2121
import subprocess
2222
import sys
23+
import tempfile
2324
from pathlib import Path
2425
from typing import List, Tuple
2526

@@ -32,50 +33,73 @@ def __init__(self, verbose: bool = False, fix: bool = False):
3233
self.fix = fix
3334
self.failed_checks = []
3435
self.project_root = Path(__file__).parent.parent.parent
36+
self.temp_file = None
37+
self.output_lines = []
38+
39+
def log(self, message: str):
40+
"""Log message to both console and temp file."""
41+
print(message)
42+
self.output_lines.append(message)
43+
44+
def write_temp_file(self):
45+
"""Write all output to temporary file."""
46+
if not self.temp_file:
47+
self.temp_file = tempfile.NamedTemporaryFile(
48+
mode='w',
49+
suffix='.txt',
50+
prefix='ci_check_',
51+
delete=False
52+
)
53+
54+
self.temp_file.write('\n'.join(self.output_lines))
55+
self.temp_file.flush()
56+
return self.temp_file.name
3557

3658
def run_command(self, cmd: List[str], description: str, allow_failure: bool = False) -> bool:
3759
"""Run a command and return success status."""
3860
if self.verbose:
39-
print(f"Running: {' '.join(cmd)}")
61+
self.log(f"Running: {' '.join(cmd)}")
4062

4163
try:
4264
result = subprocess.run(
4365
cmd,
4466
cwd=self.project_root,
45-
capture_output=not self.verbose,
67+
capture_output=True,
4668
text=True,
4769
check=True
4870
)
49-
print(f"PASS: {description}")
71+
self.log(f"PASS: {description}")
72+
if self.verbose and result.stdout:
73+
self.log(f"Output: {result.stdout}")
5074
return True
5175
except subprocess.CalledProcessError as e:
5276
if allow_failure:
53-
print(f"WARN: {description} (allowed to fail)")
77+
self.log(f"WARN: {description} (allowed to fail)")
5478
if self.verbose and e.stdout:
55-
print(f"Output: {e.stdout}")
79+
self.log(f"Output: {e.stdout}")
5680
if self.verbose and e.stderr:
57-
print(f"Error: {e.stderr}")
81+
self.log(f"Error: {e.stderr}")
5882
return True
5983
else:
60-
print(f"FAIL: {description}")
84+
self.log(f"FAIL: {description}")
6185
if e.stdout:
62-
print(f"Output: {e.stdout}")
86+
self.log(f"Output: {e.stdout}")
6387
if e.stderr:
64-
print(f"Error: {e.stderr}")
88+
self.log(f"Error: {e.stderr}")
6589
self.failed_checks.append(description)
6690
return False
6791
except FileNotFoundError:
68-
print(f"FAIL: {description} (command not found)")
92+
self.log(f"FAIL: {description} (command not found)")
6993
self.failed_checks.append(f"{description} (command not found)")
7094
return False
7195

7296
def check_mypy_config(self) -> bool:
7397
"""Check mypy.ini configuration for common issues."""
74-
print("Checking mypy.ini configuration...")
98+
self.log("Checking mypy.ini configuration...")
7599

76100
mypy_ini = self.project_root / "mypy.ini"
77101
if not mypy_ini.exists():
78-
print("FAIL: mypy.ini not found")
102+
self.log("FAIL: mypy.ini not found")
79103
self.failed_checks.append("mypy.ini not found")
80104
return False
81105

@@ -95,13 +119,13 @@ def check_mypy_config(self) -> bool:
95119
version_tuple = (major, minor)
96120

97121
if version_tuple < (3, 9):
98-
print(f"FAIL: Python version {python_version} is too old (need 3.9+)")
122+
self.log(f"FAIL: Python version {python_version} is too old (need 3.9+)")
99123
self.failed_checks.append(f"Python version {python_version} too old")
100124
return False
101125
else:
102126
raise ValueError("Invalid version format")
103127
except (ValueError, IndexError):
104-
print(f"FAIL: Invalid Python version format: {python_version}")
128+
self.log(f"FAIL: Invalid Python version format: {python_version}")
105129
self.failed_checks.append(f"Invalid Python version format: {python_version}")
106130
return False
107131

@@ -113,37 +137,37 @@ def check_mypy_config(self) -> bool:
113137
allowed_flags = {'ignore_missing_imports', 'follow_imports', 'disallow_untyped_defs'}
114138
for key in section.keys():
115139
if key not in allowed_flags:
116-
print(f"FAIL: Invalid per-module flag in {section_name}: {key}")
140+
self.log(f"FAIL: Invalid per-module flag in {section_name}: {key}")
117141
self.failed_checks.append(f"Invalid per-module flag: {section_name}.{key}")
118142
return False
119143

120-
print("PASS: mypy.ini configuration")
144+
self.log("PASS: mypy.ini configuration")
121145
return True
122146

123147
except Exception as e:
124-
print(f"FAIL: mypy.ini configuration error: {e}")
148+
self.log(f"FAIL: mypy.ini configuration error: {e}")
125149
self.failed_checks.append(f"mypy.ini error: {e}")
126150
return False
127151

128152
def check_python_version_consistency(self) -> bool:
129153
"""Check Python version consistency across configuration files."""
130-
print("Checking Python version consistency...")
154+
self.log("Checking Python version consistency...")
131155

132156
# Check pyproject.toml
133157
pyproject_toml = self.project_root / "pyproject.toml"
134158
if pyproject_toml.exists():
135159
content = pyproject_toml.read_text()
136160
if 'python_version = "3.8"' in content:
137-
print("FAIL: pyproject.toml still has Python 3.8 (need 3.11+)")
161+
self.log("FAIL: pyproject.toml still has Python 3.8 (need 3.11+)")
138162
self.failed_checks.append("pyproject.toml Python version too old")
139163
return False
140164

141-
print("PASS: Python version consistency")
165+
self.log("PASS: Python version consistency")
142166
return True
143167

144168
def check_syntax_errors(self) -> bool:
145169
"""Check for Python syntax errors in key files."""
146-
print("Checking Python syntax...")
170+
self.log("Checking Python syntax...")
147171

148172
# Files that commonly have syntax issues
149173
problem_files = [
@@ -166,7 +190,7 @@ def check_syntax_errors(self) -> bool:
166190

167191
def run_formatting_checks(self) -> bool:
168192
"""Run code formatting checks (Black, isort)."""
169-
print("\n=== Code Formatting Checks ===")
193+
self.log("\n=== Code Formatting Checks ===")
170194

171195
all_passed = True
172196

@@ -190,7 +214,7 @@ def run_formatting_checks(self) -> bool:
190214

191215
def run_linting_checks(self) -> bool:
192216
"""Run linting checks (flake8, mypy, pylint)."""
193-
print("\n=== Linting Checks ===")
217+
self.log("\n=== Linting Checks ===")
194218

195219
all_passed = True
196220

@@ -279,9 +303,9 @@ def run_tests(self, quick: bool = False) -> bool:
279303

280304
def run_all_checks(self, quick: bool = False) -> bool:
281305
"""Run all CI checks."""
282-
print("=== Comprehensive CI Testing ===")
283-
print("Running the same checks as GitHub Actions CI pipeline...")
284-
print()
306+
self.log("=== Comprehensive CI Testing ===")
307+
self.log("Running the same checks as GitHub Actions CI pipeline...")
308+
self.log("")
285309

286310
# Configuration checks
287311
config_passed = (
@@ -291,7 +315,7 @@ def run_all_checks(self, quick: bool = False) -> bool:
291315
)
292316

293317
if not config_passed:
294-
print("\nConfiguration checks failed. Fix these before running other checks.")
318+
self.log("\nConfiguration checks failed. Fix these before running other checks.")
295319
return False
296320

297321
# Code quality checks
@@ -309,18 +333,26 @@ def run_all_checks(self, quick: bool = False) -> bool:
309333
tests_passed = True # Skip tests in quick mode
310334

311335
# Summary
312-
print("\n=== CI Check Summary ===")
336+
self.log("\n=== CI Check Summary ===")
313337
if self.failed_checks:
314-
print("FAILED CHECKS:")
338+
self.log("FAILED CHECKS:")
315339
for check in self.failed_checks:
316-
print(f" - {check}")
317-
print()
318-
print("Fix these issues before pushing to avoid CI failures.")
340+
self.log(f" - {check}")
341+
self.log("")
342+
self.log("Fix these issues before pushing to avoid CI failures.")
343+
344+
# Write temp file and show location
345+
temp_file_path = self.write_temp_file()
346+
self.log(f"\nDetailed output written to: {temp_file_path}")
319347
return False
320348
else:
321-
print("All critical CI checks passed!")
349+
self.log("All critical CI checks passed!")
322350
if self.fix:
323-
print("Formatting issues have been automatically fixed.")
351+
self.log("Formatting issues have been automatically fixed.")
352+
353+
# Write temp file for reference
354+
temp_file_path = self.write_temp_file()
355+
self.log(f"\nFull output written to: {temp_file_path}")
324356
return True
325357

326358

@@ -329,12 +361,22 @@ def main():
329361
parser.add_argument("--quick", action="store_true", help="Run only fast checks")
330362
parser.add_argument("--fix", action="store_true", help="Fix formatting issues automatically")
331363
parser.add_argument("--verbose", action="store_true", help="Show detailed output")
364+
parser.add_argument("--output-file", help="Write output to specific file instead of temp file")
332365

333366
args = parser.parse_args()
334367

335368
checker = CIChecker(verbose=args.verbose, fix=args.fix)
369+
370+
# Override temp file if specified
371+
if args.output_file:
372+
checker.temp_file = open(args.output_file, 'w')
373+
336374
success = checker.run_all_checks(quick=args.quick)
337375

376+
# Clean up temp file if we created it
377+
if checker.temp_file and not args.output_file:
378+
checker.temp_file.close()
379+
338380
sys.exit(0 if success else 1)
339381

340382

src/application/base/event_handlers.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,12 @@ async def publish_cascading_events(self, events: list[DomainEvent]) -> None:
165165
def _record_success_metrics(self, event_type: str, duration: float) -> None:
166166
"""Record success metrics for monitoring."""
167167
if event_type not in self._metrics:
168-
self._metrics[event_type] = {"success_count": 0,
168+
self._metrics[event_type] = {
169+
"success_count": 0,
169170
"failure_count": 0,
170171
"total_duration": 0.0,
171-
"avg_duration": 0.0,}
172+
"avg_duration": 0.0,
173+
}
172174

173175
metrics = self._metrics[event_type]
174176
metrics["success_count"] += 1
@@ -181,11 +183,13 @@ def _record_success_metrics(self, event_type: str, duration: float) -> None:
181183
def _record_failure_metrics(self, event_type: str, duration: float, error: Exception) -> None:
182184
"""Record failure metrics for monitoring."""
183185
if event_type not in self._metrics:
184-
self._metrics[event_type] = {"success_count": 0,
186+
self._metrics[event_type] = {
187+
"success_count": 0,
185188
"failure_count": 0,
186189
"total_duration": 0.0,
187190
"avg_duration": 0.0,
188-
"last_error": None,}
191+
"last_error": None,
192+
}
189193

190194
metrics = self._metrics[event_type]
191195
metrics["failure_count"] += 1

src/application/base/handlers.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ async def wrapped_operation():
7777
if self.logger:
7878
self.logger.log_domain_event(
7979
"error",
80-
{"context": context,
80+
{
81+
"context": context,
8182
"error": str(e),
82-
"handler": self.__class__.__name__,},
83+
"handler": self.__class__.__name__,
84+
},
8385
)
8486
raise
8587

@@ -107,9 +109,11 @@ async def async_wrapper(*args, **kwargs):
107109
if self.logger:
108110
self.logger.info(f"Completed operation: {operation_id} in {duration:.3f}s")
109111

110-
self._metrics[operation_id] = {"duration": duration,
112+
self._metrics[operation_id] = {
113+
"duration": duration,
111114
"status": "success",
112-
"timestamp": datetime.utcnow(),}
115+
"timestamp": datetime.utcnow(),
116+
}
113117

114118
return result
115119

@@ -121,10 +125,12 @@ async def async_wrapper(*args, **kwargs):
121125
f"Failed operation: {operation_id} in {duration:.3f}s - {str(e)}"
122126
)
123127

124-
self._metrics[operation_id] = {"duration": duration,
128+
self._metrics[operation_id] = {
129+
"duration": duration,
125130
"status": "error",
126131
"error": str(e),
127-
"timestamp": datetime.utcnow(),}
132+
"timestamp": datetime.utcnow(),
133+
}
128134

129135
raise
130136

@@ -395,7 +401,7 @@ async def handle_provider_operation(self, operation: str, **kwargs) -> Any:
395401
else:
396402
if self.logger:
397403
self.logger.warning(
398-
f"Provider operation failed (attempt { attempt + 1}): { str(e)}"
404+
f"Provider operation failed (attempt { attempt + 1}): { str(e)}"
399405
)
400406
await asyncio.sleep(self.retry_delay * (attempt + 1))
401407

src/application/base/infrastructure_handlers.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,12 @@ async def handle(self, request: TRequest) -> TResponse:
108108
if self.error_handler:
109109
await self.error_handler.handle_error(
110110
e,
111-
{"request_type": request_type,
111+
{
112+
"request_type": request_type,
112113
"correlation_id": context.correlation_id,
113114
"duration": duration,
114-
"context": context.metadata,},
115+
"context": context.metadata,
116+
},
115117
)
116118

117119
if self.logger:
@@ -161,10 +163,12 @@ async def execute_request(self, request: TRequest, context: RequestContext) -> T
161163
def _record_success_metrics(self, request_type: str, duration: float) -> None:
162164
"""Record success metrics for monitoring."""
163165
if request_type not in self._metrics:
164-
self._metrics[request_type] = {"success_count": 0,
166+
self._metrics[request_type] = {
167+
"success_count": 0,
165168
"failure_count": 0,
166169
"total_duration": 0.0,
167-
"avg_duration": 0.0,}
170+
"avg_duration": 0.0,
171+
}
168172

169173
metrics = self._metrics[request_type]
170174
metrics["success_count"] += 1
@@ -177,11 +181,13 @@ def _record_success_metrics(self, request_type: str, duration: float) -> None:
177181
def _record_failure_metrics(self, request_type: str, duration: float, error: Exception) -> None:
178182
"""Record failure metrics for monitoring."""
179183
if request_type not in self._metrics:
180-
self._metrics[request_type] = {"success_count": 0,
184+
self._metrics[request_type] = {
185+
"success_count": 0,
181186
"failure_count": 0,
182187
"total_duration": 0.0,
183188
"avg_duration": 0.0,
184-
"last_error": None,}
189+
"last_error": None,
190+
}
185191

186192
metrics = self._metrics[request_type]
187193
metrics["failure_count"] += 1

0 commit comments

Comments
 (0)