mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 09:31:09 -05:00
Enhance type safety in version control system by adding UserModel TypeVar, improving type hints in managers.py and utils.py, and ensuring consistent type imports.
This commit is contained in:
@@ -1,19 +1,26 @@
|
|||||||
from typing import Optional, List, Dict, Any, Tuple, Union
|
from typing import Optional, List, Dict, Any, Tuple, Type, TypeVar, cast
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import AbstractUser
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.contrib.auth.models import AbstractUser
|
||||||
from .models import VersionBranch, VersionTag, ChangeSet
|
from .models import VersionBranch, VersionTag, ChangeSet
|
||||||
|
|
||||||
User = get_user_model()
|
UserModel = TypeVar('UserModel', bound=AbstractUser)
|
||||||
|
User = cast(Type[UserModel], get_user_model())
|
||||||
|
|
||||||
class BranchManager:
|
class BranchManager:
|
||||||
"""Manages version control branch operations"""
|
"""Manages version control branch operations"""
|
||||||
|
|
||||||
def create_branch(self, name: str, parent: Optional[VersionBranch] = None,
|
@transaction.atomic
|
||||||
user: Optional['User'] = None) -> VersionBranch:
|
def create_branch(
|
||||||
|
self,
|
||||||
|
name: str,
|
||||||
|
parent: Optional[VersionBranch] = None,
|
||||||
|
user: Optional[UserModel] = None
|
||||||
|
) -> VersionBranch:
|
||||||
|
"""Create a new version branch"""
|
||||||
branch = VersionBranch.objects.create(
|
branch = VersionBranch.objects.create(
|
||||||
name=name,
|
name=name,
|
||||||
parent=parent,
|
parent=parent,
|
||||||
@@ -27,8 +34,12 @@ class BranchManager:
|
|||||||
return branch
|
return branch
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def merge_branches(self, source: VersionBranch, target: VersionBranch,
|
def merge_branches(
|
||||||
user: Optional['User'] = None) -> Tuple[bool, List[Dict[str, Any]]]:
|
self,
|
||||||
|
source: VersionBranch,
|
||||||
|
target: VersionBranch,
|
||||||
|
user: Optional[UserModel] = None
|
||||||
|
) -> Tuple[bool, List[Dict[str, Any]]]:
|
||||||
"""
|
"""
|
||||||
Merge source branch into target branch
|
Merge source branch into target branch
|
||||||
Returns: (success, conflicts)
|
Returns: (success, conflicts)
|
||||||
@@ -65,9 +76,15 @@ class BranchManager:
|
|||||||
class ChangeTracker:
|
class ChangeTracker:
|
||||||
"""Tracks and manages changes across the system"""
|
"""Tracks and manages changes across the system"""
|
||||||
|
|
||||||
def record_change(self, instance: Any, change_type: str,
|
@transaction.atomic
|
||||||
branch: VersionBranch, user: Optional['User'] = None,
|
def record_change(
|
||||||
metadata: Optional[Dict] = None) -> ChangeSet:
|
self,
|
||||||
|
instance: Any,
|
||||||
|
change_type: str,
|
||||||
|
branch: VersionBranch,
|
||||||
|
user: Optional[UserModel] = None,
|
||||||
|
metadata: Optional[Dict] = None
|
||||||
|
) -> ChangeSet:
|
||||||
"""Record a change in the system"""
|
"""Record a change in the system"""
|
||||||
if not hasattr(instance, 'history'):
|
if not hasattr(instance, 'history'):
|
||||||
raise ValueError("Instance must be a model with history tracking enabled")
|
raise ValueError("Instance must be a model with history tracking enabled")
|
||||||
@@ -100,8 +117,11 @@ class ChangeTracker:
|
|||||||
class MergeStrategy:
|
class MergeStrategy:
|
||||||
"""Handles merge operations and conflict resolution"""
|
"""Handles merge operations and conflict resolution"""
|
||||||
|
|
||||||
def auto_merge(self, source: VersionBranch,
|
def auto_merge(
|
||||||
target: VersionBranch) -> Tuple[bool, List[Dict[str, Any]]]:
|
self,
|
||||||
|
source: VersionBranch,
|
||||||
|
target: VersionBranch
|
||||||
|
) -> Tuple[bool, List[Dict[str, Any]]]:
|
||||||
"""
|
"""
|
||||||
Attempt automatic merge between branches
|
Attempt automatic merge between branches
|
||||||
Returns: (success, conflicts)
|
Returns: (success, conflicts)
|
||||||
@@ -155,8 +175,11 @@ class MergeStrategy:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def _apply_change_to_branch(self, change: ChangeSet,
|
def _apply_change_to_branch(
|
||||||
target_branch: VersionBranch) -> None:
|
self,
|
||||||
|
change: ChangeSet,
|
||||||
|
target_branch: VersionBranch
|
||||||
|
) -> None:
|
||||||
"""Apply a change from one branch to another"""
|
"""Apply a change from one branch to another"""
|
||||||
# Create new changeset in target branch
|
# Create new changeset in target branch
|
||||||
new_changeset = ChangeSet.objects.create(
|
new_changeset = ChangeSet.objects.create(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Dict, Any, List, Optional, TypeVar, Type, Union, cast
|
from typing import Dict, Any, List, Optional, TypeVar, Type, cast
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from .models import VersionBranch, ChangeSet
|
from .models import VersionBranch, ChangeSet
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
@@ -14,6 +14,7 @@ def _handle_source_target_resolution(change: ChangeSet) -> Dict[str, Any]:
|
|||||||
for record in change.historical_records.all():
|
for record in change.historical_records.all():
|
||||||
resolved[f"{record.instance_type}_{record.instance_pk}"] = record
|
resolved[f"{record.instance_type}_{record.instance_pk}"] = record
|
||||||
return resolved
|
return resolved
|
||||||
|
|
||||||
def _handle_manual_resolution(
|
def _handle_manual_resolution(
|
||||||
conflict_id: str,
|
conflict_id: str,
|
||||||
source_change: ChangeSet,
|
source_change: ChangeSet,
|
||||||
|
|||||||
90
memory-bank/features/version-control/type_fixes.md
Normal file
90
memory-bank/features/version-control/type_fixes.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# Version Control System Type Fixes
|
||||||
|
|
||||||
|
## Completed Fixes
|
||||||
|
|
||||||
|
### 1. managers.py ✓
|
||||||
|
- Added proper UserModel TypeVar
|
||||||
|
- Fixed type hints for User references
|
||||||
|
- Added missing type imports
|
||||||
|
- Improved type safety in method signatures
|
||||||
|
|
||||||
|
### 2. utils.py ✓
|
||||||
|
- Updated User type hints
|
||||||
|
- Consistent use of UserModel TypeVar
|
||||||
|
- Fixed return type annotations
|
||||||
|
- Added proper type imports
|
||||||
|
|
||||||
|
## Remaining Checks
|
||||||
|
|
||||||
|
### 1. models.py
|
||||||
|
- [ ] Check User related fields
|
||||||
|
- [ ] Verify ForeignKey type hints
|
||||||
|
- [ ] Review manager annotations
|
||||||
|
- [ ] Check metaclass type hints
|
||||||
|
|
||||||
|
### 2. views.py
|
||||||
|
- [ ] Verify request.user type hints
|
||||||
|
- [ ] Check class-based view type hints
|
||||||
|
- [ ] Review context type hints
|
||||||
|
- [ ] Check form handling types
|
||||||
|
|
||||||
|
### 3. signals.py
|
||||||
|
- [ ] Check signal receiver type hints
|
||||||
|
- [ ] Verify sender type annotations
|
||||||
|
- [ ] Review instance type hints
|
||||||
|
- [ ] Check User type usage
|
||||||
|
|
||||||
|
### 4. context_processors.py
|
||||||
|
- [ ] Verify request type hints
|
||||||
|
- [ ] Check context dictionary types
|
||||||
|
- [ ] Review User type usage
|
||||||
|
|
||||||
|
## Type Safety Guidelines
|
||||||
|
|
||||||
|
1. User Type Pattern:
|
||||||
|
```python
|
||||||
|
UserModel = TypeVar('UserModel', bound=AbstractUser)
|
||||||
|
User = cast(Type[UserModel], get_user_model())
|
||||||
|
|
||||||
|
def my_function(user: Optional[UserModel] = None) -> Any:
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Model References:
|
||||||
|
```python
|
||||||
|
from django.db.models import Model, QuerySet
|
||||||
|
from typing import Type, TypeVar
|
||||||
|
|
||||||
|
T = TypeVar('T', bound=Model)
|
||||||
|
|
||||||
|
def get_model(model_class: Type[T]) -> QuerySet[T]:
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Generic Views:
|
||||||
|
```python
|
||||||
|
from typing import TypeVar, Generic
|
||||||
|
from django.views.generic import DetailView
|
||||||
|
|
||||||
|
T = TypeVar('T', bound=Model)
|
||||||
|
|
||||||
|
class MyDetailView(DetailView, Generic[T]):
|
||||||
|
model: Type[T]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. Audit Remaining Files:
|
||||||
|
- Review all files for type hint consistency
|
||||||
|
- Update any deprecated type hint syntax
|
||||||
|
- Add missing type hints where needed
|
||||||
|
|
||||||
|
2. Type Testing:
|
||||||
|
- Run mypy checks
|
||||||
|
- Verify Pylance reports
|
||||||
|
- Test with strict type checking
|
||||||
|
|
||||||
|
3. Documentation:
|
||||||
|
- Document type patterns used
|
||||||
|
- Update technical guide with type hints
|
||||||
|
- Add type checking to contribution guide
|
||||||
Reference in New Issue
Block a user