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
854
855
856
@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
898
899
900
901
902
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
878
879
880
881
882
883
884
885
886
def __call__(cls, *args: Any, **kwargs: Any) -> Any:
    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.

Classes:

  • baseclass

    Inherit from this class to automatically set the cache dict.

Methods:

Attributes:

Source code in jetpytools/types/utils.py
775
776
777
778
779
780
781
782
783
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'

baseclass

Inherit from this class to automatically set the cache dict.

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
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
@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
771
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
767
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
769
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
838
839
840
841
842
843
844
845
846
847
848
@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
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
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]], _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[_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
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
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
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
@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
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
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
410
411
412
413
414
415
416
417
418
419
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
410
411
412
413
414
415
416
417
418
419
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
480
481
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
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
@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
480
481
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
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
@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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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
363
364
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
302
303
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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
@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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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
302
303
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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
@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
302
303
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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
@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
391
392
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
302
303
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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
@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
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
@_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
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
81
82
83
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
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
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)))