Module graia.broadcast.utilles
Expand source code
import inspect
import itertools
from functools import lru_cache
from typing import (
Any,
Callable,
Generator,
Generic,
Iterable,
List,
Tuple,
TypeVar,
Union,
)
from iterwrapper import IterWrapper
from .entities.dispatcher import BaseDispatcher
async def run_always_await(any_callable):
if inspect.iscoroutine(any_callable):
return await any_callable
else:
return any_callable
async def run_always_await_safely(callable, *args, **kwargs):
if iscoroutinefunction(callable):
return await callable(*args, **kwargs)
return callable(*args, **kwargs)
def printer(value):
print(value)
return value
def group_dict(iw: IterWrapper, key: Callable[[Any], Any]):
temp = {}
for i in iw:
k = key(i)
temp.setdefault(k, [])
temp[k].append(i)
return temp
cache_size = 4096
origin_isinstance = isinstance
cached_isinstance = lru_cache(1024)(isinstance)
cached_getattr = lru_cache(cache_size)(getattr)
@lru_cache(cache_size)
def argument_signature(callable_target):
return [
(
name,
param.annotation if param.annotation != inspect._empty else None,
param.default if param.default != inspect._empty else None,
)
for name, param in dict(inspect.signature(callable_target).parameters).items()
]
@lru_cache(cache_size)
def is_asyncgener(o):
return inspect.isasyncgenfunction(o)
@lru_cache(cache_size)
def iscoroutinefunction(o):
return inspect.iscoroutinefunction(o)
@lru_cache(cache_size)
def isasyncgen(o):
return inspect.isasyncgen(o)
def flat_yield_from(l):
for i in l:
if type(i) == list:
yield from i
@lru_cache(None)
def dispatcher_mixin_handler(dispatcher: BaseDispatcher) -> List[BaseDispatcher]:
unbound_mixin = getattr(dispatcher, "mixin", [])
result = [dispatcher]
for i in unbound_mixin:
if issubclass(i, BaseDispatcher):
result.extend(dispatcher_mixin_handler(i))
else:
result.append(i)
return result
class as_sliceable:
def __init__(self, iterable) -> None:
self.iterable = iterable
def __getitem__(self, item: Union[slice, int]) -> Any:
if isinstance(item, slice):
return itertools.islice(self.iterable, item.start, item.stop, item.step)
else:
return list(itertools.islice(self.iterable, item, item + 1, None))[0]
def __iter__(self):
return self.iterable
T = TypeVar("T")
"""
class NestableIterable(Iterable[T]):
index_stack: list
iterable: Iterable[T]
def __init__(self, iterable: Iterable[T]) -> None:
self.iterable = iterable
self.index_stack = [0]
def __iter__(self):
index = self.index_stack[-1]
self.index_stack.append(self.index_stack[-1])
start_offset = index + int(bool(index))
try:
for self.index_stack[-1], content in enumerate(
itertools.islice(self.iterable, start_offset, None, None),
start=start_offset,
):
yield content
finally:
self.index_stack.pop()
def with_new(self, target):
self.iterable = target
return self
"""
I = TypeVar("I")
class NestableIterable(Generic[I, T]):
iterable: Iterable[T]
indexes: List[I]
generator_with_index_factory: Callable[
[Iterable[T], I], Generator[None, None, Tuple[I, T]]
]
index_increase_func: Callable[[I, Iterable[T]], I]
is_index_origin: Callable[[I], bool]
@staticmethod
def default_generator_factory(iterable: Iterable[T], start: I):
return enumerate(iterable[start:], start=start)
def __init__(
self,
iterable: Iterable[T],
generator_with_index_factory: Callable[
[Iterable[T], I], Generator[None, None, Tuple[I, T]]
] = None,
index_increase_func: Callable[[I, Iterable[T]], I] = lambda x, _: x + 1,
initial_index_value_factory: Callable[[], I] = lambda: 0,
is_index_origin: Callable[[I], bool] = lambda x: x == 0,
) -> None:
self.iterable = iterable
self.indexes = [initial_index_value_factory()]
self.generator_with_index_factory = (
generator_with_index_factory or self.default_generator_factory
)
self.index_increase_func = index_increase_func
self.is_index_origin = is_index_origin
def __iter__(self):
current_index = self.indexes[-1]
self.indexes.append(current_index)
if self.is_index_origin(current_index):
start_offset = current_index
else:
start_offset = self.index_increase_func(current_index, self.iterable)
# 0 = 0
# <except 0> = index + 1
try:
for self.indexes[-1], content in self.generator_with_index_factory(
self.iterable,
start=start_offset,
):
yield content
finally:
self.indexes.pop()
Global variables
var T
-
class NestableIterable(Iterable[T]): index_stack: list iterable: Iterable[T]
def __init__(self, iterable: Iterable[T]) -> None: self.iterable = iterable self.index_stack = [0] def __iter__(self): index = self.index_stack[-1] self.index_stack.append(self.index_stack[-1]) start_offset = index + int(bool(index)) try: for self.index_stack[-1], content in enumerate( itertools.islice(self.iterable, start_offset, None, None), start=start_offset, ): yield content finally: self.index_stack.pop() def with_new(self, target): self.iterable = target return self
Functions
def argument_signature(callable_target)
-
Expand source code
@lru_cache(cache_size) def argument_signature(callable_target): return [ ( name, param.annotation if param.annotation != inspect._empty else None, param.default if param.default != inspect._empty else None, ) for name, param in dict(inspect.signature(callable_target).parameters).items() ]
def dispatcher_mixin_handler(dispatcher: BaseDispatcher) ‑> List[BaseDispatcher]
-
Expand source code
@lru_cache(None) def dispatcher_mixin_handler(dispatcher: BaseDispatcher) -> List[BaseDispatcher]: unbound_mixin = getattr(dispatcher, "mixin", []) result = [dispatcher] for i in unbound_mixin: if issubclass(i, BaseDispatcher): result.extend(dispatcher_mixin_handler(i)) else: result.append(i) return result
def flat_yield_from(l)
-
Expand source code
def flat_yield_from(l): for i in l: if type(i) == list: yield from i
def group_dict(iw: iterwrapper.wrapper.IterWrapper, key: Callable[[Any], Any])
-
Expand source code
def group_dict(iw: IterWrapper, key: Callable[[Any], Any]): temp = {} for i in iw: k = key(i) temp.setdefault(k, []) temp[k].append(i) return temp
def is_asyncgener(o)
-
Expand source code
@lru_cache(cache_size) def is_asyncgener(o): return inspect.isasyncgenfunction(o)
def isasyncgen(o)
-
Expand source code
@lru_cache(cache_size) def isasyncgen(o): return inspect.isasyncgen(o)
def iscoroutinefunction(o)
-
Expand source code
@lru_cache(cache_size) def iscoroutinefunction(o): return inspect.iscoroutinefunction(o)
def printer(value)
-
Expand source code
def printer(value): print(value) return value
async def run_always_await(any_callable)
-
Expand source code
async def run_always_await(any_callable): if inspect.iscoroutine(any_callable): return await any_callable else: return any_callable
async def run_always_await_safely(callable, *args, **kwargs)
-
Expand source code
async def run_always_await_safely(callable, *args, **kwargs): if iscoroutinefunction(callable): return await callable(*args, **kwargs) return callable(*args, **kwargs)
Classes
class NestableIterable (iterable: Iterable[~T], generator_with_index_factory: Callable[[Iterable[~T], ~I], Generator[NoneType, NoneType, Tuple[~I, ~T]]] = None, index_increase_func: Callable[[~I, Iterable[~T]], ~I] = <function NestableIterable.<lambda>>, initial_index_value_factory: Callable[[], ~I] = <function NestableIterable.<lambda>>, is_index_origin: Callable[[~I], bool] = <function NestableIterable.<lambda>>)
-
Abstract base class for generic types.
A generic type is typically declared by inheriting from this class parameterized with one or more type variables. For example, a generic mapping type might be defined as::
class Mapping(Generic[KT, VT]): def getitem(self, key: KT) -> VT: … # Etc.
This class can then be used as follows::
def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: try: return mapping[key] except KeyError: return default
Expand source code
class NestableIterable(Iterable[T]): index_stack: list iterable: Iterable[T] def __init__(self, iterable: Iterable[T]) -> None: self.iterable = iterable self.index_stack = [0] def __iter__(self): index = self.index_stack[-1] self.index_stack.append(self.index_stack[-1]) start_offset = index + int(bool(index)) try: for self.index_stack[-1], content in enumerate( itertools.islice(self.iterable, start_offset, None, None), start=start_offset, ): yield content finally: self.index_stack.pop() def with_new(self, target): self.iterable = target return self
Ancestors
- typing.Generic
Class variables
var generator_with_index_factory : Callable[[Iterable[~T], ~I], Generator[NoneType, NoneType, Tuple[~I, ~T]]]
var index_increase_func : Callable[[~I, Iterable[~T]], ~I]
var indexes : List[~I]
var is_index_origin : Callable[[~I], bool]
var iterable : Iterable[~T]
Static methods
def default_generator_factory(iterable: Iterable[~T], start: ~I)
-
Expand source code
@staticmethod def default_generator_factory(iterable: Iterable[T], start: I): return enumerate(iterable[start:], start=start)
class as_sliceable (iterable)
-
Expand source code
class as_sliceable: def __init__(self, iterable) -> None: self.iterable = iterable def __getitem__(self, item: Union[slice, int]) -> Any: if isinstance(item, slice): return itertools.islice(self.iterable, item.start, item.stop, item.step) else: return list(itertools.islice(self.iterable, item, item + 1, None))[0] def __iter__(self): return self.iterable