diff --git a/src/linkahead/common/datatype.py b/src/linkahead/common/datatype.py index 65e6246c0287f0af07aa604f4bc18ce54615cae2..4aaa68d40b803554b8a0772d0a4c9b5404d6805a 100644 --- a/src/linkahead/common/datatype.py +++ b/src/linkahead/common/datatype.py @@ -22,12 +22,16 @@ # # ** end header # - +from __future__ import annotations import re import sys -if sys.version_info >= (3, 8): - from typing import Literal +from typing import TYPE_CHECKING +if TYPE_CHECKING and sys.version_info > (3, 7): + from typing import Literal, Union, List + from linkahead.common.models import Entity, Container + DATATYPE = Literal["DOUBLE", "REFERENCE", "TEXT", "DATETIME", "INTEGER", "FILE", "BOOLEAN"] + from ..exceptions import EmptyUniqueQueryError, QueryNotUniqueError @@ -38,11 +42,9 @@ DATETIME = "DATETIME" INTEGER = "INTEGER" FILE = "FILE" BOOLEAN = "BOOLEAN" -if sys.version_info >= (3, 8): - DATATYPE = Literal["DOUBLE", "REFERENCE", "TEXT", "DATETIME", "INTEGER", "FILE", "BOOLEAN"] -def LIST(datatype): +def LIST(datatype: Union[str, Entity, DATATYPE]) -> str: # FIXME May be ambiguous (if name duplicate) or insufficient (if only ID exists). if hasattr(datatype, "name"): datatype = datatype.name @@ -50,7 +52,7 @@ def LIST(datatype): return "LIST<" + str(datatype) + ">" -def get_list_datatype(datatype: str, strict: bool = False): +def get_list_datatype(datatype: str, strict: bool = False) -> Union[str, None]: """Returns the datatype of the elements in the list. If it not a list, return None.""" # TODO Union[str, Entity] if not isinstance(datatype, str) or not datatype.lower().startswith("list"): @@ -74,13 +76,13 @@ def get_list_datatype(datatype: str, strict: bool = False): return None -def is_list_datatype(datatype): +def is_list_datatype(datatype: str) -> bool: """ returns whether the datatype is a list """ return get_list_datatype(datatype) is not None -def is_reference(datatype): +def is_reference(datatype: str) -> bool: """Returns whether the value is a reference FILE and REFERENCE properties are examples, but also datatypes that are @@ -105,12 +107,12 @@ def is_reference(datatype): if datatype in [DOUBLE, BOOLEAN, INTEGER, TEXT, DATETIME]: return False elif is_list_datatype(datatype): - return is_reference(get_list_datatype(datatype)) + return is_reference(get_list_datatype(datatype)) # type: ignore else: return True -def get_referenced_recordtype(datatype): +def get_referenced_recordtype(datatype: str) -> str: """Return the record type of the referenced datatype. Raises @@ -134,7 +136,7 @@ def get_referenced_recordtype(datatype): raise ValueError("datatype must be a reference") if is_list_datatype(datatype): - datatype = get_list_datatype(datatype) + datatype = get_list_datatype(datatype) # type: ignore if datatype is None: raise ValueError("list does not have a list datatype") @@ -145,7 +147,7 @@ def get_referenced_recordtype(datatype): return datatype -def get_id_of_datatype(datatype): +def get_id_of_datatype(datatype: str) -> int: """ returns the id of a Record Type This is not trivial, as queries may also return children. A check comparing @@ -170,12 +172,14 @@ def get_id_of_datatype(datatype): from .models import execute_query if is_list_datatype(datatype): - datatype = get_list_datatype(datatype) + datatype = get_list_datatype(datatype) # type: ignore q = "FIND RECORDTYPE {}".format(datatype) # we cannot use unique=True here, because there might be subtypes res = execute_query(q) - res = [el for el in res if el.name.lower() == datatype.lower()] + if isinstance(res, int): + raise ValueError("FIND RECORDTYPE query returned an `int`") + res: List[Entity] = [el for el in res if el.name.lower() == datatype.lower()] # type: ignore if len(res) > 1: raise QueryNotUniqueError( diff --git a/src/linkahead/common/models.py b/src/linkahead/common/models.py index aa68817511332ea570a3c2a40d400b21a2ed5658..d1c1c264c6fbdfbfcdacc14232adecd4068eea96 100644 --- a/src/linkahead/common/models.py +++ b/src/linkahead/common/models.py @@ -3528,12 +3528,14 @@ class Container(list): dependent_references = set() dependencies = set() + container_item: Entity for container_item in container: item_id.add(container_item.id) for parents in container_item.get_parents(): is_parent.add(parents.id) + prop: Property for prop in container_item.get_properties(): prop_dt = prop.datatype if prop_dt is not None and is_reference(prop_dt):