diff --git a/scaffoldforge/parsers/issue_parser.py b/scaffoldforge/parsers/issue_parser.py index b51091d..8845708 100644 --- a/scaffoldforge/parsers/issue_parser.py +++ b/scaffoldforge/parsers/issue_parser.py @@ -4,11 +4,10 @@ import os import re import time from dataclasses import dataclass, field -from typing import Any, Dict, List, Optional +from typing import Any, Optional from github import Github from github.Issue import Issue -from github.Label import Label @dataclass @@ -29,25 +28,25 @@ class IssueData: title: str body: str body_html: str - labels: List[str] + labels: list[str] state: str url: str repository: str author: str created_at: str updated_at: str - checklist: List[ChecklistItem] = field(default_factory=list) - requirements: List[str] = field(default_factory=list) - acceptance_criteria: List[str] = field(default_factory=list) - suggested_files: List[str] = field(default_factory=list) - suggested_directories: List[str] = field(default_factory=list) - metadata: Dict[str, Any] = field(default_factory=dict) + checklist: list[ChecklistItem] = field(default_factory=list) + requirements: list[str] = field(default_factory=list) + acceptance_criteria: list[str] = field(default_factory=list) + suggested_files: list[str] = field(default_factory=list) + suggested_directories: list[str] = field(default_factory=list) + metadata: dict[str, Any] = field(default_factory=dict) - def get_todo_items(self) -> List[str]: + def get_todo_items(self) -> list[str]: """Get all todo items from checklist.""" return [item.text for item in self.checklist if not item.completed] - def get_completed_items(self) -> List[str]: + def get_completed_items(self) -> list[str]: """Get completed checklist items.""" return [item.text for item in self.checklist if item.completed] @@ -109,6 +108,7 @@ class IssueParser: time.sleep(60 * (attempt + 1)) else: raise + raise ValueError(f"Failed to fetch issue after {max_retries} retries") def _extract_issue_data(self, issue: Issue, repository: str) -> IssueData: """Extract structured data from a GitHub issue. @@ -147,7 +147,7 @@ class IssueParser: suggested_directories=suggested_directories, ) - def _parse_checklist(self, body: str) -> List[ChecklistItem]: + def _parse_checklist(self, body: str) -> list[ChecklistItem]: """Parse markdown checklist items from issue body. Args: @@ -156,24 +156,21 @@ class IssueParser: Returns: List of ChecklistItem objects. """ - checklist = [] + checklist: list[ChecklistItem] = [] if not body: return checklist lines = body.split("\n") - in_checklist = False - current_category = None + current_category: str | None = None for i, line in enumerate(lines): category_match = re.match(r"^\s*(?:###|##|#)\s+(.+)", line) if category_match: current_category = category_match.group(1) - in_checklist = False continue checklist_match = re.match(r"^\s*[-*]\s+\[([ xX])\]\s+(.+)$", line) if checklist_match: - in_checklist = True checked = checklist_match.group(1).lower() == "x" text = checklist_match.group(2).strip() checklist.append( @@ -187,7 +184,7 @@ class IssueParser: return checklist - def _parse_requirements(self, body: str) -> List[str]: + def _parse_requirements(self, body: str) -> list[str]: """Parse requirements from issue body. Args: @@ -196,7 +193,7 @@ class IssueParser: Returns: List of requirement strings. """ - requirements = [] + requirements: list[str] = [] if not body: return requirements @@ -216,7 +213,7 @@ class IssueParser: return requirements - def _parse_acceptance_criteria(self, body: str) -> List[str]: + def _parse_acceptance_criteria(self, body: str) -> list[str]: """Parse acceptance criteria from issue body. Args: @@ -225,7 +222,7 @@ class IssueParser: Returns: List of acceptance criteria strings. """ - criteria = [] + criteria: list[str] = [] if not body: return criteria @@ -245,7 +242,7 @@ class IssueParser: return criteria - def _parse_file_paths(self, body: str) -> List[str]: + def _parse_file_paths(self, body: str) -> list[str]: """Parse suggested file paths from issue body. Args: @@ -254,7 +251,7 @@ class IssueParser: Returns: List of file path strings. """ - files = [] + files: list[str] = [] if not body: return files @@ -271,7 +268,7 @@ class IssueParser: return list(set(files)) - def _parse_directory_paths(self, body: str) -> List[str]: + def _parse_directory_paths(self, body: str) -> list[str]: """Parse suggested directory paths from issue body. Args: @@ -280,7 +277,7 @@ class IssueParser: Returns: List of directory path strings. """ - directories = [] + directories: list[str] = [] if not body: return directories