Skip to content

Commit d0faee3

Browse files
TexasCodingclaude
andcommitted
fix(stats): Add input validation for numeric conversions
Added safe_int() helper function to validate inputs before converting to integers, preventing potential ValueError exceptions on unexpected input types. The function handles: - None values (returns default) - int/float types (safely converts) - Numeric strings (validates and converts) - Invalid types (logs warning and returns default) This addresses the input validation issue identified in PR review. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 0c2a4d7 commit d0faee3

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

src/project_x_py/utils/enhanced_stats_tracking.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,24 @@ async def track_data_quality(
211211
duplicate_points: Number of duplicate points
212212
"""
213213
async with self._stats_lock:
214-
# Type-safe integer updates
215-
current_total = int(self._data_quality.get("total_data_points", 0))
216-
current_invalid = int(self._data_quality.get("invalid_data_points", 0))
217-
current_missing = int(self._data_quality.get("missing_data_points", 0))
218-
current_duplicate = int(self._data_quality.get("duplicate_data_points", 0))
214+
# Type-safe integer updates with validation
215+
def safe_int(value: Any, default: int = 0) -> int:
216+
"""Safely convert value to int with validation."""
217+
if value is None:
218+
return default
219+
if isinstance(value, (int, float)):
220+
return int(value)
221+
if isinstance(value, str) and value.isdigit():
222+
return int(value)
223+
logger.warning(f"Invalid numeric value for data quality: {value}")
224+
return default
225+
226+
current_total = safe_int(self._data_quality.get("total_data_points", 0))
227+
current_invalid = safe_int(self._data_quality.get("invalid_data_points", 0))
228+
current_missing = safe_int(self._data_quality.get("missing_data_points", 0))
229+
current_duplicate = safe_int(
230+
self._data_quality.get("duplicate_data_points", 0)
231+
)
219232

220233
self._data_quality["total_data_points"] = current_total + total_points
221234
self._data_quality["invalid_data_points"] = current_invalid + invalid_points
@@ -324,8 +337,19 @@ async def get_data_quality_stats(self) -> dict[str, Any]:
324337
Dictionary with data quality metrics
325338
"""
326339
async with self._stats_lock:
327-
total = int(self._data_quality.get("total_data_points", 0))
328-
invalid = int(self._data_quality.get("invalid_data_points", 0))
340+
# Safe integer conversion with validation
341+
def safe_int(value: Any, default: int = 0) -> int:
342+
"""Safely convert value to int with validation."""
343+
if value is None:
344+
return default
345+
if isinstance(value, (int, float)):
346+
return int(value)
347+
if isinstance(value, str) and value.isdigit():
348+
return int(value)
349+
return default
350+
351+
total = safe_int(self._data_quality.get("total_data_points", 0))
352+
invalid = safe_int(self._data_quality.get("invalid_data_points", 0))
329353

330354
quality_score = ((total - invalid) / total * 100) if total > 0 else 100.0
331355

0 commit comments

Comments
 (0)