label-filter
A small pattern language for filtering lists of objects by their labels. Parsed to an intermediate representation and matched directly, never compiled to a regular expression, so a half-typed pattern cannot raise and cannot backtrack.
Python 3.9 or later. No dependencies, and none for the tests either.
pip install label-filter
from label_filter import compile_label_filter
matches = compile_label_filter(r"\b\app&*.pdf")
if matches.error:
# Show the reason beside the input. A refused pattern filters nothing out,
# so the list the user is looking at stays exactly as it was.
print(matches.error)
kept = [label for label in labels if matches(label)]
The compiled matcher is callable, so it drops straight into filter() or a comprehension.
Two things that are deliberate, because they are what a filter box needs:
- A pattern never raises. Every input compiles; an unusable one sets
errorand matches everything, which keeps the list visible while someone is still typing. - Compile once, call per row. The pattern is parsed a single time.
The language, in eight lines
apple contains, case-insensitive: the default
apple*pie * is any run of characters
`apple apple` anchored to the start / to the end
[0-9].pdf one character from a set: [a-z], [A-Za-z], [0-9A-F]
*.||md|txt|| a group, so a shared part is written once
\b\app whole word: app, app-1, my app, app_data: not apple
\-\test not: hide every label the pattern finds
a&b and: every item must match
Seven characters are reserved and are written with a backslash to mean themselves: *, |, &, a
backtick, \, [ and ]. Use a raw string for any pattern holding one, as above. The full
specification is
docs/syntax.md.
One language, five implementations, one fixture
This is the Python port. The same language is implemented in TypeScript, Rust, Go and PHP, and all five run against the same file of cases, so they cannot disagree quietly.
python3 tests/test_conformance.py # 96 spec cases, 568 assertions
The fixture is conformance/cases.json: cases lifted from numbered sections of the specification,
patterns that must be refused, and fragments of junk that must not raise.
Where this package is developed
The source of record is the python/ directory of
code-evolve/label-filter, which holds all five
implementations, the specification they share and the fixture they are all tested against. Issues and
pull requests belong there.
Licence
MIT. See LICENSE.txt.
Metadata
Release files for label-filter 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| label_filter-0.3.1.tar.gz | 18.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| label_filter-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.3 kB
Release files / label_filter-0.3.1.tar.gz
| Download URL | label_filter-0.3.1.tar.gz |
|---|---|
| Size | 18.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
564d0b8c38eaa1dd28511078dbd11be3706b1c6a9e700ec66e09cdb0c6f9e837
|
|
BLAKE2b-256 checksum How to use checksums |
c33a26652780f0d597f118edc2004a8bd754aca7b800df39a2cd054390100185
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.2
|
Release files / label_filter-0.3.1-py3-none-any.whl
| Download URL | label_filter-0.3.1-py3-none-any.whl |
|---|---|
| Size | 11.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0cd665deb7df000721ba3709dfc185f1a0151b32c748d9cfd16df21d330faa9e
|
|
BLAKE2b-256 checksum How to use checksums |
cb18a65580e2f6de4de4246d8d9b867652cbdac2dc95335dbb319bea4e8caad8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.2
|