diff --git a/src/linkahead/common/models.py b/src/linkahead/common/models.py index f34a474f158dc3d90994ffabf7ab9d92bab067ce..4d4692e7279e9208839ba00291e3acb033a02ffb 100644 --- a/src/linkahead/common/models.py +++ b/src/linkahead/common/models.py @@ -52,7 +52,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: from datetime import datetime - from typing import Any, Literal, Optional, Type, Union, List + from typing import Any, Literal, Optional, Type, Union, List, TextIO from warnings import warn @@ -127,12 +127,12 @@ class Entity: ): self.__role = kwargs["role"] if "role" in kwargs else None - self._checksum = None + self._checksum: Optional[str]= None self._size = None self._upload = None # If an entity is used (e.g. as parent), it is wrapped instead of being used directly. # see Entity._wrap() - self._wrapped_entity = None + self._wrapped_entity: Optional[Entity] = None self._version = None self._cuid = None self._flags = dict() @@ -392,8 +392,15 @@ class Entity: permission=permission, priority=priority, revoke_denial=revoke_denial) - def deny(self, realm=None, username=None, role=None, - permission=None, priority=False, revoke_grant=True): + def deny( + self, + realm: Optional[str] = None, + username: Optional[str] = None, + role: Optional[str] = None, + permission: str = None, + priority: bool = False, + revoke_grant: bool = True, + ): """Deny a permission to a user or role for this entity. You must specify either only the username and the realm, or only the @@ -445,7 +452,7 @@ class Entity: permission=permission, priority=priority) - def is_permitted(self, permission, role=None): + def is_permitted(self, permission: str, role: Optional[str] = None): if role is None: # pylint: disable=unsupported-membership-test @@ -453,7 +460,7 @@ class Entity: else: self.acl.is_permitted(permission=permission) - def get_all_messages(self): + def get_all_messages(self) -> Messages: ret = Messages() ret.append(self.messages) @@ -1184,7 +1191,12 @@ out: List[Entity] return False - def to_xml(self, xml=None, add_properties=ALL, local_serialization=False): + def to_xml( + self, + xml: Optional[etree._Element] = None, + add_properties=ALL, + local_serialization=False, + ): """Generate an xml representation of this entity. If the parameter xml is given, all attributes, parents, properties, and messages of this entity will be added to it instead of creating a new element. @@ -1206,7 +1218,7 @@ out: List[Entity] # unwrap wrapped entity if self._wrapped_entity is not None: - xml = self._wrapped_entity.to_xml(xml, add_properties) + xml: etree._Element = self._wrapped_entity.to_xml(xml, add_properties) if self.id is not None: xml.set("id", str(self.id)) @@ -2054,7 +2066,12 @@ class Record(Entity): property=property, id=id, name=name, description=description, datatype=datatype, value=value, unit=unit, importance=importance, inheritance=inheritance) - def __init__(self, name=None, id=None, description=None): # @ReservedAssignment + def __init__( + self, + name: Optional[str] = None, + id: Optional[int] = None, + description: Optional[str] = None, + ): # @ReservedAssignment Entity.__init__(self, name=name, id=id, description=description, role="Record") @@ -2095,9 +2112,17 @@ class File(Record): """ - def __init__(self, name=None, id=None, description=None, # @ReservedAssignment - path=None, file=None, pickup=None, # @ReservedAssignment - thumbnail=None, from_location=None): + def __init__( + self, + name: Optional[str] = None, + id: Optional[int] = None, + description: Optional[str] = None, # @ReservedAssignment + path: Optional[str] = None, + file: Union[str, TextIO, None] = None, + pickup: Optional[str] = None, # @ReservedAssignment + thumbnail: Optional[str] = None, + from_location=None, + ): Record.__init__(self, id=id, name=name, description=description) self.role = "File" self.datatype = None @@ -2233,7 +2258,7 @@ class _Properties(list): if property is not None: self._importance[property] = importance - def get_by_name(self, name): + def get_by_name(self, name: str) -> Property: """Get a property of this list via it's name. Raises a LinkAheadException if not exactly one property has this name. @@ -2275,7 +2300,9 @@ class _Properties(list): return self - def to_xml(self, add_to_element, add_properties): + def to_xml( + self, add_to_element: etree._Element, add_properties: Union[str, Inheritance] + ): for p in self: importance = self._importance.get(p) @@ -2300,7 +2327,7 @@ class _Properties(list): return xml2str(xml) - def _get_entity_by_cuid(self, cuid): + def _get_entity_by_cuid(self, cuid: str): ''' Get the first entity which has the given cuid. Note: this method is intended for internal use. @@ -2314,7 +2341,7 @@ class _Properties(list): return e raise KeyError("No entity with that cuid in this container.") - def remove(self, prop): + def remove(self, prop: Union[Entity, int]): if isinstance(prop, Entity): if prop in self: list.remove(self, prop) @@ -2438,7 +2465,7 @@ class _ParentList(list): return xml2str(xml) - def remove(self, parent): + def remove(self, parent: Union[Entity, int, str]): if isinstance(parent, Entity): if parent in self: list.remove(self, parent) @@ -4032,7 +4059,15 @@ def get_global_acl(): class ACI(): - def __init__(self, realm, username, role, permission): + """FIXME: Add docstring""" + + def __init__( + self, + realm: Optional[str], + username: Optional[str], + role: Optional[str], + permission: Optional[str], + ): self.role = role self.username = username self.realm = realm @@ -4048,7 +4083,7 @@ class ACI(): def __repr__(self): return str(self.realm) + ":" + str(self.username) + ":" + str(self.role) + ":" + str(self.permission) - def add_to_element(self, e): + def add_to_element(self, e: etree._Element): if self.role is not None: e.set("role", self.role) else: @@ -4062,16 +4097,17 @@ class ACI(): class ACL(): + """FIXME: Add docstring""" - global_acl = None + global_acl: Optional[ACL] = None - def __init__(self, xml=None): + def __init__(self, xml: Optional[etree._Element] = None): if xml is not None: self.parse_xml(xml) else: self.clear() - def parse_xml(self, xml): + def parse_xml(self, xml: etree._Element): """Clear this ACL and parse the xml. Iterate over the rules in the xml and add each rule to this ACL. @@ -4080,14 +4116,14 @@ class ACL(): Parameters ---------- - xml : lxml.etree.Element + xml : lxml.etree._Element The xml element containing the ACL rules, i.e. <Grant> and <Deny> rules. """ self.clear() self._parse_xml(xml) - def _parse_xml(self, xml): + def _parse_xml(self, xml: etree._Element): """Parse the xml. Iterate over the rules in the xml and add each rule to this ACL. @@ -4096,7 +4132,7 @@ class ACL(): Parameters ---------- - xml : lxml.etree.Element + xml : lxml.etree._Element The xml element containing the ACL rules, i.e. <Grant> and <Deny> rules. """ @@ -4120,7 +4156,7 @@ class ACL(): permission=permission, priority=priority, revoke_grant=False) - def combine(self, other): + def combine(self, other: ACL): """ Combine and return new instance.""" result = ACL() result._grants.update(other._grants) @@ -4142,15 +4178,15 @@ class ACL(): len(self._priority_denials) + len(self._denials) == 0 def clear(self): - self._grants = set() - self._denials = set() - self._priority_grants = set() - self._priority_denials = set() + self._grants: set[ACI] = set() + self._denials: set[ACI] = set() + self._priority_grants: set[ACI] = set() + self._priority_denials: set[ACI] = set() - def _get_boolean_priority(self, priority): + def _get_boolean_priority(self, priority: str): return str(priority).lower() in ["true", "1", "yes", "y"] - def _remove_item(self, item, priority): + def _remove_item(self, item, priority: str): try: self._denials.remove(item) except KeyError: @@ -4170,8 +4206,14 @@ class ACL(): except KeyError: pass - def revoke_grant(self, username=None, realm=None, - role=None, permission=None, priority=False): + def revoke_grant( + self, + username: Optional[str] = None, + realm: Optional[str] = None, + role: Optional[str] = None, + permission: str = None, + priority: Union[bool, str] = False, + ): priority = self._get_boolean_priority(priority) item = ACI(role=role, username=username, realm=realm, permission=permission) @@ -4196,8 +4238,15 @@ class ACL(): if item in self._denials: self._denials.remove(item) - def grant(self, permission, username=None, realm=None, role=None, - priority=False, revoke_denial=True): + def grant( + self, + permission: str, + username: Optional[str] = None, + realm: Optional[str] = None, + role: Optional[str] = None, + priority: bool = False, + revoke_denial: bool = True, + ): """Grant a permission to a user or role. You must specify either only the username and the realm, or only the @@ -4238,8 +4287,15 @@ class ACL(): else: self._grants.add(item) - def deny(self, username=None, realm=None, role=None, - permission=None, priority=False, revoke_grant=True): + def deny( + self, + username: Optional[str] = None, + realm: Optional[str] = None, + role: Optional[str] = None, + permission: str = None, + priority: bool = False, + revoke_grant: bool = True, + ): """Deny a permission to a user or role for this entity. You must specify either only the username and the realm, or only the @@ -4280,7 +4336,7 @@ class ACL(): else: self._denials.add(item) - def to_xml(self, xml=None): + def to_xml(self, xml: Optional[etree._Element] = None): if xml is None: xml = etree.Element("EntityACL") @@ -4310,7 +4366,7 @@ class ACL(): return xml - def get_acl_for_role(self, role): + def get_acl_for_role(self, role: str) -> ACL: ret = ACL() for aci in self._grants: @@ -4356,7 +4412,7 @@ class ACL(): return ret - def get_permissions_for_user(self, username, realm=None): + def get_permissions_for_user(self, username: str, realm: Optional[str] = None): acl = self.get_acl_for_user(username, realm) _grants = set() @@ -4377,7 +4433,7 @@ class ACL(): return ((_grants - _denials) | _priority_grants) - _priority_denials - def get_permissions_for_role(self, role): + def get_permissions_for_role(self, role: str): acl = self.get_acl_for_role(role) _grants = set()