Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 827ff61

Browse files
committedApr 5, 2023
Fix backend test failing due to recursive type
More specifically, our version of mypy has a known issue regarding processing the type hints for subclasses of NamedTuples which reference themselves. i.e., using the "DeferredScopeUploadTable" type hint in the DeferredScopeUploadTable class For more details, see python/mypy#8695
1 parent a45cc14 commit 827ff61

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed
 

‎specifyweb/workbench/upload/upload_table.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
import logging
33
from functools import reduce
4-
from typing import List, Dict, Any, NamedTuple, Union, Optional, Set, Callable, Literal
4+
from typing import List, Dict, Any, NamedTuple, Union, Optional, Set, Callable, Literal, get_type_hints
55

66
from django.db import transaction, IntegrityError
77

@@ -79,13 +79,23 @@ class DeferredScopeUploadTable(NamedTuple):
7979
relationship_name: str
8080
filter_field: str
8181

82-
# In a DeferredScopeUploadTable, the overrideScope value can be either an integer
83-
# (which follows the same logic as in UploadTable), or a function which has the parameter
84-
# signature: (deferred_upload_plan: DeferredScopeUploadTable, row_index: int) -> models.Collection
85-
# (see apply_deferred_scopes in .upload.py)
86-
overrideScope: Optional[Dict[Literal["collection"], Union[int, Callable[["DeferredScopeUploadTable", int], Any]]]] = None
82+
""" In a DeferredScopeUploadTable, the overrideScope value can be either an integer
83+
(which follows the same logic as in UploadTable), or a function which has the parameter
84+
signature: (deferred_upload_plan: DeferredScopeUploadTable, row_index: int) -> models.Collection
85+
(see apply_deferred_scopes in .upload.py)
8786
88-
def apply_scoping(self, collection, defer: bool = True) -> Union["ScopedUploadTable", "DeferredScopeUploadTable"]:
87+
overrideScope should be of type
88+
Optional[Dict[Literal["collection"], Union[int, Callable[["DeferredScopeUploadTable", int], Any]]]]
89+
90+
But recursively using the type within the class definition of a NamedTuple is not supported in our version
91+
of mypy
92+
See https://github.com/python/mypy/issues/8695
93+
"""
94+
overrideScope: Optional[Dict[Literal["collection"], Union[int, Callable[[NamedTuple, int], Any]]]] = None
95+
96+
97+
# Typehint for return type should be: Union["ScopedUploadTable", "DeferredScopeUploadTable"]
98+
def apply_scoping(self, collection, defer: bool = True) -> Union["ScopedUploadTable", NamedTuple]:
8999
if not defer:
90100
from .scoping import apply_scoping_to_uploadtable
91101
return apply_scoping_to_uploadtable(self, collection)
@@ -96,7 +106,12 @@ def get_cols(self) -> Set[str]:
96106
| set(col for u in self.toOne.values() for col in u.get_cols()) \
97107
| set(col for rs in self.toMany.values() for r in rs for col in r.get_cols())
98108

99-
def add_colleciton_override(self, collection: Union[int, Callable[["DeferredScopeUploadTable", int], Any]]) -> "DeferredScopeUploadTable":
109+
110+
"""
111+
The Typehint for parameter collection should be: Union[int, Callable[["DeferredScopeUploadTable", int], Any]]
112+
The Typehint for return type should be: "DeferredScopeUploadTable"
113+
"""
114+
def add_colleciton_override(self, collection: Union[int, Callable[[NamedTuple, int], Any]]) -> NamedTuple:
100115
''' To modify the overrideScope after the DeferredScope UploadTable is created, use add_colleciton_override
101116
To properly apply scoping (see self.bind()), the <collection> should either be a collection's id, or a callable (function),
102117
which has paramaters that accept: this DeferredScope UploadTable, and an integer representing the current row_index.

0 commit comments

Comments
 (0)
Please sign in to comment.