|
7 | 7 | from planfile.analysis.parsers.text_parser import analyze_text |
8 | 8 | from planfile.analysis.parsers.toon_parser import analyze_toon |
9 | 9 |
|
10 | | -def extract_from_yaml_structure(data: Any, path: str, parent_key: str = "") -> List[ExtractedIssue]: |
11 | | - """Extract issues from YAML structure.""" |
| 10 | +def extract_from_yaml_structure(data: Any, path: str, parent_key: str = "", visited: set = None) -> List[ExtractedIssue]: |
| 11 | + """Extract issues from YAML structure with recursion protection.""" |
| 12 | + if visited is None: |
| 13 | + visited = set() |
| 14 | + |
12 | 15 | issues = [] |
13 | 16 |
|
| 17 | + # Prevent infinite recursion |
| 18 | + if id(data) in visited: |
| 19 | + return issues |
| 20 | + visited.add(id(data)) |
| 21 | + |
14 | 22 | if isinstance(data, dict): |
15 | 23 | for key, value in data.items(): |
16 | 24 | full_key = f"{parent_key}.{key}" if parent_key else key |
17 | 25 |
|
18 | | - # Look for common issue indicators |
19 | | - if isinstance(value, str): |
| 26 | + # Skip if we're already processing issues (prevent self-reference) |
| 27 | + if 'issues' in full_key.lower(): |
| 28 | + continue |
| 29 | + |
| 30 | + # Look for common issue indicators, but not in our own generated content |
| 31 | + if isinstance(value, str) and len(value) < 500: # Limit string length |
20 | 32 | if any(keyword in value.lower() for keyword in ['error', 'fail', 'bug', 'issue']): |
21 | | - issues.append(ExtractedIssue( |
22 | | - title=f"Issue in {full_key}", |
23 | | - description=value, |
24 | | - priority="medium", |
25 | | - category="bug", |
26 | | - file_path=path |
27 | | - )) |
| 33 | + # Skip if this looks like our own generated issue |
| 34 | + if not any(skip in value.lower() for skip in ['extractedissue', 'file_path', 'priority:', 'category:']): |
| 35 | + issues.append(ExtractedIssue( |
| 36 | + title=f"Issue in {full_key}", |
| 37 | + description=value[:200], # Limit description length |
| 38 | + priority="medium", |
| 39 | + category="bug", |
| 40 | + file_path=path |
| 41 | + )) |
28 | 42 |
|
29 | | - # Recurse |
30 | | - issues.extend(extract_from_yaml_structure(value, path, full_key)) |
| 43 | + # Recurse with protection |
| 44 | + issues.extend(extract_from_yaml_structure(value, path, full_key, visited)) |
31 | 45 |
|
32 | 46 | elif isinstance(data, list): |
33 | 47 | for i, item in enumerate(data): |
34 | | - issues.extend(extract_from_yaml_structure(item, path, f"{parent_key}[{i}]")) |
| 48 | + issues.extend(extract_from_yaml_structure(item, path, f"{parent_key}[{i}]", visited)) |
35 | 49 |
|
36 | 50 | return issues |
37 | 51 |
|
|
0 commit comments