Skip to content

Commit

Permalink
refactor: Improved type annotations (#986)
Browse files Browse the repository at this point in the history
Mostly replaced `typing` by `t`
Resolve the typing part of #958

---------

Co-authored-by: Jan Max Meyer <jmm@phorward.de>
Co-authored-by: Sven Eberth <mail@sveneberth.de>
  • Loading branch information
3 people committed Jan 9, 2024
1 parent 16f5a88 commit 30e9ced
Show file tree
Hide file tree
Showing 53 changed files with 419 additions and 418 deletions.
11 changes: 6 additions & 5 deletions src/viur/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import inspect
import warnings
from types import ModuleType
from typing import Callable, Dict, Union, List
import typing as t
from google.appengine.api import wrap_wsgi_app
import yaml
from viur.core import i18n, request, utils
Expand Down Expand Up @@ -84,7 +84,8 @@
# Show DeprecationWarning from the viur-core
warnings.filterwarnings("always", category=DeprecationWarning, module=r"viur\.core.*")

def load_indexes_from_file() -> Dict[str, List]:

def load_indexes_from_file() -> dict[str, list]:
"""
Loads all indexes from the index.yaml and stores it in a dictionary sorted by the module(kind)
:return A dictionary of indexes per module
Expand Down Expand Up @@ -127,7 +128,7 @@ def setDefaultDomainLanguage(domain: str, lang: str):
conf.i18n.domain_language_mapping[host] = lang.lower()


def buildApp(modules: Union[ModuleType, object], renderers: Union[ModuleType, Dict], default: str = None) -> Module:
def buildApp(modules: ModuleType | object, renderers: ModuleType | object, default: str = None) -> Module:
"""
Creates the application-context for the current instance.
Expand Down Expand Up @@ -234,7 +235,7 @@ def buildApp(modules: Union[ModuleType, object], renderers: Union[ModuleType, Di
return root


def setup(modules: Union[object, ModuleType], render: Union[ModuleType, Dict] = None, default: str = "html"):
def setup(modules: ModuleType | object, render: ModuleType | object = None, default: str = "html"):
"""
Define whats going to be served by this instance.
Expand Down Expand Up @@ -310,7 +311,7 @@ def setup(modules: Union[object, ModuleType], render: Union[ModuleType, Dict] =
return wrap_wsgi_app(app)


def app(environ: dict, start_response: Callable):
def app(environ: dict, start_response: t.Callable):
return request.Router(environ).response(environ, start_response)


Expand Down
56 changes: 28 additions & 28 deletions src/viur/core/bones/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import Enum
from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Union
import typing as t

from viur.core import db, utils
from viur.core.config import conf
Expand Down Expand Up @@ -76,9 +76,9 @@ class ReadFromClientError:
"""A ReadFromClientErrorSeverity enumeration value representing the severity of the error."""
errorMessage: str
"""A string containing a human-readable error message describing the issue."""
fieldPath: List[str] = field(default_factory=list)
fieldPath: list[str] = field(default_factory=list)
"""A list of strings representing the path to the field where the error occurred."""
invalidatedFields: List[str] = None
invalidatedFields: list[str] = None
"""A list of strings containing the names of invalidated fields, if any."""


Expand Down Expand Up @@ -192,18 +192,18 @@ def __init__(
self,
*,
compute: Compute = None,
defaultValue: Any = None,
defaultValue: t.Any = None,
descr: str = "",
getEmptyValueFunc: callable = None,
indexed: bool = True,
isEmptyFunc: callable = None, # fixme: Rename this, see below.
languages: Union[None, List[str]] = None,
multiple: Union[bool, MultipleConstraints] = False,
params: Dict = None,
languages: None | list[str] = None,
multiple: bool | MultipleConstraints = False,
params: dict = None,
readOnly: bool = None, # fixme: Rename into readonly (all lowercase!) soon.
required: Union[bool, List[str], Tuple[str]] = False,
required: bool | list[str] | tuple[str] = False,
searchable: bool = False,
unique: Union[None, UniqueValue] = None,
unique: None | UniqueValue = None,
vfunc: callable = None, # fixme: Rename this, see below.
visible: bool = True,
):
Expand Down Expand Up @@ -306,7 +306,7 @@ def isInvalid(self, value):
"""
return False

def isEmpty(self, value: Any) -> bool:
def isEmpty(self, value: t.Any) -> bool:
"""
Check if the given single value represents the "empty" value.
This usually is the empty string, 0 or False.
Expand Down Expand Up @@ -339,7 +339,7 @@ def getDefaultValue(self, skeletonInstance):
else:
return self.defaultValue

def getEmptyValue(self) -> Any:
def getEmptyValue(self) -> t.Any:
"""
Returns the value representing an empty field for this bone.
This might be the empty string for str/text Bones, Zero for numeric bones etc.
Expand Down Expand Up @@ -482,9 +482,9 @@ def parseSubfieldsFromClient(self) -> bool:
"""
return False

def singleValueFromClient(self, value: Any, skel: 'SkeletonInstance',
def singleValueFromClient(self, value: t.Any, skel: 'SkeletonInstance',
bone_name: str, client_data: dict
) -> tuple[Any, list[ReadFromClientError] | None]:
) -> tuple[t.Any, list[ReadFromClientError] | None]:
"""Load a single value from a client
:param value: The single value which should be loaded.
Expand All @@ -501,7 +501,7 @@ def singleValueFromClient(self, value: Any, skel: 'SkeletonInstance',
return self.getEmptyValue(), [
ReadFromClientError(ReadFromClientErrorSeverity.Invalid, "Will not read a BaseBone fromClient!")]

def fromClient(self, skel: 'SkeletonInstance', name: str, data: dict) -> Union[None, List[ReadFromClientError]]:
def fromClient(self, skel: 'SkeletonInstance', name: str, data: dict) -> None | list[ReadFromClientError]:
"""
Reads a value from the client and stores it in the skeleton instance if it is valid for the bone.
Expand Down Expand Up @@ -586,7 +586,7 @@ def fromClient(self, skel: 'SkeletonInstance', name: str, data: dict) -> Union[N
errors.extend(self.validateMultipleConstraints(skel, name))
return errors or None

def validateMultipleConstraints(self, skel: 'SkeletonInstance', name: str) -> List[ReadFromClientError]:
def validateMultipleConstraints(self, skel: 'SkeletonInstance', name: str) -> list[ReadFromClientError]:
"""
Validates the value of a bone against its multiple constraints and returns a list of ReadFromClientError
objects for each violation, such as too many items or duplicates.
Expand Down Expand Up @@ -844,8 +844,8 @@ def buildDBFilter(self,
name: str,
skel: 'viur.core.skeleton.SkeletonInstance',
dbFilter: db.Query,
rawFilter: Dict,
prefix: Optional[str] = None) -> db.Query:
rawFilter: dict,
prefix: t.Optional[str] = None) -> db.Query:
"""
Parses the searchfilter a client specified in his Request into
something understood by the datastore.
Expand Down Expand Up @@ -896,7 +896,7 @@ def buildDBSort(self,
name: str,
skel: 'viur.core.skeleton.SkeletonInstance',
dbFilter: db.Query,
rawFilter: Dict) -> Optional[db.Query]:
rawFilter: dict) -> t.Optional[db.Query]:
"""
Same as buildDBFilter, but this time its not about filtering
the results, but by sorting them.
Expand Down Expand Up @@ -945,7 +945,7 @@ def buildDBSort(self,
dbFilter.order(order)
return dbFilter

def _hashValueForUniquePropertyIndex(self, value: Union[str, int]) -> List[str]:
def _hashValueForUniquePropertyIndex(self, value: str | int) -> list[str]:
"""
Generates a hash of the given value for creating unique property indexes.
Expand All @@ -958,7 +958,7 @@ def _hashValueForUniquePropertyIndex(self, value: Union[str, int]) -> List[str]:
:return: A list containing a string representation of the hashed value. If the bone is multiple,
the list may contain more than one hashed value.
"""
def hashValue(value: Union[str, int]) -> str:
def hashValue(value: str | int) -> str:
h = hashlib.sha256()
h.update(str(value).encode("UTF-8"))
res = h.hexdigest()
Expand Down Expand Up @@ -994,7 +994,7 @@ def keyHash(key):
# Lock the value for that specific list
return [hashValue(", ".join(tmpList))]

def getUniquePropertyIndexValues(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> List[str]:
def getUniquePropertyIndexValues(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> list[str]:
"""
Returns a list of hashes for the current value(s) of a bone in the skeleton, used for storing in the
unique property value index.
Expand All @@ -1011,13 +1011,13 @@ def getUniquePropertyIndexValues(self, skel: 'viur.core.skeleton.SkeletonInstanc
return []
return self._hashValueForUniquePropertyIndex(val)

def getReferencedBlobs(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> Set[str]:
def getReferencedBlobs(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> set[str]:
"""
Returns a set of blob keys referenced from this bone
"""
return set()

def performMagic(self, valuesCache: Dict, name: str, isAdd: bool):
def performMagic(self, valuesCache: dict, name: str, isAdd: bool):
"""
This function applies "magically" functionality which f.e. inserts the current Date
or the current user.
Expand Down Expand Up @@ -1051,7 +1051,7 @@ def refresh(self, skel: 'viur.core.skeleton.SkeletonInstance', boneName: str) ->
"""
pass

def mergeFrom(self, valuesCache: Dict, boneName: str, otherSkel: 'viur.core.skeleton.SkeletonInstance'):
def mergeFrom(self, valuesCache: dict, boneName: str, otherSkel: 'viur.core.skeleton.SkeletonInstance'):
"""
Merges the values from another skeleton instance into the current instance, given that the bone types match.
Expand All @@ -1076,9 +1076,9 @@ def mergeFrom(self, valuesCache: Dict, boneName: str, otherSkel: 'viur.core.skel
def setBoneValue(self,
skel: 'SkeletonInstance',
boneName: str,
value: Any,
value: t.Any,
append: bool,
language: Union[None, str] = None) -> bool:
language: None | str = None) -> bool:
"""
Sets the value of a bone in a skeleton instance, with optional support for appending and language-specific
values. Sanity checks are being performed.
Expand Down Expand Up @@ -1132,7 +1132,7 @@ def setBoneValue(self,
skel[boneName][language] = val
return True

def getSearchTags(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> Set[str]:
def getSearchTags(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> set[str]:
"""
Returns a set of strings as search index for this bone.
Expand All @@ -1150,7 +1150,7 @@ def getSearchTags(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str)

def iter_bone_value(
self, skel: 'viur.core.skeleton.SkeletonInstance', name: str
) -> Iterator[Tuple[Optional[int], Optional[str], Any]]:
) -> t.Iterator[tuple[t.Optional[int], t.Optional[str], t.Any]]:
"""
Yield all values from the Skeleton related to this bone instance.
Expand Down
14 changes: 5 additions & 9 deletions src/viur/core/bones/boolean.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List, Optional, Union
import typing as t

from viur.core import conf, db, utils
from viur.core.bones.base import BaseBone
Expand All @@ -18,11 +18,7 @@ class BooleanBone(BaseBone):
def __init__(
self,
*,
defaultValue: Union[
bool,
List[bool],
Dict[str, Union[List[bool], bool]],
] = None,
defaultValue: bool | list[bool] | dict[str, list[bool] | bool] = None,
**kwargs
):
if defaultValue is None:
Expand Down Expand Up @@ -56,7 +52,7 @@ def getEmptyValue(self):
"""
return False

def isEmpty(self, value: Any):
def isEmpty(self, value: t.Any):
"""
Checks if the given boolean value is empty.
Expand Down Expand Up @@ -85,8 +81,8 @@ def buildDBFilter(
name: str,
skel: 'viur.core.skeleton.SkeletonInstance',
dbFilter: db.Query,
rawFilter: Dict,
prefix: Optional[str] = None
rawFilter: dict,
prefix: t.Optional[str] = None
) -> db.Query:
"""
Builds a database filter based on the boolean value.
Expand Down
4 changes: 2 additions & 2 deletions src/viur/core/bones/captcha.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
import urllib.parse
import urllib.request
from typing import List, Union
import typing as t

from viur.core import conf, current
from viur.core.bones.base import BaseBone, ReadFromClientError, ReadFromClientErrorSeverity
Expand Down Expand Up @@ -49,7 +49,7 @@ def unserialize(self, skel, name) -> bool:
skel.accessedValues[name] = self.publicKey
return True

def fromClient(self, skel: 'SkeletonInstance', name: str, data: dict) -> Union[None, List[ReadFromClientError]]:
def fromClient(self, skel: 'SkeletonInstance', name: str, data: dict) -> None | list[ReadFromClientError]:
"""
Reads a value from the client.
If this value is valid for this bone,
Expand Down
6 changes: 3 additions & 3 deletions src/viur/core/bones/date.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import datetime, timedelta, timezone
from typing import Dict, Optional
import typing as t

import pytz
import tzlocal
Expand Down Expand Up @@ -316,8 +316,8 @@ def buildDBFilter(self,
name: str,
skel: 'viur.core.skeleton.SkeletonInstance',
dbFilter: db.Query,
rawFilter: Dict,
prefix: Optional[str] = None) -> db.Query:
rawFilter: dict,
prefix: t.Optional[str] = None) -> db.Query:
"""
Constructs a datastore filter for date and/or time values based on the given raw filter. It parses the
raw filter and, if successful, applies it to the datastore query.
Expand Down
14 changes: 7 additions & 7 deletions src/viur/core/bones/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from hashlib import sha256
from time import time
from typing import Any, Dict, List, Set, Union
import typing as t
from viur.core import conf, db
from viur.core.bones.treeleaf import TreeLeafBone
from viur.core.tasks import CallDeferred
Expand All @@ -16,15 +16,15 @@


@CallDeferred
def ensureDerived(key: db.Key, srcKey, deriveMap: Dict[str, Any], refreshKey: db.Key = None):
def ensureDerived(key: db.Key, srcKey, deriveMap: dict[str, t.Any], refreshKey: db.Key = None):
r"""
The function is a deferred function that ensures all pending thumbnails or other derived files
are built. It takes the following parameters:
:param db.key key: The database key of the file-object that needs to have its derivation map
updated.
:param str srcKey: A prefix for a stable key to prevent rebuilding derived files repeatedly.
:param Dict[str,Any] deriveMap: A list of DeriveDicts that need to be built or updated.
:param dict[str,Any] deriveMap: A list of DeriveDicts that need to be built or updated.
:param db.Key refreshKey: If set, the function fetches and refreshes the skeleton after
building new derived files.
Expand Down Expand Up @@ -139,9 +139,9 @@ class FileBone(TreeLeafBone):
def __init__(
self,
*,
derive: Union[None, Dict[str, Any]] = None,
maxFileSize: Union[None, int] = None,
validMimeTypes: Union[None, List[str]] = None,
derive: None | dict[str, t.Any] = None,
maxFileSize: None | int = None,
validMimeTypes: None | list[str] = None,
**kwargs
):
r"""
Expand Down Expand Up @@ -231,7 +231,7 @@ def handleDerives(values):
else:
handleDerives(values)

def getReferencedBlobs(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> Set[str]:
def getReferencedBlobs(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) -> set[str]:
r"""
Retrieves the referenced blobs in the FileBone.
Expand Down
6 changes: 3 additions & 3 deletions src/viur/core/bones/json.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ast
import json
from typing import Mapping, Union
import typing as t

import jsonschema

Expand All @@ -23,7 +23,7 @@ class JsonBone(RawBone):

type = "raw.json"

def __init__(self, indexed: bool = False, multiple: bool = False, languages: bool = None, schema: Mapping = {},
def __init__(self, indexed: bool = False, multiple: bool = False, languages: bool = None, schema: t.Mapping = {},
*args,
**kwargs):
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -52,7 +52,7 @@ def unserialize(self, skel: 'viur.core.skeleton.SkeletonInstance', name: str) ->

return False

def singleValueFromClient(self, value: Union[str, list, dict], skel, bone_name, client_data):
def singleValueFromClient(self, value: str | list | dict, skel, bone_name, client_data):
if value:
if not isinstance(value, (list, dict)):
value = str(value)
Expand Down
Loading

0 comments on commit 30e9ced

Please sign in to comment.