Skip to main content

Multiple dispatch in Python

Project description

Plum: Multiple Dispatch in Python

DOI CI Coverage Status Latest Docs Code style: black

Everybody likes multiple dispatch, just like everybody likes plums.

Installation

Plum requires Python 3.7 or higher.

pip install plum-dispatch

Basic Usage

Multiple dispatch allows you to implement multiple methods for the same function, where the methods specify the types of their arguments:

from plum import dispatch

@dispatch
def f(x: str):
    return "This is a string!"
    

@dispatch
def f(x: int):
    return "This is an integer!"
>>> f("1")
'This is a string!'

>>> f(1)
'This is an integer!'

We haven't implemented a method for floats, so in that case an exception will be raised:

>>> f(1.0)
NotFoundLookupError: For function "f", signature Signature(builtins.float) could not be resolved.

Instead of implementing a method for floats, let's implement a method for all numbers:

from numbers import Number

@dispatch
def f(x: Number):
    return "This is a number!"

Since a float is a Number, f(1.0) will return "This is a number!". But an int is also a Number, so f(1) can either return "This is an integer!" or "This is a number!". The rule of multiple dispatch is that the most specific method is chosen:

>>> f(1)
'This is an integer!'

since an int is a Number, but a Number is not necessarily an int.

For a function f, all available methods can be obtained with f.methods:

>>> f.methods
{Signature(builtins.str): (<function __main__.f(x:str)>, builtins.object),
 Signature(builtins.int): (<function __main__.f(x:int)>, builtins.object),
 Signature(numbers.Number): (<function __main__.f(x:numbers.Number)>,
  builtins.object)}

In the values, the first element in the tuple is the implementation and the second element the return type.

For an excellent and way more detailed overview of multiple dispatch, see the manual of the Julia Language.

Scope of Functions

Consider the following package design.

package/__init__.py

import a
import b

package/a.py

from plum import dispatch

@dispatch
def f(x: int):
   return "int"

package/b.py

from plum import dispatch

@dispatch
def f(x: float):
   return "float"

In a design like this, the methods for f recorded by dispatch are global:

>>> from package.a import f

>>> f(1.0)
'float'

This could be what you want, but it can also be undesirable, because it means that someone could accidentally overwrite your methods. To keep your functions private, you can create new dispatchers:

package/__init__.py

import a
import b

package/a.py

from plum import Dispatcher

dispatch = Dispatcher()


@dispatch
def f(x: int):
   return "int"

package/b.py

from plum import Dispatcher

dispatch = Dispatcher()


@dispatch
def f(x: float):
   return "float"
>>> from package.a import f

>>> f(1)
'int'

>>> f(1.0)
NotFoundLookupError: For function "f", signature Signature(builtins.float) could not be resolved.

>>> from package.b import f

>>> f(1)
NotFoundLookupError: For function "f", signature Signature(builtins.int) could not be resolved.

>>> f(1.0)
'float'

Classes

You can use dispatch within classes:

from plum import dispatch

class Real:
   @dispatch
   def __add__(self, other: int):
      return "int added"
   
   @dispatch
   def __add__(self, other: float):
      return "float added"
>>> real = Real()

>>> real + 1
'int added'

>>> real + 1.0
'float added'

If you use other decorators, then dispatch must be the outermost decorator:

class Real:
   @dispatch
   @decorator
   def __add__(self, other: int):
      return "int added"

@staticmethod, @classmethod, and @property.setter

In the case of @staticmethod, @classmethod, or @property.setter, the rules are different:

  1. The @dispatch decorator must be applied before @staticmethod, @classmethod, and @property.setter. This means that @dispatch is then not the outermost decorator.
  2. The class must have at least one other method where @dispatch is the outermost decorator. If this is not the case, you will need to add a dummy method, as the following example illustrates.
from plum import dispatch

class MyClass:
    def __init__(self):
        self._name = None
       
    @property
    def property(self):
        return self._name

    @property.setter
    @dispatch
    def property(self, value: str):
        self._name = value
      
    @staticmethod
    @dispatch
    def f(x: int):
        return x

    @classmethod
    @dispatch
    def g(cls: type, x: float):
        return x

    @dispatch
    def _(self):
        # Dummy method that needs to be added whenever no method has
        # `@dispatch` as the outermost decorator.
        pass

If you don't add the dummy method whenever it is required, you will run into a ResolutionError:

from plum import dispatch

class MyClass:
    @staticmethod
    @dispatch
    def f(x: int):
        return x
>>> MyClass.f(1)
ResolutionError: Promise `Promise()` was not kept.

Forward References

Imagine the following design:

from plum import dispatch

class Real:
    @dispatch
    def __add__(self, other: Real):
        pass # Do something here. 

If we try to run this, we get the following error:

NameError                                 Traceback (most recent call last)
<ipython-input-1-2c6fe56c8a98> in <module>
      1 from plum import dispatch
      2
----> 3 class Real:
      4     @dispatch
      5     def __add__(self, other: Real):

<ipython-input-1-2c6fe56c8a98> in Real()
      3 class Real:
      4     @dispatch
----> 5     def __add__(self, other: Real):
      6         pass # Do something here.

NameError: name 'Real' is not defined

The problem is that name Real is not yet defined, when __add__ is defined and the type hint for other is set. To circumvent this issue, you can use a forward reference:

from plum import dispatch

class Real:
    @dispatch
    def __add__(self, other: "Real"):
        pass # Do something here. 

Note: A forward reference "A" will resolve to the next defined class A in which dispatch is used. This works fine for self references. In is recommended to only use forward references for self references. For more advanced use cases of forward references, you can use plum.type.PromisedType.

Keyword Arguments and Default Values

Default arguments can be used. The type annotation must match the default value otherwise an error is thrown. As the example below illustrates, different default values can be used for different methods:

from plum import dispatch

@dispatch
def f(x: int, y: int = 3):
    return y


@dispatch
def f(x: float, y: float = 3.0):
    return y
>>> f(1)
3

>>> f(1.0)
3.0

>>> f(1.0, 4.0)
4.0

>>> f(1.0, y=4.0)
4.0

Keyword-only arguments, separated by an asterisk from the other arguments, can also be used, but are not dispatched on.

Example:

from plum import dispatch

@dispatch
def f(x, *, option="a"):
    return option
>>> f(1)
'a'

>>> f(1, option="b")
'b'

>>> f(1, "b")  # This will not work, because `option` must be given as a keyword.
NotFoundLookupError: For function "f", signature Signature(builtins.int, builtins.str) could not be resolved.

Comparison with multipledispatch

As an alternative to Plum, there is multipledispatch, which also is a great solution. Plum was developed to provide a slightly more featureful implementation of multiple dispatch.

Like multipledispatch, Plum's caching mechanism is optimised to minimise overhead.

from multipledispatch import dispatch as dispatch_md
from plum import dispatch as dispatch_plum

@dispatch_md(int)
def f_md(x):
   return x


@dispatch_plum
def f_plum(x: int):
   return x


def f_native(x):
    return x
>>> f_md(1); f_plum(1);  # Run once to populate cache.

>>> %timeit f_native(1)
82.4 ns ± 0.162 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

>>> %timeit f_md(1)
845 ns ± 77.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

>>> %timeit f_plum(1)
404 ns ± 2.83 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Plum synergises with OOP.

Consider the following snippet:

from multipledispatch import dispatch

class A:
    def f(self, x):
        return "fallback"
        

class B:
    @dispatch(int)
    def f(self, x):
        return x
>>> b = B()

>>> b.f(1)
1

>>> b.f("1")
NotImplementedError: Could not find signature for f: <str>

This behaviour might be undesirable: since B.f isn't matched, we could want A.f to be tried next. Plum supports this:

from plum import dispatch

class A:
    def f(self, x):
        return "fallback"


class B(A):
    @dispatch
    def f(self, x: int):
        return x
>>> b = B()

>>> b.f(1)
1

>>> b.f("1")
'fallback'

Plum supports forward references.

Plum supports parametric types from typing.

Plum attempts to stay close to Julia's type system.

For example, multipledispatch's union type is not a true union type:

from multipledispatch import dispatch

@dispatch((object, int), int)
def f(x, y):
    return "first"
    

@dispatch(int, object)
def f(x, y):
    return "second"
>>> f(1, 1)
'first'

Because the union of object and int is object, f(1, 1) should raise an ambiguity error! For example, compare with Julia:

julia> f(x::Union{Any, Int}, y::Int) = "first"
f (generic function with 1 method)

julia> f(x::Int, y::Any) = "second"
f (generic function with 2 methods)

julia> f(3, 3)
ERROR: MethodError: f(::Int64, ::Int64) is ambiguous. Candidates:
  f(x, y::Int64) in Main at REPL[1]:1
  f(x::Int64, y) in Main at REPL[2]:1

Plum does provide a true union type:

from typing import Union

from plum import dispatch

@dispatch
def f(x: Union[object, int], y: int):
    return "first"


@dispatch
def f(x: int, y: object):
    return "second"
>>> f(1, 1)
AmbiguousLookupError: For function "f", signature Signature(builtins.int, builtins.int) is ambiguous among the following:
  Signature(builtins.object, builtins.int) (precedence: 0)
  Signature(builtins.int, builtins.object) (precedence: 0)

Just to sanity check that things are indeed working correctly:

>>> f(1.0, 1)
'first'

>>> f(1, 1.0)
'second'

Plum implements method precedence.

Method precedence can be a very powerful tool to simplify more complicated designs.

Plum provides generic convert and promote functions.

Type System

Union Types

typing.Union can be used to instantiate union types:

from typing import Union

from plum import dispatch

@dispatch
def f(x):
    return "fallback"


@dispatch
def f(x: Union[int, str]):
    return "int or str"
>>> f(1)
'int or str'

>>> f("1")
'int or str'

>>> f(1.0)
'fallback'

Parametric Types

The parametric types typing.Tuple, typing.List, typing.Dict, typing.Iterable, and typing.Sequence can be used to dispatch on respectively tuples, lists, dictionaries, iterables, and sequence with particular types of elements. Importantly, the type system is covariant, as opposed to Julia's type system, which is invariant.

Example involving some parametric types:

from typing import Union, Tuple, List, Dict

from plum import dispatch

@dispatch
def f(x: Union[tuple, list]):
    return "tuple or list"
    
    
@dispatch
def f(x: Tuple[int, int]):
    return "tuple of two ints"
    
    
@dispatch
def f(x: List[int]):
    return "list of int"


@dispatch
def f(x: Dict[int, str]):
   return "dict of int to str"
>>> f([1, 2])
'list of int'

>>> f([1, "2"])
'tuple or list'

>>> f((1, 2))
'tuple of two ints'

>>> f((1, 2, 3))
'tuple or list'

>>> f((1, "2"))
'tuple or list'

>>> f({1: "2"})
'dict of int to str'

Note: Although parametric types are supported, parametric types do incur a significant performance hit, because the type of every element in a list or tuple must be checked. It is recommended to use parametric types only where absolutely necessary.

Variable Arguments

A variable number of arguments can be used without any problem.

from plum import dispatch

@dispatch
def f(x: int):
    return "single argument"
    

@dispatch
def f(x: int, *xs: int):
    return "multiple arguments"
>>> f(1)
'single argument'

>>> f(1, 2)
'multiple arguments'

>>> f(1, 2, 3)
'multiple arguments'

Return Types

Return types can be used without any problem.

from typing import Union

from plum import dispatch, add_conversion_method

@dispatch
def f(x: Union[int, str]) -> int:
    return x
>>> f(1)
1

>>> f("1")
TypeError: Cannot convert a "builtins.str" to a "builtins.int".

>>> add_conversion_method(type_from=str, type_to=int, f=int)

>>> f("1")
1

Conversion and Promotion

Conversion

The function convert can be used to convert objects of one type to another:

from numbers import Number

from plum import convert


class Rational:
    def __init__(self, num, denom):
        self.num = num
        self.denom = denom
>>> convert(0.5, Number)
0.5

>>> convert(Rational(1, 2), Number)
TypeError: Cannot convert a "__main__.Rational" to a "numbers.Number".

The TypeError indicates that convert does not know how to convert a Rational to a Number. Let us implement that conversion:

from operator import truediv

from plum import conversion_method
        

@conversion_method(type_from=Rational, type_to=Number)
def rational_to_number(q):
    return truediv(q.num, q.denom)
>>> convert(Rational(1, 2), Number)
0.5

Instead of the decorator conversion_method, one can also use add_conversion_method:

from plum import add_conversion_method

add_conversion_method(type_from, type_to, conversion_function)

Promotion

The function promote can be used to promote objects to a common type:

from plum import dispatch, promote, add_promotion_rule, add_conversion_method

@dispatch
def add(x, y):
    return add(*promote(x, y))
    
    
@dispatch
def add(x: int, y: int):
    return x + y
    
    
@dispatch
def add(x: float, y: float):
    return x + y
>>> add(1, 2)
3

>>> add(1.0, 2.0)
3.0

>>> add(1, 2.0)
TypeError: No promotion rule for "builtins.int" and "builtins.float".

>>> add_promotion_rule(int, float, float)

>>> add(1, 2.0)
TypeError: Cannot convert a "builtins.int" to a "builtins.float".

>>> add_conversion_method(type_from=int, type_to=float, f=float)

>>> add(1, 2.0)
3.0

Advanced Features

Abstract Function Definitions

A function can be abstractly defined using dispatch.abstract. When a function is abstractly defined, the function is created, but no methods are defined.

from plum import dispatch

@dispatch.abstract
def f(x):
    pass
>>> f
<function <function f at 0x7f9f6820aea0> with 0 method(s)>

>>> @dispatch
... def f(x: int):
...     pass

>>> f
<function <function f at 0x7f9f6820aea0> with 1 method(s)>

Method Precedence

The keyword argument precedence can be set to an integer value to specify precedence levels of methods, which are used to break ambiguity:

from plum import dispatch

class Element:
    pass


class ZeroElement(Element):
    pass


class SpecialisedElement(Element):
    pass


@dispatch
def mul_no_precedence(a: ZeroElement, b: Element):
    return "zero"


@dispatch
def mul_no_precedence(a: Element, b: SpecialisedElement):
    return "specialised operation"
    

@dispatch(precedence=1)
def mul(a: ZeroElement, b: Element):
    return "zero"


@dispatch
def mul(a: Element, b: SpecialisedElement):
    return "specialised operation"
>>> zero = ZeroElement()

>>> specialised_element = SpecialisedElement()

>>> element = Element()

>>> mul(zero, element)
'zero'

>>> mul(element, specialised_element)
'specialised operation'

>>> mul_no_precedence(zero, specialised_element)
AmbiguousLookupError: For function "mul_no_precedence", signature Signature(__main__.ZeroElement, __main__.SpecialisedElement) is ambiguous among the following:
  Signature(__main__.ZeroElement, __main__.Element) (precedence: 0)
  Signature(__main__.Element, __main__.SpecialisedElement) (precedence: 0)

>>> mul(zero, specialised_element)
'zero'

The method precedences of all implementations of a function can be obtained with the attribute precedences:

>>> mul_no_precedence.precedences
{Signature(__main__.ZeroElement, __main__.Element): 0,
 Signature(__main__.Element, __main__.SpecialisedElement): 0}

>>> mul.precedences
{Signature(__main__.ZeroElement, __main__.Element): 1,
 Signature(__main__.Element, __main__.SpecialisedElement): 0}

Parametric Classes

The decorator @parametric can be used to create parametric classes:

from plum import dispatch, parametric

@parametric
class A:
    def __init__(self, x, *, y = 3):
        self.x = x
        self.y = y
    
    
@dispatch
def f(x: A):
    return "fallback: x={}".format(x.x)
    
    
@dispatch
def f(x: A[int]):
    return "int x={}".format(x.x)
    
    
@dispatch
def f(x: A[float]):
    return "float x={}".format(x.x)
>>> A
__main__.A

>>> A[int]
__main__.A[builtins.int]

>>> issubclass(A[int], A)
True

>>> type(A(1)) == A[int]
True

>>> A[int](1)
<__main__.A[builtins.int] at 0x10c2bab70>

>>> f(A[int](1))
'int x=1'

>>> f(A(1))
'int x=1'

>>> f(A(1.0))
'float x=1.0'

>>> f(A(1 + 1j))
'fallback: x=1+1j'

Note: Calling A[pars] on parametrized type A instantiates the concrete type with parameters pars. If A(args) is called directly, the concrete type is first instantiated by taking the type of all positional arguments, and then an instance of the type is created.

This behaviour can be customized by overriding the @classmethod __infer_type_parameter__ of the parametric class. This method must return the type parameter or a tuple of type parameters.

from plum import parametric

@parametric
class NTuple:
    @classmethod
    def __infer_type_parameter__(self, *args):
        # Mimicks the type parameters of an `NTuple`.
        T = type(args[0])
        N = len(args)
        return (N, T)

    def __init__(self, *args):
        # Check that the arguments satisfy the type specification.
        T = type(self)._type_parameter[1]
        assert all(isinstance(val, T) for val in args)
        self.args = args
>>> type(NTuple(1, 2, 3))
__main__.NTuple[3, <class 'int'>]

Hooking Into Type Inference

With parametric classes, you can hook into Plum's type inference system to do cool things! Here's an example which introduces types for NumPy arrays of particular ranks:

import numpy as np
from plum import dispatch, parametric, type_of


@parametric(runtime_type_of=True)
class NPArray(np.ndarray):
    """A type for NumPy arrays where the type parameter specifies the number of
    dimensions."""


@type_of.dispatch
def type_of(x: np.ndarray):
    # Hook into Plum's type inference system to produce an appropriate instance of
    # `NPArray` for NumPy arrays.
    return NPArray[x.ndim]


@dispatch
def f(x: NPArray[1]):
    return "vector"


@dispatch
def f(x: NPArray[2]):
    return "matrix"
>>> f(np.random.randn(10))
'vector'

>>> f(np.random.randn(10, 10))
'matrix'

>>> f(np.random.randn(10, 10, 10))
NotFoundLookupError: For function "f", signature Signature(__main__.NPArray[3]) could not be resolved.

Add Multiple Methods

Dispatcher.multi can be used to implement multiple methods at once:

from typing import Union

from plum import dispatch

@dispatch.multi((int, int), (float, float))
def add(x: Union[int, float], y: Union[int, float]):
    return x + y
>>> add(1, 1)
2

>>> add(1.0, 1.0)
2.0

>>> add(1, 1.0)
NotFoundLookupError: For function "add", signature Signature(builtins.int, builtins.float) could not be resolved.

Extend a Function From Another Package

Function.dispatch can be used to extend a particular function from an external package:

from package import f

@f.dispatch
def f(x: int):
    return "new behaviour"
>>> f(1.0)
'old behaviour'

>>> f(1)
'new behaviour'

Directly Invoke a Method

Function.invoke can be used to invoke a method given types of the arguments:

from plum import dispatch

@dispatch
def f(x: int):
    return "int"
    
    
@dispatch
def f(x: str):
    return "str"
>>> f(1)
'int'

>>> f("1")
'str'

>>> f.invoke(int)("1")
'int'

>>> f.invoke(str)(1)
'str'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plum-dispatch-1.5.14.tar.gz (50.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

plum_dispatch-1.5.14-pp37-pypy37_pp73-win_amd64.whl (107.7 kB view details)

Uploaded PyPyWindows x86-64

plum_dispatch-1.5.14-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (134.2 kB view details)

Uploaded PyPymanylinux: glibc 2.12+ x86-64manylinux: glibc 2.5+ x86-64

plum_dispatch-1.5.14-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (135.6 kB view details)

Uploaded PyPymanylinux: glibc 2.12+ i686manylinux: glibc 2.5+ i686

plum_dispatch-1.5.14-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (120.4 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

plum_dispatch-1.5.14-cp310-cp310-win_amd64.whl (124.1 kB view details)

Uploaded CPython 3.10Windows x86-64

plum_dispatch-1.5.14-cp310-cp310-win32.whl (114.1 kB view details)

Uploaded CPython 3.10Windows x86

plum_dispatch-1.5.14-cp310-cp310-musllinux_1_1_x86_64.whl (618.8 kB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.14-cp310-cp310-musllinux_1_1_i686.whl (591.8 kB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ i686

plum_dispatch-1.5.14-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (549.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.12+ x86-64manylinux: glibc 2.5+ x86-64

plum_dispatch-1.5.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (526.7 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.12+ i686manylinux: glibc 2.5+ i686

plum_dispatch-1.5.14-cp310-cp310-macosx_11_0_arm64.whl (143.8 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

plum_dispatch-1.5.14-cp310-cp310-macosx_10_9_x86_64.whl (158.2 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

plum_dispatch-1.5.14-cp39-cp39-win_amd64.whl (125.7 kB view details)

Uploaded CPython 3.9Windows x86-64

plum_dispatch-1.5.14-cp39-cp39-win32.whl (115.0 kB view details)

Uploaded CPython 3.9Windows x86

plum_dispatch-1.5.14-cp39-cp39-musllinux_1_1_x86_64.whl (618.6 kB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.14-cp39-cp39-musllinux_1_1_i686.whl (594.9 kB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ i686

plum_dispatch-1.5.14-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (558.1 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.12+ x86-64manylinux: glibc 2.5+ x86-64

plum_dispatch-1.5.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (535.1 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.12+ i686manylinux: glibc 2.5+ i686

plum_dispatch-1.5.14-cp39-cp39-macosx_11_0_arm64.whl (141.0 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

plum_dispatch-1.5.14-cp39-cp39-macosx_10_9_x86_64.whl (155.3 kB view details)

Uploaded CPython 3.9macOS 10.9+ x86-64

plum_dispatch-1.5.14-cp38-cp38-win_amd64.whl (126.0 kB view details)

Uploaded CPython 3.8Windows x86-64

plum_dispatch-1.5.14-cp38-cp38-win32.whl (115.2 kB view details)

Uploaded CPython 3.8Windows x86

plum_dispatch-1.5.14-cp38-cp38-musllinux_1_1_x86_64.whl (679.3 kB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.14-cp38-cp38-musllinux_1_1_i686.whl (647.7 kB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ i686

plum_dispatch-1.5.14-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (607.5 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.12+ x86-64manylinux: glibc 2.5+ x86-64

plum_dispatch-1.5.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (580.3 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.12+ i686manylinux: glibc 2.5+ i686

plum_dispatch-1.5.14-cp38-cp38-macosx_11_0_arm64.whl (141.1 kB view details)

Uploaded CPython 3.8macOS 11.0+ ARM64

plum_dispatch-1.5.14-cp38-cp38-macosx_10_9_x86_64.whl (153.8 kB view details)

Uploaded CPython 3.8macOS 10.9+ x86-64

plum_dispatch-1.5.14-cp37-cp37m-win_amd64.whl (122.9 kB view details)

Uploaded CPython 3.7mWindows x86-64

plum_dispatch-1.5.14-cp37-cp37m-win32.whl (112.7 kB view details)

Uploaded CPython 3.7mWindows x86

plum_dispatch-1.5.14-cp37-cp37m-musllinux_1_1_x86_64.whl (555.8 kB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ x86-64

plum_dispatch-1.5.14-cp37-cp37m-musllinux_1_1_i686.whl (528.9 kB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ i686

plum_dispatch-1.5.14-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (495.0 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.12+ x86-64manylinux: glibc 2.5+ x86-64

plum_dispatch-1.5.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (470.6 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.12+ i686manylinux: glibc 2.5+ i686

plum_dispatch-1.5.14-cp37-cp37m-macosx_10_9_x86_64.whl (151.8 kB view details)

Uploaded CPython 3.7mmacOS 10.9+ x86-64

File details

Details for the file plum-dispatch-1.5.14.tar.gz.

File metadata

  • Download URL: plum-dispatch-1.5.14.tar.gz
  • Upload date:
  • Size: 50.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.4

File hashes

Hashes for plum-dispatch-1.5.14.tar.gz
Algorithm Hash digest
SHA256 737abb103da6782687f96c3cc29b346c6c70a0d9958385cc75fac26225f0d8e1
MD5 50eb3eedb30844c10053043848a0f2a7
BLAKE2b-256 d7cacf9e4e59e336138380fc1064d6d500d4059a345388211cd3b0fb31c0ef80

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-pp37-pypy37_pp73-win_amd64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-pp37-pypy37_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 2d06ab0d56eb61a103efcbf9a32a098e0d09f746bff90a5ab2c24f00b0dd9750
MD5 d14f1c5b5a310155fa1c814b0254a99f
BLAKE2b-256 123f1e9feccabde5db75891e5b7948e1885207f55c996746d29b1657dac3ef51

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 83a517de531221528b735031711ee157f886892cf05b8acc016986ae32a46dc7
MD5 7d4ed5cb3496f05e79a982604a9e9672
BLAKE2b-256 296e491111df5dfef63bde4b6ea39ba464b8cdda65d487a3a8d5a7badb85f8b0

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 312f74f68c9dbe9b45c42383375cbeb75326f7ea319609b345f9116fdf71429c
MD5 540c0c8174385ac6fb8eaf281c7d280e
BLAKE2b-256 2fca721fd0591435887b4194cf64c7c3e1e4e34f793e6f368190647e32de727d

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-pp37-pypy37_pp73-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-pp37-pypy37_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 76ff444c81e1ec634264adab2877a231347aa9633466f199740f8b5e177d3721
MD5 325c92de958b02c0dca3111cc0ef48bc
BLAKE2b-256 15e8a80a5b4e4399027196adfae11fbaa280766b801003cfa6533903f9926d65

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 3cb35657db610697af15c4e9f41914538a2fe1ac860a6250a036e2ba12325401
MD5 84fbecc1d661c7f4b14b874b83f3a7a3
BLAKE2b-256 e7b0d80fa115e0aefd52381c04f1a9e594278483441375f60992b348f60e3cd9

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-win32.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 a07f46690ecb536f9edef13b57107ae103aff2808cbb634a6a49f2a10cbc30a8
MD5 62c24e5022c5181baf12b3c18f6880df
BLAKE2b-256 c0e180186cd4a65c77a42adfaa19565ad68bcd27ecb5a34b157e102e68a03cdd

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 7873461b5addc3de864027d6d49907f2d93d3e024ae2071d7af2c23f8136063a
MD5 730e9d605c731c6eb420c4bdcb72a406
BLAKE2b-256 dec795222e6d95bc988119403775daeb8a8ad73bcbf9080bbfddb82873d49871

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 0b6d6ecab290a8f5a7f0678223ed3a7549b73f3283c5383d89953261983d84e0
MD5 49d8b4316c471146bca87beaaf7493c1
BLAKE2b-256 3374a305469e1913d9675312c55498caf3f6d5fa8dd300fd8d8ca49e9df8f7b4

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 438c99641eb1b5822551c71d99931364188940a0158547f5663d440dccce0d85
MD5 7dd9589f7c138af5c365dc09d8e0dcb4
BLAKE2b-256 a49892ddf50df4162ebde2f732aea8aaee0d18f71d113bdf83862786b438a0c4

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 0ad0d75de22b4ec4a0179b263779de65e311645c4735878e651c947c2dcb6596
MD5 1888bcfc26ad71800595470daac6b32d
BLAKE2b-256 10eb5b454070ad881fc00b6544e8a133425cfe64ce04f80b4e4f4ff27edeef42

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fc23bf3e32aad73f8d7b5ff3bdef667141491d33e2401fb10e9402edd2fea9f7
MD5 716bb0a924fd784d83edff482d2a9f9a
BLAKE2b-256 1d9e95f24af18757e6ac2c9af4098a22bba438e75fab66b0c4dcc7f86be09315

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 4f3d92a2e01f6abff5cb57a50cde75c9f91a4aa144a28d6b8394e9837715dd04
MD5 cbb65c76e7b79016ef0d3c77184c013c
BLAKE2b-256 38d95a23f38ad830aa9641518f3fa4b2d7cc40ee895b87f87581e111a8b9c4f1

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 e2068957010c3a3f92296c2ba586b26bf262c51dea71dd3afefd99fb97617ef8
MD5 f7effb35a697257441464367ca2a0302
BLAKE2b-256 313a3b2ea2b182b53f75f6f623a78de1a14fb96c8022ba76cde8920c25bb4959

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-win32.whl.

File metadata

  • Download URL: plum_dispatch-1.5.14-cp39-cp39-win32.whl
  • Upload date:
  • Size: 115.0 kB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.10

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 5dcee9f0f4f31734bd417180b3743c85f22b7cf0f029004b12bab3d75a22f655
MD5 00e722ca3637333ac29ff3904097f327
BLAKE2b-256 b330c1efc406c11ecc7db25fcfa9ceb37b6ae0ce0a88b07bc2b8d51be9d9942c

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 f7598fee63ff467742d884d4f60b3d085517eaba38f2441de26c991564cf421c
MD5 b893751e88f917087d6225763d9d67f4
BLAKE2b-256 eb8c8a26ae2e6f5706fc872f7adaa95d1f2385da734986f69af86571dde94e0e

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 fde505466b8e2d9e17d9ffeb7b1c71ef4b40f409757db786dd06feea8d25e236
MD5 a2e10df6649e67182377a2c15c2edaae
BLAKE2b-256 2940c5744a86e1b71e9c1597f5987df69efabcec3a6ae0e3da038ec07710530a

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 660ad627381511bc71f16bb729dcb608c8b57ac061871348aed0b97b1825ba35
MD5 c9ded547feb8c0e89fac77aea665f2bc
BLAKE2b-256 231e9dbbdb4b78ddfae5cb8913b5c781be1bda729e46b672ba13b17f2474f567

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 a6e9c57ca39153993a1472b25b2de1821991f744274f4926a8a0d2bbed350b85
MD5 c1045397651ca53ae6c9974128461fdf
BLAKE2b-256 29db3640b172461dba9b479701891a7ae68b6ff005a63789ffcc4fb81cb9fbc2

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1e4348e2fd30b8dcf99477880a4793639583c9252621071a117a5dfe7bba7a7a
MD5 6d6a10799d682817c9227bc14b9ecfc2
BLAKE2b-256 e47ea24464f8077e1c194d03ec8d894fa04cc528d6798c3afc41293807fcaefd

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5948f04a7733728bd2c1a4850b0ae665c38d7b9e91d9497c4c3a193d32de20bf
MD5 a7be2163694e5df5090531cf93816765
BLAKE2b-256 e5a2c6ad1327e89d17d744851fdca621085df6de4391506fdefc0e750e6d1a05

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 d60845fc4efe0c361f480edd94b60f10d7e6673cda2003c8166cfe19274ab45e
MD5 10f0e8cc347b37113078a037dad48448
BLAKE2b-256 9fa6236a6407d1b18fd17fb20e4e3cd08829712cefed14671f0819fa1a1bef83

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-win32.whl.

File metadata

  • Download URL: plum_dispatch-1.5.14-cp38-cp38-win32.whl
  • Upload date:
  • Size: 115.2 kB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.10

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 1300a09d5929b8cdaee8cb92733400eb5f14ea8d54ce2179e1c5ae48a9cb9ca8
MD5 06bb89038d510aa9207ad11579410329
BLAKE2b-256 1298e9fb26dadf7583ea4a80083b852ad8dfdbc2fa90ee0e7c1d88191c4be69e

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 13af9ef2abe15f9f1314caf9dff199bda41058ef4eb0a81958bf73c8a7b45aa4
MD5 f648332fa3c921bebd485eece7728e43
BLAKE2b-256 660b0f4e85c42408588e71b4747233582e9185f1063c26e6f521375ee079669c

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 f61131392fe857bd46b77b743b54810c3c19d9f6c9f7c85c18cd58f4caf62edd
MD5 7191bdcdb9169b6746652c125309d4a9
BLAKE2b-256 dee910d0e5dd3dbe4994020c7c9cd341898be13a90e91057fc8b15555df6d0b6

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 0db3f976b448be72abaac4d1694a8a90aa7cd80c485cc154fe60429dab14754f
MD5 486181d7236c25a42f0136cc087291d4
BLAKE2b-256 e887ae85ff9258db760b19c76e74caaca6c63c68847dd72bab16c198ad2f6307

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 204807122d99abd44c31a6254459b457417a4e93a2c1d89fc0b9de8d48788d49
MD5 3036bfdee018035f78a6b21ff1cee3e6
BLAKE2b-256 a4d4bc09f694f66e3637944e61c8c908a6c97077911d024cd3e04a71b29f1199

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 888f4aa593f9e8e09971aefe351a14c6571a74387cb58b9b9c681a7e5eae1cb0
MD5 a5d3c803da486b9d49cf4c5a8c3016df
BLAKE2b-256 8cc2c9e30d6b5f860f0508145a606baaf7c02b4226e7df53dd0eba3d88970c8e

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 4c940619326759d027868717327ed7049fe318363c0a1e639d94c73798103f7e
MD5 6b567cf7b853b17ceec5ebf8ec0fca36
BLAKE2b-256 cf3d840e195c618f1b7ab1bc09af7f5b5dab3ae961501f3acfbef5a6fdbb341c

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp37-cp37m-win_amd64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 058b96d2653a2c6b88b5dc84b85edb389750d51c1d5ea64c41c724198e2d9c8a
MD5 5500bcb39f05c958a14cecac56605986
BLAKE2b-256 363fc1189785f7d8e3e9c5b72a235661ecdcd2cb3f3c1c8261315a7554e9ae62

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp37-cp37m-win32.whl.

File metadata

  • Download URL: plum_dispatch-1.5.14-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 112.7 kB
  • Tags: CPython 3.7m, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.10

File hashes

Hashes for plum_dispatch-1.5.14-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 11b75dbefaebfd6694643ef28cf4e51d3f5d74837d249369d3d63968d8764237
MD5 52dbd122ac09d48a86abcb90dd90811f
BLAKE2b-256 3fdca5c395179b4094514e1e158a2f0875c6ddf380d606b39a8c9afbb0a8a6c4

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp37-cp37m-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 a72f55c73a417daceb97556522944e47f650fdc1b7c5abacb9e4250bf9cef21c
MD5 4585b61ffa395dc3bf3e4faab454eadc
BLAKE2b-256 a07e88f46bc2716562cbdd3b2a9a21d029f7e377bfb01963696b3a6de0b898e3

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp37-cp37m-musllinux_1_1_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp37-cp37m-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 379aa7a0c893e2c48e4bf84ddd9661c45b10bb34684e70bd241721dd16e82865
MD5 5f7448232afd5fc3c5cacc9961dcab74
BLAKE2b-256 d27f53655a26119c0cba3d2a21dc3ea0b40554e2c0fd906d9947a709ca3d0f43

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 e57585cec18baab5e97558d4cd52e129e1ce7832d1258f3b09a7c7589310abf2
MD5 6c46e83fea0f8765488338d443d84690
BLAKE2b-256 8922e532b46eb84b0858e50feb0c66ba13b7ed0f49d187c462aab6a16791cd56

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 7fc4a72e59c44072fa57a1bb2fc407a0c263bb859dcf316ee085dec3a57b12bc
MD5 494e289f696f1b0e8ae2a03ce6072cd8
BLAKE2b-256 ea7bdff78e1f91a0e413ad3e4994a1723e9f3b08dceec83b722a13039bd8ce68

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.14-cp37-cp37m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for plum_dispatch-1.5.14-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 42bd251fff645d46abf9a26851ce0eb050465eeebdc549fd2e064984015fe49a
MD5 f4561045723990eb399ff93cbacd9f66
BLAKE2b-256 baa5852404a7d2924c975b7aa1394bf0577775a2443c7dc3a0481a6d247045bb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page