diff --git a/src/linkahead/common/versioning.py b/src/linkahead/common/versioning.py index facfbc488e413e090ea1a856501ccd96334f8354..beced57a277e8bacae18b9be0bc2f5879a378b04 100644 --- a/src/linkahead/common/versioning.py +++ b/src/linkahead/common/versioning.py @@ -26,10 +26,15 @@ Currently this module defines nothing but a single class, `Version`. """ -from __future__ import absolute_import +from __future__ import absolute_import, annotations from .utils import xml2str from lxml import etree +from typing import TYPE_CHECKING +import sys +if TYPE_CHECKING and sys.version_info > (3, 7): + from typing import Optional, List, Union, Literal + class Version(): """The version of an entity. @@ -95,9 +100,11 @@ class Version(): """ # pylint: disable=redefined-builtin - def __init__(self, id=None, date=None, username=None, realm=None, - predecessors=None, successors=None, is_head=False, - is_complete_history=False): + def __init__(self, id: Optional[str] = None, date: Optional[str] = None, + username: Optional[str] = None, realm: Optional[str] = None, + predecessors: Optional[List[Version]] = None, successors: Optional[List[Version]] = None, + is_head: Union[bool, str] = False, + is_complete_history: Union[bool, str] = False): """Typically the `predecessors` or `successors` should not "link back" to an existing Version object.""" self.id = id @@ -109,7 +116,7 @@ object.""" self.is_head = str(is_head).lower() == "true" self.is_complete_history = str(is_complete_history).lower() == "true" - def get_history(self): + def get_history(self) -> List[Version]: """ Returns a flat list of Version instances representing the history of the entity. @@ -126,7 +133,7 @@ object.""" ------- list of Version """ - versions = [] + versions: List[Version] = [] for p in self.predecessors: # assuming that predecessors don't have any successors versions = p.get_history() @@ -137,7 +144,7 @@ object.""" versions.extend(s.get_history()) return versions - def to_xml(self, tag="Version"): + def to_xml(self, tag: str = "Version") -> etree._Element: """Serialize this version to xml. The tag name is 'Version' per default. But since this method is called @@ -184,7 +191,7 @@ object.""" return xml2str(self.to_xml()) @staticmethod - def from_xml(xml): + def from_xml(xml: etree._Element) -> Version: """Parse a version object from a 'Version' xml element. Parameters @@ -199,11 +206,22 @@ object.""" version : Version a new version instance """ - predecessors = [Version.from_xml(p) for p in xml if p.tag.lower() == "predecessor"] - successors = [Version.from_xml(s) for s in xml if s.tag.lower() == "successor"] + predecessors = [Version.from_xml( + p) for p in xml if p.tag.lower() == "predecessor"] + successors = [Version.from_xml(s) + for s in xml if s.tag.lower() == "successor"] + is_head = xml.get("head") + if is_head is None: + raise ValueError(f"Version head is missing from xml:{str(xml)}") + + is_complete_history = xml.get("completeHistory") + if is_complete_history is None: + raise ValueError( + f"Version completeHistory is missing from xml:{str(xml)}") + return Version(id=xml.get("id"), date=xml.get("date"), - is_head=xml.get("head"), - is_complete_history=xml.get("completeHistory"), + is_head=is_head, + is_complete_history=is_complete_history, username=xml.get("username"), realm=xml.get("realm"), predecessors=predecessors, successors=successors)