Skip to content

Miscellaneous Functions

The functions module provides a collection of utility functions and decorators for safer type casting, function execution control, retry logic, and more. These tools help simplify common patterns in both synchronous and asynchronous Python code.


Why?

Many Python patterns—such as safe type casting, retrying operations, or memoizing results—require repetitive boilerplate code. The functions module centralizes these patterns into reusable, type-safe utilities that work seamlessly with both sync and async code.


Features

  • Safe type casting (safe_cast, asafe_cast)
  • Call-once and memoization (call_once, cache)
  • Sync-to-async conversion (as_async)
  • No-op function factories (make_noop)
  • Context-managed function execution (do_with, asyncdo_with)
  • Retry logic (sync and async) via Retry
  • Frozen coroutine wrapper (FrozenCoroutine)
  • Object path walking (walk_object)

Usage

Safe Type Casting

from escudeiro.misc.functions import safe_cast, asafe_cast

result = safe_cast(int, "123")  # 123
result = safe_cast(int, "abc", default=0)  # 0

import asyncio
async def parse_async(val):
    return int(val)

result = await asafe_cast(parse_async, "456")  # 456
result = await asafe_cast(parse_async, "oops", default=-1)  # -1

Call Once

from escudeiro.misc.functions import call_once

@call_once
def expensive_init():
    print("Initializing...")
    return 42

expensive_init()  # Prints "Initializing...", returns 42
expensive_init()  # Returns 42 (no print)

Memoization

from escudeiro.misc.functions import cache

@cache
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

Sync-to-Async Conversion

from escudeiro.misc.functions import as_async

@as_async
def compute(x):
    return x * 2

result = await compute(21)  # 42

No-Op Functions

from escudeiro.misc.functions import make_noop

noop = make_noop()
noop(1, 2, 3)  # Returns None

async_noop = make_noop(asyncio=True, returns="done")
await async_noop()  # Returns "done"

Context-Managed Execution

from escudeiro.misc.functions import do_with, asyncdo_with

with open("file.txt") as f:
    content = do_with(f, lambda file: file.read())

# Async context manager
import aiofiles
async with aiofiles.open("file.txt") as f:
    content = await asyncdo_with(f, lambda file: file.read())

Retry Logic

from escudeiro.misc.functions import Retry

retry = Retry(signal=ValueError, count=3, delay=1)

@retry
def might_fail():
    # ...
    pass

@retry.acall
async def might_fail_async():
    # ...
    pass

Frozen Coroutine

from escudeiro.misc.functions import FrozenCoroutine

async def fetch():
    print("Fetching...")
    return 123

frozen = FrozenCoroutine(fetch())
result1 = await frozen  # Prints "Fetching..."
result2 = await frozen  # Returns cached result, no print

Walk Object

from escudeiro.misc.functions import walk_object

data = {"user": {"profile": {"age": 30}}}
age = walk_object(data, "user.profile.age")  # 30

lst = [1, 2, [3, 4, 5]]
val = walk_object(lst, "[2].[1]")  # 4

API Reference

safe_cast

Safely cast a value using a function, returning a default if an exception occurs.

def safe_cast(caster, value, *ignore_childof, default=None)
  • caster: Function to convert the value.
  • value: Value to cast.
  • ignore_childof: Exception types to catch (default: TypeError, ValueError).
  • default: Value to return if casting fails.

asafe_cast

Async version of safe_cast.

async def asafe_cast(caster, value, *ignore_childof, default=None)

call_once

Decorator to ensure a function is called only once; result is cached.

def call_once(func)

cache

Memoization decorator (thin wrapper over functools.cache).

def cache(f)

as_async

Decorator/factory to convert a sync function to async (runs in thread by default).

def as_async(func=None, *, cast=asyncio.to_thread)

make_noop

Creates a no-op function (sync or async) that returns a fixed value.

def make_noop(*, returns=None, asyncio=False)

do_with

Executes a function within a context manager.

def do_with(context_manager, func, *args, **kwargs)

asyncdo_with

Async version of do_with, supports sync/async context managers and functions.

async def asyncdo_with(context_manager, func, *args, **kwargs)

Retry

A class for retrying functions on failure (sync and async).

@dataclass
class Retry:
    signal: type[Exception] | tuple[type[Exception], ...]
    count: int = 3
    delay: float = 0
    backoff: float = 1

    def __call__(self, func)
    def acall(self, func)
    def map(self, predicate, collection, strategy="threshold")
    async def amap(self, predicate, collection, strategy="threshold")
    async def agenmap(self, predicate, collection, strategy="threshold")

FrozenCoroutine

A coroutine wrapper that ensures the coroutine is executed at most once.

class FrozenCoroutine:
    def __init__(self, coro)
    @classmethod
    def decorate(cls, func)

walk_object

Safely retrieves a value from an object using a dot-separated path.

def walk_object(obj, path)

See Also