fix: Corregir todos los warnings de linting (ruff, black)

- Corregir import ordering (TC002) moviendo User a TYPE_CHECKING
- Corregir type hints implícitos (RUF013) usando | None
- Corregir boolean traps (FBT001/FBT002) usando keyword-only args
- Corregir logging warnings (G201) usando logger.exception()
- Formatear código con ruff format y black

Co-authored-by: dawnsystem <42047891+dawnsystem@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-11-12 13:17:08 +00:00
parent 2d7345f0bc
commit 8a5ece9e2b
3 changed files with 38 additions and 26 deletions

View file

@ -14,9 +14,11 @@ According to agents.md requirements:
from __future__ import annotations from __future__ import annotations
import logging import logging
from typing import TYPE_CHECKING
from typing import Any from typing import Any
from django.contrib.auth.models import User if TYPE_CHECKING:
from django.contrib.auth.models import User
logger = logging.getLogger("paperless.ai_deletion") logger = logging.getLogger("paperless.ai_deletion")

View file

@ -51,7 +51,8 @@ class AIScanResult:
None # (storage_path_id, confidence) None # (storage_path_id, confidence)
) )
self.custom_fields: dict[ self.custom_fields: dict[
int, tuple[Any, float], int,
tuple[Any, float],
] = {} # {field_id: (value, confidence), ...} ] = {} # {field_id: (value, confidence), ...}
self.workflows: list[tuple[int, float]] = [] # [(workflow_id, confidence), ...] self.workflows: list[tuple[int, float]] = [] # [(workflow_id, confidence), ...]
self.extracted_entities: dict[str, Any] = {} # NER results self.extracted_entities: dict[str, Any] = {} # NER results
@ -97,8 +98,9 @@ class AIDocumentScanner:
self, self,
auto_apply_threshold: float = 0.80, auto_apply_threshold: float = 0.80,
suggest_threshold: float = 0.60, suggest_threshold: float = 0.60,
enable_ml_features: bool = None, *,
enable_advanced_ocr: bool = None, enable_ml_features: bool | None = None,
enable_advanced_ocr: bool | None = None,
): ):
""" """
Initialize AI scanner. Initialize AI scanner.
@ -188,7 +190,7 @@ class AIDocumentScanner:
self, self,
document: Document, document: Document,
document_text: str, document_text: str,
original_file_path: str = None, original_file_path: str | None = None,
) -> AIScanResult: ) -> AIScanResult:
""" """
Perform comprehensive AI scan of a document. Perform comprehensive AI scan of a document.
@ -215,7 +217,9 @@ class AIDocumentScanner:
# Analyze and suggest tags # Analyze and suggest tags
result.tags = self._suggest_tags( result.tags = self._suggest_tags(
document, document_text, result.extracted_entities, document,
document_text,
result.extracted_entities,
) )
# Detect correspondent # Detect correspondent
@ -296,7 +300,7 @@ class AIDocumentScanner:
logger.debug("Extracted entities from NER") logger.debug("Extracted entities from NER")
return entities return entities
except Exception as e: except Exception as e:
logger.error(f"Entity extraction failed: {e}", exc_info=True) logger.exception(f"Entity extraction failed: {e}")
return {} return {}
def _suggest_tags( def _suggest_tags(
@ -357,7 +361,7 @@ class AIDocumentScanner:
logger.debug(f"Suggested {len(suggestions)} tags") logger.debug(f"Suggested {len(suggestions)} tags")
except Exception as e: except Exception as e:
logger.error(f"Tag suggestion failed: {e}", exc_info=True) logger.exception(f"Tag suggestion failed: {e}")
return suggestions return suggestions
@ -384,7 +388,8 @@ class AIDocumentScanner:
try: try:
# Use existing matching logic # Use existing matching logic
matched_correspondents = match_correspondents( matched_correspondents = match_correspondents(
document, self._get_classifier(), document,
self._get_classifier(),
) )
if matched_correspondents: if matched_correspondents:
@ -413,7 +418,7 @@ class AIDocumentScanner:
return (correspondent.id, confidence) return (correspondent.id, confidence)
except Exception as e: except Exception as e:
logger.error(f"Correspondent detection failed: {e}", exc_info=True) logger.exception(f"Correspondent detection failed: {e}")
return None return None
@ -452,7 +457,7 @@ class AIDocumentScanner:
pass pass
except Exception as e: except Exception as e:
logger.error(f"Document type classification failed: {e}", exc_info=True) logger.exception(f"Document type classification failed: {e}")
return None return None
@ -484,7 +489,7 @@ class AIDocumentScanner:
return (storage_path.id, confidence) return (storage_path.id, confidence)
except Exception as e: except Exception as e:
logger.error(f"Storage path suggestion failed: {e}", exc_info=True) logger.exception(f"Storage path suggestion failed: {e}")
return None return None
@ -523,7 +528,7 @@ class AIDocumentScanner:
) )
except Exception as e: except Exception as e:
logger.error(f"Custom field extraction failed: {e}", exc_info=True) logger.exception(f"Custom field extraction failed: {e}")
return extracted_fields return extracted_fields
@ -628,7 +633,7 @@ class AIDocumentScanner:
) )
except Exception as e: except Exception as e:
logger.error(f"Workflow suggestion failed: {e}", exc_info=True) logger.exception(f"Workflow suggestion failed: {e}")
return suggestions return suggestions
@ -699,7 +704,7 @@ class AIDocumentScanner:
return suggested_title[:127] # Respect title length limit return suggested_title[:127] # Respect title length limit
except Exception as e: except Exception as e:
logger.error(f"Title suggestion failed: {e}", exc_info=True) logger.exception(f"Title suggestion failed: {e}")
return None return None
@ -719,13 +724,14 @@ class AIDocumentScanner:
logger.debug(f"Extracted {len(tables)} tables from document") logger.debug(f"Extracted {len(tables)} tables from document")
return tables return tables
except Exception as e: except Exception as e:
logger.error(f"Table extraction failed: {e}", exc_info=True) logger.exception(f"Table extraction failed: {e}")
return [] return []
def apply_scan_results( def apply_scan_results(
self, self,
document: Document, document: Document,
scan_result: AIScanResult, scan_result: AIScanResult,
*,
auto_apply: bool = True, auto_apply: bool = True,
user_confirmed: bool = False, user_confirmed: bool = False,
) -> dict[str, Any]: ) -> dict[str, Any]:
@ -842,7 +848,7 @@ class AIDocumentScanner:
document.save() document.save()
except Exception as e: except Exception as e:
logger.error(f"Failed to apply scan results: {e}", exc_info=True) logger.exception(f"Failed to apply scan results: {e}")
return { return {
"applied": applied, "applied": applied,

View file

@ -489,9 +489,11 @@ class ConsumerPlugin(
document=document, document=document,
logging_group=self.logging_group, logging_group=self.logging_group,
classifier=classifier, classifier=classifier,
original_file=self.unmodified_original original_file=(
if self.unmodified_original self.unmodified_original
else self.working_copy, if self.unmodified_original
else self.working_copy
),
) )
# After everything is in the database, copy the files into # After everything is in the database, copy the files into
@ -502,9 +504,11 @@ class ConsumerPlugin(
self._write( self._write(
document.storage_type, document.storage_type,
self.unmodified_original (
if self.unmodified_original is not None self.unmodified_original
else self.working_copy, if self.unmodified_original is not None
else self.working_copy
),
document.source_path, document.source_path,
) )
@ -865,9 +869,9 @@ class ConsumerPreflightPlugin(
Confirm the input file still exists where it should Confirm the input file still exists where it should
""" """
if TYPE_CHECKING: if TYPE_CHECKING:
assert isinstance(self.input_doc.original_file, Path), ( assert isinstance(
self.input_doc.original_file self.input_doc.original_file, Path,
) ), self.input_doc.original_file
if not self.input_doc.original_file.is_file(): if not self.input_doc.original_file.is_file():
self._fail( self._fail(
ConsumerStatusShortMessage.FILE_NOT_FOUND, ConsumerStatusShortMessage.FILE_NOT_FOUND,