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.11.tar.gz (50.2 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.11-pp37-pypy37_pp73-win_amd64.whl (107.0 kB view details)

Uploaded PyPyWindows x86-64

plum_dispatch-1.5.11-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (133.2 kB view details)

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

plum_dispatch-1.5.11-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (134.7 kB view details)

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

plum_dispatch-1.5.11-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (119.5 kB view details)

Uploaded PyPymacOS 10.9+ x86-64

plum_dispatch-1.5.11-cp310-cp310-win_amd64.whl (123.2 kB view details)

Uploaded CPython 3.10Windows x86-64

plum_dispatch-1.5.11-cp310-cp310-win32.whl (113.2 kB view details)

Uploaded CPython 3.10Windows x86

plum_dispatch-1.5.11-cp310-cp310-musllinux_1_1_x86_64.whl (615.1 kB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.11-cp310-cp310-musllinux_1_1_i686.whl (588.8 kB view details)

Uploaded CPython 3.10musllinux: musl 1.1+ i686

plum_dispatch-1.5.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (546.1 kB view details)

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

plum_dispatch-1.5.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (523.0 kB view details)

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

plum_dispatch-1.5.11-cp310-cp310-macosx_11_0_arm64.whl (142.8 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

plum_dispatch-1.5.11-cp310-cp310-macosx_10_9_x86_64.whl (157.0 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

plum_dispatch-1.5.11-cp39-cp39-win_amd64.whl (124.7 kB view details)

Uploaded CPython 3.9Windows x86-64

plum_dispatch-1.5.11-cp39-cp39-win32.whl (114.2 kB view details)

Uploaded CPython 3.9Windows x86

plum_dispatch-1.5.11-cp39-cp39-musllinux_1_1_x86_64.whl (614.3 kB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.11-cp39-cp39-musllinux_1_1_i686.whl (590.5 kB view details)

Uploaded CPython 3.9musllinux: musl 1.1+ i686

plum_dispatch-1.5.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (553.9 kB view details)

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

plum_dispatch-1.5.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (532.4 kB view details)

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

plum_dispatch-1.5.11-cp39-cp39-macosx_11_0_arm64.whl (139.9 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

plum_dispatch-1.5.11-cp39-cp39-macosx_10_9_x86_64.whl (154.1 kB view details)

Uploaded CPython 3.9macOS 10.9+ x86-64

plum_dispatch-1.5.11-cp38-cp38-win_amd64.whl (124.9 kB view details)

Uploaded CPython 3.8Windows x86-64

plum_dispatch-1.5.11-cp38-cp38-win32.whl (114.4 kB view details)

Uploaded CPython 3.8Windows x86

plum_dispatch-1.5.11-cp38-cp38-musllinux_1_1_x86_64.whl (674.6 kB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ x86-64

plum_dispatch-1.5.11-cp38-cp38-musllinux_1_1_i686.whl (643.6 kB view details)

Uploaded CPython 3.8musllinux: musl 1.1+ i686

plum_dispatch-1.5.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (603.8 kB view details)

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

plum_dispatch-1.5.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (576.4 kB view details)

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

plum_dispatch-1.5.11-cp38-cp38-macosx_11_0_arm64.whl (140.0 kB view details)

Uploaded CPython 3.8macOS 11.0+ ARM64

plum_dispatch-1.5.11-cp38-cp38-macosx_10_9_x86_64.whl (152.8 kB view details)

Uploaded CPython 3.8macOS 10.9+ x86-64

plum_dispatch-1.5.11-cp37-cp37m-win_amd64.whl (121.9 kB view details)

Uploaded CPython 3.7mWindows x86-64

plum_dispatch-1.5.11-cp37-cp37m-win32.whl (111.8 kB view details)

Uploaded CPython 3.7mWindows x86

plum_dispatch-1.5.11-cp37-cp37m-musllinux_1_1_x86_64.whl (552.9 kB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ x86-64

plum_dispatch-1.5.11-cp37-cp37m-musllinux_1_1_i686.whl (524.6 kB view details)

Uploaded CPython 3.7mmusllinux: musl 1.1+ i686

plum_dispatch-1.5.11-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (491.9 kB view details)

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

plum_dispatch-1.5.11-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl (467.5 kB view details)

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

plum_dispatch-1.5.11-cp37-cp37m-macosx_10_9_x86_64.whl (150.7 kB view details)

Uploaded CPython 3.7mmacOS 10.9+ x86-64

File details

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

File metadata

  • Download URL: plum-dispatch-1.5.11.tar.gz
  • Upload date:
  • Size: 50.2 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.11.tar.gz
Algorithm Hash digest
SHA256 fe64726d5e4dbaafa8cbe1de6e5b598931036bafc5b2e310878b5def77dae415
MD5 401f3c66ebb6c3670a0186395d2ad417
BLAKE2b-256 d594589cace49230d91084655d0823e43ba680f51d9767121cb726d9c3ec375e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-pp37-pypy37_pp73-win_amd64.whl
Algorithm Hash digest
SHA256 1f6b530572e12496ec66be9de094895b9dcc9e4b27d53d1fba4d0df0ed4b7f63
MD5 549748ad008968a40a6902a0e6143c0e
BLAKE2b-256 615ece1e8146154b6d79822b25628c22f5a27ad8b318e32b3d93e154a2de1205

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 413154b84a62cbe601faec7f27eac0be2d1b40f08a7d737de9b8f5294aeaa4e6
MD5 6511028a720812632fb69421a1a1c803
BLAKE2b-256 3abae8a6fcc1fde9e203c6e1317ac3f6c2b0b780d4992f48b82d31296fba9e74

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 c89f112762e605965bb0ca3e51a02af711177dee898c7642f3f5dd352eecad22
MD5 f185db03561f44ce3febd95a4f6f6869
BLAKE2b-256 dfd4f166906da067ddbdad42a1f0ea2d3c0ce5f4ed18e3097c59c18297bad027

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-pp37-pypy37_pp73-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 75686e474de97946c3884104e74b12093a3fbefd0426d0189c5e20d243e5359c
MD5 b167aea4b601f00ae1364cab76859d87
BLAKE2b-256 77a9bba5802b26114f418bd74823a72fa0c45220d1250e09fbd5ce302a260652

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 2b03c23099469e15b43d85c6d212ce6fe4c8151e6239aae1eb9055785a7a8b41
MD5 a6294167fc43cae18ac4e4c6278f2910
BLAKE2b-256 ce04567dd705162afa65582b7b08a06993b33ea6ca5149e8d253e4c43168be6a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 3b0a76a94fb2aee9257722c10a6be7367d7f1cf62ea144e3fa4d862584b99e08
MD5 924203c320349d73dcce9449c9dd77d0
BLAKE2b-256 585db66e09950b1d846d37b45328261bd5cc0d0fefc6f31d87b431e4abe07403

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 66cf20d60bf8da7cb891aa461462dce45e4215b96bbbc208b478bd8486673832
MD5 7835b42983720122a0583be5c7ab0eb1
BLAKE2b-256 6a9b08a68d7afcc0c945d841c50e3443c883d3881d224ad20113540c57bf215b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp310-cp310-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 1677f873fb709f2cd8f90efc6d5d38f7eec43ab172058875fa133f1f0df62967
MD5 d4e9b3e3dc1b4976d3d8c801afcce2d2
BLAKE2b-256 943bdd9616b856c7ad86e2e0017b5ce28b364f4057b88a82635c8c2554ce0a35

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 d8e7a203e66ee66d15d680fdc6794fbb547288ff1c02908b6ae97cb8fdfee39f
MD5 428e6d3e9cd1f6a366418c601588ad1c
BLAKE2b-256 6bf6cb1598ae883e4f74e1950ffc99b0ed033bbecb85c43ac99da8e3137533be

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 bee961126ef2ae6e245ab62412b9acfbf239393cdf64b7c6afe9ae5b0436f65d
MD5 3bf93585d124ba37e1bd744444d7aa5c
BLAKE2b-256 199c3992962b096748153adcfcae2cf5b71e6f6cc2249c06f26a7a44244f29a6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 eb3744bcaa3390a0440947c368aefb3e76d81bffad13900ae5b47d8581c96459
MD5 d495dce62498b6c54fe0223c822b5fea
BLAKE2b-256 08ecdb6148ebd05808bc565579fd6b644b2069db744607c5d3d519fd1294ebf0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 f13d07ed882cef0dd997de9f008ad392c1489c828d89c1bdf96ebe13a7314b53
MD5 67269f6ddf586613939dd3a46256e630
BLAKE2b-256 9947bffa383f0196e54e1f55dd83cf3f5768b31b79ea7657d230464ac0e62663

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 b1e2f489182fecc793d825581990422537da1a09c18e9de539bdf4254da8ddc4
MD5 1ca2102ec5c05431b67ab2b67634d667
BLAKE2b-256 b563ff733a669fc4ac043ac1647884cdfce319c181c0efb94348aae532ed2840

See more details on using hashes here.

File details

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

File metadata

  • Download URL: plum_dispatch-1.5.11-cp39-cp39-win32.whl
  • Upload date:
  • Size: 114.2 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.11-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 cda19a31d714ebc701f40f6cc426393f815d9e059c27e08b8744c7fb872401d0
MD5 a840671c15a5eaf1ab8dac2c7fa77d93
BLAKE2b-256 d000b25b7c79e6fd9961684204ed4eb89b8044280d2085d167825e2d30cc9172

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 d13c4653c39bc20f3c3dcb59fa97b6c269a2672d653cc9aa5af4e1233175c9ad
MD5 54300e487d42f7f636871cbc3f8a593c
BLAKE2b-256 669747bfe523c8bae64ecff8de1e569d109e1468b20c2a0e42b9b3cb9b3a90fe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp39-cp39-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 596ddc17e85c1d12c0c30bba2cce19ff70114fe31e04e580d598edd045377b6b
MD5 5e0176f6d23c4d091f002a6e7f64af6c
BLAKE2b-256 0a004e633b6183533bcfe434f881ddae9c22c2284441b26f533181211aadcc67

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 97e58f914bd882ef2d9bce3c5eaceefcd9aa23cabf8f6512dab326302098b1e1
MD5 5cadf4a35e8d1853fdfeb58f54209f86
BLAKE2b-256 1bb5288b4ff09ce9cdf4691a2b9fad37e622c516145913514333d03af973bf9d

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 b5e6c3c5bef8a23cb227ca8fe6d70ba3feae1d55a0f6fba0106e2e742af6c8d3
MD5 0798085fbb8b55e8d3524b0bc832a602
BLAKE2b-256 66af3aeb9ab40ca049afe95d1316105fccb5e7c3d0155964dac4a831a3dcc9e3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ced777f0e2c9b761c0c3a00eac4ed4412cf2bead02cd26709bc9ba6cb0a255ee
MD5 338561d1b7304c23237827b949e53302
BLAKE2b-256 d98a027c699abed7a5241a6994e902ec28f94808cf657a09a70c980996d274d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 143d8c653080c8f9b8c257ff15b9ce68332abd551a22f25c0d0997898fe6bf06
MD5 4f89182d58a7d7973749eed113678466
BLAKE2b-256 77b970bd674c71508d208544650673c41f98c8b5e8913a0ef54f6523bc882432

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 d254eff71282457513e6d3728002632ff3bc26738752b1a697647fd4e59dc1cf
MD5 a32b9bced09c2804d182e50c1c8dcf7b
BLAKE2b-256 4b0da70b35aafa2b14d55ab949437e518b72e587f659379716908e9d33641f02

See more details on using hashes here.

File details

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

File metadata

  • Download URL: plum_dispatch-1.5.11-cp38-cp38-win32.whl
  • Upload date:
  • Size: 114.4 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.11-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 f562ee950411d07a7cab9d930a815f014af868cc5de11492cabdb0f4480c85fb
MD5 e7837440def68f2327842434e0f08626
BLAKE2b-256 e06a503941596640eef41f3e3094db917ff4f3d462f6c98f8ffa40b71e9a986a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 d829b4f450eaf43f2adcbb02667c53c236a40db2affff1703df6c95dcfb04b3e
MD5 3517b80c8b709b955f51a317187df42b
BLAKE2b-256 846f942d1d32f92a72a24442c281a76758913b3929754997c120a5570a96927c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp38-cp38-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 41fbd29dbc63b456abed2354ba2fefc58b94ee4165026ef1212a639bc1ce3eda
MD5 9e350e1f24f941795a1e7a0dc4b22662
BLAKE2b-256 00ae4a9999e454ce76c573f814688e086c110c75ce8128cfbef79f8b1c3c8764

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 ac091be30457d951c822fb859986633f3949507fe38d191f7db154d5a3bfd3bf
MD5 2725db2609e8e4373fca4659ac93189c
BLAKE2b-256 b89a20a2455c2550e038c7c16bcc4abd9141fa713928ef42968a3572c6542905

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 c2785fd0f9d7449d6e361ae8de4d4c27bb355f0a7862d0703ff1872afeee0826
MD5 6b7855218a630b3e0a9f9ba18411552e
BLAKE2b-256 01b7376792fd472f8fbe5627a270d1e704504d2718232564f798e5fb70368737

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b891cf99b61021c36e399a50ae3ec530993bf08c1e75fd27f3a60c135e12ff5f
MD5 cec4028f1ecac3e9b2fe73de42376b32
BLAKE2b-256 db70e41297ce0e085c71129edb6613d6cfa74e0e7c527435ef7ed1fa8689be94

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5010165aa30e968b08dfd5605d8ea8b55cf24d446955b0f9acfc7068a1bfe58c
MD5 b2e4cb8b739922a1167842fb48e94406
BLAKE2b-256 b4a1a03e1b1f0475b75e2dd1494df363cc176abdb7266134a708248dab517bfb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 c7efc6487415ed02fabdb89baa51bb6504ed6f59e884a41b1fd65c90a25bd2d9
MD5 a11ff50968fd5048ebd5723cf030fe92
BLAKE2b-256 89c6a353f02cb4f46c439aab77aec784ba6e9008a309817fa358198e1cfd9d10

See more details on using hashes here.

File details

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

File metadata

  • Download URL: plum_dispatch-1.5.11-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 111.8 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.11-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 bdf903806247ad711fb1b78e5af46a8a4330d61e27fff1a368de2f52eff2fdce
MD5 1237f2e9ccc570cf9399607b8e712772
BLAKE2b-256 495b0952ea1644eb7d7c0eba54003bb815480c8f164a306eb723356a512f6dba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 6f7fbcaf362464e277817245449b2fccadf55dbe3f1b31c4fd2b3efc3ac8bf2e
MD5 4bb2a119cff4549efa1b7e0910f19edf
BLAKE2b-256 b7dedd761d190a8a95afa8ffeed75b51f12420fa5a3e08dc5aadc37c3ab1bed6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp37-cp37m-musllinux_1_1_i686.whl
Algorithm Hash digest
SHA256 bba6482aef6e6ca15b7b16f36fb5008cb8f8b2fe18f5ed862d15be0642777f60
MD5 b02f322dd354295707d2ede5ac1173ae
BLAKE2b-256 f10761f1fba3ea310db14d8366b2e737a613a343d05105a4f8fcfa77cf21a873

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 056ef313a32fcdc0d0bd2afd2b41b0164c54ddcd22fb0226bd7c3f4039540d6e
MD5 46ace849e21e752da20eeae2e790fe42
BLAKE2b-256 eeacedf69b05cabf25f3b418bfe3ba7331e90115c43afe1413c274911bc60b1e

See more details on using hashes here.

File details

Details for the file plum_dispatch-1.5.11-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.11-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 620cbc184869d94235a6c0f29e249bbdc48d156ba58ef50b6dba23e6f6f4dadd
MD5 40fb5f12c5bb685b725a70675e2ae3cb
BLAKE2b-256 b0b7981931fcb7f1a161b8584be4bb61013e1859a4d35ffbd57a6e9d65ac406a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for plum_dispatch-1.5.11-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d32821107422e564ad9d8e65af322878933e174834211cd8de514712ea72bb43
MD5 4c2bee7566519d5cc83d6e29d47d7cf8
BLAKE2b-256 4a0c48fe72e144e96298308d2b4057d53bc3b270b6a0e5ec658d9537f8954d6c

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