Application Programming Interface#
Types#
- class plum.type.ModuleType(module, name, allow_fail=False)[source]#
A type from another module.
- Parameters:
module (str) – Module that the type lives in.
name (str) – Name of the type that is promised.
allow_fail (bool, optional) – If the type is does not exist in module, do not raise an AttributeError.
- class plum.type.PromisedType(name='SomeType')[source]#
A type that is promised to be available when you will you need it.
- Parameters:
name (str, optional) – Name of the type that is promised. Defaults to “SomeType”.
- plum.type.is_faithful(x)[source]#
Check whether a type hint is faithful.
A type or type hint t is defined _faithful_ if, for all x, the following holds true:
isinstance(x, x) == issubclass(type(x), t)
You can control whether types are faithful or not by setting the attribute __faithful__:
class UnfaithfulType: __faithful__ = False
- Parameters:
x (type or type hint) – Type hint.
- Returns:
Whether x is faithful or not.
- Return type:
bool
- plum.type.resolve_type_hint(x)[source]#
Resolve all
ResolvableType
in a type or type hint.- Parameters:
x (type or type hint) – Type hint.
- Returns:
x, but with all
ResolvableType
s resolved.- Return type:
type or type hint
- plum.type.type_mapping = {}#
When running
resolve_type_hint()
, map keys in this dictionary to the values.- Type:
dict
Signatures#
- class plum.signature.Signature(*types: ~typing.Tuple[object, ...], varargs: ~typing.Union[object, ~plum.util._MissingType] = <class 'plum.util.Missing'>, precedence: int = 0)[source]#
Object representing a call signature that may be used to dispatch a function call.
This object differs structurally from the return value of
inspect.signature()
as it only contains information necessary for performing dispatch.For example, for the current implementation of Plum, which does not dispatch on keyword arguments, those are left out of this signature object. Similarly, return type information and argument names are not present.
- varargs#
Type of the variable number of arguments.
- Type:
type or
util.Missing
- has_varargs#
Whether varargs is not
util.Missing
.- Type:
bool
- precedence#
Precedence.
- Type:
int
- is_faithful#
Whether this signature only uses faithful types.
- Type:
bool
- compute_distance(values: Tuple[object, ...]) int [source]#
For given values, computes the edit distance between these vales and this signature.
- Parameters:
values (tuple[object, ...]) – Values.
- Returns:
Edit distance.
- Return type:
int
- compute_mismatches(values: Tuple) Tuple[Set[int], bool] [source]#
For given values, find the indices of the arguments that are mismatched. Also return whether the varargs is matched.
- Parameters:
values (tuple[object, ...]) – Values.
- Returns:
Indices of invalid values. bool: Whether the varargs was matched or not.
- Return type:
set[int]
- expand_varargs(n: int) Tuple[object, ...] [source]#
Expand variable arguments.
- Parameters:
n (int) – Desired number of types.
- Returns:
Expanded types.
- Return type:
tuple[type, …]
- plum.signature.append_default_args(signature: Signature, f: Callable) List[Signature] [source]#
Returns a list of signatures of function f, where those signatures are derived from the input arguments of f by treating every non-keyword-only argument with a default value as a keyword-only argument turn by turn.
- Parameters:
f (function) – Function to extract default arguments from.
signature (
signature.Signature
) – Signature of f from which to remove default arguments.
- Returns:
- List of signatures excluding from no to all
default arguments.
- Return type:
list[
signature.Signature
]
Methods#
- class plum.method.Method(implementation: Callable, signature: Signature, *, function_name: Optional[str] = None, return_type: Optional[object] = None)[source]#
Method.
- return_type#
Return type.
- Type:
type
- implementation#
Implementation.
- Type:
function or None
- repr_mismatch(mismatches: Set[int] = frozenset({}), varargs_matched: bool = True) str [source]#
Version of __repr__ that can print which arguments are mismatched. This is mainly used in hints.
- Parameters:
mismatches (set[int], optional) – Indices of the positional arguments which are mismatched. Defaults to no mismatched arguments.
varargs_matched (bool, optional) – Whether the varargs are matched. Defaults to True.
- Returns:
rich
representation of the method showing which arguments are mismatched.- Return type:
list
Functions#
- class plum.function.Function(f: Callable, owner: Optional[str] = None, warn_redefinition: bool = False)[source]#
A function.
- Parameters:
f (function) – Function that is wrapped.
owner (str, optional) – Name of the class that owns the function.
warn_redefinition (bool, optional) – Throw a warning whenever a method is redefined. Defaults to False.
- clear_cache(reregister: bool = True) None [source]#
Clear cache.
- Parameters:
reregister (bool, optional) – Also reregister all methods. Defaults to True.
- dispatch(method: Optional[Callable] = None, precedence=0) Union[Self, Callable[[Callable], Self]] [source]#
Decorator to extend the function with another signature.
- Parameters:
precedence (int, optional) – Precedence of the signature. Defaults to 0.
- Returns:
Decorator.
- Return type:
function
- dispatch_multi(*signatures: Union[Signature, Tuple[object, ...]]) Callable[[Callable], Self] [source]#
Decorator to extend the function with multiple signatures at once.
- Parameters:
*signatures (tuple or
signature.Signature
) – Signatures to register.- Returns:
Decorator.
- Return type:
function
- invoke(*types: object) Callable [source]#
Invoke a particular method.
- Parameters:
*types – Types to resolve.
- Returns:
Method.
- Return type:
function
- property methods: List[Signature]#
All available methods.
- Type:
list[
signature.Signature
]
- property owner#
Owner of the function. If None, then there is no owner.
- Type:
object or None
- register(f: Callable, signature: Optional[Signature] = None, precedence=0) None [source]#
Register a method.
Either signature or precedence must be given.
- Parameters:
f (function) – Function that implements the method.
signature (
signature.Signature
, optional) – Signature. If it is not given, it will be derived from f.precedence (int, optional) – Precedence of the function. If signature is given, then this argument will not be used. Defaults to 0.
Dispatchers#
- class plum.dispatcher.Dispatcher(warn_redefinition: bool = False, functions: ~typing.Dict[str, ~plum.function.Function] = <factory>, classes: ~typing.Dict[str, ~typing.Dict[str, ~plum.function.Function]] = <factory>)[source]#
A namespace for functions.
- Parameters:
warn_redefinition (bool, optional) – Throw a warning whenever a method is redefined. Defaults to False.
- functions#
Functions by name.
- Type:
dict[str,
function.Function
]
- classes#
Methods of all classes by the qualified name of a class.
- Type:
dict[str, dict[str,
function.Function
]]
- warn_redefinition#
Throw a warning whenever a method is redefined.
- Type:
bool
- abstract(method: Callable) Function [source]#
Decorator for an abstract function definition. The abstract function definition does not implement any methods.
- multi(*signatures: Union[Signature, Tuple[object, ...]]) Callable[[Callable], Function] [source]#
Decorator to register multiple signatures at once.
- Parameters:
*signatures (tuple or
signature.Signature
) – Signatures to register.- Returns:
Decorator.
- Return type:
function
- plum.dispatcher.clear_all_cache()[source]#
Clear all cache, including the cache of subclass checks. This should be called if types are modified.
- plum.dispatcher.dispatch = Dispatcher(warn_redefinition=False, functions={}, classes={})#
A default dispatcher for convenience purposes.
- exception plum.resolver.AmbiguousLookupError(f_name: Optional[str], target: Union[Tuple, Signature], methods: MethodList)[source]#
A signature cannot be resolved due to ambiguity.
- exception plum.resolver.NotFoundLookupError(f_name: Optional[str], target: Union[Tuple, Signature], methods: MethodList, *, max_suggestions: int = 3)[source]#
A signature cannot be resolved because no applicable method can be found.
This error object is used to display the closest methods to the target signature.
Parametric Classes#
- class plum.parametric.CovariantMeta[source]#
A metaclass that implements covariance of parametric types.
- class plum.parametric.Kind(*args, **kw_args)#
A default kind provided for convenience.
- plum.parametric.kind(SuperClass=<class 'object'>)[source]#
Create a parametric wrapper type for dispatch purposes.
- Parameters:
SuperClass (type) – Super class.
- Returns:
New parametric type wrapper.
- Return type:
object
- plum.parametric.parametric(original_class=None)[source]#
A decorator for parametric classes.
When the constructor of this parametric type is called before the type parameter has been specified, the type parameter is inferred from the arguments of the constructor by calling __inter_type_parameter__. The default implementation is shown here, but it is possible to override it:
@classmethod def __infer_type_parameter__(cls, *args, **kw_args) -> tuple: return tuple(type(arg) for arg in args)
After the type parameter is given or inferred, __init_type_parameter__ is called. Again, the default implementation is show here, but it is possible to override it:
@classmethod def __init_type_parameter__(cls, *ps) -> tuple: return ps
To determine which one instance of a parametric class is a subclass of another, the type parameters are compared with __le_type_parameter__:
@classmethod def __le_type_parameter__(cls, left, right) -> bool: # Is `left <= right`? ...
- plum.parametric.type_nonparametric(q: T) Type[T] [source]#
Return the non-parametric type of an object.
plum.parametric
produces parametric subtypes of classes. This method can be used to get the original non-parametric type of an object.See also
plum.type_unparametrized()
A function that returns the non-concrete, but still parametric, type of an object.
Examples
In this example we will demonstrate how to retrieve the original non-parametric class from a
plum.parametric()
decorated class.plum.parametric()
defines a parametric class of the same name as the original class, and then creates a subclass of the original class with the type parameter inferred from the arguments of the constructor.>>> from plum import parametric >>> class Obj: ... @classmethod ... def __infer_type_parameter__(cls, *arg): ... return type(arg[0]) ... ... def __init__(self, x): ... self.x = x ... ... def __repr__(self): ... return f"Obj({self.x})" >>> PObj = parametric(Obj) >>> pobj = PObj(1)
>>> type(pobj).mro() [<class 'plum.parametric.Obj[int]'>, <class 'plum.parametric.Obj'>, <class 'plum.parametric.Obj'>, <class 'object'>]
Note that the class Obj appears twice in the MRO. The first one is the parametric class, and the second one is the non-parametric class. The non-parametric class is the original class that was passed to the
parametric
decorator.Rather than navigating the MRO, we can get the non-parametric class of an object by calling
type_nonparametric
function.>>> type(pobj) is PObj[int] True >>> type(pobj) is PObj False >>> type(pobj) is Obj False
>>> type_nonparametric(pobj) is PObj[int] False >>> type_nonparametric(pobj) is PObj False >>> type_nonparametric(pobj) is Obj True
- plum.parametric.type_parameter(x)[source]#
Get the type parameter of concrete parametric type or an instance of a concrete parametric type.
- Parameters:
x (object) – Concrete parametric type or instance thereof.
- Returns:
Type parameter.
- Return type:
object
- plum.parametric.type_unparametrized(q: T) Type[T] [source]#
Return the unparametrized type of an object.
plum.parametric
produces parametric subtypes of classes. This function can be used to get the un-parametrized type of an object. This function also works for normal,plum.parametric
-wrapped classes.See also
plum.type_nonparametric()
A function to get the non-parametric type of an object.
Examples
In this example we will demonstrate how to retrieve the original non-parametric class from a
plum.parametric()
decorated class.plum.parametric()
defines a parametric class of the same name as the original class, and then creates a subclass of the original class with the type parameter inferred from the arguments of the constructor.>>> from plum import parametric >>> class Obj: ... @classmethod ... def __infer_type_parameter__(cls, *arg): ... return type(arg[0]) ... ... def __init__(self, x): ... self.x = x ... ... def __repr__(self): ... return f"Obj({self.x})" >>> PObj = parametric(Obj) >>> pobj = PObj(1)
>>> type(pobj).mro() [<class 'plum.parametric.Obj[int]'>, <class 'plum.parametric.Obj'>, <class 'plum.parametric.Obj'>, <class 'object'>]
Note that the class Obj appears twice in the MRO. The first one is the non-concrete parametric class, and the second one is the non-parametric class. Rather than navigating the MRO, we can get the non-concrete parametric class of an object by calling the
type_unparametrized
function.>>> type(pobj) is PObj[int] True >>> type(pobj) is PObj False >>> type(pobj) is Obj False
>>> type_unparametrized(pobj) is PObj[int] False >>> type_unparametrized(pobj) is PObj True >>> type_unparametrized(pobj) is Obj False
Note that this is still NOT the ‘original’ non-
plum.parametric()
-wrapped type. This is the type that is wrapped byplum.parametric
, but without the inferred type parameter(s).
Promotion and Conversion#
Promotion and conversion functions.
- plum.promotion.add_conversion_method(type_from: Type[T], type_to: Type[R], f: _ConversionCallable[T, R]) None [source]#
Add a conversion method to convert an object from one type to another.
- Parameters:
type_from (type) – Type to convert from.
type_to (type) – Type to convert to.
f (function) – Function that converts an object of type type_from to type type_to.
- plum.promotion.add_promotion_rule(type1, type2, type_to)[source]#
Add a promotion rule.
- Parameters:
type1 (type) – First type to promote.
type2 (type) – Second type to promote.
type_to (type) – Type to convert to.
- plum.promotion.conversion_method(type_from: Type[T], type_to: Type[R]) Callable[[_ConversionCallable[T, R]], _ConversionCallable[T, R]] [source]#
Decorator to add a conversion method to convert an object from one type to another.
- Parameters:
type_from (type) – Type to convert from.
type_to (type) – Type to convert to.
Union Aliases#
This module monkey patches __repr__ and __str__ of typing.Union to control how typing.Unions are displayed.
Example:
>> plum.activate_union_aliases()
>> IntOrFloat = typing.Union[int, float]
>> IntOrFloat
Union[int, float]
>> plum.set_union_alias(IntOrFloat, "IntOrFloat")
>> IntOrFloat
typing.Union[IntOrFloat]
>> typing.Union[int, float]
typing.Union[IntOrFloat]
>> typing.Union[int, float, str]
typing.Union[IntOrFloat, str]
Note that IntOrFloat prints to typing.Union[IntOrFloat] rather than just IntOrFloat. This is deliberate, with the goal of not breaking code that relies on parsing how unions print.
- plum.alias.activate_union_aliases() None [source]#
When printing typing.Union`s, replace all aliased unions by the aliased names. This monkey patches `__repr__ and __str__ for typing.Union.
iPython AutoReload#
- plum.autoreload.activate_autoreload()[source]#
Pirate Autoreload’s update_instance function to have Plum work with Autoreload.
- plum.autoreload.deactivate_autoreload()[source]#
Disable Plum’s autoreload hack. This undoes what
autoreload.activate_autoreload()
did.
Other Utilities#
- plum.repr.repr_pyfunction(f: Callable) Text [source]#
Create a
rich.Text
object representation a function, including a link to the source definition created withrepr_source_path()
.- Parameters:
f (Callable) – A function.
- Returns:
Representation of f.
- Return type:
rich.Text
- plum.repr.repr_short(x) str [source]#
Representation as a string, but in shorter form. This just calls
typing._type_repr()
.- Parameters:
x (object) – Object.
- Returns:
Shorter representation of x.
- Return type:
str
- plum.repr.repr_source_path(function: Callable) Text [source]#
Create a
rich.Text
object with an hyperlink to the function definition.- Parameters:
function (Callable) – A function.
- Returns:
Representation with a hyperlink to the source. If the introspection failed, it returns
None
.- Return type:
rich.Text
or None
- plum.repr.repr_type(x) Text [source]#
Returns a
rich.Text
representation of a type or module.Does some light syntax highlighting mimicking Julia, boldening class names and coloring module names with a lighter color.
- Parameters:
x (object) – Type or module.
- Returns:
Representation.
- Return type:
rich.Text
- plum.repr.rich_repr(cls: Optional[Type[T]] = None, str: bool = False) Type[T] [source]#
Class decorator defining a __repr__ method that calls
rich.
This also sets _repr_mimebundle_ for better rendering in Jupyter.
- Parameters:
cls (type, optional) – Class to decorate. If None, this function returns a decorator.
str (bool, optional) – Also define __str__. Defaults to not defining __str__
- Returns:
The decorated class. If cls is None, returns a decorator.
- class plum.util.Comparable[source]#
A mixin that makes instances of the class comparable.
Requires the subclass to just implement __le__.
- class plum.util.Missing[source]#
A class that can be used to indicate that a value is missing. This class cannot be instantiated and has no boolean value.
- plum.util.TypeHint#
alias of
object
- plum.util.argsort(seq: Sequence) List[int] [source]#
Compute the indices that sort a sequence.
- Parameters:
seq (Sequence) – Sequence to sort.
- Returns:
Indices that sort seq.
- Return type:
list[int]
- plum.util.get_class(f: Callable) str [source]#
Assuming that f is part of a class, get the fully qualified name of the class.
- Parameters:
f (function) – Method to get class name for.
- Returns:
Fully qualified name of class.
- Return type:
str
- plum.util.get_context(f) str [source]#
Get the fully qualified name of the context for f.
If f is part of a class, then the context corresponds to the scope of the class. If f is not part of a class, then the context corresponds to the scope of the function.
- Parameters:
f (function) – Method to get context for.
- Returns:
The context of f.
- Return type:
str