![](https://seccdn.libravatar.org/avatar/e2145bc5cf53dda95c308a3c75e8fef3.jpg?s=120&d=mm&r=g)
Hello community, here is the log from the commit of package python-yapf for openSUSE:Factory checked in at 2018-10-26 11:08:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-yapf (Old) and /work/SRC/openSUSE:Factory/.python-yapf.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-yapf" Fri Oct 26 11:08:25 2018 rev:4 rq:644316 version:0.24.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-yapf/python-yapf.changes 2018-08-31 10:46:25.671346272 +0200 +++ /work/SRC/openSUSE:Factory/.python-yapf.new/python-yapf.changes 2018-10-26 11:08:32.129861722 +0200 @@ -1,0 +2,6 @@ +Wed Oct 24 13:23:45 UTC 2018 - Tomáš Chvátal <tchvatal@suse.com> + +- Version update to 0.24.0: + * Support for python 3.7 + +------------------------------------------------------------------- Old: ---- yapf-0.23.0.tar.gz New: ---- yapf-0.24.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-yapf.spec ++++++ --- /var/tmp/diff_new_pack.IRlly2/_old 2018-10-26 11:08:33.317860065 +0200 +++ /var/tmp/diff_new_pack.IRlly2/_new 2018-10-26 11:08:33.317860065 +0200 @@ -12,13 +12,13 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-yapf -Version: 0.23.0 +Version: 0.24.0 Release: 0 Summary: A formatter for Python code License: Apache-2.0 ++++++ yapf-0.23.0.tar.gz -> yapf-0.24.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/CHANGELOG new/yapf-0.24.0/CHANGELOG --- old/yapf-0.23.0/CHANGELOG 2018-08-27 14:09:07.000000000 +0200 +++ new/yapf-0.24.0/CHANGELOG 2018-09-07 13:01:39.000000000 +0200 @@ -2,6 +2,30 @@ # All notable changes to this project will be documented in this file. # This project adheres to [Semantic Versioning](http://semver.org/). +## [0.24.0] 2018-09-07 +### Added +- Added 'SPLIT_BEFORE_DOT' knob to support "builder style" calls. The "builder + style" option didn't work as advertised. Lines would split after the dots, + not before them regardless of the penalties. +### Changed +- Support Python 3.7 in the tests. The old "comp_for" and "comp_if" nodes are + now "old_comp_for" and "old_comp_if" in lib2to3. +### Fixed +- Don't count inner function calls when marking arguments as named assignments. +- Make sure that tuples and the like are formatted nicely if they all can't fit + on a single line. This is similar to how we format function calls within an + argument list. +- Allow splitting in a subscript if it goes over the line limit. +- Increase the split penalty for an if-expression. +- Increase penalty for splitting in a subscript so that it's more likely to + split in a function call or other data literal. +- Cloning a pytree node doesn't transfer its a annotations. Make sure we do + that so that we don't lose information. +- Revert change that broke the "no_spaces_around_binary_operators" option. +- The "--style-help" option would output string lists and sets in Python types. + If the output was used as a style, then it wouldn't parse those values + correctly. + ## [0.23.0] 2018-08-27 ### Added - `DISABLE_ENDING_COMMA_HEURISTIC` is a new knob to disable the heuristic which diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/PKG-INFO new/yapf-0.24.0/PKG-INFO --- old/yapf-0.23.0/PKG-INFO 2018-08-27 14:10:44.000000000 +0200 +++ new/yapf-0.24.0/PKG-INFO 2018-09-07 13:03:46.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: yapf -Version: 0.23.0 +Version: 0.24.0 Summary: A formatter for Python code. Home-page: UNKNOWN Author: Bill Wendling @@ -157,11 +157,11 @@ file that specifies the desired style, or a dictionary of key/value pairs. The config file is a simple listing of (case-insensitive) ``key = value`` pairs - with a ``[style]`` heading. For example: + with a ``[yapf]`` heading. For example: .. code-block:: ini - [style] + [yapf] based_on_style = pep8 spaces_before_comment = 4 split_before_logical_operator = true @@ -466,7 +466,7 @@ 1 + 2 * 3 - 4 / 5 - will be formatted as follows when configured with ``"*/"``: + will be formatted as follows when configured with ``*,/``: .. code-block:: python @@ -511,6 +511,20 @@ for variable in bar if variable != 42 } + ``SPLIT_BEFORE_DOT`` + Split before the '.' if we need to split a longer expression: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) + + would reformat to something like: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}' + .format(a, b, c, d)) + ``SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN`` Split after the opening paren which surrounds an expression if it doesn't fit on a single line. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/README.rst new/yapf-0.24.0/README.rst --- old/yapf-0.23.0/README.rst 2018-08-27 06:43:49.000000000 +0200 +++ new/yapf-0.24.0/README.rst 2018-09-07 12:36:04.000000000 +0200 @@ -149,11 +149,11 @@ file that specifies the desired style, or a dictionary of key/value pairs. The config file is a simple listing of (case-insensitive) ``key = value`` pairs -with a ``[style]`` heading. For example: +with a ``[yapf]`` heading. For example: .. code-block:: ini - [style] + [yapf] based_on_style = pep8 spaces_before_comment = 4 split_before_logical_operator = true @@ -458,7 +458,7 @@ 1 + 2 * 3 - 4 / 5 - will be formatted as follows when configured with ``"*/"``: + will be formatted as follows when configured with ``*,/``: .. code-block:: python @@ -503,6 +503,20 @@ for variable in bar if variable != 42 } +``SPLIT_BEFORE_DOT`` + Split before the '.' if we need to split a longer expression: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) + + would reformat to something like: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}' + .format(a, b, c, d)) + ``SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN`` Split after the opening paren which surrounds an expression if it doesn't fit on a single line. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf/__init__.py new/yapf-0.24.0/yapf/__init__.py --- old/yapf-0.23.0/yapf/__init__.py 2018-08-27 14:09:13.000000000 +0200 +++ new/yapf-0.24.0/yapf/__init__.py 2018-09-07 13:01:48.000000000 +0200 @@ -38,7 +38,7 @@ from yapf.yapflib import style from yapf.yapflib import yapf_api -__version__ = '0.23.0' +__version__ = '0.24.0' def main(argv): @@ -145,7 +145,10 @@ for option, docstring in sorted(style.Help().items()): for line in docstring.splitlines(): print('#', line and ' ' or '', line, sep='') - print(option.lower(), '=', style.Get(option), sep='') + option_value = style.Get(option) + if isinstance(option_value, set) or isinstance(option_value, list): + option_value = ', '.join(option_value) + print(option.lower(), '=', option_value, sep='') print() return 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf/yapflib/format_decision_state.py new/yapf-0.24.0/yapf/yapflib/format_decision_state.py --- old/yapf-0.23.0/yapf/yapflib/format_decision_state.py 2018-06-12 06:44:06.000000000 +0200 +++ new/yapf-0.24.0/yapf/yapflib/format_decision_state.py 2018-09-07 12:15:01.000000000 +0200 @@ -44,9 +44,6 @@ next_token: The next token to be formatted. paren_level: The level of nesting inside (), [], and {}. lowest_level_on_line: The lowest paren_level on the current line. - newline: Indicates if a newline is added along the edge to this format - decision state node. - previous: The previous format decision state in the decision tree. stack: A stack (of _ParenState) keeping track of properties applying to parenthesis levels. comp_stack: A stack (of ComprehensionState) keeping track of properties @@ -74,8 +71,6 @@ self.stack = [_ParenState(first_indent, first_indent)] self.comp_stack = [] self.first_indent = first_indent - self.newline = False - self.previous = None self.column_limit = style.Get('COLUMN_LIMIT') def Clone(self): @@ -89,8 +84,6 @@ new.lowest_level_on_line = self.lowest_level_on_line new.ignore_stack_for_comparison = self.ignore_stack_for_comparison new.first_indent = self.first_indent - new.newline = self.newline - new.previous = self.previous new.stack = [state.Clone() for state in self.stack] new.comp_stack = [state.Clone() for state in self.comp_stack] return new @@ -186,7 +179,8 @@ if (self.stack[-1].split_before_closing_bracket and current.value in '}]' and style.Get('SPLIT_BEFORE_CLOSING_BRACKET')): # Split before the closing bracket if we can. - return current.node_split_penalty != split_penalty.UNBREAKABLE + if format_token.Subtype.SUBSCRIPT_BRACKET not in current.subtypes: + return current.node_split_penalty != split_penalty.UNBREAKABLE if (current.value == ')' and previous.value == ',' and not _IsSingleElementTuple(current.matching_bracket)): @@ -287,6 +281,15 @@ if not self._FitsOnLine(current, tok.matching_bracket): return True + if current.OpensScope() and previous.value == ',': + # If we have a list of tuples, then we can get a similar look as above. If + # the full list cannot fit on the line, then we want a split. + open_bracket = unwrapped_line.IsSurroundedByBrackets(current) + if (open_bracket and open_bracket.value in '[{' and + format_token.Subtype.SUBSCRIPT_BRACKET not in open_bracket.subtypes): + if not self._FitsOnLine(current, current.matching_bracket): + return True + ########################################################################### # Dict/Set Splitting if (style.Get('EACH_DICT_ENTRY_ON_SEPARATE_LINE') and @@ -336,8 +339,8 @@ ########################################################################### # Argument List Splitting if (style.Get('SPLIT_BEFORE_NAMED_ASSIGNS') and not current.is_comment and - format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST in - current.subtypes): + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST in current + .subtypes): if (previous.value not in {'=', ':', '*', '**'} and current.value not in ':=,)' and not _IsFunctionDefinition(previous)): # If we're going to split the lines because of named arguments, then we diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf/yapflib/pytree_utils.py new/yapf-0.24.0/yapf/yapflib/pytree_utils.py --- old/yapf-0.23.0/yapf/yapflib/pytree_utils.py 2018-03-28 07:29:50.000000000 +0200 +++ new/yapf-0.24.0/yapf/yapflib/pytree_utils.py 2018-09-07 11:47:58.000000000 +0200 @@ -219,6 +219,18 @@ _NODE_ANNOTATION_PREFIX = '_yapf_annotation_' +def CopyYapfAnnotations(src, dst): + """Copy all YAPF annotations from the source node to the destination node. + + Argumsnts: + src: the source node. + dst: the destination node. + """ + for annotation in dir(src): + if annotation.startswith(_NODE_ANNOTATION_PREFIX): + setattr(dst, annotation, getattr(src, annotation, None)) + + def GetNodeAnnotation(node, annotation, default=None): """Get annotation value from a node. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf/yapflib/split_penalty.py new/yapf-0.24.0/yapf/yapflib/split_penalty.py --- old/yapf-0.23.0/yapf/yapflib/split_penalty.py 2018-03-28 07:29:50.000000000 +0200 +++ new/yapf-0.24.0/yapf/yapflib/split_penalty.py 2018-09-07 12:18:21.000000000 +0200 @@ -26,7 +26,7 @@ # TODO(morbo): Document the annotations in a centralized place. E.g., the # README file. UNBREAKABLE = 1000 * 1000 -NAMED_ASSIGN = 11000 +NAMED_ASSIGN = 15000 DOTTED_NAME = 4000 VERY_STRONGLY_CONNECTED = 3500 STRONGLY_CONNECTED = 3000 @@ -46,7 +46,8 @@ FACTOR = 2100 POWER = 2200 ATOM = 2300 -ONE_ELEMENT_ARGUMENT = 2500 +ONE_ELEMENT_ARGUMENT = 500 +SUBSCRIPT = 6000 def ComputeSplitPenalties(tree): @@ -193,8 +194,11 @@ def Visit_trailer(self, node): # pylint: disable=invalid-name # trailer ::= '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME if node.children[0].value == '.': - self._SetUnbreakableOnChildren(node) - _SetSplitPenalty(node.children[1], DOTTED_NAME) + before = style.Get('SPLIT_BEFORE_DOT') + _SetSplitPenalty(node.children[0], + STRONGLY_CONNECTED if before else DOTTED_NAME) + _SetSplitPenalty(node.children[1], + DOTTED_NAME if before else STRONGLY_CONNECTED) elif len(node.children) == 2: # Don't split an empty argument list if at all possible. _SetSplitPenalty(node.children[1], VERY_STRONGLY_CONNECTED) @@ -236,7 +240,12 @@ 'atom', 'power' }: # Don't split an argument list with one element if at all possible. - _SetStronglyConnected(node.children[1], node.children[2]) + subtypes = pytree_utils.GetNodeAnnotation( + pytree_utils.FirstLeafNode(node), pytree_utils.Annotation.SUBTYPE) + if subtypes and format_token.Subtype.SUBSCRIPT_BRACKET in subtypes: + _IncreasePenalty(node, SUBSCRIPT) + else: + _SetStronglyConnected(node.children[1], node.children[2]) if name == 'arglist': _SetStronglyConnected(node.children[-1]) @@ -253,7 +262,9 @@ pytree_utils.NodeName(node.children[1]) == 'trailer'): # children[1] itself is a whole trailer: we don't want to # mark all of it as unbreakable, only its first token: (, [ or . - _SetUnbreakable(node.children[1].children[0]) + first = pytree_utils.FirstLeafNode(node.children[1]) + if first.value != '.': + _SetUnbreakable(node.children[1].children[0]) # A special case when there are more trailers in the sequence. Given: # atom tr1 tr2 @@ -310,10 +321,6 @@ # split the two. _SetStronglyConnected(trailer.children[-1]) - # If the original source has a "builder" style calls, then we should allow - # the reformatter to retain that. - _AllowBuilderStyleCalls(node) - def Visit_subscript(self, node): # pylint: disable=invalid-name # subscript ::= test | [test] ':' [test] [sliceop] _SetStronglyConnected(*node.children) @@ -325,6 +332,10 @@ _SetStronglyConnected(*node.children[1:]) self.DefaultNodeVisit(node) + def Visit_old_comp_for(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_for(node) + def Visit_comp_if(self, node): # pylint: disable=invalid-name # comp_if ::= 'if' old_test [comp_iter] _SetSplitPenalty(node.children[0], @@ -332,6 +343,15 @@ _SetStronglyConnected(*node.children[1:]) self.DefaultNodeVisit(node) + def Visit_old_comp_if(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_if(node) + + def Visit_test(self, node): # pylint: disable=invalid-name + # test ::= or_test ['if' or_test 'else' test] | lambdef + _IncreasePenalty(node, OR_TEST) + self.DefaultNodeVisit(node) + def Visit_or_test(self, node): # pylint: disable=invalid-name # or_test ::= and_test ('or' and_test)* self.DefaultNodeVisit(node) @@ -536,7 +556,7 @@ return if isinstance(node, pytree.Leaf): - if node.value in {'(', 'for', 'if'}: + if node.value in {'(', 'for'}: return penalty = pytree_utils.GetNodeAnnotation( node, pytree_utils.Annotation.SPLIT_PENALTY, default=0) @@ -590,23 +610,3 @@ def _SetSplitPenalty(node, penalty): pytree_utils.SetNodeAnnotation(node, pytree_utils.Annotation.SPLIT_PENALTY, penalty) - - -def _AllowBuilderStyleCalls(node): - """Allow splitting before '.' if it's a builder style function call.""" - - def RecGetLeaves(node): - if isinstance(node, pytree.Leaf): - return [node] - children = [] - for child in node.children: - children += RecGetLeaves(child) - return children - - list_of_children = RecGetLeaves(node) - prev_child = None - for child in list_of_children: - if child.value == '.': - if prev_child.lineno != child.lineno: - _SetSplitPenalty(child, 0) - prev_child = child diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf/yapflib/style.py new/yapf-0.24.0/yapf/yapflib/style.py --- old/yapf-0.23.0/yapf/yapflib/style.py 2018-08-27 06:43:49.000000000 +0200 +++ new/yapf-0.24.0/yapf/yapflib/style.py 2018-09-07 12:53:16.000000000 +0200 @@ -161,7 +161,7 @@ 1 + 2 * 3 - 4 / 5 - will be formatted as follows when configured with *,/: + will be formatted as follows when configured with "*,/": 1 + 2*3 - 4/5 @@ -194,6 +194,16 @@ variable: 'Hello world, have a nice day!' for variable in bar if variable != 42 }"""), + SPLIT_BEFORE_DOT=textwrap.dedent("""\ + Split before the '.' if we need to split a longer expression: + + foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) + + would reformat to something like: + + foo = ('This is a really long string: {}, {}, {}, {}' + .format(a, b, c, d)) + """), SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN=textwrap.dedent("""\ Split after the opening paren which surrounds an expression if it doesn't fit on a single line. @@ -292,6 +302,7 @@ SPLIT_BEFORE_BITWISE_OPERATOR=True, SPLIT_BEFORE_CLOSING_BRACKET=True, SPLIT_BEFORE_DICT_SET_GENERATOR=True, + SPLIT_BEFORE_DOT=False, SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN=False, SPLIT_BEFORE_FIRST_ARGUMENT=False, SPLIT_BEFORE_LOGICAL_OPERATOR=True, @@ -302,7 +313,7 @@ SPLIT_PENALTY_BEFORE_IF_EXPR=0, SPLIT_PENALTY_BITWISE_OPERATOR=300, SPLIT_PENALTY_COMPREHENSION=80, - SPLIT_PENALTY_EXCESS_CHARACTER=4500, + SPLIT_PENALTY_EXCESS_CHARACTER=7000, SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT=30, SPLIT_PENALTY_IMPORT_NAMES=0, SPLIT_PENALTY_LOGICAL_OPERATOR=300, @@ -334,6 +345,7 @@ style['INDENT_WIDTH'] = 2 style['JOIN_MULTIPLE_LINES'] = False style['SPLIT_BEFORE_BITWISE_OPERATOR'] = True + style['SPLIT_BEFORE_DOT'] = True style['SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN'] = True return style @@ -390,8 +402,6 @@ def _StringListConverter(s): """Option value converter for a comma-separated list of strings.""" - if len(s) > 2 and s[0] in '"\'': - s = s[1:-1] return [part.strip() for part in s.split(',')] @@ -399,9 +409,7 @@ """Option value converter for a comma-separated set of strings.""" if len(s) > 2 and s[0] in '"\'': s = s[1:-1] - if ',' in s: - return set(part.strip() for part in s.split(',')) - return set(s.strip()) + return set(part.strip() for part in s.split(',')) def _BoolConverter(s): @@ -447,6 +455,7 @@ SPLIT_BEFORE_BITWISE_OPERATOR=_BoolConverter, SPLIT_BEFORE_CLOSING_BRACKET=_BoolConverter, SPLIT_BEFORE_DICT_SET_GENERATOR=_BoolConverter, + SPLIT_BEFORE_DOT=_BoolConverter, SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN=_BoolConverter, SPLIT_BEFORE_FIRST_ARGUMENT=_BoolConverter, SPLIT_BEFORE_LOGICAL_OPERATOR=_BoolConverter, @@ -527,10 +536,10 @@ config = py3compat.ConfigParser() config.add_section('style') for key, value, _ in re.findall( - r'([a-zA-Z0-9_]+)\s*[:=]\s*' + - r'(?:' + - r'((?P<quote>[\'"]).*?(?P=quote)|' + - r'[a-zA-Z0-9_]+)' + + r'([a-zA-Z0-9_]+)\s*[:=]\s*' + r'(?:' + r'((?P<quote>[\'"]).*?(?P=quote)|' + r'[a-zA-Z0-9_]+)' r')', config_string): # yapf: disable config.set('style', key, value) return config diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf/yapflib/subtype_assigner.py new/yapf-0.24.0/yapf/yapflib/subtype_assigner.py --- old/yapf-0.23.0/yapf/yapflib/subtype_assigner.py 2018-08-27 06:43:49.000000000 +0200 +++ new/yapf-0.24.0/yapf/yapflib/subtype_assigner.py 2018-09-07 12:17:16.000000000 +0200 @@ -315,11 +315,19 @@ _AppendSubtypeRec(node.parent.children[0], format_token.Subtype.COMP_EXPR) self.DefaultNodeVisit(node) + def Visit_old_comp_for(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_for(node) + def Visit_comp_if(self, node): # pylint: disable=invalid-name # comp_if ::= 'if' old_test [comp_iter] _AppendSubtypeRec(node, format_token.Subtype.COMP_IF) self.DefaultNodeVisit(node) + def Visit_old_comp_if(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_if(node) + def _ProcessArgLists(self, node): """Common method for processing argument lists.""" for child in node.children: @@ -337,20 +345,24 @@ def HasSubtype(node): """Return True if the arg list has a named assign subtype.""" if isinstance(node, pytree.Leaf): - if node_subtype in pytree_utils.GetNodeAnnotation( - node, pytree_utils.Annotation.SUBTYPE, set()): - return True - return False - has_subtype = False - for child in node.children: - if pytree_utils.NodeName(child) != 'arglist': - has_subtype |= HasSubtype(child) - return has_subtype + return node_subtype in pytree_utils.GetNodeAnnotation( + node, pytree_utils.Annotation.SUBTYPE, set()) - if HasSubtype(node): for child in node.children: - if pytree_utils.NodeName(child) != 'COMMA': - _AppendFirstLeafTokenSubtype(child, list_subtype) + node_name = pytree_utils.NodeName(child) + if node_name not in {'atom', 'arglist', 'power'}: + if HasSubtype(child): + return True + + return False + + if not HasSubtype(node): + return + + for child in node.children: + node_name = pytree_utils.NodeName(child) + if node_name not in {'atom', 'COMMA'}: + _AppendFirstLeafTokenSubtype(child, list_subtype) def _AppendTokenSubtype(node, subtype): @@ -391,7 +403,13 @@ # A comment was inserted before the value, which is a pytree.Leaf. # Encompass the dictionary's value into an ATOM node. last = first.next_sibling - new_node = pytree.Node(syms.atom, [first.clone(), last.clone()]) + last_clone = last.clone() + new_node = pytree.Node(syms.atom, [first.clone(), last_clone]) + for orig_leaf, clone_leaf in zip(last.leaves(), last_clone.leaves()): + pytree_utils.CopyYapfAnnotations(orig_leaf, clone_leaf) + if hasattr(orig_leaf, 'is_pseudo'): + clone_leaf.is_pseudo = orig_leaf.is_pseudo + node.replace(new_node) node = new_node last.remove() @@ -423,6 +441,8 @@ _AppendFirstLeafTokenSubtype(node, format_token.Subtype.DICTIONARY_VALUE) else: clone = node.clone() + for orig_leaf, clone_leaf in zip(node.leaves(), clone.leaves()): + pytree_utils.CopyYapfAnnotations(orig_leaf, clone_leaf) new_node = pytree.Node(syms.atom, [lparen, clone, rparen]) node.replace(new_node) _AppendFirstLeafTokenSubtype(clone, format_token.Subtype.DICTIONARY_VALUE) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf/yapflib/unwrapped_line.py new/yapf-0.24.0/yapf/yapflib/unwrapped_line.py --- old/yapf-0.23.0/yapf/yapflib/unwrapped_line.py 2018-08-27 14:07:22.000000000 +0200 +++ new/yapf-0.24.0/yapf/yapflib/unwrapped_line.py 2018-09-03 12:54:07.000000000 +0200 @@ -418,9 +418,6 @@ if prev_token.is_name and cval == '[': # Don't break in the middle of an array dereference. return False - if prev_token.is_name and cval == '.': - # Don't break before the '.' in a dotted name. - return False if cur_token.is_comment and prev_token.lineno == cur_token.lineno: # Don't break a comment at the end of the line. return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapf.egg-info/PKG-INFO new/yapf-0.24.0/yapf.egg-info/PKG-INFO --- old/yapf-0.23.0/yapf.egg-info/PKG-INFO 2018-08-27 14:10:43.000000000 +0200 +++ new/yapf-0.24.0/yapf.egg-info/PKG-INFO 2018-09-07 13:03:46.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: yapf -Version: 0.23.0 +Version: 0.24.0 Summary: A formatter for Python code. Home-page: UNKNOWN Author: Bill Wendling @@ -157,11 +157,11 @@ file that specifies the desired style, or a dictionary of key/value pairs. The config file is a simple listing of (case-insensitive) ``key = value`` pairs - with a ``[style]`` heading. For example: + with a ``[yapf]`` heading. For example: .. code-block:: ini - [style] + [yapf] based_on_style = pep8 spaces_before_comment = 4 split_before_logical_operator = true @@ -466,7 +466,7 @@ 1 + 2 * 3 - 4 / 5 - will be formatted as follows when configured with ``"*/"``: + will be formatted as follows when configured with ``*,/``: .. code-block:: python @@ -511,6 +511,20 @@ for variable in bar if variable != 42 } + ``SPLIT_BEFORE_DOT`` + Split before the '.' if we need to split a longer expression: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) + + would reformat to something like: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}' + .format(a, b, c, d)) + ``SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN`` Split after the opening paren which surrounds an expression if it doesn't fit on a single line. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapftests/file_resources_test.py new/yapf-0.24.0/yapftests/file_resources_test.py --- old/yapf-0.23.0/yapftests/file_resources_test.py 2018-05-22 08:11:25.000000000 +0200 +++ new/yapf-0.24.0/yapftests/file_resources_test.py 2018-08-29 10:59:54.000000000 +0200 @@ -91,11 +91,13 @@ _touch_files([file1, file2]) self.assertEqual( - file_resources.GetCommandLineFiles( - [file1, file2], recursive=False, exclude=None), [file1, file2]) + file_resources.GetCommandLineFiles([file1, file2], + recursive=False, + exclude=None), [file1, file2]) self.assertEqual( - file_resources.GetCommandLineFiles( - [file1, file2], recursive=True, exclude=None), [file1, file2]) + file_resources.GetCommandLineFiles([file1, file2], + recursive=True, + exclude=None), [file1, file2]) def test_nonrecursive_find_in_dir(self): tdir1 = self._make_test_dir('test1') @@ -124,9 +126,9 @@ self.assertEqual( sorted( - file_resources.GetCommandLineFiles( - [self.test_tmpdir], recursive=True, exclude=None)), - sorted(files)) + file_resources.GetCommandLineFiles([self.test_tmpdir], + recursive=True, + exclude=None)), sorted(files)) def test_recursive_find_in_dir_with_exclude(self): tdir1 = self._make_test_dir('test1') @@ -141,8 +143,9 @@ self.assertEqual( sorted( - file_resources.GetCommandLineFiles( - [self.test_tmpdir], recursive=True, exclude=['*test*3.py'])), + file_resources.GetCommandLineFiles([self.test_tmpdir], + recursive=True, + exclude=['*test*3.py'])), sorted([ os.path.join(tdir1, 'testfile1.py'), os.path.join(tdir2, 'testfile2.py'), @@ -159,8 +162,9 @@ ] _touch_files(files) - actual = file_resources.GetCommandLineFiles( - [self.test_tmpdir], recursive=True, exclude=['*.test1*']) + actual = file_resources.GetCommandLineFiles([self.test_tmpdir], + recursive=True, + exclude=['*.test1*']) self.assertEqual( sorted(actual), @@ -225,22 +229,22 @@ os.chdir(self.test_tmpdir) found = sorted( - file_resources.GetCommandLineFiles( - ['test1', 'test2', 'test3'], - recursive=True, - exclude=[ - 'test1', - 'test2/testinner/', - ])) + file_resources.GetCommandLineFiles(['test1', 'test2', 'test3'], + recursive=True, + exclude=[ + 'test1', + 'test2/testinner/', + ])) self.assertEqual(found, ['test3/foo/bar/bas/xxx/testfile3.py']) found = sorted( - file_resources.GetCommandLineFiles( - ['.'], recursive=True, exclude=[ - 'test1', - 'test3', - ])) + file_resources.GetCommandLineFiles(['.'], + recursive=True, + exclude=[ + 'test1', + 'test3', + ])) self.assertEqual(found, ['./test2/testinner/testfile2.py']) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapftests/reformatter_basic_test.py new/yapf-0.24.0/yapftests/reformatter_basic_test.py --- old/yapf-0.23.0/yapftests/reformatter_basic_test.py 2018-07-02 08:24:20.000000000 +0200 +++ new/yapf-0.24.0/yapftests/reformatter_basic_test.py 2018-09-07 12:05:24.000000000 +0200 @@ -16,6 +16,7 @@ import textwrap import unittest +from yapf.yapflib import py3compat from yapf.yapflib import reformatter from yapf.yapflib import style @@ -1339,18 +1340,18 @@ self.assertCodeEqual(code, reformatter.Reformat(uwlines)) def testRelaxArraySubscriptAffinity(self): - code = textwrap.dedent("""\ - class A(object): + code = """\ +class A(object): - def f(self, aaaaaaaaa, bbbbbbbbbbbbb, row): - if True: - if True: - if True: - if True: - if row[4] is None or row[5] is None: - bbbbbbbbbbbbb['..............'] = row[ - 5] if row[5] is not None else 5 - """) + def f(self, aaaaaaaaa, bbbbbbbbbbbbb, row): + if True: + if True: + if True: + if True: + if row[4] is None or row[5] is None: + bbbbbbbbbbbbb[ + '..............'] = row[5] if row[5] is not None else 5 +""" uwlines = yapf_test_helper.ParseAndUnwrap(code) self.assertCodeEqual(code, reformatter.Reformat(uwlines)) @@ -2350,6 +2351,24 @@ uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) self.assertEqual(expected_code, reformatter.Reformat(uwlines)) + def testPseudoParens(self): + unformatted_code = """\ +my_dict = { + 'key': # Some comment about the key + {'nested_key': 1, }, +} +""" + expected_code = """\ +my_dict = { + 'key': # Some comment about the key + { + 'nested_key': 1, + }, +} +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertEqual(expected_code, reformatter.Reformat(uwlines)) + def testSplittingBeforeFirstArgumentOnFunctionCall(self): """Tests split_before_first_argument on a function call.""" try: @@ -2469,6 +2488,7 @@ finally: style.SetGlobalStyle(style.CreateChromiumStyle()) + @unittest.skipUnless(not py3compat.PY3, 'Requires Python 2.7') def testAsyncAsNonKeyword(self): try: style.SetGlobalStyle(style.CreatePEP8Style()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapftests/reformatter_buganizer_test.py new/yapf-0.24.0/yapftests/reformatter_buganizer_test.py --- old/yapf-0.23.0/yapftests/reformatter_buganizer_test.py 2018-06-12 06:50:45.000000000 +0200 +++ new/yapf-0.24.0/yapftests/reformatter_buganizer_test.py 2018-09-04 04:31:30.000000000 +0200 @@ -28,6 +28,156 @@ def setUpClass(cls): style.SetGlobalStyle(style.CreateChromiumStyle()) + def testB112711217(self): + code = """\ +def _(): + stats['moderated'] = ~stats.moderation_reason.isin( + approved_moderation_reasons) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB112867548(self): + unformatted_code = """\ +def _(): + return flask.make_response( + 'Records: {}, Problems: {}, More: {}'.format( + process_result.result_ct, process_result.problem_ct, + process_result.has_more), + httplib.ACCEPTED if process_result.has_more else httplib.OK, + {'content-type': _TEXT_CONTEXT_TYPE}) +""" + expected_formatted_code = """\ +def _(): + return flask.make_response( + 'Records: {}, Problems: {}, More: {}'.format(process_result.result_ct, + process_result.problem_ct, + process_result.has_more), + httplib.ACCEPTED if process_result.has_more else httplib.OK, + {'content-type': _TEXT_CONTEXT_TYPE}) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB112651423(self): + unformatted_code = """\ +def potato(feeditems, browse_use_case=None): + for item in turnip: + if kumquat: + if not feeds_variants.variants['FEEDS_LOAD_PLAYLIST_VIDEOS_FOR_ALL_ITEMS'] and item.video: + continue +""" + expected_formatted_code = """\ +def potato(feeditems, browse_use_case=None): + for item in turnip: + if kumquat: + if not feeds_variants.variants[ + 'FEEDS_LOAD_PLAYLIST_VIDEOS_FOR_ALL_ITEMS'] and item.video: + continue +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB112651423(self): + unformatted_code = """\ +def potato(feeditems, browse_use_case=None): + for item in turnip: + if kumquat: + if not feeds_variants.variants['FEEDS_LOAD_PLAYLIST_VIDEOS_FOR_ALL_ITEMS'] and item.video: + continue +""" + expected_formatted_code = """\ +def potato(feeditems, browse_use_case=None): + for item in turnip: + if kumquat: + if not feeds_variants.variants[ + 'FEEDS_LOAD_PLAYLIST_VIDEOS_FOR_ALL_ITEMS'] and item.video: + continue +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB80484938(self): + code = """\ +for sssssss, aaaaaaaaaa in [ + ('ssssssssssssssssssss', 'sssssssssssssssssssssssss'), + ('nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn', + 'nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn'), + ('pppppppppppppppppppppppppppp', 'pppppppppppppppppppppppppppppppp'), + ('wwwwwwwwwwwwwwwwwwww', 'wwwwwwwwwwwwwwwwwwwwwwwww'), + ('sssssssssssssssss', 'sssssssssssssssssssssss'), + ('ggggggggggggggggggggggg', 'gggggggggggggggggggggggggggg'), + ('ggggggggggggggggg', 'gggggggggggggggggggggg'), + ('eeeeeeeeeeeeeeeeeeeeee', 'eeeeeeeeeeeeeeeeeeeeeeeeeee') +]: + pass + +for sssssss, aaaaaaaaaa in [ + ('ssssssssssssssssssss', 'sssssssssssssssssssssssss'), + ('nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn', 'nnnnnnnnnnnnnnnnnnnnnnnnn'), + ('pppppppppppppppppppppppppppp', 'pppppppppppppppppppppppppppppppp'), + ('wwwwwwwwwwwwwwwwwwww', 'wwwwwwwwwwwwwwwwwwwwwwwww'), + ('sssssssssssssssss', 'sssssssssssssssssssssss'), + ('ggggggggggggggggggggggg', 'gggggggggggggggggggggggggggg'), + ('ggggggggggggggggg', 'gggggggggggggggggggggg'), + ('eeeeeeeeeeeeeeeeeeeeee', 'eeeeeeeeeeeeeeeeeeeeeeeeeee') +]: + pass + +for sssssss, aaaaaaaaaa in [ + ('ssssssssssssssssssss', 'sssssssssssssssssssssssss'), + ('nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn', + 'nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn'), + ('pppppppppppppppppppppppppppp', 'pppppppppppppppppppppppppppppppp'), + ('wwwwwwwwwwwwwwwwwwww', 'wwwwwwwwwwwwwwwwwwwwwwwww'), + ('sssssssssssssssss', 'sssssssssssssssssssssss'), + ('ggggggggggggggggggggggg', 'gggggggggggggggggggggggggggg'), + ('ggggggggggggggggg', 'gggggggggggggggggggggg'), + ('eeeeeeeeeeeeeeeeeeeeee', 'eeeeeeeeeeeeeeeeeeeeeeeeeee'), +]: + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB79462249(self): + code = """\ +foo.bar(baz, [ + quux(thud=42), + norf, +]) +foo.bar(baz, [ + quux(), + norf, +]) +foo.bar(baz, quux(thud=42), aaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbb, + ccccccccccccccccccc) +foo.bar( + baz, + quux(thud=42), + aaaaaaaaaaaaaaaaaaaaaa=1, + bbbbbbbbbbbbbbbbbbbbb=2, + ccccccccccccccccccc=3) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB113210278(self): + unformatted_code = """\ +def _(): + aaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc(\ +eeeeeeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffffffffffffffffffffff.\ +ggggggggggggggggggggggggggggggggg.hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh()) +""" + expected_formatted_code = """\ +def _(): + aaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc( + eeeeeeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffffffffffffffffffffff + .ggggggggggggggggggggggggggggggggg.hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh()) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + def testB77923341(self): code = """\ def f(): @@ -845,8 +995,8 @@ """) expected_formatted_code = textwrap.dedent("""\ def lulz(): - return (some_long_module_name.SomeLongClassName.some_long_attribute_name. - some_long_method_name()) + return (some_long_module_name.SomeLongClassName.some_long_attribute_name + .some_long_method_name()) """) uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) @@ -944,8 +1094,8 @@ def _(): _xxxxxxxxxxxxxxx( aaaaaaaa, - bbbbbbbbbbbbbb.cccccccccc[dddddddddddddddddddddddddddd. - eeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffff]) + bbbbbbbbbbbbbb.cccccccccc[dddddddddddddddddddddddddddd + .eeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffff]) """) uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) @@ -1017,8 +1167,8 @@ expected_formatted_code = textwrap.dedent("""\ def _(): aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = ( - self.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb. - cccccccccccccccccccccccccccccccccccc) + self.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + .cccccccccccccccccccccccccccccccccccc) """) uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) @@ -1779,19 +1929,20 @@ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) def testB15597568(self): - unformatted_code = textwrap.dedent("""\ - if True: - if True: - if True: - print(("Return code was %d" + (", and the process timed out." if did_time_out else ".")) % errorcode) - """) - expected_formatted_code = textwrap.dedent("""\ - if True: - if True: - if True: - print(("Return code was %d" + (", and the process timed out." - if did_time_out else ".")) % errorcode) - """) + unformatted_code = """\ +if True: + if True: + if True: + print(("Return code was %d" + (", and the process timed out." if did_time_out else ".")) % errorcode) +""" + expected_formatted_code = """\ +if True: + if True: + if True: + print(("Return code was %d" + + (", and the process timed out." if did_time_out else ".")) % + errorcode) +""" uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapftests/split_penalty_test.py new/yapf-0.24.0/yapftests/split_penalty_test.py --- old/yapf-0.23.0/yapftests/split_penalty_test.py 2018-01-15 01:48:30.000000000 +0100 +++ new/yapf-0.24.0/yapftests/split_penalty_test.py 2018-09-03 12:02:33.000000000 +0200 @@ -22,6 +22,9 @@ from yapf.yapflib import pytree_utils from yapf.yapflib import pytree_visitor from yapf.yapflib import split_penalty +from yapf.yapflib import style + +from yapftests import yapf_test_helper UNBREAKABLE = split_penalty.UNBREAKABLE VERY_STRONGLY_CONNECTED = split_penalty.VERY_STRONGLY_CONNECTED @@ -29,7 +32,11 @@ STRONGLY_CONNECTED = split_penalty.STRONGLY_CONNECTED -class SplitPenaltyTest(unittest.TestCase): +class SplitPenaltyTest(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreateChromiumStyle()) def _ParseAndComputePenalties(self, code, dumptree=False): """Parses the code and computes split penalties. @@ -198,7 +205,7 @@ ('foo', STRONGLY_CONNECTED), ('if', 0), ('a', STRONGLY_CONNECTED), - ('.', UNBREAKABLE), + ('.', STRONGLY_CONNECTED), ('x', DOTTED_NAME), ('==', STRONGLY_CONNECTED), ('37', STRONGLY_CONNECTED), @@ -224,7 +231,7 @@ tree = self._ParseAndComputePenalties(code) self._CheckPenalties(tree, [ ('foo', None), - ('.', UNBREAKABLE), + ('.', STRONGLY_CONNECTED), ('bar', DOTTED_NAME), ('.', STRONGLY_CONNECTED), ('baz', DOTTED_NAME), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yapf-0.23.0/yapftests/yapf_test.py new/yapf-0.24.0/yapftests/yapf_test.py --- old/yapf-0.23.0/yapftests/yapf_test.py 2018-08-27 14:07:22.000000000 +0200 +++ new/yapf-0.24.0/yapftests/yapf_test.py 2018-08-29 10:59:54.000000000 +0200 @@ -1363,7 +1363,7 @@ expected_formatted_code, extra_options=[ '--style', - '{based_on_style: pep8, ' + + '{based_on_style: pep8, ' 'no_spaces_around_selected_binary_operators: "@,**,-"}', ])