Usage
This library exposes a simple Matcher class and helper constructors via the mtch alias.
mtch.any
Matches any value.
mtch.type
Matches when the value is an instance of the provided type or types.
mtch.regex
Matches a string against a regular expression.
mtch.pred
Create a matcher from a custom predicate function.
def is_even(value: int) -> bool:
return value % 2 == 0
assert mtch.pred(is_even) == 2
assert mtch.pred(lambda v: v > 0, "positive") == 3
mtch.eq
Creates a persistent matcher that remembers the first value it was compared with and requires subsequent comparisons to match that value.
Persistent matchers shine when you need to assert that the same value appears multiple times. Some handy scenarios include:
- Repeated identifiers in nested objects – capture an ID once and ensure it matches everywhere else in the response.
- Tokens shared across multi-step operations – store a session token from one request and verify it is reused in later calls.
- Mock call sequences – check that the exact argument value is passed to different functions or multiple calls of the same mock.
For example:
from unittest.mock import Mock, call
user_id = mtch.eq()
assert {"id": 1, "child": {"id": 1}} == {"id": user_id, "child": {"id": user_id}}
token = mtch.eq()
assert {"token": "abc"} == {"token": token}
assert {"auth": "abc"} == {"auth": token}
mock = Mock()
mock(user_id)
mock(user_id)
assert mock.call_args_list == [call(user_id), call(user_id)]
bad = {"id": 1, "child": {"id": 2}}
assert bad != {"id": user_id, "child": {"id": user_id}}
Combining matchers
Matchers support logical operators:
&— logical AND|— logical OR~— logical NOT
number = mtch.type(int) | (mtch.type(str) & mtch.regex(r"\d+"))
assert number == 123
assert number == "456"
Matchers can also be used inside dictionaries or other containers for nested comparisons.
Nested data structures
Matchers can be mixed into lists or dictionaries to validate complex results without checking every value exactly.
matcher = {
"id": mtch.type(int),
"items": [
{"value": mtch.regex(r"^x"), "meta": mtch.any()},
mtch.type(float),
],
}
data = {"id": 1, "items": [{"value": "xyz", "meta": {}}, 1.5]}
assert matcher == data
Mock call assertions
Matcher instances work with unittest.mock and pytest helpers. They can be used to assert against call_args or call_args_list when exact values vary.