Skip to content

Commit

Permalink
Use "logical line" instead of "unwrapped line"
Browse files Browse the repository at this point in the history
The concept of an "unwrapped line" is better described as a "logical
line". Use that nomenclature instead.
  • Loading branch information
isanbard committed Dec 26, 2021
1 parent 46180bc commit 5b75e6f
Show file tree
Hide file tree
Showing 24 changed files with 1,163 additions and 1,171 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
- Use GitHub Actions instead of Travis for CI.
- Clean up the FormatToken interface to limit how much it relies upon the
pytree node object.
- Rename "unwrapped_line" module to "logical_line."
- Rename "UnwrappedLine" class to "LogicalLine."
### 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
Expand Down
16 changes: 8 additions & 8 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ Knobs
The penalty for characters over the column limit.

``SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT``
The penalty incurred by adding a line split to the unwrapped line. The more
The penalty incurred by adding a line split to the logical line. The more
line splits added the higher the penalty.

``SPLIT_PENALTY_IMPORT_NAMES``
Expand Down Expand Up @@ -962,15 +962,15 @@ Gory Details
Algorithm Design
----------------

The main data structure in YAPF is the ``UnwrappedLine`` object. It holds a list
of ``FormatToken``\s, that we would want to place on a single line if there were
no column limit. An exception being a comment in the middle of an expression
statement will force the line to be formatted on more than one line. The
formatter works on one ``UnwrappedLine`` object at a time.
The main data structure in YAPF is the ``LogicalLine`` object. It holds a list
of ``FormatToken``\s, that we would want to place on a single line if there
were no column limit. An exception being a comment in the middle of an
expression statement will force the line to be formatted on more than one line.
The formatter works on one ``LogicalLine`` object at a time.

An ``UnwrappedLine`` typically won't affect the formatting of lines before or
An ``LogicalLine`` typically won't affect the formatting of lines before or
after it. There is a part of the algorithm that may join two or more
``UnwrappedLine``\s into one line. For instance, an if-then statement with a
``LogicalLine``\s into one line. For instance, an if-then statement with a
short body can be placed on a single line:

.. code-block:: python
Expand Down
31 changes: 12 additions & 19 deletions yapf/yapflib/format_decision_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,22 @@
"""

from yapf.yapflib import format_token
from yapf.yapflib import logical_line
from yapf.yapflib import object_state
from yapf.yapflib import split_penalty
from yapf.yapflib import style
from yapf.yapflib import subtypes
from yapf.yapflib import unwrapped_line


class FormatDecisionState(object):
"""The current state when indenting an unwrapped line.
"""The current state when indenting a logical line.
The FormatDecisionState object is meant to be copied instead of referenced.
Attributes:
first_indent: The indent of the first token.
column: The number of used columns in the current line.
line: The unwrapped line we're currently processing.
line: The logical line we're currently processing.
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.
Expand All @@ -64,7 +64,7 @@ def __init__(self, line, first_indent):
'first_indent'.
Arguments:
line: (UnwrappedLine) The unwrapped line we're currently processing.
line: (LogicalLine) The logical line we're currently processing.
first_indent: (int) The indent of the first token.
"""
self.next_token = line.first
Expand Down Expand Up @@ -234,7 +234,7 @@ def MustSplit(self):
return False

if (not _IsLastScopeInLine(bracket) or
unwrapped_line.IsSurroundedByBrackets(bracket)):
logical_line.IsSurroundedByBrackets(bracket)):
last_token = bracket.matching_bracket
else:
last_token = _LastTokenInLine(bracket.matching_bracket)
Expand Down Expand Up @@ -268,7 +268,7 @@ def SurroundedByParens(token):
return False

if (previous.value == '(' and not previous.is_pseudo and
not unwrapped_line.IsSurroundedByBrackets(previous)):
not logical_line.IsSurroundedByBrackets(previous)):
pptoken = previous.previous_token
if (pptoken and not pptoken.is_name and not pptoken.is_keyword and
SurroundedByParens(current)):
Expand Down Expand Up @@ -300,7 +300,7 @@ def SurroundedByParens(token):
tok = tok.next_token
func_call_or_string_format = tok and tok.value == '%'
if func_call_or_string_format:
open_bracket = unwrapped_line.IsSurroundedByBrackets(current)
open_bracket = logical_line.IsSurroundedByBrackets(current)
if open_bracket:
if open_bracket.value in '[{':
if not self._FitsOnLine(open_bracket,
Expand All @@ -314,7 +314,7 @@ def SurroundedByParens(token):
subtypes.DICTIONARY_KEY not in current.next_token.subtypes):
# 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)
open_bracket = logical_line.IsSurroundedByBrackets(current)
if (open_bracket and open_bracket.value in '[{' and
subtypes.SUBSCRIPT_BRACKET not in open_bracket.subtypes):
if not self._FitsOnLine(current, current.matching_bracket):
Expand Down Expand Up @@ -382,7 +382,7 @@ def SurroundedByParens(token):
# b=1,
# c=2)
if (self._FitsOnLine(previous, previous.matching_bracket) and
unwrapped_line.IsSurroundedByBrackets(previous)):
logical_line.IsSurroundedByBrackets(previous)):
# An argument to a function is a function call with named
# assigns.
return False
Expand Down Expand Up @@ -551,7 +551,7 @@ def SurroundedByParens(token):

if (current.is_comment and
previous.lineno < current.lineno - current.value.count('\n')):
# If a comment comes in the middle of an unwrapped line (like an if
# If a comment comes in the middle of a logical line (like an if
# conditional with comments interspersed), then we want to split if the
# original comments were on a separate line.
return True
Expand Down Expand Up @@ -1088,14 +1088,7 @@ def _ArgumentListHasDictionaryEntry(self, token):
return False

def _ContainerFitsOnStartLine(self, opening):
"""Check if the container can fit on its starting line.
Arguments:
opening: (FormatToken) The unwrapped line we're currently processing.
Returns:
True if the container fits on the start line.
"""
"""Check if the container can fit on its starting line."""
return (opening.matching_bracket.total_length - opening.total_length +
self.stack[-1].indent) <= self.column_limit

Expand Down Expand Up @@ -1128,7 +1121,7 @@ def _IsFunctionCallWithArguments(token):


def _IsArgumentToFunction(token):
bracket = unwrapped_line.IsSurroundedByBrackets(token)
bracket = logical_line.IsSurroundedByBrackets(token)
if not bracket or bracket.value != '(':
return False
previous = bracket.previous_token
Expand Down
10 changes: 5 additions & 5 deletions yapf/yapflib/format_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ class FormatToken(object):
Attributes:
node: The PyTree node this token represents.
next_token: The token in the unwrapped line after this token or None if this
is the last token in the unwrapped line.
previous_token: The token in the unwrapped line before this token or None if
this is the first token in the unwrapped line.
next_token: The token in the logical line after this token or None if this
is the last token in the logical line.
previous_token: The token in the logical line before this token or None if
this is the first token in the logical line.
matching_bracket: If a bracket token ('[', '{', or '(') the matching
bracket.
parameters: If this and its following tokens make up a parameter list, then
Expand All @@ -74,7 +74,7 @@ class FormatToken(object):
formatter won't place n spaces before all comments. Only those that are
moved to the end of a line of code. The formatter may use different
spacing when appropriate.
total_length: The total length of the unwrapped line up to and including
total_length: The total length of the logical line up to and including
whitespace and this token. However, this doesn't include the initial
indentation amount.
split_penalty: The penalty for splitting the line before this token.
Expand Down
8 changes: 4 additions & 4 deletions yapf/yapflib/line_joiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Join unwrapped lines together.
"""Join logical lines together.
Determine how many lines can be joined into one line. For instance, we could
join these statements into one line:
Expand Down Expand Up @@ -43,8 +43,8 @@ def CanMergeMultipleLines(lines, last_was_merged=False):
"""Determine if multiple lines can be joined into one.
Arguments:
lines: (list of UnwrappedLine) This is a splice of UnwrappedLines from the
full code base.
lines: (list of LogicalLine) This is a splice of LogicalLines from the full
code base.
last_was_merged: (bool) The last line was merged.
Returns:
Expand Down Expand Up @@ -91,7 +91,7 @@ def _CanMergeLineIntoIfStatement(lines, limit):
'continue', and 'break'.
Arguments:
lines: (list of UnwrappedLine) The lines we are wanting to merge.
lines: (list of LogicalLine) The lines we are wanting to merge.
limit: (int) The amount of space remaining on the line.
Returns:
Expand Down
46 changes: 23 additions & 23 deletions yapf/yapflib/unwrapped_line.py → yapf/yapflib/logical_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""UnwrappedLine primitive for formatting.
"""LogicalLine primitive for formatting.
An unwrapped line is the containing data structure produced by the parser. It
collects all nodes (stored in FormatToken objects) that could appear on a
single line if there were no line length restrictions. It's then used by the
parser to perform the wrapping required to comply with the style guide.
A logical line is the containing data structure produced by the parser. It
collects all nodes (stored in FormatToken objects) that could appear on a single
line if there were no line length restrictions. It's then used by the parser to
perform the wrapping required to comply with the style guide.
"""

from yapf.yapflib import format_token
Expand All @@ -29,8 +29,8 @@
from lib2to3.fixer_util import syms as python_symbols


class UnwrappedLine(object):
"""Represents a single unwrapped line in the output.
class LogicalLine(object):
"""Represents a single logical line in the output.
Attributes:
depth: indentation depth of this line. This is just a numeric value used to
Expand All @@ -41,7 +41,7 @@ class UnwrappedLine(object):
def __init__(self, depth, tokens=None):
"""Constructor.
Creates a new unwrapped line with the given depth an initial list of tokens.
Creates a new logical line with the given depth an initial list of tokens.
Constructs the doubly-linked lists for format tokens using their built-in
next_token and previous_token attributes.
Expand All @@ -63,7 +63,7 @@ def __init__(self, depth, tokens=None):
def CalculateFormattingInformation(self):
"""Calculate the split penalty and total length for the tokens."""
# Say that the first token in the line should have a space before it. This
# means only that if this unwrapped line is joined with a predecessor line,
# means only that if this logical line is joined with a predecessor line,
# then there will be a space between them.
self.first.spaces_required_before = 1
self.first.total_length = len(self.first.value)
Expand Down Expand Up @@ -106,23 +106,23 @@ def Split(self):
if not self.has_semicolon or self.disable:
return [self]

uwlines = []
uwline = UnwrappedLine(self.depth)
llines = []
lline = LogicalLine(self.depth)
for tok in self._tokens:
if tok.value == ';':
uwlines.append(uwline)
uwline = UnwrappedLine(self.depth)
llines.append(lline)
lline = LogicalLine(self.depth)
else:
uwline.AppendToken(tok)
lline.AppendToken(tok)

if uwline.tokens:
uwlines.append(uwline)
if lline.tokens:
llines.append(lline)

for uwline in uwlines:
uwline.first.previous_token = None
uwline.last.next_token = None
for lline in llines:
lline.first.previous_token = None
lline.last.next_token = None

return uwlines
return llines

############################################################################
# Token Access and Manipulation Methods #
Expand Down Expand Up @@ -184,7 +184,7 @@ def __str__(self): # pragma: no cover
def __repr__(self): # pragma: no cover
tokens_repr = ','.join(
'{0}({1!r})'.format(tok.name, tok.value) for tok in self._tokens)
return 'UnwrappedLine(depth={0}, tokens=[{1}])'.format(
return 'LogicalLine(depth={0}, tokens=[{1}])'.format(
self.depth, tokens_repr)

############################################################################
Expand All @@ -204,10 +204,10 @@ def tokens(self):

@property
def lineno(self):
"""Return the line number of this unwrapped line.
"""Return the line number of this logical line.
Returns:
The line number of the first token in this unwrapped line.
The line number of the first token in this logical line.
"""
return self.first.lineno

Expand Down
Loading

0 comments on commit 5b75e6f

Please sign in to comment.