
YAPF – A formatter for Python files - sudmishra
https://github.com/google/yapf
======
fweespeech
> YAPF is not an official Google product (experimental or otherwise), it is
> just code that happens to be owned by Google.

Just in case anyone thought "by Google" meant "a Google product" like me.

------
pdknsk
This passed HN duplicate detector, despite same URL and submission title.

[https://news.ycombinator.com/item?id=9260786](https://news.ycombinator.com/item?id=9260786)

------
kolanos
I definitely would like to see configuration options for the vertical
alignment of arguments. If the arguments don't fit within the line length then
having the option to put them on separate lines (still pep8) would be nice.

------
rbanffy

      --style STYLE         specify formatting style: either a style name (for
                            example "pep8" or "google"), or the name of a file
                            with style settings. pep8 is the default.
    

> pep8 is the default.

I can breathe again.

~~~
rcthompson
I don't think there was any other option. If the default wasn't pep8, the tool
would have no chance of seeing wide adoption in the Python community, unless
someone forked it and changed the default to pep8.

------
Pirate-of-SV
I've been using YAPF for a while and I really like the idea. Be aware that
there are still some nasty bugs that haven't been fixed yet so be careful if
you use it for something important.

Do anyone of you guys know what the name YAPF comes from? (The only thing I
can think of is "Yet Another Python Formatter", but I'm just guessing)

~~~
eliben
Indeed, it's just "Yet Another Python Formatter"

------
sergiotapia
Also see go fmt

~~~
pekk
Thought experiment: wouldn't it be just awesome if Google decided to promote
an alternative to the format used by go fmt, so that newbies could learn that
instead and then have a constant conflict with the core Go community?

edit: this is directly relevant to the thread, which is about Python
formatting and Google promoting its weird style

------
zk00006
Is it possible to YAPF it in Sublime?

~~~
jkane
For sublime 2 yes:

[https://github.com/jason-kane/PyYapf](https://github.com/jason-kane/PyYapf)

It isn't in Sublime package control yet.

------
baq
i use autopep8 and haven't been thrilled. it gets the job done, but i'll
switch in a heartbeat if this is better. we'll see.

~~~
morbo_yapf
YAPF is still brand spanking new, so please use it and report any bugs you
find.

We mention in the documentation that data literals are a sticking point to
most people and most automatic formatters. Even clang-format tends to balk on
them. We try our best at them, but it might be best to just disable formatting
them if they are already formatted to something you like. :-)

------
B4CKlash
>YAPF is not an official Google product (experimental or otherwise), it is
just code that happens to be owned by Google.

~~~
yeukhon
Sounds like one of those "20%" kind of project and Google GitHubers just
happened to have the permission to release this project under google/ wow ...

~~~
nostrademons
True, but that category also includes protobufs, LevelDB, Snappy, Gumbo,
Guice, re2, gtest, and Angular (initially; it soon became an official thing
when it got popular). While the "official" open-source projects are things
like Chrome, Android, GWT, Go, Dart, gRPC, and Bazel.

Paul Graham once said that you should use the tools that programmers build to
solve their own problems, not the tools that big corporations build to solve
their ideas of what other peoples' problems are. That doesn't mean every
little library is a good one (Sturgeon's Law applies - 90% of everything is
crap), but it does mean that being "official" is usually a negative signal on
product quality.

This applies to other companies' code as well; I've never used a buggy piece
of shit quite so bad as Sun's JSF (which was supposed to be the "official" way
to build webapps with Java, circa 2004-2006), while BSD and Linux continue to
be great pieces of software 25 years later.

------
mas1n
Interesting to see the formatter is written using 2 space indentation when
both pep8 and google's style guides say 4.

~~~
Pirate-of-SV
I think the original Python Google Style guide did use 2 spaces.
[https://code.google.com/p/soc/wiki/PythonStyleGuide#Indentat...](https://code.google.com/p/soc/wiki/PythonStyleGuide#Indentation)

And it seems like that's used in YAPF as well:
[https://github.com/google/yapf/blob/master/yapf/yapflib/styl...](https://github.com/google/yapf/blob/master/yapf/yapflib/style.py#L122)

~~~
geoelectric
This was submitted not long ago, and that was pointed out there too.

[https://news.ycombinator.com/item?id=9260786](https://news.ycombinator.com/item?id=9260786)

I suggested to the author that they restore "google" style to the public one
and rename the existing one to "chromium" style, since that's the most
prominent public project still on Google's internal style.

------
Fuzzwah
I've got a python project where I've been pretty naughty with long lines
containing sql queries.

I found that running this tool over it resulted in some strange new lines.

For example, this was my old hideously long line:

query_qual = "INSERT OR REPLACE INTO Qualifying (poleid, seasonid,
race_week_num, carclassid, pole) values (%s%s, %s, %s, %s, %s)" %
(race[u'seasonid'], race[u'race_week_num'], race[u'seasonid'],
race[u'race_week_num'], race[u'carclassid'], pole)

Changed to this:

query_qual = "INSERT OR REPLACE INTO Qualifying (poleid, seasonid,
race_week_num, carclassid, pole) values (%s%s, %s, %s, %s, %s)" % (
race[u'seasonid'], race[u'race_week_num'], race[ u'seasonid' ],
race[u'race_week_num'], race[u'carclassid'], pole)

~~~
hyperpallium
To my eye, HN has rendered them identically. You can preserve literal
whitespace on HN by indenting by two spaces (and a newline to separate the
code formatting from ordinary text).

    
    
      it appears     like  this

------
alok-g
Off-topic, but why is no space before opening parenthesis the norm in
programming ("class foo(object):") when normal English usage is to have one? I
know myself as the only one who puts this space.

~~~
dragonwriter
Because the convention in mathematics, from whence the function call syntax
used in programming (from which many of the other programming uses then
derive), is no space.

~~~
alok-g
While I take your answer, in mathematics, people often use shorter variable
names like y(x). Meaningful names given to functions make them read a lot more
like English than mathematics.

~~~
ciupicri
Though mathematics has also longer names like arcsin, arctan, etc.

------
bkcooper
I'm sure there are some cases where this is useful, but I'm not really sold.
The pitch at the beginning is "satisfying PEP 8 doesn't mean it looks good!"
But then it seems most of the changes cleaned up in the code (indentation
level, indents on split lines, spacing between operators) are just PEP 8
violations. I think you could find a more convincing demonstration.

The warning about choking on large data literals (which are probably one of
the places where prettifying would be most useful, at least to me) also seems
ominous.

edit: for my personal use, I tend to use flycheck with flake8 in emacs. This
keeps me honest. Is the primary use case for something like this cleaning your
own code or other people's?

~~~
bpicolo
The point is there are things that don't violate pep8 that are still atrocious

for example:

    
    
        some_function(long_variable_name_and_stuff, long_variable_name_and_stuff,
                                      long_variable_name_and_stuff)
    

The lower indentation level doesnt actually matter at all says flake8

edit: To below, that's possible. I can't remember the exact case right now but
there are things along these lines that are valid and shouldn't be. Multiple
possible indentation formats is not necessarily something you want to allow as
an org, which is where something like YAPF comes into play

~~~
bkcooper
I wonder if that's a configuration thing. Mine gives me a "continuation line
over-indented for visual indent" here.

------
teddyh
There seems to be a problem parsing backslash escapes:

echo 'foo="\\\"' | PYTHONPATH=/tmp/yapf/yapf python /tmp/yapf

Raises a lib2to3.pgen2.parse.ParseError.

Also crashes on \n, but not, strangely, on \t.

I’m guessing that the backslashes get interpreted twice, somehow.

~~~
eliben
Are you sure this is not a shell artifact? Does the same problem happen when
there's a \\\ in a file? In any case, feel free to open a Github issue for
yapf, we'll take a look

~~~
teddyh
Yes, it was when parsing a file I encountered it. The one-liner shell command
is just a minimal repro of the bug.

Apparently I need to “Sign in” to report a Github issue, so I won’t.

~~~
eliben
Sorry, I can't reproduce this. I'm trying on this file:
[https://gist.github.com/eliben/9727758f4847d2e7d86e](https://gist.github.com/eliben/9727758f4847d2e7d86e)

And yapf runs just fine on it. Does this file work for you?

~~~
teddyh
Nope.

    
    
      Traceback (most recent call last):
        File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
          "__main__", fname, loader, pkg_name)
        File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
          exec code in run_globals
        File "/tmp/yapf/yapf/__main__.py", line 18, in <module>
          sys.exit(yapf.main(sys.argv))
        File "/tmp/yapf/yapf/__init__.py", line 104, in main
          verify=args.verify))
        File "/tmp/yapf/yapf/yapflib/yapf_api.py", line 99, in FormatCode
          tree = pytree_utils.ParseCodeToTree(unformatted_source.rstrip() + '\n')
        File "/tmp/yapf/yapf/yapflib/pytree_utils.py", line 100, in ParseCodeToTree
          tree = parser_driver.parse_string(code, debug=False)
        File "/usr/lib/python2.7/lib2to3/pgen2/driver.py", line 106, in parse_string
          return self.parse_tokens(tokens, debug)
        File "/usr/lib/python2.7/lib2to3/pgen2/driver.py", line 71, in parse_tokens
          if p.addtoken(type, value, (prefix, start)):
        File "/usr/lib/python2.7/lib2to3/pgen2/parse.py", line 116, in addtoken
          ilabel = self.classify(type, value, context)
        File "/usr/lib/python2.7/lib2to3/pgen2/parse.py", line 172, in classify
          raise ParseError("bad token", type, value, context)
      lib2to3.pgen2.parse.ParseError: bad token: type=55, value=u' ', context=('', (1, 5))

~~~
eliben
Interesting. Can you cite the exact version of Python 2.7 you're using?

Mine is 2.7.6

I'm asking because bugs get fixed in lib2to3 occasionally, and we see
differences between minor Python versions in this regard.

~~~
teddyh
Python 2.7.3, the normal one from the current Debian stable.

~~~
eliben
The time diff between 2.7.3 and 2.7.6 is a year and a half, and lib2to3 got a
bunch of fixed merge in during that period. I peeked at the CPython logs, and
there's a number of changes so this bug may very well have been plugged.

I guess we should be recommending the latest Python 2.7 possible, since it's
very difficult for us to work around lib2to3 bugs in yapf - we're basically
limited to whatever it can parse. Some things can be monkey-patched, but core
parsing bugs are challenging.

