• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 Google Inc. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Represents the state of Python objects being formatted.
15
16Objects (e.g., list comprehensions, dictionaries, etc.) have specific
17requirements on how they're formatted. These state objects keep track of these
18requirements.
19"""
20
21from __future__ import absolute_import
22from __future__ import division
23from __future__ import print_function
24
25
26class ComprehensionState(object):
27  """Maintains the state of list comprehension formatting decisions.
28
29  A stack of ComprehensionState objects are kept to ensure that list
30  comprehensions are wrapped with well-defined rules.
31
32  Attributes:
33    expr_token: The first token in the comprehension.
34    for_token: The first 'for' token of the comprehension.
35    has_split_at_for: Whether there is a newline immediately before the
36        for_token.
37    has_interior_split: Whether there is a newline within the comprehension.
38        That is, a split somewhere after expr_token or before closing_bracket.
39  """
40
41  def __init__(self, expr_token):
42    self.expr_token = expr_token
43    self.for_token = None
44    self.has_split_at_for = False
45    self.has_interior_split = False
46
47  def HasTrivialExpr(self):
48    """Returns whether the comp_expr is "trivial" i.e. is a single token."""
49    return self.expr_token.next_token.value == 'for'
50
51  @property
52  def opening_bracket(self):
53    return self.expr_token.previous_token
54
55  @property
56  def closing_bracket(self):
57    return self.opening_bracket.matching_bracket
58
59  def Clone(self):
60    clone = ComprehensionState(self.expr_token)
61    clone.for_token = self.for_token
62    clone.has_split_at_for = self.has_split_at_for
63    clone.has_interior_split = self.has_interior_split
64    return clone
65
66  def __repr__(self):
67    return ('[opening_bracket::%s, for_token::%s, has_split_at_for::%s,'
68            ' has_interior_split::%s, has_trivial_expr::%s]' %
69            (self.opening_bracket, self.for_token, self.has_split_at_for,
70             self.has_interior_split, self.HasTrivialExpr()))
71
72  def __eq__(self, other):
73    return hash(self) == hash(other)
74
75  def __ne__(self, other):
76    return not self == other
77
78  def __hash__(self, *args, **kwargs):
79    return hash((self.expr_token, self.for_token, self.has_split_at_for,
80                 self.has_interior_split))
81