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.13.tar.gz (50.4 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.13-pp37-pypy37_pp73-win_amd64.whl (107.6 kB view details)

Uploaded PyPyWindows x86-64

plum_dispatch-1.5.13-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (134.1 kB view details)

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

plum_dispatch-1.5.13-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.13-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (120.3 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

plum_dispatch-1.5.13-cp310-cp310-win_amd64.whl (124.0 kB view details)

Uploaded CPython 3.10Windows x86-64

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

Uploaded CPython 3.10Windows x86

plum_dispatch-1.5.13-cp310-cp310-musllinux_1_1_x86_64.whl (618.4 kB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.13-cp310-cp310-musllinux_1_1_i686.whl (591.9 kB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ i686

plum_dispatch-1.5.13-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.13-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.13-cp310-cp310-macosx_11_0_arm64.whl (143.7 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

plum_dispatch-1.5.13-cp310-cp310-macosx_10_9_x86_64.whl (158.1 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

plum_dispatch-1.5.13-cp39-cp39-win_amd64.whl (125.6 kB view details)

Uploaded CPython 3.9Windows x86-64

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

Uploaded CPython 3.9Windows x86

plum_dispatch-1.5.13-cp39-cp39-musllinux_1_1_x86_64.whl (618.2 kB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.13-cp39-cp39-musllinux_1_1_i686.whl (593.3 kB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ i686

plum_dispatch-1.5.13-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (557.3 kB view details)

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

plum_dispatch-1.5.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (535.3 kB view details)

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

plum_dispatch-1.5.13-cp39-cp39-macosx_11_0_arm64.whl (140.8 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

plum_dispatch-1.5.13-cp39-cp39-macosx_10_9_x86_64.whl (155.2 kB view details)

Uploaded CPython 3.9macOS 10.9+ x86-64

plum_dispatch-1.5.13-cp38-cp38-win_amd64.whl (125.9 kB view details)

Uploaded CPython 3.8Windows x86-64

plum_dispatch-1.5.13-cp38-cp38-win32.whl (115.1 kB view details)

Uploaded CPython 3.8Windows x86

plum_dispatch-1.5.13-cp38-cp38-musllinux_1_1_x86_64.whl (678.7 kB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.13-cp38-cp38-musllinux_1_1_i686.whl (647.3 kB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ i686

plum_dispatch-1.5.13-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (607.3 kB view details)

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

plum_dispatch-1.5.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (579.8 kB view details)

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

plum_dispatch-1.5.13-cp38-cp38-macosx_11_0_arm64.whl (141.0 kB view details)

Uploaded CPython 3.8macOS 11.0+ ARM64

plum_dispatch-1.5.13-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.13-cp37-cp37m-win_amd64.whl (122.8 kB view details)

Uploaded CPython 3.7mWindows x86-64

plum_dispatch-1.5.13-cp37-cp37m-win32.whl (112.6 kB view details)

Uploaded CPython 3.7mWindows x86

plum_dispatch-1.5.13-cp37-cp37m-musllinux_1_1_x86_64.whl (555.5 kB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ x86-64

plum_dispatch-1.5.13-cp37-cp37m-musllinux_1_1_i686.whl (528.7 kB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ i686

plum_dispatch-1.5.13-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (494.4 kB view details)

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

plum_dispatch-1.5.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (470.8 kB view details)

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

plum_dispatch-1.5.13-cp37-cp37m-macosx_10_9_x86_64.whl (151.6 kB view details)

Uploaded CPython 3.7mmacOS 10.9+ x86-64

File details

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

File metadata

  • Download URL: plum-dispatch-1.5.13.tar.gz
  • Upload date:
  • Size: 50.4 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.13.tar.gz
Algorithm Hash digest
SHA256 2264dfc413f61ed4af106da8d214de17ed5799a08eb42762759f23270351e67a
MD5 8ae78fe3290bae51068f96388ba83701
BLAKE2b-256 f75dae970832b1b63eb270b915ce2976757cab591775bbba1ce572dd07d6f243

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-pp37-pypy37_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 7669ed7456c5111511257301105479b0e0d578dc7d63e7f2b83d49aabbb778e0
MD5 6dfcde170578247ad28a7621adeddc38
BLAKE2b-256 35ce75f1b0afbe657da9904f179605b7293147d7a15e35e5b7fada2e0a8537d6

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 ac2abe6aa14eba8af61bccf03c9f081e2d96f4583f3c8deda67ad06c1e2a5be8
MD5 4136960ef1e9f4168cfa49520e5b168d
BLAKE2b-256 be59a14bace9da6ddd66525078152f9cd68ce79a0e291942460f783ca253c41e

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 d904451a72ff427c812721f29122fd0fd6fb43dcdba34c796c5861c2b1af8092
MD5 c1dc463a9e957c870f12b6049044df1b
BLAKE2b-256 77710e89e308304a6f7887848038eed9eded43a98d1f972bd6dd51cec2f0ea97

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-pp37-pypy37_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 66f53d918ba0395d365095702740a27b07968fd517b02705764c66830d9d2440
MD5 e9c378b550fc22cd55db26c7515ecaf7
BLAKE2b-256 4817bba85e9fd097173d1dbb8c346debdb898c41aa4a3928bc29ec219445e342

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 03b43e2ec054fd08f4cd206b7ea6fdbe47f97c54849d736c7929fb7bbdec90fb
MD5 25d9d44bf647382a763b96a2cd335779
BLAKE2b-256 c2b3d258a68c946001e554152b417ef560bc83c61b3d3eeb5f1818ca0e1dfd2c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 378b54759ac309dbb5e19fbd6e70423583f66f6f97b2e4a759f12b036f446194
MD5 7a0f304f7c45f4630827d931a28e7e1f
BLAKE2b-256 4fa2d253aaec2efef84a3c69003a58faaa54520f672d89763002c2273f3d2efa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ca5d9f2ddfccb272de1b075b1219b4282c794920bde29f34449524bf8553f077
MD5 4c14607907ef05d8bfc807706d93b127
BLAKE2b-256 db6e432d9eba9ce50e068146b979d914f23535c18e1116f6419102f79e81c46a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp310-cp310-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 7f0237cce01910cd1149400ea9de56e4074806e2fe2892a01d8a93042bc77e63
MD5 6e70f0ba99a1ddfa2cfb93003cde2fa1
BLAKE2b-256 bbca4f2c0407f5db1498817d70099ce1cf362d94e02e41f49564627ca7fa0f78

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 32059e5b08f6956cc0dc9c17ca06b70bc838fab84f2b47198059a4b109fc090a
MD5 3de55200d56e688214aa4b3af7303859
BLAKE2b-256 adbbfb8e81105c6c98a40341339b4684190b84acb62e17242f0095b987219398

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 3ea8520d7edf361d8121a5f65b01407d46b9b9e6e0a49fc23bd43afe5dbd009c
MD5 736f9207e8155c32ac2aa82875dad54b
BLAKE2b-256 b3e5aac83cc796f591d97c819a832127973fe9b19dce3bfc5b097685e19e6bf4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3f2ef83fcaf2b6ebd99c29abd6757188e57faeec6e867c469234cccb9e826ad7
MD5 a7fb12d84a46f3fbde04c363f0e9426a
BLAKE2b-256 a55e397a95d1e820e852369488e31d5f273c3189322adf0bc074fb06e2f0d88e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 660a70b5bc835414836fe42e48abd625a718886369985eac7c5be15660977d2e
MD5 5b85e3ead2e06b3b5862482deb2734e8
BLAKE2b-256 d5f94f79baff492575302fd7459c4a45d320b6d77dfbef81409e35d8d4b5f3cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 9383da86a5ffa4f7e729f611fab9f3592e73e8554e23f08073e661cc40ba6c49
MD5 d873f5799ad24e2da64c04b9ef5ef83f
BLAKE2b-256 3a3060e56fcf60e457675cdf58ea89aa62a0ffe5038bcebd96802268c86ecb66

See more details on using hashes here.

File details

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

File metadata

  • Download URL: plum_dispatch-1.5.13-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.13-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 56cb8821687ebe353dc4f58582902da4ac4ec2859749a1cc2e378f7cbd6d01c4
MD5 05a09a863677b6a86dd38bf0d5094721
BLAKE2b-256 48437d83d14a393ffd39e8e6eb84ed6aa0679219823a9fefd190bfaa8d158f69

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 d4d51483c26ba4e027e8be3912f3b48e6a09f5f24d814a5a259de60fcf41e2e3
MD5 eb879e21e7be70f124feccfd4609eb98
BLAKE2b-256 c99bf4c477a0b4e99a21d21c30c3c174b8033fd5e6cac6a48aac734cdf0733f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp39-cp39-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 0922f8a775ec21a32fa34d6f8b01b688c1163dc89bc55cdca062b59cf5e26575
MD5 98c6ac9be22c8d7c73a36b66b189c994
BLAKE2b-256 fe6f813c0e8d8654564837dc24de57ec189f84faed1fb15b3f2fbd9f4663c915

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 21113843e91aee433dd7b6c4fea99732df013410a0b506db1262c51056eb1a6f
MD5 aef81b26fa41c14edb96d66381b6c4c4
BLAKE2b-256 d755efaee254edae1fd328216d59e38912fac4ab402dd18856317c4bb6070552

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 a5cbc5a40caccffe90c499e77abdb9304a849ed72ad942ce4cecf8cd228a308d
MD5 205cbab4e27f153be94eeb06e3f184be
BLAKE2b-256 76e3a505cdc11f2a280c4812098f748ad879b41dd3c8f00a58c684923f9fb3fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ad39fdace06578686bc28a2f93f875ba1216bd55b2f82859b5932c596847666a
MD5 934e57b64e296f784d4f89578a924946
BLAKE2b-256 1b0a90240532abb41dee7a4f6b1a461b96badd62ce35c9850258c95cad90a0eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 f82d8ff404c970609e7f832c046bc4ab8c81c34eadbeb3b8e40059ab6d6b7228
MD5 0696bff1eac7adb1e5d8aaaa77e920da
BLAKE2b-256 0c7d80bc5de46de8785f784767551b672b16321ef26fb0aff6fe34e25c11dc77

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 de65e7a72f3aa37cd2098d816615b29b2c9c0fbeb0909e013a42ad8dd03422ed
MD5 a56d07fc04e354bec8d0ea3dcfbd23c9
BLAKE2b-256 0fc037dd2f61ae76879e7066c135d9b87be1b70ff1f01654898fd548e422aa47

See more details on using hashes here.

File details

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

File metadata

  • Download URL: plum_dispatch-1.5.13-cp38-cp38-win32.whl
  • Upload date:
  • Size: 115.1 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.13-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 3738a3f99170064a20e4dcf7117ce632286c0e6d472f70e28c357aeb17f8740b
MD5 1b6a0385f7ae25017b18dd051b6e34e4
BLAKE2b-256 22c36a44109254158128a54e9d07b15646f069c3ad1984cf16abe6c35314dfe1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 e809f3681c0746b12928bcad91a550a6c6682d7b7b36c9efeb3af8fcf96ce36a
MD5 7b81549d0906859f83028fd1a223c55c
BLAKE2b-256 663197a3b11662e1b14d8029747bee2a7374f1bd2b9c453e83c2e35b82b4b15d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp38-cp38-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 5ef006dcfe0221ab539e4e23a47a655659cb1c760eef0b50bc2d962b2e919ae2
MD5 2b69cb9dddd5aa965786a2bcf915852a
BLAKE2b-256 8377c1845e4b9ebb056da733631bfa3b8194c1729833dbe9dd3ce3699b7e74ea

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 4be31d2b9e8d36301dd4f4868a53b9f379a8e81de69c24dda066349f99e93d4b
MD5 31dd18a13fccac8c47f7cc6eae06d8bd
BLAKE2b-256 8ac8bea16cc17b4127313a616a9a69fa698edb87591885665f4275e9856a4baa

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 23030e64a37dbd6ee73e10a84bfa4c3339fba4d833c469dad1484d788b14998f
MD5 7bcfefd74eb01e323f6fa4f3c3e7f7ff
BLAKE2b-256 582df0dd355d5e236c8b5493a6bcc2cf9daddea3f886b35edced225864255e0c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7fa64b55cc36b9f17a8686c92463fc8ec904f5885c06d07674ec7bcb2027ec59
MD5 bc95f85f3bae738084ad918316a7f6b3
BLAKE2b-256 b3facea2166780f659ac21a69dbfedbc588fb54de37cc1d3b352871180d6f374

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 eae7b4e419f56b93de6dcbebcd507f3d4574c4b44ffea85f151260d4d8f4104e
MD5 4c1c0ec3a206fcb15bc43cecc21cc61c
BLAKE2b-256 be234049ac898d691d6ee6f6b20b58f15315b9ffb3a05d02b775995d4ab5fad4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 29872bf7b23ef69f4c570b41279d62bdd426d6abca0cd01a97b31b5f95e2ea6c
MD5 00a53d37cd3cf4c1bfee381a9b6433ac
BLAKE2b-256 768112841f21e945bb5951b80dfa08e1dd55dde4a70eaa4c5bf9c7cbd4a1a955

See more details on using hashes here.

File details

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

File metadata

  • Download URL: plum_dispatch-1.5.13-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 112.6 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.13-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 b76f64d0608f00e7cf981576a21864d3fc37a5e90eb608410c114f603e6878de
MD5 6591fe3e8683c605717df1d9f488ed35
BLAKE2b-256 82674036fc24f1b6c931da1412b308c3c404e92ad2cd7f59fb13993d9e044aa6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 84106ebd59a22f56e6cf5e6d985224a82c62724aea5cd4307a770236c2b0607c
MD5 e09f0154c7f07999cefa668477843930
BLAKE2b-256 3d0a8db85c2d20ff512f03f694e24e391935de9bfd27fb33777a3089b7a06c64

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp37-cp37m-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 52183d0c71fa6601914aadc62dcb16efbae3d7c32312109f0829fb9571f7387c
MD5 071408d41b69a315039c2dd3aa6fa868
BLAKE2b-256 9a1a8eb5c9ff897458c768fdfd3220ff2480842cbdeedb26da94b1027d4a4c08

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 435e879aa6902cd90414c65f1c26cacd94f0958aaa278ff2b6d597484fc6ee6d
MD5 e3cedded6c2d5b1a428ced476bc2d11f
BLAKE2b-256 dfb98831dee126bad4427aec8a9a2695057187025d94cfa362ca5c3141edae14

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.13-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.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 f252f86d2aa205891457c21346de2bee0425ccfe0dcd36f6d7adb6c06e8efb36
MD5 616b896c6224299e071d4e9b381a1cc7
BLAKE2b-256 17226e28169d9e918d185cbd251afe9e7de55d240ac05d5e6fdd0423452e2848

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.13-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 7a3bdefd467af408eb37b31a9471668a60c8df25ff4d3f9e7e387ff604f16805
MD5 74cd4adb9aeedfcac7f902e5cfc6cfe8
BLAKE2b-256 30c2f2cf72fc714e59edb764771552184955cf613a1c4b2a4a81b781e74ddeb5

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