Awesome Pattern Matching
Project description
Awesome Python Pattern Matching
- Simple
- Powerful
- Extensible
- Python 3.8+
- Typed (IDE friendly)
from apm import *
from apm.patterns import Regex
record = {
"ID": 9340,
"First-Name": "Jane",
"Last-Name": "Doe",
}
if result := match(record, {"First-Name": Capture(Regex("[A-Z][a-z]*"), name="name")}):
print(result['name'])
Some Features
Demonstrated below: Junction of Patterns using &
, Strict
dictionary matching, Each
.
records = [
{
"Foo": 1,
"Bar": "Quux"
},
{
"Foo": 2,
"Bar": "Baz"
}
]
assertTrue(
match(records, Each(Strict({"Foo": InstanceOf(int), "Bar": InstanceOf(str) & Regex("[A-Z][a-z]+")}))))
records = [
{
"Foo": 1,
"Bar": "Quux"
},
{
"Foo": 2,
"Bar": "Baz",
"Strict": "Does not allow unknown keys"
}
]
assertFalse(
match(records, Each(Strict({"Foo": InstanceOf(int), "Bar": InstanceOf(str) & Regex("[A-Z][a-z]+")}))))
records = [
{
"Foo": 1,
"Bar": "Quux"
},
{
"Foo": 2,
"Bar": "Baz",
"No Problem": "When Not Strict"
}
]
assertTrue( # Note how this pattern is the same as above but without `Strict`
match(records, Each({"Foo": InstanceOf(int), "Bar": InstanceOf(str) & Regex("[A-Z][a-z]+")})))
Very slim User Guide
Any value which occurs verbatim in a pattern is matched verbatim (int
, str
, list
, ...), except Dictionaries (
anything which has an items()
actually).
Thus:
some_very_complex_object = {
"A": 1,
"B": 2,
"C": 3,
}
match(some_very_complex_object, {"C": 3}) # matches!
If you do not want unknown keys to be ignored, wrap the pattern in a Strict
:
# does not match, only matches exactly `{"C": 3}`
match(some_very_complex_object, Strict({"C": 3}))
Lists (anything iterable which does not have an items()
actually) are also compared as they are, i.e.:
ls = [1, 2, 3]
match(ls, [1, 2, 3]) # matches
match(ls, [1, 2]) # does not match
It is possible to match the remainder of a list though:
match(ls, [1, 2, Remaining(InstanceOf(int))])
And each item:
match(ls, Each(InstanceOf(int)))
Patterns can be joined using &
, |
, and ^
:
match(ls, Each(InstanceOf(int) & Between(1, 3)))
Wild-card matches are supported using Ellipsis (...
):
match(ls, [1, Remaining(..., at_least=2)])
The above example also showcases how Remaining
can be made to match
at_least
n number of items (Each
also has an at_least
keyword argument).
Capture(pattern, name=<str>)
(apm.*
)
Captures a piece of the thing being matched by name.
if result := match([1, 2, 3, 4], [1, 2, Capture(Remaining(InstanceOf(int)), name='tail')]):
print(result['tail']) ## -> [3, 4]
Each(pattern [, at_least=]
(apm.*
)
Matches each item in an iterable.
match(range(1, 10), Each(Between(1, 9)))
OneOf(pattern1, pattern2, ...)
(apm.*
)
Matches against any of the provided patterns. Equivalent to p1 | p2 | p3
(but operator overloading does not work with values that do not inherit from Pattern
)
match("quux", OneOf("bar", "baz", "quux"))
Extensible
New patterns can be added, just like the ones in apm.patterns.*
. Simply extend the apm.Pattern
class:
class Min(Pattern):
def __init__(self, min):
self.min = min
def match(self, value, *, ctx: MatchContext, strict=False) -> MatchResult:
return ctx.match_if(value >= self.min)
match(3, Min(1)) # matches
match(3, Min(5)) # does not match
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file awesome_pattern_matching-0.2.0.tar.gz
.
File metadata
- Download URL: awesome_pattern_matching-0.2.0.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.8.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b1f7aca32bf55cdda77d9a7923b6766484ba96960742823c75ea99509051d218 |
|
MD5 | 0967bd3c905c711558a178d30bca8a57 |
|
BLAKE2b-256 | cfaa906520bd7f8882a0aa8cc1f5773a9f0242ff5fd2c728e2d3ff001fd7f64c |
Provenance
File details
Details for the file awesome_pattern_matching-0.2.0-py3-none-any.whl
.
File metadata
- Download URL: awesome_pattern_matching-0.2.0-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.8.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ac63c13339a521a629a9d8f2f8e2e226a465dff9e8359c7d63fafb3cdb724096 |
|
MD5 | d1e215fdf5b935062d438a043f350457 |
|
BLAKE2b-256 | f76a92bb71c51a4268b65da601ab2a9a12f5693da8c7e6096ddaa8aa5868ad84 |