ts-lib-parsy #

Version #

v0.1.2

Table of Contents #

Summary#

Parsy is a library for parsing text in Python by combining small parsers into complex, larger parsers.

Installation#

This package is available on JFrog Artifactory. Run pip install ts-lib-parsy or the equivalent command using a package manager such as poetry add ts-lib-parsy.

How to use ts_lib_parsy#

Most of the parsy docs apply to this package, apart from the differences explained below. Those docs are a good place to learn what is possible with this package.

The examples folder in this repo shows some typical applications of ts_lib_parsy.

Turn on IDE type checking and see the sequence and dataclass-related examples, which show the benefit of using IDE type checking is with this package. A type checker can warn you when incompatible parsers are being combined, making it easy to combine parsers into larger parsers.

Here’s an example to get started, after installing ts-lib-parsy the following code shows an example of defining a parser which can parse text into a dataclass instance.

"""Definition of a parser which matches strings like "<name>: <score>"."""

from dataclasses import dataclass

from ts_lib_parsy import dataclass_parser, parser_field, regex, string

separator = string(": ")


@dataclass
class Demo:
    name: str = parser_field(regex(r"\w+") << separator)
    score: int = parser_field(regex(r"\d+").map(int))


demo_parser = dataclass_parser(Demo)
assert demo_parser.parse("Example: 100") == Demo(name="Example", score=100)

Differences with parsy#

This package is a modified version of parsy. The maintainer of parsy created an experiment to begin adding type annotations to each part of parsy here: typed-parsy. This package continued that effort and has type annotations for all parser combinators, by removing certain features which can’t be type annotated in Python’s type system, and adding alternatives which can be type annotated. The key differences between this package and parsy are:

  • Changed the seq parser to have a result type of tuple instead of list, enabling combining a sequence of parsers such as Parser[str], Parser[int] and Parser[bool] into a single parser of type Parser[Tuple[str, int, bool]]. These can be used with the Parser.combine method to bind the output of a parser to a function with a compatible argument signature like Callable[[str, int, bool], None] for the example above ([str, int, bool] matches between the two). If they did not match, an IDE with type checking enabled would show type problems, meaning parsers can be combined into more complex parsers with help from a type checker to avoid mistakes. See examples/sequence.py for examples.

  • Removed the keyword-arg version of seq which can’t be fully type annotated.

  • Added a way of defining parsers on fields of a dataclass using the parser_field field descriptor function which wraps dataclasses.field. A dataclass defined in this way can be converted to a parser using the dataclass_parser function. See examples/dataclass_parsing.py for examples, and examples/dataclass_parser_demo.py for a more complex example. This is an alternative to the keyword-arg version of seq, where instead of parsing to dictionaries, it parses to dataclasses which have more structured type information.

  • Removed forward-declarations which couldn’t easily be type-annotated. Instead, type annotations have been added to generate, which can be used to create recursive parsers which fulfil the same purpose as forward-declarations. See the definition of json_parser in examples/json.py for an example.

Changelog#

v0.1.2#

  • Update type annotations for dataclass parsers with no change in functionality. A recent change to Pyright/Pylance modified how Ellipsis is type checked which led to type problems in this package, so Ellipsis has been removed from the dataclass type annotations.

v0.1.1#

  • Updated parser error messages to show context around the place in the text where parsing failed.

v0.1.0#

  • Initial version

See also

ts-lib-parsy-components builds IDS-specific parsy components on top of this package.