Maintainers

Classifiers

Project Description

This Python 2.7/Python 3.x package provides the ability to dispatch on values
(as opposed to dispatching on types) by pairing functions with patterns. It
uses pattern matching to dispatch on complex, nested data structures containing
lists, dictionaries and primitive types. You can use lambda to do
expression matching and utilise wildcard parameters to ensure identical values
can be matched (see any_a). It can alleviate complicated and difficult to
read if ... elif ... elif ... chains and simplify the code.

Value patterns can be registered dynamically, allowing a great flexibility
in determining which functions are called on which value patterns.

Match everything in a list with single token

@dispatch_on_value.add(['a', dv.all_same(4)])
def _(a):
# Do something
# This will match as the nested list contains all fours
dispatch_on_value.dispatch(['a', [4,4,4,4,4,4,4]])

You can combine them with the any_X token:

@dispatch_on_value.add(['a', dv.all_same(dv.any_a)])
def _(a):
# Do something
# These will match as the nested list contains all the same values
dispatch_on_value.dispatch(['a', [4,4,4,4,4,4,4]])
dispatch_on_value.dispatch(['a', [5,5,5]])
# This won't match
dispatch_on_value.dispatch(['a', [1,2,3]])

These examples are simplistic but a more complex example might be:

@dispatch_on_value.add(dv.all_same({'age': 32}))
def _(a):
# Do something
# This would match since all the items in the list have the same age
dispatch_on_value.dispatch([{'name': 'john', 'age': 32},
{'hair': 'brown', 'age': 32, 'car': 'lada'}])
# This wouldn't match since the ages are different
dispatch_on_value.dispatch([{'name': 'john', 'age': 32},
{'name': 'john', 'age': 9}])

Another example:

# Match on a list of dictionaries where the name is 'john' and the
# age is between 30 and 40
@dispatch_on_value.add(dv.all_same({'name': 'john',
'age': lamba x: 30 < x < 40})
def _(a):
# Do something
# This would match
dispatch_on_value.dispatch([{'name': 'john', 'age': 32},
{'name': 'john', 'age': 37}])
# This would not match
dispatch_on_value.dispatch([{'name': 'john', 'age': 32},
{'name': 'john', 'age': 45}])

You can ensure dictionaries have to be exactly the same when matched by using
dispatch_strict() rather than dispatch(). For example:

# This will match because it's strict and the pattern is exactly the same
dispatch_on_value.dispatch_strict({'name': 'john', 'age': 32})
# This will not match because the dictionary doesn't match exactly
dispatch_on_value.dispatch_strict({'name': 'john', 'age': 32, 'sex': 'male'})