Install & Compatibility
Where this runs
tested against v2.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.038s · 17.8MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.6s · import 0.036s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
string
✓ from parsy import string
regex
✓ from parsy import regex
generate
✓ from parsy import generate
ParseError
✓ from parsy import ParseError
This quickstart demonstrates basic parser creation using `string` and `regex` primitives, chaining with `then`, and transforming results with `map`. It also showcases the powerful `@generate` decorator for building parsers that yield intermediate results and return a structured object, which is crucial for complex grammars. Error handling with `ParseError` is also illustrated.
from parsy import string, regex, generate, ParseError
from datetime import date
# Example 1: Simple date parsing using combinators
year = regex(r"[0-9]{4}").map(int)
month = regex(r"[0-9]{2}").map(int)
day = regex(r"[0-9]{2}").map(int)
dash = string('-')
iso_date_parser = year.then(dash).then(month).then(dash).then(day)
try:
parsed_date_list = iso_date_parser.parse("2023-10-26")
# The default behavior of .then() chain is to return the value of the *last* parser.
# To combine results, .map() or @generate is often used.
print(f"Simple parse result (last element): {parsed_date_list}")
except ParseError as e:
print(f"Parse Error: {e}")
# Example 2: More complex date parsing using the @generate decorator
# This allows you to combine parsed values into a structured result.
@generate
def full_date_parser():
y = yield year << dash
m = yield month << dash
d = yield day
return date(y, m, d)
try:
parsed_date_obj = full_date_parser.parse("2023-10-26")
print(f"Structured parse result (date object): {parsed_date_obj}")
assert parsed_date_obj == date(2023, 10, 26)
# Example of a failure
full_date_parser.parse("2023/10/26")
except ParseError as e:
print(f"Parse Error for '2023/10/26': {e}")
# Example 3: Using .map to transform simple results
weekday_parser = string('Mon') | string('Tue') | string('Wed') # ...and so on
weekday_mapping = {'Mon': 'Monday', 'Tue': 'Tuesday', 'Wed': 'Wednesday'}
mapped_weekday_parser = weekday_parser.map(lambda s: weekday_mapping.get(s, s))
try:
print(f"Mapped weekday: {mapped_weekday_parser.parse('Tue')}")
except ParseError as e:
print(f"Parse Error: {e}")
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'parsy'
The 'parsy' library is not installed in your Python environment.
fixInstall the library using pip: `pip install parsy`
parsy.ParseError: expected '...' at X:Y
The input string does not match the grammar defined by the parser at the specified position. The 'expected' message indicates what the parser was looking for.
fixReview the input string and the parser definition to ensure they align, or handle the ParseError exception with a `try...except` block if non-conforming input is expected.
TypeError: unsupported type for ...: str (e.g., TypeError: unsupported type for timedelta days component: str)
This typically occurs when a parser's output (often a string from `regex` or `string`) is passed to a `.map()` function that expects a different type (e.g., an integer), leading to a type mismatch in the mapping function.
fixEnsure that the parser output type matches the expected input type of the function provided to `.map()`. Often, an intermediate `.map(int)` or `.map(float)` is needed. For example, `P.regex(r'\d+').map(int).map(lambda x: datetime.timedelta(days=x))`.
NameError: name '...' is not defined (e.g., NameError: name 'expr' is not defined)
This error arises when defining recursive parsers where one part of the grammar refers to a parser (like `expr`) that has not yet been fully defined at that point in the code.
fixUse `parsy.forward_declaration()` to create a placeholder for the parser before its full definition, then assign the complete parser to it later. Example: `expr = forward_declaration(); simple = regex('[0-9]+').map(int); group = string('(') >> expr.sep_by(string(' ')) << string(')'); expr.become(simple | group)` TypeError: op() missing X required positional argument: 'Y' (when using @generate)
The `@parsy.generate` decorator expects the decorated function to be a generator that takes no arguments. If you define the generator function with parameters, `parsy` will try to call it without arguments, leading to this `TypeError`.
fixIf you need parameterized parsers, define a factory function that takes the parameters and returns a *new*, argument-less generator function decorated with `@generate`. Example: `def opP(symbol, f): @generate def op(): a = yield numberP; yield lex(pr.string(symbol)); b = yield numberP; return f(a,b); return op`
Upgrade
Version history
2.2latest on PyPI · released Sep 12, 2025
Audit
Dependencies
No dependency data recorded yet.