Google Slides explaining how this repository works!.
This project is currently under development, with a release of a partialdispatch function expected soon. If you're interested in it, please get in touch, but but be aware this is very much "building in (semi)-public", until a proper documented version is up.
Currently, the only supported function is partialdispatch.singledispatch_literal
, which implements the functionality of functools.singledispatch for literal types and values, including enums.
Transform a function into a single-dispatch generic function, which also supports dispatching to a different callable based on a literal value.
Literal values are specified using either the typing.Literal type annotation, a literal type such as an enum
, or by passing the keyword argument literal=True
to the register
function.
The example below shows how this function can be used. The code should run "as-is" (and will use rich to print in colour if you have it on your system or in your virtualenv).
import enum
import typing
import partialdispatch
_use_rich = None
try:
import rich
except ModuleNotFoundError:
pass
_use_rich = False
else:
_use_rich = True
print = rich.print
class Pet(enum.Enum):
Cat: str = "🐱"
Dog: str = "🐕"
Shark: str = "🦈"
@partialdispatch.singledispatch_literal
def func(a, b):
return f"default: {a=}, {b=}"
@func.register
def _(a: int, b):
return f"int: {a=}, {b=}"
@func.register
def _(a: typing.Literal[49], b):
return f"The meaning of life {a=}, {b=}"
@func.register
def _(a: Pet.Cat, b):
return f"meow! {a=}, {b=}"
@func.register(Pet.Dog, literal=True)
def _(a, b):
return f"Good boy! {a=}, {b=}"
vals = [
123,
"some string",
49,
Pet.Cat,
Pet.Dog,
Pet.Shark,
None,
]
for v in vals:
output = func(v, None)
fmt = ("[yellow]", "[/yellow]") if _use_rich else ("", "")
print(f"Calling func with {v}: {fmt[0]}{output}{fmt[1]}")
$ pdm run python example.py
Calling func with 123: int: a=123, b=None
Calling func with some string: default: a='some string', b=None
Calling func with 49: The meaning of life a=49, b=None
Calling func with Pet.Cat: meow! a=<Pet.Cat: '🐱'>, b=None
Calling func with Pet.Dog: Good boy! a=<Pet.Dog: '🐕'>, b=None
Calling func with Pet.Shark: default: a=<Pet.Shark: '🦈'>, b=None
Calling func with None: default: a=None, b=None
Drawbacks
- Currently only works on hash equality
The argument literal=True
must be passed when:
- Value is callable
- Value is a type
- Value is None