Repository: google/yapf
Pull request #950 (2021-08-12 17:09:42)

Fix typos discovered by codespell
https://pypi.org/project/codespell/


Patch:
diff --git a/CHANGELOG b/CHANGELOG
index a35ce68..8bc75aa 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,12 @@
 ### Added
 - Look at the 'pyproject.toml' file to see if it contains ignore file information
   for YAPF.
+- New entry point `yapf_api.FormatTree` for formatting lib2to3 concrete
+  syntax trees.
+### Fixed
+- Enable `BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF` knob for "pep8" style, so
+  method definitions inside a class are surrounded by a single blank line as
+  prescribed by PEP8.
 
 ## [0.31.0] 2021-03-14
 ### Added
@@ -17,7 +23,7 @@
 - Look at the 'pyproject.toml' file to see if it contains style information for
   YAPF.
 ### Changed
-- Do not scan exlcuded directories. Prior versions would scan an exluded
+- Do not scan excluded directories. Prior versions would scan an excluded
   folder then exclude its contents on a file by file basis. Preventing the
   folder being scanned is faster.
 ### Fixed
@@ -246,7 +252,7 @@
 ### Fixed
 - Use tabs when constructing a continuation line when `USE_TABS` is enabled.
 - A dictionary entry may not end in a colon, but may be an "unpacking"
-  operation: `**foo`. Take that into accound and don't split after the
+  operation: `**foo`. Take that into account and don't split after the
   unpacking operator.
 
 ## [0.20.1] 2018-01-13
@@ -669,7 +675,7 @@
 - Retain proper vertical spacing before comments in a data literal.
 - Make sure that continuations from a compound statement are distinguished from
   the succeeding line.
-- Ignore preceding comments when calculating what is a "dictonary maker".
+- Ignore preceding comments when calculating what is a "dictionary maker".
 - Add a small penalty for splitting before a closing bracket.
 - Ensure that a space is enforced after we remove a pseudo-paren that's between
   two names, keywords, numbers, etc.
@@ -697,7 +703,7 @@
 - Improve splitting heuristic when the first argument to a function call is
   itself a function call with arguments. In cases like this, the remaining
   arguments to the function call would look badly aligned, even though they are
-  techincally correct (the best kind of correct!).
+  technically correct (the best kind of correct!).
 - Improve splitting heuristic more so that if the first argument to a function
   call is a data literal that will go over the column limit, then we want to
   split before it.
diff --git a/pylintrc b/pylintrc
index 9e8a554..0008df2 100644
--- a/pylintrc
+++ b/pylintrc
@@ -55,7 +55,7 @@ confidence=
 # can either give multiple identifiers separated by comma (,) or put this
 # option multiple times (only on the command line, not in the configuration
 # file where it should appear only once).You can also use "--disable=all" to
-# disable everything first and then reenable specific checks. For example, if
+# disable everything first and then re-enable specific checks. For example, if
 # you want to run only the similarities checker, you can use "--disable=all
 # --enable=similarities". If you want to run only the classes checker, but have
 # no Warning level messages displayed, use"--disable=all --enable=classes
diff --git a/yapf/yapflib/format_decision_state.py b/yapf/yapflib/format_decision_state.py
index 59f6201..3c0db37 100644
--- a/yapf/yapflib/format_decision_state.py
+++ b/yapf/yapflib/format_decision_state.py
@@ -446,7 +446,7 @@ class FormatDecisionState(object):
 
     # A function call with a dictionary as its first argument may result in
     # unreadable formatting if the dictionary spans multiple lines. The
-    # dictionary itself is formatted just fine, but the remaning arguments are
+    # dictionary itself is formatted just fine, but the remaining arguments are
     # indented too far:
     #
     #     function_call({
diff --git a/yapf/yapflib/pytree_utils.py b/yapf/yapflib/pytree_utils.py
index 75d4ca2..8762032 100644
--- a/yapf/yapflib/pytree_utils.py
+++ b/yapf/yapflib/pytree_utils.py
@@ -25,6 +25,7 @@ the lib2to3 library.
 """
 
 import ast
+import os
 
 from lib2to3 import pygram
 from lib2to3 import pytree
@@ -108,6 +109,9 @@ def ParseCodeToTree(code):
   """
   # This function is tiny, but the incantation for invoking the parser correctly
   # is sufficiently magical to be worth abstracting away.
+  if not code.endswith(os.linesep):
+    code += os.linesep
+
   try:
     # Try to parse using a Python 3 grammar, which is more permissive (print and
     # exec are not keywords).
diff --git a/yapf/yapflib/pytree_visitor.py b/yapf/yapflib/pytree_visitor.py
index 49da056..a39331c 100644
--- a/yapf/yapflib/pytree_visitor.py
+++ b/yapf/yapflib/pytree_visitor.py
@@ -19,7 +19,7 @@ and Leaf types. This module implements a visitor pattern for such trees.
 It also exports a basic "dumping" visitor that dumps a textual representation of
 a pytree into a stream.
 
-  PyTreeVisitor: a generic visitor pattern fo pytrees.
+  PyTreeVisitor: a generic visitor pattern for pytrees.
   PyTreeDumper: a configurable "dumper" for displaying pytrees.
   DumpPyTree(): a convenience function to dump a pytree.
 """
diff --git a/yapf/yapflib/style.py b/yapf/yapflib/style.py
index 3d27109..a1e6940 100644
--- a/yapf/yapflib/style.py
+++ b/yapf/yapflib/style.py
@@ -418,7 +418,7 @@ def CreatePEP8Style():
       ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS=True,
       ALLOW_SPLIT_BEFORE_DICT_VALUE=True,
       ARITHMETIC_PRECEDENCE_INDICATION=False,
-      BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=False,
+      BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=True,
       BLANK_LINE_BEFORE_CLASS_DOCSTRING=False,
       BLANK_LINE_BEFORE_MODULE_DOCSTRING=False,
       BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION=2,
@@ -479,7 +479,6 @@ def CreateGoogleStyle():
   """Create the Google formatting style."""
   style = CreatePEP8Style()
   style['ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT'] = False
-  style['BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'] = True
   style['COLUMN_LIMIT'] = 80
   style['INDENT_DICTIONARY_VALUE'] = True
   style['INDENT_WIDTH'] = 4
@@ -511,6 +510,7 @@ def CreateFacebookStyle():
   """Create the Facebook formatting style."""
   style = CreatePEP8Style()
   style['ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT'] = False
+  style['BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'] = False
   style['COLUMN_LIMIT'] = 80
   style['DEDENT_CLOSING_BRACKETS'] = True
   style['INDENT_CLOSING_BRACKETS'] = False
diff --git a/yapf/yapflib/yapf_api.py b/yapf/yapflib/yapf_api.py
index efa1a79..1977692 100644
--- a/yapf/yapflib/yapf_api.py
+++ b/yapf/yapflib/yapf_api.py
@@ -110,6 +110,45 @@ def FormatFile(filename,
   return reformatted_source, encoding, changed
 
 
+def FormatTree(tree, style_config=None, lines=None, verify=False):
+  """Format a parsed lib2to3 pytree.
+
+  This provides an alternative entry point to YAPF.
+
+  Arguments:
+    tree: (pytree.Node) The root of the pytree to format.
+    style_config: (string) Either a style name or a path to a file that contains
+      formatting style settings. If None is specified, use the default style
+      as set in style.DEFAULT_STYLE_FACTORY
+    lines: (list of tuples of integers) A list of tuples of lines, [start, end],
+      that we want to format. The lines are 1-based indexed. It can be used by
+      third-party code (e.g., IDEs) when reformatting a snippet of code rather
+      than a whole file.
+    verify: (bool) True if reformatted code should be verified for syntax.
+
+  Returns:
+    The source formatted according to the given formatting style.
+  """
+  _CheckPythonVersion()
+  style.SetGlobalStyle(style.CreateStyleFromConfig(style_config))
+
+  # Run passes on the tree, modifying it in place.
+  comment_splicer.SpliceComments(tree)
+  continuation_splicer.SpliceContinuations(tree)
+  subtype_assigner.AssignSubtypes(tree)
+  identify_container.IdentifyContainers(tree)
+  split_penalty.ComputeSplitPenalties(tree)
+  blank_line_calculator.CalculateBlankLines(tree)
+
+  uwlines = pytree_unwrapper.UnwrapPyTree(tree)
+  for uwl in uwlines:
+    uwl.CalculateFormattingInformation()
+
+  lines = _LineRangesToSet(lines)
+  _MarkLinesToFormat(uwlines, lines)
+  return reformatter.Reformat(_SplitSemicolons(uwlines), verify, lines)
+
+
 def FormatCode(unformatted_source,
                filename='<unknown>',
                style_config=None,
@@ -138,33 +177,17 @@ def FormatCode(unformatted_source,
     Tuple of (reformatted_source, changed). reformatted_source conforms to the
     desired formatting style. changed is True if the source changed.
   """
-  _CheckPythonVersion()
-  style.SetGlobalStyle(style.CreateStyleFromConfig(style_config))
-  if not unformatted_source.endswith('\n'):
-    unformatted_source += '\n'
-
   try:
     tree = pytree_utils.ParseCodeToTree(unformatted_source)
   except parse.ParseError as e:
     e.msg = filename + ': ' + e.msg
     raise
 
-  # Run passes on the tree, modifying it in place.
-  comment_splicer.SpliceComments(tree)
-  continuation_splicer.SpliceContinuations(tree)
-  subtype_assigner.AssignSubtypes(tree)
-  identify_container.IdentifyContainers(tree)
-  split_penalty.ComputeSplitPenalties(tree)
-  blank_line_calculator.CalculateBlankLines(tree)
-
-  uwlines = pytree_unwrapper.UnwrapPyTree(tree)
-  for uwl in uwlines:
-    uwl.CalculateFormattingInformation()
-
-  lines = _LineRangesToSet(lines)
-  _MarkLinesToFormat(uwlines, lines)
-  reformatted_source = reformatter.Reformat(
-      _SplitSemicolons(uwlines), verify, lines)
+  reformatted_source = FormatTree(
+      tree,
+      style_config=style_config,
+      lines=lines,
+      verify=verify)
 
   if unformatted_source == reformatted_source:
     return '' if print_diff else reformatted_source, False


Test patch:
diff --git a/yapftests/reformatter_basic_test.py b/yapftests/reformatter_basic_test.py
index a67e4c4..7e07651 100644
--- a/yapftests/reformatter_basic_test.py
+++ b/yapftests/reformatter_basic_test.py
@@ -1982,6 +1982,7 @@ class A(object):
   def testStableDictionaryFormatting(self):
     code = textwrap.dedent("""\
         class A(object):
+
           def method(self):
             filters = {
                 'expressions': [{
@@ -2432,7 +2433,7 @@ class A(object):
         AAAAAAAAAAAAAAAAAAAAAAAA = {
             Environment.XXXXXXXXXX: 'some text more text even more tex',
             Environment.YYYYYYY: 'some text more text even more text yet ag',
-            Environment.ZZZZZZZZZZZ: 'some text more text even mor etext yet again tex',
+            Environment.ZZZZZZZZZZZ: 'some text more text even more text yet again tex',
         }
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(code)
diff --git a/yapftests/reformatter_buganizer_test.py b/yapftests/reformatter_buganizer_test.py
index e96f6da..e95c96c 100644
--- a/yapftests/reformatter_buganizer_test.py
+++ b/yapftests/reformatter_buganizer_test.py
@@ -2151,7 +2151,7 @@ instance = (
           ok = an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A]
           bad_slice = map(math.sqrt, an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A])
           a_long_name_slicing = an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A]
-          bad_slice = ("I am a crazy, no good, string whats too long, etc." + " no really ")[:ARBITRARY_CONSTANT_A]
+          bad_slice = ("I am a crazy, no good, string what's too long, etc." + " no really ")[:ARBITRARY_CONSTANT_A]
         """)
     expected_formatted_code = textwrap.dedent("""\
         def main(unused_argv):
@@ -2162,7 +2162,7 @@ instance = (
                           an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A])
           a_long_name_slicing = an_array_with_an_exceedingly_long_name[:
                                                                        ARBITRARY_CONSTANT_A]
-          bad_slice = ("I am a crazy, no good, string whats too long, etc." +
+          bad_slice = ("I am a crazy, no good, string what's too long, etc." +
                        " no really ")[:ARBITRARY_CONSTANT_A]
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
diff --git a/yapftests/reformatter_pep8_test.py b/yapftests/reformatter_pep8_test.py
index a5301f1..e1202c2 100644
--- a/yapftests/reformatter_pep8_test.py
+++ b/yapftests/reformatter_pep8_test.py
@@ -50,22 +50,22 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
     uwlines = yapf_test_helper.ParseAndUnwrap(code)
     self.assertCodeEqual(code, reformatter.Reformat(uwlines))
 
-  def testNoBlankBetweenClassAndDef(self):
+  def testBlankBetweenClassAndDef(self):
     unformatted_code = textwrap.dedent("""\
         class Foo:
-
           def joe():
             pass
         """)
     expected_formatted_code = textwrap.dedent("""\
         class Foo:
+
             def joe():
                 pass
         """)
     uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
     self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
 
-  def testNoBlankBetweenDefsInClass(self):
+  def testBlankBetweenDefsInClass(self):
     unformatted_code = textwrap.dedent('''\
         class TestClass:
             def __init__(self):
@@ -77,6 +77,7 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
         ''')
     expected_formatted_code = textwrap.dedent('''\
         class TestClass:
+
             def __init__(self):
                 self.running = False
 
@@ -174,6 +175,7 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
         """)
     expected_formatted_code = textwrap.dedent("""\
         def f():
+
             def g():
                 while (xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa'
                        and xxxxxxxxxxxxxxxxxxxx(
@@ -341,11 +343,13 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
   def testSplitAroundNamedAssigns(self):
     unformatted_code = textwrap.dedent("""\
         class a():
+
             def a(): return a(
              aaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)
         """)
     expected_formatted_code = textwrap.dedent("""\
         class a():
+
             def a():
                 return a(
                     aaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -501,6 +505,7 @@ class Demo:
     """
     Demo docs
     """
+
     def foo(self):
         """
         foo docs
@@ -602,6 +607,7 @@ class _():
         """)
     expected_formatted_code = textwrap.dedent("""\
 class _():
+
     def __init__(
             self,
             title: Optional[str],
diff --git a/yapftests/reformatter_python3_test.py b/yapftests/reformatter_python3_test.py
index d06e406..ae55755 100644
--- a/yapftests/reformatter_python3_test.py
+++ b/yapftests/reformatter_python3_test.py
@@ -238,6 +238,7 @@ None.__ne__()
       return
     code = textwrap.dedent("""\
         async def outer():
+
             async def inner():
                 pass
         """)
@@ -365,6 +366,7 @@ class Foo:
 """
     expected_formatted_code = """\
 class Foo:
+
     def foo(self):
         foofoofoofoofoofoofoofoo('foofoofoofoofoo', {
             'foo': 'foo',
diff --git a/yapftests/yapf_test.py b/yapftests/yapf_test.py
index dc0d0a5..4e062cf 100644
--- a/yapftests/yapf_test.py
+++ b/yapftests/yapf_test.py
@@ -735,12 +735,14 @@ class CommandLineTest(unittest.TestCase):
   def testDisableButAdjustIndentations(self):
     unformatted_code = textwrap.dedent("""\
         class SplitPenaltyTest(unittest.TestCase):
+
           def testUnbreakable(self):
             self._CheckPenalties(tree, [
             ])  # yapf: disable
         """)
     expected_formatted_code = textwrap.dedent("""\
         class SplitPenaltyTest(unittest.TestCase):
+
             def testUnbreakable(self):
                 self._CheckPenalties(tree, [
                 ])  # yapf: disable