google / yapf

A formatter for Python files
Apache License 2.0
13.73k stars 885 forks source link

python 3.6 variable annotation #500

Open kamahen opened 6 years ago

kamahen commented 6 years ago

Python 3.6 allows variable annotation, but yapf doesn't support it. e.g.:

self.anchors: Dict[Tuple[Int, Int], Vname] = {}
bwendling commented 6 years ago

We should support it. But you might need to run yapf with Python 3.6+ to enable it. I looked at the link. Are there specific examples that were being messed up?

kamahen commented 6 years ago

Right now, I need to write something like this snippet taken from my code:

        anchors = []  # type: List[kythe.Anchor]
        cooked_nodes.anchors(
            ast_cooked.FqnCtx(
                fqn_dot=file_to_module(src) + '.',
                bindings=collections.ChainMap(collections.OrderedDict()),
                python_version=args.python_version), anchors)

If Python 3.6 variable annotations were supported, I could write this:

        anchors: List[kythe.Anchor] = []
        cooked_nodes.anchors(
            ast_cooked.FqnCtx(
                fqn_dot=file_to_module(src) + '.',
                bindings=collections.ChainMap(collections.OrderedDict()),
                python_version=args.python_version), 
           anchors,
        )

The variable annotation is needed for mypy, which can't infer the type of an empty list.

Another example is this (which is a workaround for mypy issue 4547:

    __slots__ = ()  # type: Sequence[str]

which I'd like to write:

    __slots__: Sequence[str] = ()
kamahen commented 6 years ago

@gwelymernans Is this the kind of thing that I could fix by myself, if you point me at the appropriate place(s) in yapf?

kamahen commented 6 years ago

Python 3.7 dataclasses require the use of variable annotations, so it would be really nice if variable annotatios could be supported by yapf.

https://www.python.org/dev/peps/pep-0557/

bwendling commented 6 years ago

I'm not familiar with this new syntax, but from briefly looking at the grammar we would need to add Visit_annassign() methods to the various visitor modules (at least where needed). After that, we just need to make sure that the format_decision_state.py module is enforcing the proper splits and penalties. In truth, it should support most of the type annotations, since they don't violate the original Python syntax too much. There would only be issues like "there should be a space here" or "a split here would be keen" to contend with...

kamahen commented 6 years ago

The new syntax is essentially the same as the parameter:type=default syntax in "def" statements.

Probably it can be processed the same way.

lib2to3/Grammar.txt has some changes between 3.6 and 3.7 (besides the one change you've already handled), so I'm surprised that yapf even works without handling the other grammar changes. If it helps, I can go back through some of my changelists to find out what changes I've needed to handle the changes between 3.6 and 3.7.

Yoshi325 commented 5 years ago

I would like to help with this Issue, but I am unfamiliar with the codebase. Is there any way I may contribute?