Domain Driven Utils Library
Project description
DDUtils
DDUtils is a lightweight Python library that provides helper functions and decorators for common programming tasks. It focuses on type safety, robustness, and runtime introspection — all without external dependencies.
Installation
Install the library using pip:
pip install ddutils
Type Annotation Helpers
Utilities for inspecting and working with Python type hints and generic types. These helpers let you analyze and modify complex annotations at runtime.
get_annotation_origin
Returns the base (origin) type of a generic annotation, unwrapping NewType and handling generic aliases recursively.
from typing import List
from ddutils.annotation_helpers import get_annotation_origin
get_annotation_origin(List[int]) # <class 'list'>
get_annotation_origin(dict[str, int]) # <class 'dict'>
is_subclass
Checks whether a type annotation is a subclass of the given base type(s).
Supports both regular and generic annotations, following standard issubclass behavior.
from typing import List
from ddutils.annotation_helpers import is_subclass
is_subclass(List[int], list) # True
is_subclass(dict[str, int], dict) # True
is_subclass(List[str], dict) # False
is_complex_sequence
Checks whether a type annotation represents a sequence type, excluding str, bytes, and bytearray.
from typing import List, Tuple
from ddutils.annotation_helpers import is_complex_sequence
is_complex_sequence(List[int]) # True
is_complex_sequence(Tuple[str, ...]) # True
is_complex_sequence(str) # False
is_complex_sequence(dict) # False
get_complex_sequence_element_annotation
Returns the element type from a sequence annotation.
Raises ValueError if the annotation doesn’t specify an element type.
from typing import List, Set
from ddutils.annotation_helpers import get_complex_sequence_element_annotation
get_complex_sequence_element_annotation(List[int]) # <class 'int'>
get_complex_sequence_element_annotation(Set[str]) # <class 'str'>
get_dict_items_annotation
Returns the key and value types from a dictionary annotation.
from typing import Dict
from ddutils.annotation_helpers import get_dict_items_annotation
key_type, value_type = get_dict_items_annotation(Dict[str, int])
# key_type = <class 'str'>, value_type = <class 'int'>
get_annotation_without_optional
Returns a type annotation without its Optional wrapper, extracting the underlying type from Union[T, None].
Raises TypeError for unions that include multiple non-None types.
from typing import Optional
from ddutils.annotation_helpers import get_annotation_without_optional
get_annotation_without_optional(Optional[int]) # <class 'int'>
get_annotation_without_optional(Optional[List[str]]) # typing.List[str]
Class Helpers
Helper functions for inspecting and extending class-level behavior
classproperty
Works like @property, but for class attributes.
Can be accessed as ClassName.property_name without creating an instance.
from ddutils.class_helpers import classproperty
class BaseModel:
@classproperty
def table_name(cls):
return f'{cls.__name__.lower()}_table'
class User(BaseModel):
pass
User.table_name # 'user_table'
get_origin_class_of_method
Traverses the Method Resolution Order (MRO) to find the class where a method was originally defined.
Returns None if the method doesn’t exist.
from ddutils.class_helpers import get_origin_class_of_method
class A:
def method(self):
pass
class B(A):
pass
class C(B):
def method(self):
pass
get_origin_class_of_method(C, 'method') # <class 'C'>
get_origin_class_of_method(B, 'method') # <class 'A'>
Function Helpers
Tools for creating and modifying Python functions at runtime.
create_new_function
Creates a new function from an existing one, with an optional new name. Preserves default values and closures.
from ddutils.function_helpers import create_new_function
def original_function():
return 'original'
new_function = create_new_function(original_function, new_name='renamed_function')
new_function.__name__ # 'renamed_function'
Data Conversion
Helpers for converting data between different formats.
convert_camel_case_to_snake_case
Converts a camelCase string to snake_case.
from ddutils.convertors import convert_camel_case_to_snake_case
convert_camel_case_to_snake_case('SomeClassName') # 'some_class_name'
convert_to_repr
Builds a __repr__ string for objects that have a __dict__.
Ignores private attributes and raises TypeError if the object doesn’t have __dict__.
from ddutils.convertors import convert_to_repr
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
self._internal = 'hidden'
person = Person('Alice', 30)
convert_to_repr(person) # "Person(name='Alice', age=30)"
convert_timedelta_to_milliseconds
Converts timedelta objects to milliseconds as an integer.
from datetime import timedelta
from ddutils.convertors import convert_timedelta_to_milliseconds
delta = timedelta(seconds=5, milliseconds=500)
convert_timedelta_to_milliseconds(delta) # 5500
Datetime Helpers
Utilities for working with dates and times.
utc_now
Returns the current datetime in UTC timezone.
Safe Decorators
Decorators that help functions fail safely and handle exceptions gracefully.
safe_call
Wraps a function to catch exceptions and return a default value instead of raising errors.
import requests
from ddutils.safe_decorators import safe_call
@safe_call(default_result=[])
def fetch_data_from_api():
response = requests.get('https://api.example.com/data')
return response.json()
@safe_call(default_result=0, exceptions=(ValueError,))
def convert_to_int(value):
return int(value)
retry_once_after_exception
Retries a function once if it raises an exception.
import requests
from ddutils.safe_decorators import retry_once_after_exception
@retry_once_after_exception
def unstable_network_call():
return requests.get('https://api.example.com/unstable')
Module and Object Management
Helpers for importing and accessing modules or objects at runtime.
get_module
Finds a nested module by path within a parent module.
import os
from ddutils.module_getter import get_module
get_module(os, ['path']) # <module 'os.path'>
get_object_by_path
Imports and returns an object by its full dotted path (e.g. 'json.loads').
from ddutils.object_getter import get_object_by_path
json_loads = get_object_by_path('json.loads')
Scoped Registry
A registry that manages object instances within defined scopes.
ScopedRegistry
Manages object instances within scopes (like per request or per session).
from ddutils.scoped_registry import ScopedRegistry
def get_current_request_id(): ...
def create_database_connection(): ...
db_registry = ScopedRegistry(
create_func=create_database_connection,
scope_func=get_current_request_id,
)
async def handle_request():
db = await db_registry() # Returns existing or creates new db connection
await db.execute('select ...')
Function Exception Extraction
AST-based introspection for extracting exceptions from function source code.
extract_function_exceptions
Parses a function’s source code to find all raise statements and identify the exception types they use.
Returns an iterator of ExceptionInfo objects describing each raised exception.
Sequence Helpers
Safe operations on sequence types.
get_safe_element
Returns an element from a sequence by index without raising IndexError.
Returns None if the index is out of range.
from ddutils.sequence_helpers import get_safe_element
items = [1, 2, 3]
get_safe_element(items, 0) # 1
get_safe_element(items, 10) # None (no IndexError)
get_safe_element(items, -1) # 3
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ddutils-0.1.4.tar.gz.
File metadata
- Download URL: ddutils-0.1.4.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17ecda8c3e01ffaad2bc40001b93234a764d2466e60c60a0f77839cb412ab64a
|
|
| MD5 |
a52da3faf5024cb75df7bc97d21af63f
|
|
| BLAKE2b-256 |
f7db782be5e9bba53889d65e07115d9dd0eebee3d3924cf2d3dea8a191c2a551
|
Provenance
The following attestation bundles were made for ddutils-0.1.4.tar.gz:
Publisher:
publish_python_package.yml on davyddd/ddutils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddutils-0.1.4.tar.gz -
Subject digest:
17ecda8c3e01ffaad2bc40001b93234a764d2466e60c60a0f77839cb412ab64a - Sigstore transparency entry: 790699658
- Sigstore integration time:
-
Permalink:
davyddd/ddutils@5576379cf86b27005f7d71ba4589ba9109d41e81 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/davyddd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish_python_package.yml@5576379cf86b27005f7d71ba4589ba9109d41e81 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ddutils-0.1.4-py3-none-any.whl.
File metadata
- Download URL: ddutils-0.1.4-py3-none-any.whl
- Upload date:
- Size: 12.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
324d1d22990c9b6dac1cc74026f51ef835cb945a2de5eee700c3760763768f3c
|
|
| MD5 |
35a4d5ab45a5dd94bacb0677a319600a
|
|
| BLAKE2b-256 |
b065bfc2c9e7d53794ad98d66c35a8d26b31f99429ee234aecc62ec383c10584
|
Provenance
The following attestation bundles were made for ddutils-0.1.4-py3-none-any.whl:
Publisher:
publish_python_package.yml on davyddd/ddutils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ddutils-0.1.4-py3-none-any.whl -
Subject digest:
324d1d22990c9b6dac1cc74026f51ef835cb945a2de5eee700c3760763768f3c - Sigstore transparency entry: 790699660
- Sigstore integration time:
-
Permalink:
davyddd/ddutils@5576379cf86b27005f7d71ba4589ba9109d41e81 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/davyddd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish_python_package.yml@5576379cf86b27005f7d71ba4589ba9109d41e81 -
Trigger Event:
push
-
Statement type: