python-parsy / typed-parsy

Experimental fork of parsy with strict types
MIT License
3 stars 1 forks source link

Include a sequence and combine alternative which is typed #1

Open robjhornby opened 1 year ago

robjhornby commented 1 year ago

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:

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.

image

robjhornby commented 1 year ago

Other comments:

spookylukey commented 1 year ago

Hi @robjhornby thanks for your input.

I currently have no plans to further develop this project, for the reasons I described in that blog post, and I'm afraid I'm not likely to have the bandwidth in the foreseeable future to look at your PR in anything like a timely fashion.

However, if you would like to continue work on it, I'm very happy for you to do so. I could make you an admin on it if you would like? My only request is that you make clear the status of the project, and the fact that it has a different maintainer

robjhornby commented 1 year ago

Hi @spookylukey, thanks for the quick response

I'm not sure I would have a clear goal for this project, so I'm happy to keep experimenting in a fork for now, and if I make some progress I will come back to this repo - thanks for the offer/suggestion.

If I make some progress, are you open to including more type annotations in parsy, even if you're not pursuing this fully typed version? The idea of annotations as "clear and concise documentation for humans that pop up in a code editor" is also what I'm aiming for, as opposed to a complete statically typed solution.

spookylukey commented 1 year ago

If I make some progress, are you open to including more type annotations in parsy, even if you're not pursuing this fully typed version? The idea of annotations as "clear and concise documentation for humans that pop up in a code editor" is also what I'm aiming for, as opposed to a complete statically typed solution.

Yes, I'm very interested in type hints along those lines. I already added quite a lot, covering all the main methods - https://github.com/python-parsy/parsy/pull/69 released in v 2.1 - but if there are things I missed or ways it can be improved please go ahead.