-
Notifications
You must be signed in to change notification settings - Fork 1
Description
I am interested in a typed version of parsy and would find it useful, the effort in typed-parsy so far is a nice improvement. I read this blog post on this topic and had an idea for an alternative to seq and combine for the *args synatax (not **kwargs unfortunately). I have something working with Pyright (I haven't tried mypy) - see the linked PR below
By using tuple type unpacking from PEP 646, it's possible to add type information to both of these functions which enable creating a sequence of parsers with a flat tuple result type:
- A function which joins the results of two parsers into a tuple:
Parser[A], Parser[B] -> Parser[Tuple[A, B]]. I've called thisjoinfor now. (This one doesn't need tuple type unpacking - it is just theParser.__and__function.) - A function which takes a tuple result and appends a second parser's result to the end:
Parser[Tuple[A, B]], Parser[C] -> Parser[Tuple[A, B, C]]. I've called thisappendfor now.
And it's also possible to create a combine method which expects function whose arguments have the same type as the parser's result tuple. The type signature is like this:
from typing import TypeVar
from typing_extensions import TypeVarTuple, Unpack
OUT2 = TypeVar("OUT2")
OUT_T = TypeVarTuple("OUT_T")
# ... in the Parser class
def combine(self: Parser[Tuple[Unpack[OUT_T]]], combine_fn: Callable[[Unpack[OUT_T]], OUT2]) -> Parser[OUT2]:
...
The benefit is that Pyright will compare the Parser result type with the combine_fn arguments and show an issue when they don't match. It also doesn't need the extra step of indexing tuples in a lambda function as shown in the blog post.
I've made these changes in a fork and they seem to be working nicely with Pyright - it's showing me mismatches between a sequence of parsers' results and a function's arguments with useful messages.
For example, in the screenshot below, the demo function expects its first argument to have a type of str. A parser of type Parser[int, str, bool] can be made with the join and append functions. Then where combine is called, VSCode shows that there's a problem - the parser result type doesn't match demo's parameter type in the first argument.
