Skip to content

utils

Classes:

  • KwargsNotNone

    Remove all None objects from this kwargs dict.

  • LinearRangeLut
  • Singleton

    Handy class to inherit to have the SingletonMeta metaclass.

  • cachedproperty

    Wrapper for a one-time get property, that will be cached.

  • classproperty

    A combination of classmethod and property.

  • inject_kwargs_params

    Descriptor that injects parameters into functions based on an instance's keyword mapping.

  • inject_self

    Descriptor that ensures the wrapped function always has a constructed self.

Functions:

  • complex_hash

    Class decorator that automatically adds a __hash__ method to the target class.

  • copy_signature

    Utility function to copy the signature of one function to another one.

  • get_subclasses

    Get all subclasses of a given type.

KwargsNotNone

KwargsNotNone(*args: Any, **kwargs: Any)

Bases: KwargsT

Remove all None objects from this kwargs dict.

Source code in jetpytools/types/utils.py
845
846
847
@copy_signature(KwargsT.__init__)
def __init__(self, *args: Any, **kwargs: Any) -> None:
    super().__init__({key: value for key, value in dict(*args, **kwargs).items() if value is not None})

LinearRangeLut

LinearRangeLut(ranges: Mapping[int, range])

Bases: Mapping[int, int]

Attributes:

Source code in jetpytools/types/utils.py
895
896
897
898
899
def __init__(self, ranges: Mapping[int, range]) -> None:
    self.ranges = ranges

    self._ranges_idx_lut = list(self.ranges.items())
    self._misses_n = 0

ranges instance-attribute

ranges = ranges

Singleton

Handy class to inherit to have the SingletonMeta metaclass.

SingletonMeta

Bases: type

Methods:

__call__

__call__(*args: Any, **kwargs: Any) -> Any
Source code in jetpytools/types/utils.py
871
872
873
874
875
876
877
878
879
880
881
882
883
def __call__(cls, *args: Any, **kwargs: Any) -> Any:
    if cls in cls._instances and not cls._singleton_init:
        return cls._instances[cls]

    with cls._lock:
        if cls not in cls._instances:
            cls._instances[cls] = obj = super().__call__(*args, **kwargs)
            return obj

        if cls._singleton_init:
            cls._instances[cls].__init__(*args, **kwargs)

    return cls._instances[cls]

cachedproperty

cachedproperty(
    fget: Callable[[Any], _R_co],
    fset: Callable[[Any, _T_Any], None] | None = None,
    fdel: Callable[[Any], None] | None = None,
    doc: str | None = None,
)

Bases: property, Generic[_R_co, _T_Any]

Wrapper for a one-time get property, that will be cached.

You shouldn't hold a reference to itself or it will never get garbage collected.

Methods:

Attributes:

Source code in jetpytools/types/utils.py
766
767
768
769
770
771
772
773
774
def __init__(
    self,
    fget: Callable[[Any], _R_co],
    fset: Callable[[Any, _T_Any], None] | None = None,
    fdel: Callable[[Any], None] | None = None,
    doc: str | None = None,
) -> None:
    self.__name__ = fget.__name__ + f"_{id(fget)}" if isinstance(fget, LambdaType) else fget.__name__
    super().__init__(fget, fset, fdel, doc)

cache_key class-attribute instance-attribute

cache_key = '_jetpt_cachedproperty_cache'

clear_cache classmethod

clear_cache(obj: object, names: str | Iterable[str] | None = None) -> None

Clear cached properties of an object instance.

Parameters:

  • obj

    (object) –

    The object whose cache should be cleared.

  • names

    (str | Iterable[str] | None, default: None ) –

    Specific property names to clear. If None, all cached properties are cleared.

Source code in jetpytools/types/utils.py
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
@classmethod
def clear_cache(cls, obj: object, names: str | Iterable[str] | None = None) -> None:
    """
    Clear cached properties of an object instance.

    Args:
        obj: The object whose cache should be cleared.
        names: Specific property names to clear. If None, all cached properties are cleared.
    """
    if names is None:
        obj.__dict__.get(cls.cache_key, {}).clear()
        return None

    from ..functions import to_arr

    cache = obj.__dict__.get(cls.cache_key, {})

    for name in to_arr(names):
        with suppress(KeyError):
            del cache[name]

deleter

deleter(fdel: Callable[..., None]) -> cachedproperty[_R_co, _T_Any]
Source code in jetpytools/types/utils.py
762
def deleter(self, fdel: Callable[..., None]) -> cachedproperty[_R_co, _T_Any]: ...

getter

getter(fget: Callable[..., _R_co]) -> cachedproperty[_R_co, _T_Any]
Source code in jetpytools/types/utils.py
758
def getter(self, fget: Callable[..., _R_co]) -> cachedproperty[_R_co, _T_Any]: ...

setter

setter(fset: Callable[[Any, _T_Any], None]) -> cachedproperty[_R_co, _T_Any]
Source code in jetpytools/types/utils.py
760
def setter(self, fset: Callable[[Any, _T_Any], None]) -> cachedproperty[_R_co, _T_Any]: ...

update_cache classmethod

update_cache(obj: object, name: str, value: Any) -> None

Update cached property of an object instance.

Parameters:

  • obj

    (object) –

    The object whose cache should be updated.

  • name

    (str) –

    Property name to update.

  • value

    (Any) –

    The value to assign.

Source code in jetpytools/types/utils.py
829
830
831
832
833
834
835
836
837
838
839
@classmethod
def update_cache(cls, obj: object, name: str, value: Any) -> None:
    """
    Update cached property of an object instance.

    Args:
        obj: The object whose cache should be updated.
        name: Property name to update.
        value: The value to assign.
    """
    obj.__dict__.setdefault(cls.cache_key, {})[name] = value

classproperty

classproperty(
    fget: Callable[[type[_T]], _R_co] | classmethod[_T, ..., _R_co],
    fset: Callable[Concatenate[type[_T], _T_Any, ...], None]
    | classmethod[_T, Concatenate[_T_Any, ...], None]
    | None = None,
    fdel: Callable[[type[_T]], None] | classmethod[_T, ..., None] | None = None,
    doc: str | None = None,
)

Bases: classproperty_base[_T, _R_co, _T_Any]

A combination of classmethod and property.

Classes:

  • cached

    A combination of classmethod and property.

Attributes:

Source code in jetpytools/types/utils.py
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
def __init__(
    self,
    fget: Callable[[type[_T]], _R_co] | classmethod[_T, ..., _R_co],
    fset: Callable[Concatenate[type[_T], _T_Any, ...], None]
    | classmethod[_T, Concatenate[_T_Any, ...], None]
    | None = None,
    fdel: Callable[[type[_T]], None] | classmethod[_T, ..., None] | None = None,
    doc: str | None = None,
) -> None:
    self.fget = fget.__func__ if isinstance(fget, classmethod) else fget
    self.fset = fset.__func__ if isinstance(fset, classmethod) else fset
    self.fdel = fdel.__func__ if isinstance(fdel, classmethod) else fdel

    self.__doc__ = doc
    self.__name__ = self.fget.__name__

fdel instance-attribute

fdel: Callable[[type[_T]], None] | None = (
    __func__ if isinstance(fdel, classmethod) else fdel
)

fget instance-attribute

fget: Callable[[type[_T]], _R_co] = (
    __func__ if isinstance(fget, classmethod) else fget
)

fset instance-attribute

fset: Callable[Concatenate[type[_T], _T_Any, ...], None] | None = (
    __func__ if isinstance(fset, classmethod) else fset
)

cached

cached(
    fget: Callable[[type[_T" backlink-type="used-by" backlink-anchor="jetpytools.types.utils.classproperty.cached" optional hover>_T]], _R_co] | classmethod[_T" backlink-type="used-by" backlink-anchor="jetpytools.types.utils.classproperty.cached" optional hover>_T, ..., _R_co],
    fset: Callable[Concatenate[type[_T" backlink-type="used-by" backlink-anchor="jetpytools.types.utils.classproperty.cached" optional hover>_T], _T_Any, ...], None]
    | classmethod[_T, Concatenate[_T_Any, ...], None]
    | None = None,
    fdel: Callable[[type[_T]], None] | classmethod[_T, ..., None] | None = None,
    doc: str | None = None,
)

Bases: classproperty_base[_T0, _R0_co, _T0_Any]

A combination of classmethod and property.

The value is computed once and then cached in a dictionary (under cache_key) attached to the class type. If a setter or deleter is defined and invoked, the cache is cleared.

Methods:

  • clear_cache

    Clear cached properties of an type instance.

Attributes:

Source code in jetpytools/types/utils.py
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
def __init__(
    self,
    fget: Callable[[type[_T]], _R_co] | classmethod[_T, ..., _R_co],
    fset: Callable[Concatenate[type[_T], _T_Any, ...], None]
    | classmethod[_T, Concatenate[_T_Any, ...], None]
    | None = None,
    fdel: Callable[[type[_T]], None] | classmethod[_T, ..., None] | None = None,
    doc: str | None = None,
) -> None:
    self.fget = fget.__func__ if isinstance(fget, classmethod) else fget
    self.fset = fset.__func__ if isinstance(fset, classmethod) else fset
    self.fdel = fdel.__func__ if isinstance(fdel, classmethod) else fdel

    self.__doc__ = doc
    self.__name__ = self.fget.__name__

cache_key class-attribute instance-attribute

cache_key = '_jetpt_classproperty_cached'

fdel instance-attribute

fdel: Callable[[type[_T]], None] | None = (
    __func__ if isinstance(fdel, classmethod) else fdel
)

fget instance-attribute

fget: Callable[[type[_T]], _R_co] = (
    __func__ if isinstance(fget, classmethod) else fget
)

fset instance-attribute

fset: Callable[Concatenate[type[_T], _T_Any, ...], None] | None = (
    __func__ if isinstance(fset, classmethod) else fset
)

clear_cache classmethod

clear_cache(type_: type, names: str | Iterable[str] | None = None) -> None

Clear cached properties of an type instance.

Parameters:

  • type_
    (type) –

    The type whose cache should be cleared.

  • names
    (str | Iterable[str] | None, default: None ) –

    Specific property names to clear. If None, all cached properties are cleared.

Source code in jetpytools/types/utils.py
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
@classmethod
def clear_cache(cls, type_: type, names: str | Iterable[str] | None = None) -> None:
    """
    Clear cached properties of an type instance.

    Args:
        type_: The type whose cache should be cleared.
        names: Specific property names to clear. If None, all cached properties are cleared.
    """
    if names is None:
        with suppress(AttributeError):
            getattr(type_, cls.cache_key).clear()
        return None

    from ..functions import to_arr

    cache = getattr(type_, cls.cache_key, {})

    for name in to_arr(names):
        with suppress(KeyError):
            del cache[name]

classproperty_base

classproperty_base(
    fget: Callable[[type[_T]], _R_co] | classmethod[_T, ..., _R_co],
    fset: Callable[Concatenate[type[_T], _T_Any, ...], None]
    | classmethod[_T, Concatenate[_T_Any, ...], None]
    | None = None,
    fdel: Callable[[type[_T]], None] | classmethod[_T, ..., None] | None = None,
    doc: str | None = None,
)

Bases: Generic[_T, _R_co, _T_Any]

Attributes:

Source code in jetpytools/types/utils.py
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
def __init__(
    self,
    fget: Callable[[type[_T]], _R_co] | classmethod[_T, ..., _R_co],
    fset: Callable[Concatenate[type[_T], _T_Any, ...], None]
    | classmethod[_T, Concatenate[_T_Any, ...], None]
    | None = None,
    fdel: Callable[[type[_T]], None] | classmethod[_T, ..., None] | None = None,
    doc: str | None = None,
) -> None:
    self.fget = fget.__func__ if isinstance(fget, classmethod) else fget
    self.fset = fset.__func__ if isinstance(fset, classmethod) else fset
    self.fdel = fdel.__func__ if isinstance(fdel, classmethod) else fdel

    self.__doc__ = doc
    self.__name__ = self.fget.__name__

fdel instance-attribute

fdel: Callable[[type[_T]], None] | None = (
    __func__ if isinstance(fdel, classmethod) else fdel
)

fget instance-attribute

fget: Callable[[type[_T]], _R_co] = (
    __func__ if isinstance(fget, classmethod) else fget
)

fset instance-attribute

fset: Callable[Concatenate[type[_T], _T_Any, ...], None] | None = (
    __func__ if isinstance(fset, classmethod) else fset
)

inject_kwargs_params

inject_kwargs_params(func: Callable[Concatenate[_T_co, _P], _R_co])

Bases: _InjectKwargsParamsBase[_T_co, _P, _R_co]

Descriptor that injects parameters into functions based on an instance's keyword mapping.

When a method wrapped with @inject_kwargs_params is called, the descriptor inspects the function's signature and replaces any arguments matching keys in self.kwargs (or another mapping defined by _kwargs_name) if their values equal the parameter's default.

Initialize the inject_kwargs_params descriptor.

Parameters:

  • func

    (Callable[Concatenate[_T_co, _P], _R_co]) –

    The target function or method whose parameters will be injected from the instance's self.kwargs mapping.

Classes:

  • add_to_kwargs

    Variant of inject_kwargs_params that merges unused entries from self.kwargs into the keyword arguments

Methods:

  • __call__
  • with_name

    Decorator factory that creates a subclass of inject_kwargs_params with a custom name

Source code in jetpytools/types/utils.py
407
408
409
410
411
412
413
414
415
416
def __init__(self, func: Callable[Concatenate[_T_co, _P], _R_co], /) -> None:
    """
    Initialize the inject_kwargs_params descriptor.

    Args:
        func: The target function or method whose parameters will be injected
            from the instance's `self.kwargs` mapping.
    """
    self._function = func
    self._signature = None

add_to_kwargs

add_to_kwargs(func: Callable[Concatenate[_T_co, _P], _R_co])

Bases: _InjectKwargsParamsBase[_T0_co, _P0, _R0_co]

Variant of inject_kwargs_params that merges unused entries from self.kwargs into the keyword arguments passed to the target function.

This allows additional context or configuration values to be forwarded without requiring explicit parameters.

Initialize the inject_kwargs_params descriptor.

Parameters:

  • func

    (Callable[Concatenate[_T_co, _P], _R_co]) –

    The target function or method whose parameters will be injected from the instance's self.kwargs mapping.

Methods:

  • __call__
  • with_name

    Decorator factory that creates a subclass of inject_kwargs_params with a custom name

Source code in jetpytools/types/utils.py
407
408
409
410
411
412
413
414
415
416
def __init__(self, func: Callable[Concatenate[_T_co, _P], _R_co], /) -> None:
    """
    Initialize the inject_kwargs_params descriptor.

    Args:
        func: The target function or method whose parameters will be injected
            from the instance's `self.kwargs` mapping.
    """
    self._function = func
    self._signature = None

__call__

__call__(self_, self: _T_co, *args: args, **kwargs: kwargs) -> _R_co
Source code in jetpytools/types/utils.py
477
478
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co:  # type: ignore[misc]  # noqa: N805
    return self_.__get__(self, type(self))(*args, **kwargs)

with_name classmethod

with_name(
    kwargs_name: str = "kwargs",
) -> Callable[
    [Callable[Concatenate[T0, P0], R0]], inject_kwargs_params[T0, P0, R0]
]

Decorator factory that creates a subclass of inject_kwargs_params with a custom name for the keyword argument store.

Source code in jetpytools/types/utils.py
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
@classmethod
def with_name[T0, **P0, R0](
    cls, kwargs_name: str = "kwargs"
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_kwargs_params[T0, P0, R0]]:
    """
    Decorator factory that creates a subclass of `inject_kwargs_params` with a custom name
    for the keyword argument store.
    """
    ns = cls.__dict__.copy()
    ns["_kwargs_name"] = kwargs_name

    custom_cls = type(cls.__name__, cls.__bases__, ns)

    # TODO: The precise subclass type cannot be expressed yet when the class is itself generic.
    def _wrapper(function: Callable[Concatenate[T0, P0], R0]) -> inject_kwargs_params[T0, P0, R0]:
        return custom_cls(function)  # pyright: ignore[reportReturnType, reportArgumentType]

    return _wrapper

__call__

__call__(self_, self: _T_co, *args: args, **kwargs: kwargs) -> _R_co
Source code in jetpytools/types/utils.py
477
478
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co:  # type: ignore[misc]  # noqa: N805
    return self_.__get__(self, type(self))(*args, **kwargs)

with_name classmethod

with_name(
    kwargs_name: str = "kwargs",
) -> Callable[
    [Callable[Concatenate[T0, P0], R0]], inject_kwargs_params[T0, P0, R0]
]

Decorator factory that creates a subclass of inject_kwargs_params with a custom name for the keyword argument store.

Source code in jetpytools/types/utils.py
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
@classmethod
def with_name[T0, **P0, R0](
    cls, kwargs_name: str = "kwargs"
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_kwargs_params[T0, P0, R0]]:
    """
    Decorator factory that creates a subclass of `inject_kwargs_params` with a custom name
    for the keyword argument store.
    """
    ns = cls.__dict__.copy()
    ns["_kwargs_name"] = kwargs_name

    custom_cls = type(cls.__name__, cls.__bases__, ns)

    # TODO: The precise subclass type cannot be expressed yet when the class is itself generic.
    def _wrapper(function: Callable[Concatenate[T0, P0], R0]) -> inject_kwargs_params[T0, P0, R0]:
        return custom_cls(function)  # pyright: ignore[reportReturnType, reportArgumentType]

    return _wrapper

inject_self

inject_self(
    function: Callable[Concatenate[_T_co, _P], _R_co],
    /,
    *args: Any,
    **kwargs: Any,
)

Bases: _InjectSelfBase[_T_co, _P, _R_co]

Descriptor that ensures the wrapped function always has a constructed self.

When accessed via a class, it will automatically instantiate an object before calling the function. When accessed via an instance, it simply binds.

Subclasses such as cached, init_kwargs, and init_kwargs.clean define variations in how the injected object is created or reused.

Initialize the inject_self descriptor.

Parameters:

  • function

    (Callable[Concatenate[_T_co, _P], _R_co]) –

    The function or method to wrap.

  • *args

    (Any, default: () ) –

    Positional arguments to pass when instantiating the target class.

  • **kwargs

    (Any, default: {} ) –

    Keyword arguments to pass when instantiating the target class.

Classes:

  • cached

    Variant of inject_self that caches the constructed instance.

  • init_kwargs

    Variant of inject_self that forwards function keyword arguments to the class constructor

  • property

    Property variant of inject_self that auto-calls the wrapped method.

Methods:

  • __call__
  • with_args

    Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.)

Attributes:

Source code in jetpytools/types/utils.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
def __init__(self, function: Callable[Concatenate[_T_co, _P], _R_co], /, *args: Any, **kwargs: Any) -> None:
    """
    Initialize the inject_self descriptor.

    Args:
        function: The function or method to wrap.
        *args: Positional arguments to pass when instantiating the target class.
        **kwargs: Keyword arguments to pass when instantiating the target class.
    """
    self._function = function

    self._signature = self._init_signature = None

    self.args = args
    self.kwargs = kwargs

args instance-attribute

args = args

kwargs instance-attribute

kwargs = kwargs

cached

cached(
    function: Callable[Concatenate[_T_co, _P], _R_co],
    /,
    *args: Any,
    **kwargs: Any,
)

Bases: _InjectSelfBase[_T0_co, _P0, _R0_co]

Variant of inject_self that caches the constructed instance.

The first time the method is accessed via the class, a self object is created and stored. Subsequent calls reuse it.

Initialize the inject_self descriptor.

Parameters:

  • function

    (Callable[Concatenate[_T_co, _P], _R_co]) –

    The function or method to wrap.

  • *args

    (Any, default: () ) –

    Positional arguments to pass when instantiating the target class.

  • **kwargs

    (Any, default: {} ) –

    Keyword arguments to pass when instantiating the target class.

Classes:

  • property

    Property variant of inject_self.cached that auto-calls the wrapped method.

Methods:

  • __call__
  • with_args

    Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.)

Attributes:

Source code in jetpytools/types/utils.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
def __init__(self, function: Callable[Concatenate[_T_co, _P], _R_co], /, *args: Any, **kwargs: Any) -> None:
    """
    Initialize the inject_self descriptor.

    Args:
        function: The function or method to wrap.
        *args: Positional arguments to pass when instantiating the target class.
        **kwargs: Keyword arguments to pass when instantiating the target class.
    """
    self._function = function

    self._signature = self._init_signature = None

    self.args = args
    self.kwargs = kwargs

args instance-attribute

args = args

kwargs instance-attribute

kwargs = kwargs

property

property(function: Callable[[_T1_co], _R1_co])

Bases: Generic[_T1_co, _P1, _R1_co]

Property variant of inject_self.cached that auto-calls the wrapped method.

Source code in jetpytools/types/utils.py
360
361
def __init__(self, function: Callable[[_T1_co], _R1_co], /) -> None:
    self.__func__ = inject_self.cached(function)

__call__

__call__(self_, self: _T_co, *args: args, **kwargs: kwargs) -> _R_co
Source code in jetpytools/types/utils.py
299
300
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co:  # type: ignore[misc]  # noqa: N805
    return self_.__get__(self, None)(*args, **kwargs)

with_args classmethod

with_args(
    *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]

Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.) with specific instantiation arguments.

Source code in jetpytools/types/utils.py
316
317
318
319
320
321
322
323
324
325
326
327
328
329
@classmethod
def with_args[T0, **P0, R0](
    cls, *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]:
    """
    Decorator factory to construct an `inject_self` or subclass (`cached`, `init_kwargs`, etc.)
    with specific instantiation arguments.
    """

    # TODO: The precise subclass type cannot be expressed yet when the class is itself generic.
    def _wrapper(function: Callable[Concatenate[T0, P0], R0]) -> inject_self[T0, P0, R0]:
        return cls(function, *args, **kwargs)  # type: ignore[return-value, arg-type]

    return _wrapper

init_kwargs

init_kwargs(
    function: Callable[Concatenate[_T_co, _P], _R_co],
    /,
    *args: Any,
    **kwargs: Any,
)

Bases: _InjectSelfBase[_T0_co, _P0, _R0_co]

Variant of inject_self that forwards function keyword arguments to the class constructor when instantiating self.

Initialize the inject_self descriptor.

Parameters:

  • function

    (Callable[Concatenate[_T_co, _P], _R_co]) –

    The function or method to wrap.

  • *args

    (Any, default: () ) –

    Positional arguments to pass when instantiating the target class.

  • **kwargs

    (Any, default: {} ) –

    Keyword arguments to pass when instantiating the target class.

Classes:

  • clean

    Variant of inject_self.init_kwargs that removes any forwarded kwargs from the final function call

Methods:

  • __call__
  • with_args

    Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.)

Attributes:

Source code in jetpytools/types/utils.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
def __init__(self, function: Callable[Concatenate[_T_co, _P], _R_co], /, *args: Any, **kwargs: Any) -> None:
    """
    Initialize the inject_self descriptor.

    Args:
        function: The function or method to wrap.
        *args: Positional arguments to pass when instantiating the target class.
        **kwargs: Keyword arguments to pass when instantiating the target class.
    """
    self._function = function

    self._signature = self._init_signature = None

    self.args = args
    self.kwargs = kwargs

args instance-attribute

args = args

kwargs instance-attribute

kwargs = kwargs

clean

clean(
    function: Callable[Concatenate[_T_co, _P], _R_co],
    /,
    *args: Any,
    **kwargs: Any,
)

Bases: _InjectSelfBase[_T1_co, _P1, _R1_co]

Variant of inject_self.init_kwargs that removes any forwarded kwargs from the final function call after using them for construction.

Initialize the inject_self descriptor.

Parameters:

  • function
    (Callable[Concatenate[_T_co, _P], _R_co]) –

    The function or method to wrap.

  • *args
    (Any, default: () ) –

    Positional arguments to pass when instantiating the target class.

  • **kwargs
    (Any, default: {} ) –

    Keyword arguments to pass when instantiating the target class.

Methods:

  • __call__
  • with_args

    Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.)

Attributes:

Source code in jetpytools/types/utils.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
def __init__(self, function: Callable[Concatenate[_T_co, _P], _R_co], /, *args: Any, **kwargs: Any) -> None:
    """
    Initialize the inject_self descriptor.

    Args:
        function: The function or method to wrap.
        *args: Positional arguments to pass when instantiating the target class.
        **kwargs: Keyword arguments to pass when instantiating the target class.
    """
    self._function = function

    self._signature = self._init_signature = None

    self.args = args
    self.kwargs = kwargs
args instance-attribute
args = args
kwargs instance-attribute
kwargs = kwargs
__call__
__call__(self_, self: _T_co, *args: args, **kwargs: kwargs) -> _R_co
Source code in jetpytools/types/utils.py
299
300
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co:  # type: ignore[misc]  # noqa: N805
    return self_.__get__(self, None)(*args, **kwargs)
with_args classmethod
with_args(
    *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]

Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.) with specific instantiation arguments.

Source code in jetpytools/types/utils.py
316
317
318
319
320
321
322
323
324
325
326
327
328
329
@classmethod
def with_args[T0, **P0, R0](
    cls, *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]:
    """
    Decorator factory to construct an `inject_self` or subclass (`cached`, `init_kwargs`, etc.)
    with specific instantiation arguments.
    """

    # TODO: The precise subclass type cannot be expressed yet when the class is itself generic.
    def _wrapper(function: Callable[Concatenate[T0, P0], R0]) -> inject_self[T0, P0, R0]:
        return cls(function, *args, **kwargs)  # type: ignore[return-value, arg-type]

    return _wrapper

__call__

__call__(self_, self: _T_co, *args: args, **kwargs: kwargs) -> _R_co
Source code in jetpytools/types/utils.py
299
300
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co:  # type: ignore[misc]  # noqa: N805
    return self_.__get__(self, None)(*args, **kwargs)

with_args classmethod

with_args(
    *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]

Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.) with specific instantiation arguments.

Source code in jetpytools/types/utils.py
316
317
318
319
320
321
322
323
324
325
326
327
328
329
@classmethod
def with_args[T0, **P0, R0](
    cls, *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]:
    """
    Decorator factory to construct an `inject_self` or subclass (`cached`, `init_kwargs`, etc.)
    with specific instantiation arguments.
    """

    # TODO: The precise subclass type cannot be expressed yet when the class is itself generic.
    def _wrapper(function: Callable[Concatenate[T0, P0], R0]) -> inject_self[T0, P0, R0]:
        return cls(function, *args, **kwargs)  # type: ignore[return-value, arg-type]

    return _wrapper

property

property(function: Callable[[_T0_co], _R0_co])

Bases: Generic[_T0_co, _R0_co]

Property variant of inject_self that auto-calls the wrapped method.

Source code in jetpytools/types/utils.py
388
389
def __init__(self, function: Callable[[_T0_co], _R0_co], /) -> None:
    self.__func__ = inject_self(function)

__call__

__call__(self_, self: _T_co, *args: args, **kwargs: kwargs) -> _R_co
Source code in jetpytools/types/utils.py
299
300
def __call__(self_, self: _T_co, *args: _P.args, **kwargs: _P.kwargs) -> _R_co:  # type: ignore[misc]  # noqa: N805
    return self_.__get__(self, None)(*args, **kwargs)

with_args classmethod

with_args(
    *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]

Decorator factory to construct an inject_self or subclass (cached, init_kwargs, etc.) with specific instantiation arguments.

Source code in jetpytools/types/utils.py
316
317
318
319
320
321
322
323
324
325
326
327
328
329
@classmethod
def with_args[T0, **P0, R0](
    cls, *args: Any, **kwargs: Any
) -> Callable[[Callable[Concatenate[T0, P0], R0]], inject_self[T0, P0, R0]]:
    """
    Decorator factory to construct an `inject_self` or subclass (`cached`, `init_kwargs`, etc.)
    with specific instantiation arguments.
    """

    # TODO: The precise subclass type cannot be expressed yet when the class is itself generic.
    def _wrapper(function: Callable[Concatenate[T0, P0], R0]) -> inject_self[T0, P0, R0]:
        return cls(function, *args, **kwargs)  # type: ignore[return-value, arg-type]

    return _wrapper

complex_hash

complex_hash(cls: type[T]) -> type[T]

Class decorator that automatically adds a __hash__ method to the target class.

The generated __hash__ method computes a hash value derived from: - the class's name - the values of all attributes listed in its type annotations.

This is particularly useful for immutable data structures (e.g., NamedTuples or dataclasses).

Source code in jetpytools/types/utils.py
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
@_ComplexHash
def complex_hash[T](cls: type[T]) -> type[T]:
    """
    Class decorator that automatically adds a ``__hash__`` method to the target class.

    The generated ``__hash__`` method computes a hash value derived from:
    - the class's name
    - the values of all attributes listed in its type annotations.

    This is particularly useful for immutable data structures (e.g., NamedTuples or dataclasses).
    """

    def __hash__(self: T) -> int:  # noqa: N807
        if sys.version_info >= (3, 14):
            from annotationlib import get_annotations
        else:
            from inspect import get_annotations

        return complex_hash.hash(self.__class__.__name__, *(getattr(self, key) for key in get_annotations(cls)))

    setattr(cls, __hash__.__name__, __hash__)

    return cls

copy_signature

copy_signature(target: F) -> Callable[[Callable[..., Any]], F]

Utility function to copy the signature of one function to another one.

Especially useful for passthrough functions.

.. code-block::

class SomeClass: def init( self, some: Any, complex: Any, /, args: Any, long: Any, signature: Any, *kwargs: Any ) -> None: ...

class SomeClassChild(SomeClass): @copy_signature(SomeClass.init) def init(args: Any, kwargs: Any) -> None: super().init(args, **kwargs) # do some other thing

class Example(SomeClass): @copy_signature(SomeClass.init) def init(args: Any, kwargs: Any) -> None: super().init(args, **kwargs) # another thing

Source code in jetpytools/types/utils.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def copy_signature[F: Callable[..., Any]](target: F, /) -> Callable[[Callable[..., Any]], F]:
    """
    Utility function to copy the signature of one function to another one.

    Especially useful for passthrough functions.

    .. code-block::

       class SomeClass:
           def __init__(
               self, some: Any, complex: Any, /, *args: Any,
               long: Any, signature: Any, **kwargs: Any
           ) -> None:
               ...

       class SomeClassChild(SomeClass):
           @copy_signature(SomeClass.__init__)
           def __init__(*args: Any, **kwargs: Any) -> None:
               super().__init__(*args, **kwargs)
               # do some other thing

       class Example(SomeClass):
           @copy_signature(SomeClass.__init__)
           def __init__(*args: Any, **kwargs: Any) -> None:
               super().__init__(*args, **kwargs)
               # another thing
    """

    def decorator(wrapped: Callable[..., Any]) -> F:
        return cast(F, wrapped)

    return decorator

get_subclasses

get_subclasses(
    family: type[T], exclude: Sequence[type[T]] = []
) -> list[type[T]]

Get all subclasses of a given type.

Parameters:

  • family

    (type[T]) –

    "Main" type all other classes inherit from.

  • exclude

    (Sequence[type[T]], default: [] ) –

    Excluded types from the yield. Note that they won't be excluded from search. For examples, subclasses of these excluded classes will be yield.

Returns:

  • list[type[T]]

    List of all subclasses of "family".

Source code in jetpytools/types/utils.py
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
def get_subclasses[T](family: type[T], exclude: Sequence[type[T]] = []) -> list[type[T]]:
    """
    Get all subclasses of a given type.

    Args:
        family: "Main" type all other classes inherit from.
        exclude: Excluded types from the yield. Note that they won't be excluded from search. For examples, subclasses
            of these excluded classes will be yield.

    Returns:
        List of all subclasses of "family".
    """

    def _subclasses(cls: type[T]) -> Iterator[type[T]]:
        for subclass in cls.__subclasses__():
            yield from _subclasses(subclass)
            if subclass in exclude:
                continue
            yield subclass

    return list(set(_subclasses(family)))