Source code for jangle.utils
import re
from itertools import islice
from typing import Any, Iterable, Optional, TypeVar
from django.db import models
[docs]class StrReprCls:
"""Provides __repr__ showing
the object's module, class name and string representation.
"""
def __repr__(self) -> str:
return f"<{self.__module__}.{type(self).__qualname__} '{str(self)}'>"
[docs]def findattr(obj, path) -> Optional[Any]:
"""This thing is goofy. Don't use it."""
if isinstance(path, tuple):
for subpath in path:
attr = findattr(obj, subpath)
if attr is not None:
return attr
elif isinstance(path, list):
if len(path) < 1:
raise ValueError("empty path")
obj = getattr(obj, path.pop(0))
if not path:
return obj
elif len(path) > 1:
return findattr(obj, path)
else:
raise TypeError(
"path should be list[str | tuple] or tuple[str | list]"
)
[docs]def choice_from_iana(choices: type[models.TextChoices], string: str) -> Any:
"""Chooses a Django TextChoices field from text used in the IANA registry."""
return getattr(choices, string.upper().replace("-", "_"))
_T = TypeVar("_T", bound=models.Model)
[docs]class BatchedCreateManager(models.Manager[_T]):
""""""
[docs] def batched_create(self, objs: Iterable, batch_size=64, **kwargs) -> None:
"""Bulk-creates objects in batches of specified size."""
it = iter(objs)
while True:
batch = list(islice(it, batch_size))
if not batch:
break
self.bulk_create(batch, batch_size, **kwargs)