From 00e14b8bd77a7ac74af0e7cb13ed2a4e35414d5e Mon Sep 17 00:00:00 2001
From: George Katsikas <giorgakis.katsikas@gmail.com>
Date: Wed, 20 Mar 2024 12:15:20 +0100
Subject: [PATCH] add minor static typing annotations and exceptions

---
 scipost_django/production/models.py             | 17 ++++++++++++-----
 scipost_django/submissions/models/submission.py |  7 +++++--
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/scipost_django/production/models.py b/scipost_django/production/models.py
index f8f283eea..e7e9445ab 100644
--- a/scipost_django/production/models.py
+++ b/scipost_django/production/models.py
@@ -2,7 +2,7 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
-from typing import List
+from typing import TYPE_CHECKING
 from django.db import models
 from django.contrib.contenttypes.fields import GenericRelation
 from django.urls import reverse
@@ -43,6 +43,9 @@ from .utils import proofs_id_to_slug
 from finances.models import WorkLog
 from scipost.storage import SecureFileStorage
 
+if TYPE_CHECKING:
+    from submissions.models import Submission
+
 
 class ProductionUser(models.Model):
     """
@@ -68,7 +71,7 @@ class ProductionUser(models.Model):
 
 
 class ProductionStream(models.Model):
-    submission = models.OneToOneField(
+    submission = models.OneToOneField["Submission"](
         "submissions.Submission",
         on_delete=models.CASCADE,
         related_name="production_stream",
@@ -297,7 +300,7 @@ class ProofsRepository(models.Model):
         (PROOFS_REPO_PRODUCTION_READY, "The repository is ready for production"),
     )
 
-    stream = models.OneToOneField(
+    stream = models.OneToOneField["ProductionStream"](
         ProductionStream,
         on_delete=models.CASCADE,
         related_name="proofs_repository",
@@ -348,7 +351,11 @@ class ProofsRepository(models.Model):
         a Selections paper, it is the flagship journal of the college.
         """
 
-        decision_journal = self.stream.submission.editorial_decision.for_journal
+        # Guard against null editorial decision
+        if not (decision := self.stream.submission.editorial_decision):
+            raise ValueError("No (non-deprecated) editorial decision exists")
+
+        decision_journal = decision.for_journal
 
         if "Selections" in decision_journal.name:
             paper_field = self.stream.submission.acad_field
@@ -410,7 +417,7 @@ class ProofsRepository(models.Model):
         )
 
     @cached_property
-    def template_paths(self) -> List[str]:
+    def template_paths(self) -> list[str]:
         """
         Return the list of paths to the various templates used for the proofs.
         """
diff --git a/scipost_django/submissions/models/submission.py b/scipost_django/submissions/models/submission.py
index 332e5bf3d..20ffdbddf 100644
--- a/scipost_django/submissions/models/submission.py
+++ b/scipost_django/submissions/models/submission.py
@@ -3,7 +3,7 @@ __license__ = "AGPL v3"
 
 
 import datetime
-from typing import List
+from typing import TYPE_CHECKING
 import feedparser
 import uuid
 
@@ -43,6 +43,9 @@ from ..exceptions import StageNotDefinedError
 from ..managers import SubmissionQuerySet, SubmissionEventQuerySet
 from ..refereeing_cycles import ShortCycle, DirectCycle, RegularCycle
 
+if TYPE_CHECKING:
+    from submissions.models import EditorialDecision
+
 
 class SubmissionAuthorProfile(models.Model):
     submission = models.ForeignKey(
@@ -942,7 +945,7 @@ class Submission(models.Model):
         return list(set(fellows))
 
     @property
-    def editorial_decision(self):
+    def editorial_decision(self) -> "EditorialDecision | None":
         """Returns the latest EditorialDecision (if it exists)."""
         if self.editorialdecision_set.nondeprecated().exists():
             return self.editorialdecision_set.nondeprecated().latest_version()
-- 
GitLab