aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:01:57 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:01:57 +0000
commit6b4d662efb8cf6af41516bc30a47f2d720a34397 (patch)
treedc88d4ff4bd74b39e2bcd06ea95e79574733f9d9
parent72ff55e1c383d11df15a4e6245e43f5fbe3bedc2 (diff)
parent7249d1a64f4850ccf838e62a46276f891f72998e (diff)
downloadyapf-android14-mainline-mediaprovider-release.tar.gz
Change-Id: I3a4a470f0adedc705274b7943e38a9b38a8dc8d9
-rw-r--r--.flake818
-rw-r--r--.github/workflows/ci.yml34
-rw-r--r--.gitignore3
-rw-r--r--.pre-commit-config.yaml30
-rw-r--r--.pre-commit-config.yml30
-rw-r--r--.pre-commit-hooks.yaml9
-rw-r--r--.pre-commit-hooks.yml9
-rw-r--r--.style.yapf3
-rw-r--r--.travis.yml28
-rw-r--r--CHANGELOG216
-rw-r--r--CONTRIBUTING.rst7
-rw-r--r--CONTRIBUTORS2
-rw-r--r--METADATA10
-rw-r--r--README.rst433
-rw-r--r--plugins/README.rst2
-rwxr-xr-x[-rw-r--r--]plugins/pre-commit.sh41
-rw-r--r--pylintrc2
-rw-r--r--setup.py9
-rw-r--r--tox.ini2
-rw-r--r--yapf/__init__.py266
-rw-r--r--yapf/third_party/__init__.py0
-rw-r--r--yapf/third_party/yapf_diff/LICENSE219
-rw-r--r--yapf/third_party/yapf_diff/__init__.py0
-rw-r--r--yapf/third_party/yapf_diff/yapf_diff.py145
-rw-r--r--yapf/yapflib/blank_line_calculator.py33
-rw-r--r--yapf/yapflib/comment_splicer.py21
-rw-r--r--yapf/yapflib/errors.py25
-rw-r--r--yapf/yapflib/file_resources.py155
-rw-r--r--yapf/yapflib/format_decision_state.py427
-rw-r--r--yapf/yapflib/format_token.py234
-rw-r--r--yapf/yapflib/identify_container.py6
-rw-r--r--yapf/yapflib/line_joiner.py8
-rw-r--r--yapf/yapflib/logical_line.py (renamed from yapf/yapflib/unwrapped_line.py)334
-rw-r--r--yapf/yapflib/object_state.py157
-rw-r--r--yapf/yapflib/py3compat.py21
-rw-r--r--yapf/yapflib/pytree_unwrapper.py117
-rw-r--r--yapf/yapflib/pytree_utils.py16
-rw-r--r--yapf/yapflib/pytree_visitor.py2
-rw-r--r--yapf/yapflib/reformatter.py469
-rw-r--r--yapf/yapflib/split_penalty.py249
-rw-r--r--yapf/yapflib/style.py314
-rw-r--r--yapf/yapflib/subtype_assigner.py253
-rw-r--r--yapf/yapflib/subtypes.py40
-rw-r--r--yapf/yapflib/yapf_api.py132
-rw-r--r--yapftests/blank_line_calculator_test.py117
-rw-r--r--yapftests/file_resources_test.py275
-rw-r--r--yapftests/format_decision_state_test.py26
-rw-r--r--yapftests/format_token_test.py30
-rw-r--r--yapftests/line_joiner_test.py8
-rw-r--r--yapftests/logical_line_test.py (renamed from yapftests/unwrapped_line_test.py)48
-rw-r--r--yapftests/main_test.py29
-rw-r--r--yapftests/pytree_unwrapper_test.py104
-rw-r--r--yapftests/reformatter_basic_test.py1795
-rw-r--r--yapftests/reformatter_buganizer_test.py1085
-rw-r--r--yapftests/reformatter_facebook_test.py108
-rw-r--r--yapftests/reformatter_pep8_test.py654
-rw-r--r--yapftests/reformatter_python3_test.py256
-rw-r--r--yapftests/reformatter_style_config_test.py133
-rw-r--r--yapftests/reformatter_verify_test.py32
-rw-r--r--yapftests/split_penalty_test.py31
-rw-r--r--yapftests/style_test.py174
-rw-r--r--yapftests/subtype_assigner_test.py323
-rw-r--r--yapftests/yapf_test.py796
-rw-r--r--yapftests/yapf_test_helper.py34
64 files changed, 7871 insertions, 2718 deletions
diff --git a/.flake8 b/.flake8
index 06d70e9..bb1ce94 100644
--- a/.flake8
+++ b/.flake8
@@ -1,8 +1,18 @@
[flake8]
ignore =
- # indentation is not a multiple of four,
- E111,E114,
+ # 'toml' imported but unused
+ F401,
+ # closing bracket does not match visual indentation
+ E124,
+ # continuation line over-indented for hanging indent
+ E126,
# visually indented line with same indent as next logical line,
- E129
+ E129,
+ # line break before binary operator
+ W503,
+ # line break after binary operator
+ W504
-max-line-length=80
+disable-noqa
+indent-size = 2
+max-line-length = 80
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..280af43
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,34 @@
+# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: YAPF
+
+on: [push]
+
+jobs:
+ build:
+
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ python-version: [2.7, 3.7, 3.8, 3.9]
+ os: [ubuntu-latest, macos-latest]
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ - name: Lint with flake8
+ run: |
+ python -m pip install toml flake8
+ flake8 . --statistics
+ - name: Test with pytest
+ run: |
+ pip install pytest
+ pip install pytest-cov
+ pytest
diff --git a/.gitignore b/.gitignore
index 3fd6b2b..960818e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,6 @@
/dist
/.tox
/yapf.egg-info
+
+/.idea
+
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..3bd65c2
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,30 @@
+# File introduces automated checks triggered on git events
+# to enable run `pip install pre-commit && pre-commit install`
+
+repos:
+ - repo: local
+ hooks:
+ - id: yapf
+ name: yapf
+ language: python
+ entry: yapf
+ args: [-i, -vv]
+ types: [python]
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.2.0
+ hooks:
+ - id: trailing-whitespace
+ - id: check-docstring-first
+ - id: check-json
+ - id: check-added-large-files
+ - id: check-yaml
+ - id: debug-statements
+ - id: requirements-txt-fixer
+ - id: check-merge-conflict
+ - id: double-quote-string-fixer
+ - id: end-of-file-fixer
+ - id: sort-simple-yaml
+ - repo: meta
+ hooks:
+ - id: check-hooks-apply
+ - id: check-useless-excludes
diff --git a/.pre-commit-config.yml b/.pre-commit-config.yml
new file mode 100644
index 0000000..3bd65c2
--- /dev/null
+++ b/.pre-commit-config.yml
@@ -0,0 +1,30 @@
+# File introduces automated checks triggered on git events
+# to enable run `pip install pre-commit && pre-commit install`
+
+repos:
+ - repo: local
+ hooks:
+ - id: yapf
+ name: yapf
+ language: python
+ entry: yapf
+ args: [-i, -vv]
+ types: [python]
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.2.0
+ hooks:
+ - id: trailing-whitespace
+ - id: check-docstring-first
+ - id: check-json
+ - id: check-added-large-files
+ - id: check-yaml
+ - id: debug-statements
+ - id: requirements-txt-fixer
+ - id: check-merge-conflict
+ - id: double-quote-string-fixer
+ - id: end-of-file-fixer
+ - id: sort-simple-yaml
+ - repo: meta
+ hooks:
+ - id: check-hooks-apply
+ - id: check-useless-excludes
diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
new file mode 100644
index 0000000..3eba1f2
--- /dev/null
+++ b/.pre-commit-hooks.yaml
@@ -0,0 +1,9 @@
+# File configures YAPF to be used as a git hook with https://github.com/pre-commit/pre-commit
+
+- id: yapf
+ name: yapf
+ description: "A formatter for Python files."
+ entry: yapf
+ args: [-i] #inplace
+ language: python
+ types: [python]
diff --git a/.pre-commit-hooks.yml b/.pre-commit-hooks.yml
new file mode 100644
index 0000000..3eba1f2
--- /dev/null
+++ b/.pre-commit-hooks.yml
@@ -0,0 +1,9 @@
+# File configures YAPF to be used as a git hook with https://github.com/pre-commit/pre-commit
+
+- id: yapf
+ name: yapf
+ description: "A formatter for Python files."
+ entry: yapf
+ args: [-i] #inplace
+ language: python
+ types: [python]
diff --git a/.style.yapf b/.style.yapf
index 823a973..fdd0723 100644
--- a/.style.yapf
+++ b/.style.yapf
@@ -1,3 +1,2 @@
[style]
-# YAPF uses the chromium style
-based_on_style = chromium
+based_on_style = yapf
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1d90518..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-language: python
-
-python:
- - 2.7
- - 3.4
- - 3.5
- - 3.6
- - nightly
-
-matrix:
- allow_failures:
- - python: nightly
- include:
- - python: 2.7
- env: SCA=true
- - python: 3.5
- env: SCA=true
-
-install:
- - if [ -z "$SCA" ]; then pip install --quiet coveralls; else echo skip; fi
- - if [ -n "$SCA" ]; then python setup.py develop; else echo skip; fi
-
-script:
- - if [ -n "$SCA" ]; then yapf --diff --recursive . || exit; else echo skip; fi
- - if [ -z "$SCA" ]; then nosetests --with-coverage --cover-package=yapf; else echo skip; fi
-
-after_success:
- - coveralls
diff --git a/CHANGELOG b/CHANGELOG
index 4693f03..4e62520 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,7 +2,211 @@
# All notable changes to this project will be documented in this file.
# This project adheres to [Semantic Versioning](http://semver.org/).
-## [0.23.0] UNRELEASED
+## [0.32.0] 2021-12-26
+### 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.
+- Add CI via GitHub Actions.
+### Changes
+- Change tests to support "pytest".
+- Reformat so that "flake8" is happy.
+- 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
+ prescribed by PEP8.
+- Fixed the '...' token to be spaced after a colon.
+
+## [0.31.0] 2021-03-14
+### Added
+- Renamed 'master' brannch to 'main'.
+- Add 'BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES' to support setting
+ a custom number of blank lines between top-level imports and variable
+ definitions.
+- Ignore end of line `# copybara:` directives when checking line length.
+- Look at the 'pyproject.toml' file to see if it contains style information for
+ YAPF.
+### Changed
+- 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
+- Exclude directories on Windows.
+
+## [0.30.0] 2020-04-23
+### Added
+- Added `SPACES_AROUND_LIST_DELIMITERS`, `SPACES_AROUND_DICT_DELIMITERS`,
+ and `SPACES_AROUND_TUPLE_DELIMITERS` to add spaces after the opening-
+ and before the closing-delimiters for lists, dicts, and tuples.
+- Adds `FORCE_MULTILINE_DICT` knob to ensure dictionaries always split,
+ even when shorter than the max line length.
+- New knob `SPACE_INSIDE_BRACKETS` to add spaces inside brackets, braces, and
+ parentheses.
+- New knob `SPACES_AROUND_SUBSCRIPT_COLON` to add spaces around the subscript /
+ slice operator.
+### Changed
+- Renamed "chromium" style to "yapf". Chromium will now use PEP-8 directly.
+- `CONTINUATION_ALIGN_STYLE` with `FIXED` or `VALIGN-RIGHT` now works with
+ space indentation.
+### Fixed
+- Honor a disable directive at the end of a multiline comment.
+- Don't require splitting before comments in a list when
+ `SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES` is set. The knob is meant for
+ values, not comments, which may be associated with the current line.
+- Don't over-indent a parameter list when not needed. But make sure it is
+ properly indented so that it doesn't collide with the lines afterwards.
+- Don't split between two-word comparison operators: "is not", "not in", etc.
+
+## [0.29.0] 2019-11-28
+### Added
+- Add the `--quiet` flag to suppress output. The return code is 1 if there are
+ changes, similarly to the `--diff` flag.
+- Add the `indent_closing_brackets` option. This is the same as the
+ `dedent_closing_brackets` option except the brackets are indented the same
+ as the previous line.
+### Changed
+- Collect a parameter list into a single object. This allows us to track how a
+ parameter list is formatted, keeping state along the way. This helps when
+ supporting Python 3 type annotations.
+- Catch and report `UnicodeDecodeError` exceptions.
+- Improved description of .yapfignore syntax.
+### Fixed
+- Format subscript lists so that splits are essentially free after a comma.
+- Don't add a space between a string and its subscript.
+- Extend discovery of '.style.yapf' & 'setup.cfg' files to search the root
+ directory as well.
+- Make sure we have parameters before we start calculating penalties for
+ splitting them.
+- Indicate if a class/function is nested to ensure blank lines when needed.
+- Fix extra indentation in async-for else statement.
+- A parameter list with no elements shouldn't count as exceeding the column
+ limit.
+- When splitting all comma separated values, don't treat the ending bracket as
+ special.
+- The "no blank lines between nested classes or functions" knob should only
+ apply to the first nested class or function, not all of them.
+
+## [0.28.0] 2019-07-11
+### Added
+- New knob `SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES` is a variation on
+ `SPLIT_ALL_COMMA_SEPARATED_VALUES` in which, if a subexpression with a comma
+ fits in its starting line, then the subexpression is not split (thus avoiding
+ unnecessary splits).
+### Changed
+- Set `INDENT_DICTIONARY_VALUE` for Google style.
+- Set `JOIN_MULTIPLE_LINES = False` for Google style.
+### Fixed
+- `BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=False` wasn't honored because the
+ number of newlines was erroneously calculated beforehand.
+- Lambda expressions shouldn't have an increased split penalty applied to the
+ 'lambda' keyword. This prevents them from being properly formatted when they're
+ arguments to functions.
+- A comment with continuation markers (??) shouldn't mess with the lineno count.
+- Only emit unformatted if the "disable long line" is at the end of the line.
+ Otherwise we could mess up formatting for containers which have them
+ interspersed with code.
+- Fix a potential race condition by using the correct style for opening a file
+ which may not exist.
+
+## [0.27.0] 2019-04-07
+### Added
+- `SPLIT_BEFORE_ARITHMETIC_OPERATOR` splits before an arithmetic operator when
+ set. `SPLIT_PENALTY_ARITHMETIC_OPERATOR` allows you to set the split penalty
+ around arithmetic operators.
+### Changed
+- Catch lib2to3's "TokenError" exception and output a nicer message.
+### Fixed
+- Parse integer lists correctly, removing quotes if the list is within a
+ string.
+- Adjust the penalties of bitwise operands for '&' and '^', similar to '|'.
+- Avoid splitting after opening parens if SPLIT_BEFORE_FIRST_ARGUMENT is set
+ to False.
+- Adjust default SPLIT_PENALTY_AFTER_OPENING_BRACKET.
+- Re-enable removal of extra lines on the boundaries of formatted regions.
+- Adjust list splitting to avoid splitting before a dictionary element, because
+ those are likely to be split anyway. If we do split, it leads to horrible
+ looking code.
+- Dictionary arguments were broken in a recent version. It resulted in
+ unreadable formatting, where the remaining arguments were indented far more
+ than the dictionary. Fixed so that if the dictionary is the first argument in
+ a function call and doesn't fit on a single line, then it forces a split.
+- Improve the connectiveness between items in a list. This prevents random
+ splitting when it's not 100% necessary.
+- Don't remove a comment attached to a previous object just because it's part
+ of the "prefix" of a function/class node.
+
+## [0.26.0] 2019-02-08
+### Added
+- `ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS` allows us to split before
+ default / named assignments.
+- `ARITHMETIC_PRECEDENCE_INDICATION` removes spacing around binary operators
+ if they have higher precedence than other operators in the same expression.
+### Changed
+- `SPACES_BEFORE_COMMENT` can now be assigned to a specific value (standard
+ behavior) or a list of column values. When assigned to a list, trailing
+ comments will be horizontally aligned to the first column value within
+ the list that is greater than the maximum line length in the block.
+- Don't modify the vertical spacing of a line that has a comment "pylint:
+ disable=line-too-long". The line is expected to be too long.
+- improved `CONTINUATION_ALIGN_STYLE` to accept quoted or underline-separated
+ option value for passing option with command line arguments.
+### Fixed
+- When retrieving the opening bracket make sure that it's actually an opening
+ bracket.
+- Don't completely deny a lambda formatting if it goes over the column limit.
+ Split only if absolutely necessary.
+- Bump up penalty for splitting before a dot ('.').
+- Ignore pseudo tokens when calculating split penalties.
+- Increase the penalty for splitting before the first bit of a subscript.
+- Improve splitting before dictionary values. Look more closely to see if the
+ dictionary entry is a container. If so, then it's probably split over
+ multiple lines with the opening bracket on the same line as the key.
+ Therefore, we shouldn't enforce a split because of that.
+- Increase split penalty around exponent operator.
+- Correct spacing when using binary operators on strings with the
+ `NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS` option enabled.
+
+## [0.25.0] 2018-11-25
+### Added
+- Added `INDENT_BLANK_LINES` knob to select whether the blank lines are empty
+ or indented consistently with the current block.
+- Support additional file exclude patterns in .yapfignore file.
+### Fixed
+- Correctly determine if a scope is the last in line. It avoids a wrong
+ computation of the line end when determining if it must split after the
+ opening bracket with `DEDENT_CLOSING_BRACKETS` enabled.
+
+## [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
splits a list onto separate lines if the list is comma-terminated.
@@ -11,6 +215,10 @@
use lib2to3 to fail if called from YAPF.
- Change the exception message instead of creating a new one that's just a
clone.
+- Make sure not to reformat when a line is disabled even if the --lines option
+ is specified.
+- The "no spaces around operators" flag wasn't correctly converting strings to
+ sets. Changed the regexp to handle it better.
## [0.22.0] 2018-05-15
### Added
@@ -54,7 +262,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
@@ -477,7 +685,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.
@@ -505,7 +713,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/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 0b113c0..fa6cda0 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -27,12 +27,11 @@ use Github pull requests for this purpose.
YAPF coding style
-----------------
-YAPF follows the `Chromium Python Style Guide
-<https://www.chromium.org/chromium-os/python-style-guidelines>`_. It's the same
-as the Google Python Style guide with two exceptions:
+YAPF follows the `Google Python Style Guide
+<https://google.github.io/styleguide/pyguide.html>`_ with two exceptions:
- 2 spaces for indentation rather than 4.
-- CamelCase for function and method names rather than words_with_underscores.
+- CamelCase for function and method names rather than snake_case.
The rationale for this is that YAPF was initially developed at Google where
these two exceptions are still part of the internal Python style guide.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 62e2a5f..054ef26 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -13,3 +13,5 @@ Bill Wendling <morbo@google.com>
Eli Bendersky <eliben@google.com>
Sam Clegg <sbc@google.com>
Łukasz Langa <ambv@fb.com>
+Oleg Butuzov <butuzov@made.ua>
+Mauricio Herrera Cuadra <mauricio@arareko.net>
diff --git a/METADATA b/METADATA
index d97975c..f278228 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,13 @@
+name: "yapf"
+description:
+ "A formatter for Python files"
+
third_party {
+ url {
+ type: GIT
+ value: "https://github.com/google/yapf.git"
+ }
+ version: "v0.32.0"
+ last_upgrade_date { year: 2022 month: 11 day: 2 }
license_type: NOTICE
}
diff --git a/README.rst b/README.rst
index 19ef0c2..12286a9 100644
--- a/README.rst
+++ b/README.rst
@@ -6,12 +6,12 @@ YAPF
:target: https://badge.fury.io/py/yapf
:alt: PyPI version
-.. image:: https://travis-ci.org/google/yapf.svg?branch=master
- :target: https://travis-ci.org/google/yapf
+.. image:: https://github.com/google/yapf/actions/workflows/ci.yml/badge.svg
+ :target: https://github.com/google/yapf/actions
:alt: Build status
-.. image:: https://coveralls.io/repos/google/yapf/badge.svg?branch=master
- :target: https://coveralls.io/r/google/yapf?branch=master
+.. image:: https://coveralls.io/repos/google/yapf/badge.svg?branch=main
+ :target: https://coveralls.io/r/google/yapf?branch=main
:alt: Coverage status
@@ -23,21 +23,20 @@ are made to remove lint errors from code. This has some obvious limitations.
For instance, code that conforms to the PEP 8 guidelines may not be
reformatted. But it doesn't mean that the code looks good.
-YAPF takes a different approach. It's based off of 'clang-format', developed by
-Daniel Jasper. In essence, the algorithm takes the code and reformats it to the
-best formatting that conforms to the style guide, even if the original code
-didn't violate the style guide. The idea is also similar to the 'gofmt' tool for
-the Go programming language: end all holy wars about formatting - if the whole
-codebase of a project is simply piped through YAPF whenever modifications are
-made, the style remains consistent throughout the project and there's no point
-arguing about style in every code review.
+YAPF takes a different approach. It's based off of `'clang-format' <https://cl
+ang.llvm.org/docs/ClangFormat.html>`_, developed by Daniel Jasper. In essence,
+the algorithm takes the code and reformats it to the best formatting that
+conforms to the style guide, even if the original code didn't violate the
+style guide. The idea is also similar to the `'gofmt' <https://golang.org/cmd/
+gofmt/>`_ tool for the Go programming language: end all holy wars about
+formatting - if the whole codebase of a project is simply piped through YAPF
+whenever modifications are made, the style remains consistent throughout the
+project and there's no point arguing about style in every code review.
The ultimate goal is that the code YAPF produces is as good as the code that a
programmer would write if they were following the style guide. It takes away
some of the drudgery of maintaining your code.
-Try out YAPF with this `online demo <https://yapf.now.sh>`_.
-
.. footer::
YAPF is not an official Google product (experimental or otherwise), it is
@@ -114,10 +113,10 @@ Options::
--style STYLE specify formatting style: either a style name (for
example "pep8" or "google"), or the name of a file
with style settings. The default is pep8 unless a
- .style.yapf or setup.cfg file located in the same
- directory as the source or one of its parent
- directories (for stdin, the current directory is
- used).
+ .style.yapf or setup.cfg or pyproject.toml file
+ located in the same directory as the source or one of
+ its parent directories (for stdin, the current
+ directory is used).
--style-help show style settings and exit; this output can be saved
to .style.yapf to make your settings permanent
--no-local-style don't search for local style definition
@@ -136,6 +135,33 @@ If ``--diff`` is supplied, YAPF returns zero when no changes were necessary, non
otherwise (including program error). You can use this in a CI workflow to test that code
has been YAPF-formatted.
+---------------------------------------------
+Excluding files from formatting (.yapfignore or pyproject.toml)
+---------------------------------------------
+
+In addition to exclude patterns provided on commandline, YAPF looks for additional
+patterns specified in a file named ``.yapfignore`` or ``pyproject.toml`` located in the
+working directory from which YAPF is invoked.
+
+``.yapfignore``'s syntax is similar to UNIX's filename pattern matching::
+
+ * matches everything
+ ? matches any single character
+ [seq] matches any character in seq
+ [!seq] matches any character not in seq
+
+Note that no entry should begin with `./`.
+
+If you use ``pyproject.toml``, exclude patterns are specified by ``ignore_pattens`` key
+in ``[tool.yapfignore]`` section. For example:
+
+.. code-block:: ini
+
+ [tool.yapfignore]
+ ignore_patterns = [
+ "temp/**/*.py",
+ "temp2/*.py"
+ ]
Formatting style
================
@@ -159,26 +185,41 @@ with a ``[style]`` heading. For example:
split_before_logical_operator = true
The ``based_on_style`` setting determines which of the predefined styles this
-custom style is based on (think of it like subclassing).
+custom style is based on (think of it like subclassing). Four
+styles are predefined:
+
+- ``pep8`` (default)
+- ``google`` (based off of the `Google Python Style Guide`_)
+- ``yapf`` (for use with Google open source projects)
+- ``facebook``
+
+.. _`Google Python Style Guide`: https://github.com/google/styleguide/blob/gh-pages/pyguide.md
+
+See ``_STYLE_NAME_TO_FACTORY`` in style.py_ for details.
+
+.. _style.py: https://github.com/google/yapf/blob/main/yapf/yapflib/style.py
It's also possible to do the same on the command line with a dictionary. For
example:
.. code-block:: shell
- --style='{based_on_style: chromium, indent_width: 4}'
+ --style='{based_on_style: pep8, indent_width: 2}'
-This will take the ``chromium`` base style and modify it to have four space
+This will take the ``pep8`` base style and modify it to have two space
indentations.
YAPF will search for the formatting style in the following manner:
1. Specified on the command line
-2. In the `[style]` section of a `.style.yapf` file in either the current
+2. In the ``[style]`` section of a ``.style.yapf`` file in either the current
+ directory or one of its parent directories.
+3. In the ``[yapf]`` section of a ``setup.cfg`` file in either the current
directory or one of its parent directories.
-3. In the `[yapf]` section of a `setup.cfg` file in either the current
+4. In the ``[tool.yapf]`` section of a ``pyproject.toml`` file in either the current
directory or one of its parent directories.
-4. In the `~/.config/yapf/style` file in your home directory.
+5. In the ``[style]`` section of a ``~/.config/yapf/style`` file in your home
+ directory.
If none of those files are found, the default style is used (PEP8).
@@ -239,8 +280,11 @@ share several arguments which are described below:
>>> from yapf.yapflib.yapf_api import FormatCode # reformat a string of code
- >>> FormatCode("f ( a = 1, b = 2 )")
+ >>> formatted_code, changed = FormatCode("f ( a = 1, b = 2 )")
+ >>> formatted_code
'f(a=1, b=2)\n'
+ >>> changed
+ True
A ``style_config`` argument: Either a style name or a path to a file that contains
formatting style settings. If None is specified, use the default style
@@ -248,7 +292,7 @@ as set in ``style.DEFAULT_STYLE_FACTORY``.
.. code-block:: python
- >>> FormatCode("def g():\n return True", style_config='pep8')
+ >>> FormatCode("def g():\n return True", style_config='pep8')[0]
'def g():\n return True\n'
A ``lines`` argument: A list of tuples of lines (ints), [start, end],
@@ -258,15 +302,15 @@ than a whole file.
.. code-block:: python
- >>> FormatCode("def g( ):\n a=1\n b = 2\n return a==b", lines=[(1, 1), (2, 3)])
+ >>> FormatCode("def g( ):\n a=1\n b = 2\n return a==b", lines=[(1, 1), (2, 3)])[0]
'def g():\n a = 1\n b = 2\n return a==b\n'
A ``print_diff`` (bool): Instead of returning the reformatted source, return a
-diff that turns the formatted source into reformatter source.
+diff that turns the formatted source into reformatted source.
.. code-block:: python
- >>> print(FormatCode("a==b", filename="foo.py", print_diff=True))
+ >>> print(FormatCode("a==b", filename="foo.py", print_diff=True)[0])
--- foo.py (original)
+++ foo.py (reformatted)
@@ -1 +1 @@
@@ -285,19 +329,61 @@ the diff, the default is ``<unknown>``.
>>> print(open("foo.py").read()) # contents of file
a==b
- >>> FormatFile("foo.py")
- ('a == b\n', 'utf-8')
+ >>> reformatted_code, encoding, changed = FormatFile("foo.py")
+ >>> formatted_code
+ 'a == b\n'
+ >>> encoding
+ 'utf-8'
+ >>> changed
+ True
-The ``in-place`` argument saves the reformatted code back to the file:
+The ``in_place`` argument saves the reformatted code back to the file:
.. code-block:: python
- >>> FormatFile("foo.py", in_place=True)
+ >>> FormatFile("foo.py", in_place=True)[:2]
(None, 'utf-8')
>>> print(open("foo.py").read()) # contents of file (now fixed)
a == b
+Formatting diffs
+================
+
+Options::
+
+ usage: yapf-diff [-h] [-i] [-p NUM] [--regex PATTERN] [--iregex PATTERN][-v]
+ [--style STYLE] [--binary BINARY]
+
+ This script reads input from a unified diff and reformats all the changed
+ lines. This is useful to reformat all the lines touched by a specific patch.
+ Example usage for git/svn users:
+
+ git diff -U0 --no-color --relative HEAD^ | yapf-diff -i
+ svn diff --diff-cmd=diff -x-U0 | yapf-diff -p0 -i
+
+ It should be noted that the filename contained in the diff is used
+ unmodified to determine the source file to update. Users calling this script
+ directly should be careful to ensure that the path in the diff is correct
+ relative to the current working directory.
+
+ optional arguments:
+ -h, --help show this help message and exit
+ -i, --in-place apply edits to files instead of displaying a diff
+ -p NUM, --prefix NUM strip the smallest prefix containing P slashes
+ --regex PATTERN custom pattern selecting file paths to reformat
+ (case sensitive, overrides -iregex)
+ --iregex PATTERN custom pattern selecting file paths to reformat
+ (case insensitive, overridden by -regex)
+ -v, --verbose be more verbose, ineffective without -i
+ --style STYLE specify formatting style: either a style name (for
+ example "pep8" or "google"), or the name of a file
+ with style settings. The default is pep8 unless a
+ .style.yapf or setup.cfg or pyproject.toml file
+ located in the same directory as the source or one of
+ its parent directories (for stdin, the current
+ directory is used).
+ --binary BINARY location of binary to use for yapf
Knobs
=====
@@ -319,9 +405,35 @@ Knobs
value,
}
+``ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS``
+ Allow splitting before a default / named assignment in an argument list.
+
``ALLOW_SPLIT_BEFORE_DICT_VALUE``
Allow splits before the dictionary value.
+``ARITHMETIC_PRECEDENCE_INDICATION``
+ Let spacing indicate operator precedence. For example:
+
+ .. code-block:: python
+
+ a = 1 * 2 + 3 / 4
+ b = 1 / 2 - 3 * 4
+ c = (1 + 2) * (3 - 4)
+ d = (1 - 2) / (3 + 4)
+ e = 1 * 2 - 3
+ f = 1 + 2 + 3 + 4
+
+ will be formatted as follows to indicate precedence:
+
+ .. code-block:: python
+
+ a = 1*2 + 3/4
+ b = 1/2 - 3*4
+ c = (1+2) * (3-4)
+ d = (1-2) / (3+4)
+ e = 1*2 - 3
+ f = 1 + 2 + 3 + 4
+
``BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF``
Insert a blank line before a ``def`` or ``class`` immediately nested within
another ``def`` or ``class``. For example:
@@ -352,9 +464,14 @@ Knobs
class Bar:
pass
+``BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES``
+ Sets the number of desired blank lines between top-level imports and
+ variable definitions. Useful for compatibility with tools like isort.
+
``COALESCE_BRACKETS``
Do not split consecutive brackets. Only relevant when
- ``DEDENT_CLOSING_BRACKETS`` is set. For example:
+ ``DEDENT_CLOSING_BRACKETS`` or ``INDENT_CLOSING_BRACKETS``
+ is set. For example:
.. code-block:: python
@@ -381,16 +498,14 @@ Knobs
``CONTINUATION_ALIGN_STYLE``
The style for continuation alignment. Possible values are:
- - SPACE: Use spaces for continuation alignment. This is default behavior.
- - FIXED: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns
- (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs) for continuation
- alignment.
- - VALIGN-RIGHT: Vertically align continuation lines with indent characters.
- Slightly right (one more indent character) if cannot vertically align
- continuation lines with indent characters.
-
- For options ``FIXED``, and ``VALIGN-RIGHT`` are only available when
- ``USE_TABS`` is enabled.
+ - ``SPACE``: Use spaces for continuation alignment. This is default
+ behavior.
+ - ``FIXED``: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns
+ (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or CONTINUATION_INDENT_WIDTH
+ spaces) for continuation alignment.
+ - ``VALIGN-RIGHT``: Vertically align continuation lines to multiple of
+ INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if cannot
+ vertically align continuation lines with indent characters.
``CONTINUATION_INDENT_WIDTH``
Indent width used for line continuations.
@@ -422,6 +537,10 @@ Knobs
``EACH_DICT_ENTRY_ON_SEPARATE_LINE``
Place each dictionary entry onto its own line.
+``FORCE_MULTILINE_DICT``
+ Respect EACH_DICT_ENTRY_ON_SEPARATE_LINE even if the line is shorter than
+ COLUMN_LIMIT.
+
``I18N_COMMENT``
The regex for an internationalization comment. The presence of this comment
stops reformatting of that line, because the comments are required to be
@@ -448,12 +567,32 @@ Knobs
``INDENT_WIDTH``
The number of columns to use for indentation.
+``INDENT_BLANK_LINES``
+ Set to ``True`` to prefer indented blank lines rather than empty
+
+``INDENT_CLOSING_BRACKETS``
+ Put closing brackets on a separate line, indented, if the bracketed
+ expression can't fit in a single line. Applies to all kinds of brackets,
+ including function definitions and calls. For example:
+
+ .. code-block:: python
+
+ config = {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ } # <--- this bracket is indented and on a separate line
+
+ time_series = self.remote_client.query_entity_counters(
+ entity='dev3246.region1',
+ key='dns.query_latency_tcp',
+ transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
+ start_ts=now()-timedelta(days=3),
+ end_ts=now(),
+ ) # <--- this bracket is indented and on a separate line
+
``JOIN_MULTIPLE_LINES``
Join short lines into one line. E.g., single line ``if`` statements.
-``SPACES_AROUND_POWER_OPERATOR``
- Set to ``True`` to prefer using spaces around ``**``.
-
``NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS``
Do not include spaces around selected binary operators. For example:
@@ -461,36 +600,163 @@ Knobs
1 + 2 * 3 - 4 / 5
- will be formatted as follows when configured with ``*,/``:
+ will be formatted as follows when configured with ``*``, ``/``:
.. code-block:: python
1 + 2*3 - 4/5
+``SPACES_AROUND_POWER_OPERATOR``
+ Set to ``True`` to prefer using spaces around ``**``.
+
``SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN``
Set to ``True`` to prefer spaces around the assignment operator for default
or keyword arguments.
+``SPACES_AROUND_DICT_DELIMITERS``
+ Adds a space after the opening '{' and before the ending '}' dict delimiters.
+
+ .. code-block:: python
+
+ {1: 2}
+
+ will be formatted as:
+
+ .. code-block:: python
+
+ { 1: 2 }
+
+``SPACES_AROUND_LIST_DELIMITERS``
+ Adds a space after the opening '[' and before the ending ']' list delimiters.
+
+ .. code-block:: python
+
+ [1, 2]
+
+ will be formatted as:
+
+ .. code-block:: python
+
+ [ 1, 2 ]
+
+``SPACES_AROUND_SUBSCRIPT_COLON``
+ Use spaces around the subscript / slice operator. For example:
+
+ .. code-block:: python
+
+ my_list[1 : 10 : 2]
+
+``SPACES_AROUND_TUPLE_DELIMITERS``
+ Adds a space after the opening '(' and before the ending ')' tuple delimiters.
+
+ .. code-block:: python
+
+ (1, 2, 3)
+
+ will be formatted as:
+
+ .. code-block:: python
+
+ ( 1, 2, 3 )
+
``SPACES_BEFORE_COMMENT``
The number of spaces required before a trailing comment.
+ This can be a single value (representing the number of spaces
+ before each trailing comment) or list of of values (representing
+ alignment column values; trailing comments within a block will
+ be aligned to the first column value that is greater than the maximum
+ line length within the block). For example:
+
+ With ``spaces_before_comment=5``:
+
+ .. code-block:: python
+
+ 1 + 1 # Adding values
+
+ will be formatted as:
+
+ .. code-block:: python
+
+ 1 + 1 # Adding values <-- 5 spaces between the end of the statement and comment
+
+ With ``spaces_before_comment=15, 20``:
+
+ .. code-block:: python
+
+ 1 + 1 # Adding values
+ two + two # More adding
+
+ longer_statement # This is a longer statement
+ short # This is a shorter statement
+
+ a_very_long_statement_that_extends_beyond_the_final_column # Comment
+ short # This is a shorter statement
+
+ will be formatted as:
+
+ .. code-block:: python
+
+ 1 + 1 # Adding values <-- end of line comments in block aligned to col 15
+ two + two # More adding
+
+ longer_statement # This is a longer statement <-- end of line comments in block aligned to col 20
+ short # This is a shorter statement
+
+ a_very_long_statement_that_extends_beyond_the_final_column # Comment <-- the end of line comments are aligned based on the line length
+ short # This is a shorter statement
``SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET``
Insert a space between the ending comma and closing bracket of a list, etc.
+``SPACE_INSIDE_BRACKETS``
+ Use spaces inside brackets, braces, and parentheses. For example:
+
+ .. code-block:: python
+
+ method_call( 1 )
+ my_dict[ 3 ][ 1 ][ get_index( *args, **kwargs ) ]
+ my_set = { 1, 2, 3 }
+
``SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED``
Split before arguments if the argument list is terminated by a comma.
``SPLIT_ALL_COMMA_SEPARATED_VALUES``
- If a comma separated list (dict, list, tuple, or function def) is on a
- line that is too long, split such that all elements are on a single line.
+ If a comma separated list (``dict``, ``list``, ``tuple``, or function
+ ``def``) is on a line that is too long, split such that each element
+ is on a separate line.
+
+``SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES``
+ Variation on ``SPLIT_ALL_COMMA_SEPARATED_VALUES`` in which, if a
+ subexpression with a comma fits in its starting line, then the
+ subexpression is not split. This avoids splits like the one for
+ ``b`` in this code:
+
+ .. code-block:: python
+
+ abcdef(
+ aReallyLongThing: int,
+ b: [Int,
+ Int])
+
+ With the new knob this is split as:
+
+ .. code-block:: python
+
+ abcdef(
+ aReallyLongThing: int,
+ b: [Int, Int])
``SPLIT_BEFORE_BITWISE_OPERATOR``
Set to ``True`` to prefer splitting before ``&``, ``|`` or ``^`` rather
than after.
+``SPLIT_BEFORE_ARITHMETIC_OPERATOR``
+ Set to ``True`` to prefer splitting before ``+``, ``-``, ``*``, ``/``, ``//``,
+ or ``@`` rather than after.
+
``SPLIT_BEFORE_CLOSING_BRACKET``
- Split before the closing bracket if a list or dict literal doesn't fit on
- a single line.
+ Split before the closing bracket if a ``list`` or ``dict`` literal doesn't
+ fit on a single line.
``SPLIT_BEFORE_DICT_SET_GENERATOR``
Split before a dictionary or set generator (comp_for). For example, note
@@ -503,6 +769,20 @@ Knobs
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.
@@ -520,8 +800,8 @@ Knobs
``SPLIT_COMPLEX_COMPREHENSION``
For list comprehensions and generator expressions with multiple clauses
- (e.g multiple "for" calls, "if" filter expressions) and which need to be
- reflowed, split each clause onto its own line. For example:
+ (e.g multiple ``for`` calls, ``if`` filter expressions) and which need to
+ be reflowed, split each clause onto its own line. For example:
.. code-block:: python
@@ -545,6 +825,10 @@ Knobs
``SPLIT_PENALTY_AFTER_UNARY_OPERATOR``
The penalty for splitting the line after a unary operator.
+``SPLIT_PENALTY_ARITHMETIC_OPERATOR``
+ The penalty of splitting the line around the ``+``, ``-``, ``*``, ``/``,
+ ``//``, ``%``, and ``@`` operators.
+
``SPLIT_PENALTY_BEFORE_IF_EXPR``
The penalty for splitting right before an ``if`` expression.
@@ -559,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``
@@ -645,6 +929,31 @@ Can I Use YAPF In My Program?
Please do! YAPF was designed to be used as a library as well as a command line
tool. This means that a tool or IDE plugin is free to use YAPF.
+-----------------------------------------
+I still get non Pep8 compliant code! Why?
+-----------------------------------------
+
+YAPF tries very hard to be fully PEP 8 compliant. However, it is paramount
+to not risk altering the semantics of your code. Thus, YAPF tries to be as
+safe as possible and does not change the token stream
+(e.g., by adding parentheses).
+All these cases however, can be easily fixed manually. For instance,
+
+.. code-block:: python
+
+ from my_package import my_function_1, my_function_2, my_function_3, my_function_4, my_function_5
+
+ FOO = my_variable_1 + my_variable_2 + my_variable_3 + my_variable_4 + my_variable_5 + my_variable_6 + my_variable_7 + my_variable_8
+
+won't be split, but you can easily get it right by just adding parentheses:
+
+.. code-block:: python
+
+ from my_package import (my_function_1, my_function_2, my_function_3,
+ my_function_4, my_function_5)
+
+ FOO = (my_variable_1 + my_variable_2 + my_variable_3 + my_variable_4 +
+ my_variable_5 + my_variable_6 + my_variable_7 + my_variable_8)
Gory Details
============
@@ -653,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
diff --git a/plugins/README.rst b/plugins/README.rst
index f7657cc..b87bb2d 100644
--- a/plugins/README.rst
+++ b/plugins/README.rst
@@ -65,7 +65,7 @@ directory:
.. code-block:: bash
# From the root of your git project.
- curl -o pre-commit.sh https://raw.githubusercontent.com/google/yapf/master/plugins/pre-commit.sh
+ curl -o pre-commit.sh https://raw.githubusercontent.com/google/yapf/main/plugins/pre-commit.sh
chmod a+x pre-commit.sh
mv pre-commit.sh .git/hooks/pre-commit
diff --git a/plugins/pre-commit.sh b/plugins/pre-commit.sh
index 896f0ff..3e68739 100644..100755
--- a/plugins/pre-commit.sh
+++ b/plugins/pre-commit.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
# Git pre-commit hook to check staged Python files for formatting issues with
# yapf.
@@ -21,15 +21,16 @@
# is used.
# Find all staged Python files, and exit early if there aren't any.
-PYTHON_FILES=(`git diff --name-only --cached --diff-filter=AM | \
- grep --color=never '.py$'`)
-if [ ! "$PYTHON_FILES" ]; then
+PYTHON_FILES=()
+while IFS=$'\n' read -r line; do PYTHON_FILES+=("$line"); done \
+ < <(git diff --name-only --cached --diff-filter=AM | grep --color=never '.py$')
+if [ ${#PYTHON_FILES[@]} -eq 0 ]; then
exit 0
fi
########## PIP VERSION #############
# Verify that yapf is installed; if not, warn and exit.
-if [ -z $(which yapf) ]; then
+if ! command -v yapf >/dev/null; then
echo 'yapf not on path; can not format. Please install yapf:'
echo ' pip install yapf'
exit 2
@@ -37,7 +38,7 @@ fi
######### END PIP VERSION ##########
########## PIPENV VERSION ##########
-# if [ -z $(pipenv run which yapf) ]; then
+# if ! pipenv run yapf --version 2>/dev/null 2>&1; then
# echo 'yapf not on path; can not format. Please install yapf:'
# echo ' pipenv install yapf'
# exit 2
@@ -46,16 +47,14 @@ fi
# Check for unstaged changes to files in the index.
-CHANGED_FILES=(`git diff --name-only ${PYTHON_FILES[@]}`)
-if [ "$CHANGED_FILES" ]; then
+CHANGED_FILES=()
+while IFS=$'\n' read -r line; do CHANGED_FILES+=("$line"); done \
+ < <(git diff --name-only "${PYTHON_FILES[@]}")
+if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
echo 'You have unstaged changes to some files in your commit; skipping '
echo 'auto-format. Please stage, stash, or revert these changes. You may '
echo 'find `git stash -k` helpful here.'
- echo
- echo 'Files with unstaged changes:'
- for file in ${CHANGED_FILES[@]}; do
- echo " $file"
- done
+ echo 'Files with unstaged changes:' "${CHANGED_FILES[@]}"
exit 1
fi
@@ -64,22 +63,20 @@ fi
echo 'Formatting staged Python files . . .'
########## PIP VERSION #############
-yapf -i -r ${PYTHON_FILES[@]}
+yapf -i -r "${PYTHON_FILES[@]}"
######### END PIP VERSION ##########
########## PIPENV VERSION ##########
-# pipenv run yapf -i -r ${PYTHON_FILES[@]}
+# pipenv run yapf -i -r "${PYTHON_FILES[@]}"
###### END PIPENV VERSION ##########
-CHANGED_FILES=(`git diff --name-only ${PYTHON_FILES[@]}`)
-if [ "$CHANGED_FILES" ]; then
+CHANGED_FILES=()
+while IFS=$'\n' read -r line; do CHANGED_FILES+=("$line"); done \
+ < <(git diff --name-only "${PYTHON_FILES[@]}")
+if [ ${#CHANGED_FILES[@]} -gt 0 ]; then
echo 'Reformatted staged files. Please review and stage the changes.'
- echo
- echo 'Files updated:'
- for file in ${CHANGED_FILES[@]}; do
- echo " $file"
- done
+ echo 'Files updated: ' "${CHANGED_FILES[@]}"
exit 1
else
exit 0
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/setup.py b/setup.py
index 21e9470..70e57da 100644
--- a/setup.py
+++ b/setup.py
@@ -17,7 +17,7 @@ import codecs
import sys
import unittest
-from setuptools import setup, Command
+from setuptools import find_packages, setup, Command
import yapf
@@ -49,7 +49,7 @@ with codecs.open('README.rst', 'r', 'utf-8') as fd:
author='Google Inc.',
maintainer='Bill Wendling',
maintainer_email='morbo@google.com',
- packages=['yapf', 'yapf.yapflib', 'yapftests'],
+ packages=find_packages('.'),
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',
@@ -65,7 +65,10 @@ with codecs.open('README.rst', 'r', 'utf-8') as fd:
'Topic :: Software Development :: Quality Assurance',
],
entry_points={
- 'console_scripts': ['yapf = yapf:run_main'],
+ 'console_scripts': [
+ 'yapf = yapf:run_main',
+ 'yapf-diff = yapf.third_party.yapf_diff.yapf_diff:main',
+ ],
},
cmdclass={
'test': RunTests,
diff --git a/tox.ini b/tox.ini
index dca30d2..f42b884 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist=py27,py34,py35,py36
+envlist=py27,py34,py35,py36,py37,py38
[testenv]
commands=
diff --git a/yapf/__init__.py b/yapf/__init__.py
index 22ab014..0c2fb95 100644
--- a/yapf/__init__.py
+++ b/yapf/__init__.py
@@ -38,7 +38,7 @@ from yapf.yapflib import py3compat
from yapf.yapflib import style
from yapf.yapflib import yapf_api
-__version__ = '0.22.0'
+__version__ = '0.32.0'
def main(argv):
@@ -55,98 +55,12 @@ def main(argv):
Raises:
YapfError: if none of the supplied files were Python files.
"""
- parser = argparse.ArgumentParser(description='Formatter for Python code.')
- parser.add_argument(
- '-v',
- '--version',
- action='store_true',
- help='show version number and exit')
-
- diff_inplace_group = parser.add_mutually_exclusive_group()
- diff_inplace_group.add_argument(
- '-d',
- '--diff',
- action='store_true',
- help='print the diff for the fixed source')
- diff_inplace_group.add_argument(
- '-i',
- '--in-place',
- action='store_true',
- help='make changes to files in place')
-
- lines_recursive_group = parser.add_mutually_exclusive_group()
- lines_recursive_group.add_argument(
- '-r',
- '--recursive',
- action='store_true',
- help='run recursively over directories')
- lines_recursive_group.add_argument(
- '-l',
- '--lines',
- metavar='START-END',
- action='append',
- default=None,
- help='range of lines to reformat, one-based')
-
- parser.add_argument(
- '-e',
- '--exclude',
- metavar='PATTERN',
- action='append',
- default=None,
- help='patterns for files to exclude from formatting')
- parser.add_argument(
- '--style',
- action='store',
- help=('specify formatting style: either a style name (for example "pep8" '
- 'or "google"), or the name of a file with style settings. The '
- 'default is pep8 unless a %s or %s file located in the same '
- 'directory as the source or one of its parent directories '
- '(for stdin, the current directory is used).' %
- (style.LOCAL_STYLE, style.SETUP_CONFIG)))
- parser.add_argument(
- '--style-help',
- action='store_true',
- help=('show style settings and exit; this output can be '
- 'saved to .style.yapf to make your settings '
- 'permanent'))
- parser.add_argument(
- '--no-local-style',
- action='store_true',
- help="don't search for local style definition")
- parser.add_argument('--verify', action='store_true', help=argparse.SUPPRESS)
- parser.add_argument(
- '-p',
- '--parallel',
- action='store_true',
- help=('Run yapf in parallel when formatting multiple files. Requires '
- 'concurrent.futures in Python 2.X'))
- parser.add_argument(
- '-vv',
- '--verbose',
- action='store_true',
- help='Print out file names while processing')
-
- parser.add_argument(
- 'files', nargs='*', help='Reads from stdin when no files are specified.')
+ parser = _BuildParser()
args = parser.parse_args(argv[1:])
-
- if args.version:
- print('yapf {}'.format(__version__))
- return 0
-
style_config = args.style
if args.style_help:
- if style_config is None and not args.no_local_style:
- style_config = file_resources.GetDefaultStyleForDir(os.getcwd())
- style.SetGlobalStyle(style.CreateStyleFromConfig(style_config))
- print('[style]')
- 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='')
- print()
+ _PrintHelp(args)
return 0
if args.lines and len(args.files) > 1:
@@ -161,7 +75,9 @@ def main(argv):
original_source = []
while True:
- if sys.stdin.closed:
+ # Test that sys.stdin has the "closed" attribute. When using pytest, it
+ # co-opts sys.stdin, which makes the "main_tests.py" fail. This is gross.
+ if hasattr(sys.stdin, "closed") and sys.stdin.closed:
break
try:
# Use 'raw_input' instead of 'sys.stdin.read', because otherwise the
@@ -171,24 +87,39 @@ def main(argv):
original_source.append(py3compat.raw_input())
except EOFError:
break
+ except KeyboardInterrupt:
+ return 1
if style_config is None and not args.no_local_style:
style_config = file_resources.GetDefaultStyleForDir(os.getcwd())
source = [line.rstrip() for line in original_source]
- reformatted_source, _ = yapf_api.FormatCode(
- py3compat.unicode('\n'.join(source) + '\n'),
- filename='<stdin>',
- style_config=style_config,
- lines=lines,
- verify=args.verify)
+ source[0] = py3compat.removeBOM(source[0])
+
+ try:
+ reformatted_source, _ = yapf_api.FormatCode(
+ py3compat.unicode('\n'.join(source) + '\n'),
+ filename='<stdin>',
+ style_config=style_config,
+ lines=lines,
+ verify=args.verify)
+ except errors.YapfError:
+ raise
+ except Exception as e:
+ raise errors.YapfError(errors.FormatErrorMsg(e))
+
file_resources.WriteReformattedCode('<stdout>', reformatted_source)
return 0
+ # Get additional exclude patterns from ignorefile
+ exclude_patterns_from_ignore_file = file_resources.GetExcludePatternsForDir(
+ os.getcwd())
+
files = file_resources.GetCommandLineFiles(args.files, args.recursive,
- args.exclude)
+ (args.exclude or []) +
+ exclude_patterns_from_ignore_file)
if not files:
- raise errors.YapfError('Input filenames did not match any python files')
+ raise errors.YapfError('input filenames did not match any python files')
changed = FormatFiles(
files,
@@ -199,8 +130,26 @@ def main(argv):
print_diff=args.diff,
verify=args.verify,
parallel=args.parallel,
+ quiet=args.quiet,
verbose=args.verbose)
- return 1 if changed and args.diff else 0
+ return 1 if changed and (args.diff or args.quiet) else 0
+
+
+def _PrintHelp(args):
+ """Prints the help menu."""
+
+ if args.style is None and not args.no_local_style:
+ args.style = file_resources.GetDefaultStyleForDir(os.getcwd())
+ style.SetGlobalStyle(style.CreateStyleFromConfig(args.style))
+ print('[style]')
+ for option, docstring in sorted(style.Help().items()):
+ for line in docstring.splitlines():
+ print('#', line and ' ' or '', line, sep='')
+ option_value = style.Get(option)
+ if isinstance(option_value, (set, list)):
+ option_value = ', '.join(map(str, option_value))
+ print(option.lower(), '=', option_value, sep='')
+ print()
def FormatFiles(filenames,
@@ -211,6 +160,7 @@ def FormatFiles(filenames,
print_diff=False,
verify=False,
parallel=False,
+ quiet=False,
verbose=False):
"""Format a list of files.
@@ -228,6 +178,7 @@ def FormatFiles(filenames,
diff that turns the formatted source into reformatter source.
verify: (bool) True if reformatted code should be verified for syntax.
parallel: (bool) True if should format multiple files in parallel.
+ quiet: (bool) True if should output nothing.
verbose: (bool) True if should print out filenames while processing.
Returns:
@@ -241,15 +192,15 @@ def FormatFiles(filenames,
with concurrent.futures.ProcessPoolExecutor(workers) as executor:
future_formats = [
executor.submit(_FormatFile, filename, lines, style_config,
- no_local_style, in_place, print_diff, verify, verbose)
- for filename in filenames
+ no_local_style, in_place, print_diff, verify, quiet,
+ verbose) for filename in filenames
]
for future in concurrent.futures.as_completed(future_formats):
changed |= future.result()
else:
for filename in filenames:
changed |= _FormatFile(filename, lines, style_config, no_local_style,
- in_place, print_diff, verify, verbose)
+ in_place, print_diff, verify, quiet, verbose)
return changed
@@ -260,12 +211,16 @@ def _FormatFile(filename,
in_place=False,
print_diff=False,
verify=False,
+ quiet=False,
verbose=False):
- if verbose:
+ """Format an individual file."""
+ if verbose and not quiet:
print('Reformatting %s' % filename)
+
if style_config is None and not no_local_style:
style_config = file_resources.GetDefaultStyleForDir(
os.path.dirname(filename))
+
try:
reformatted_code, encoding, has_change = yapf_api.FormatFile(
filename,
@@ -275,13 +230,15 @@ def _FormatFile(filename,
print_diff=print_diff,
verify=verify,
logger=logging.warning)
- if not in_place and reformatted_code:
- file_resources.WriteReformattedCode(filename, reformatted_code, encoding,
- in_place)
- return has_change
- except SyntaxError as e:
- e.filename = filename
+ except errors.YapfError:
raise
+ except Exception as e:
+ raise errors.YapfError(errors.FormatErrorMsg(e))
+
+ if not in_place and not quiet and reformatted_code:
+ file_resources.WriteReformattedCode(filename, reformatted_code, encoding,
+ in_place)
+ return has_change
def _GetLines(line_strings):
@@ -304,11 +261,100 @@ def _GetLines(line_strings):
if line[0] < 1:
raise errors.YapfError('invalid start of line range: %r' % line)
if line[0] > line[1]:
- raise errors.YapfError('end comes before start in line range: %r', line)
+ raise errors.YapfError('end comes before start in line range: %r' % line)
lines.append(tuple(line))
return lines
+def _BuildParser():
+ """Constructs the parser for the command line arguments.
+
+ Returns:
+ An ArgumentParser instance for the CLI.
+ """
+ parser = argparse.ArgumentParser(
+ prog='yapf', description='Formatter for Python code.')
+ parser.add_argument(
+ '-v',
+ '--version',
+ action='version',
+ version='%(prog)s {}'.format(__version__))
+
+ diff_inplace_quiet_group = parser.add_mutually_exclusive_group()
+ diff_inplace_quiet_group.add_argument(
+ '-d',
+ '--diff',
+ action='store_true',
+ help='print the diff for the fixed source')
+ diff_inplace_quiet_group.add_argument(
+ '-i',
+ '--in-place',
+ action='store_true',
+ help='make changes to files in place')
+ diff_inplace_quiet_group.add_argument(
+ '-q',
+ '--quiet',
+ action='store_true',
+ help='output nothing and set return value')
+
+ lines_recursive_group = parser.add_mutually_exclusive_group()
+ lines_recursive_group.add_argument(
+ '-r',
+ '--recursive',
+ action='store_true',
+ help='run recursively over directories')
+ lines_recursive_group.add_argument(
+ '-l',
+ '--lines',
+ metavar='START-END',
+ action='append',
+ default=None,
+ help='range of lines to reformat, one-based')
+
+ parser.add_argument(
+ '-e',
+ '--exclude',
+ metavar='PATTERN',
+ action='append',
+ default=None,
+ help='patterns for files to exclude from formatting')
+ parser.add_argument(
+ '--style',
+ action='store',
+ help=('specify formatting style: either a style name (for example "pep8" '
+ 'or "google"), or the name of a file with style settings. The '
+ 'default is pep8 unless a %s or %s or %s file located in the same '
+ 'directory as the source or one of its parent directories '
+ '(for stdin, the current directory is used).' %
+ (style.LOCAL_STYLE, style.SETUP_CONFIG, style.PYPROJECT_TOML)))
+ parser.add_argument(
+ '--style-help',
+ action='store_true',
+ help=('show style settings and exit; this output can be '
+ 'saved to .style.yapf to make your settings '
+ 'permanent'))
+ parser.add_argument(
+ '--no-local-style',
+ action='store_true',
+ help="don't search for local style definition")
+ parser.add_argument('--verify', action='store_true', help=argparse.SUPPRESS)
+ parser.add_argument(
+ '-p',
+ '--parallel',
+ action='store_true',
+ help=('run yapf in parallel when formatting multiple files. Requires '
+ 'concurrent.futures in Python 2.X'))
+ parser.add_argument(
+ '-vv',
+ '--verbose',
+ action='store_true',
+ help='print out file names while processing')
+
+ parser.add_argument(
+ 'files', nargs='*', help='reads from stdin when no files are specified.')
+ return parser
+
+
def run_main(): # pylint: disable=invalid-name
try:
sys.exit(main(sys.argv))
diff --git a/yapf/third_party/__init__.py b/yapf/third_party/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/yapf/third_party/__init__.py
diff --git a/yapf/third_party/yapf_diff/LICENSE b/yapf/third_party/yapf_diff/LICENSE
new file mode 100644
index 0000000..f9dc506
--- /dev/null
+++ b/yapf/third_party/yapf_diff/LICENSE
@@ -0,0 +1,219 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ 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.
+
+
+--- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
diff --git a/yapf/third_party/yapf_diff/__init__.py b/yapf/third_party/yapf_diff/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/yapf/third_party/yapf_diff/__init__.py
diff --git a/yapf/third_party/yapf_diff/yapf_diff.py b/yapf/third_party/yapf_diff/yapf_diff.py
new file mode 100644
index 0000000..810a6a2
--- /dev/null
+++ b/yapf/third_party/yapf_diff/yapf_diff.py
@@ -0,0 +1,145 @@
+# Modified copy of clang-format-diff.py that works with yapf.
+#
+# Licensed under the Apache License, Version 2.0 (the "License") with LLVM
+# Exceptions; you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://llvm.org/LICENSE.txt
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+"""
+This script reads input from a unified diff and reformats all the changed
+lines. This is useful to reformat all the lines touched by a specific patch.
+Example usage for git/svn users:
+
+ git diff -U0 --no-color --relative HEAD^ | yapf-diff -i
+ svn diff --diff-cmd=diff -x-U0 | yapf-diff -p0 -i
+
+It should be noted that the filename contained in the diff is used unmodified
+to determine the source file to update. Users calling this script directly
+should be careful to ensure that the path in the diff is correct relative to the
+current working directory.
+"""
+from __future__ import absolute_import, division, print_function
+
+import argparse
+import difflib
+import re
+import subprocess
+import sys
+
+if sys.version_info.major >= 3:
+ from io import StringIO
+else:
+ from io import BytesIO as StringIO
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument(
+ '-i',
+ '--in-place',
+ action='store_true',
+ default=False,
+ help='apply edits to files instead of displaying a diff')
+ parser.add_argument(
+ '-p',
+ '--prefix',
+ metavar='NUM',
+ default=1,
+ help='strip the smallest prefix containing P slashes')
+ parser.add_argument(
+ '--regex',
+ metavar='PATTERN',
+ default=None,
+ help='custom pattern selecting file paths to reformat '
+ '(case sensitive, overrides -iregex)')
+ parser.add_argument(
+ '--iregex',
+ metavar='PATTERN',
+ default=r'.*\.(py)',
+ help='custom pattern selecting file paths to reformat '
+ '(case insensitive, overridden by -regex)')
+ parser.add_argument(
+ '-v',
+ '--verbose',
+ action='store_true',
+ help='be more verbose, ineffective without -i')
+ parser.add_argument(
+ '--style',
+ help='specify formatting style: either a style name (for '
+ 'example "pep8" or "google"), or the name of a file with '
+ 'style settings. The default is pep8 unless a '
+ '.style.yapf or setup.cfg file located in one of the '
+ 'parent directories of the source file (or current '
+ 'directory for stdin)')
+ parser.add_argument(
+ '--binary', default='yapf', help='location of binary to use for yapf')
+ args = parser.parse_args()
+
+ # Extract changed lines for each file.
+ filename = None
+ lines_by_file = {}
+ for line in sys.stdin:
+ match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.prefix, line)
+ if match:
+ filename = match.group(2)
+ if filename is None:
+ continue
+
+ if args.regex is not None:
+ if not re.match('^%s$' % args.regex, filename):
+ continue
+ elif not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
+ continue
+
+ match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
+ if match:
+ start_line = int(match.group(1))
+ line_count = 1
+ if match.group(3):
+ line_count = int(match.group(3))
+ if line_count == 0:
+ continue
+ end_line = start_line + line_count - 1
+ lines_by_file.setdefault(filename, []).extend(
+ ['--lines', str(start_line) + '-' + str(end_line)])
+
+ # Reformat files containing changes in place.
+ for filename, lines in lines_by_file.items():
+ if args.in_place and args.verbose:
+ print('Formatting {}'.format(filename))
+ command = [args.binary, filename]
+ if args.in_place:
+ command.append('-i')
+ command.extend(lines)
+ if args.style:
+ command.extend(['--style', args.style])
+ p = subprocess.Popen(
+ command,
+ stdout=subprocess.PIPE,
+ stderr=None,
+ stdin=subprocess.PIPE,
+ universal_newlines=True)
+ stdout, stderr = p.communicate()
+ if p.returncode != 0:
+ sys.exit(p.returncode)
+
+ if not args.in_place:
+ with open(filename) as f:
+ code = f.readlines()
+ formatted_code = StringIO(stdout).readlines()
+ diff = difflib.unified_diff(code, formatted_code, filename, filename,
+ '(before formatting)', '(after formatting)')
+ diff_string = ''.join(diff)
+ if len(diff_string) > 0:
+ sys.stdout.write(diff_string)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/yapf/yapflib/blank_line_calculator.py b/yapf/yapflib/blank_line_calculator.py
index c239ee7..3d78646 100644
--- a/yapf/yapflib/blank_line_calculator.py
+++ b/yapf/yapflib/blank_line_calculator.py
@@ -22,6 +22,8 @@ Annotations:
newlines: The number of newlines required before the node.
"""
+from lib2to3.pgen2 import token as grammar_token
+
from yapf.yapflib import py3compat
from yapf.yapflib import pytree_utils
from yapf.yapflib import pytree_visitor
@@ -64,15 +66,15 @@ class _BlankLineCalculator(pytree_visitor.PyTreeVisitor):
def Visit_simple_stmt(self, node): # pylint: disable=invalid-name
self.DefaultNodeVisit(node)
- if pytree_utils.NodeName(node.children[0]) == 'COMMENT':
+ if node.children[0].type == grammar_token.COMMENT:
self.last_comment_lineno = node.children[0].lineno
def Visit_decorator(self, node): # pylint: disable=invalid-name
if (self.last_comment_lineno and
self.last_comment_lineno == node.children[0].lineno - 1):
- self._SetNumNewlines(node.children[0], _NO_BLANK_LINES)
+ _SetNumNewlines(node.children[0], _NO_BLANK_LINES)
else:
- self._SetNumNewlines(node.children[0], self._GetNumNewlines(node))
+ _SetNumNewlines(node.children[0], self._GetNumNewlines(node))
for child in node.children:
self.Visit(child)
self.last_was_decorator = True
@@ -93,7 +95,7 @@ class _BlankLineCalculator(pytree_visitor.PyTreeVisitor):
if _AsyncFunction(node):
index = self._SetBlankLinesBetweenCommentAndClassFunc(
node.prev_sibling.parent)
- self._SetNumNewlines(node.children[0], None)
+ _SetNumNewlines(node.children[0], None)
else:
index = self._SetBlankLinesBetweenCommentAndClassFunc(node)
self.last_was_decorator = False
@@ -115,7 +117,7 @@ class _BlankLineCalculator(pytree_visitor.PyTreeVisitor):
if self.last_was_class_or_function:
if pytree_utils.NodeName(node) in _PYTHON_STATEMENTS:
leaf = pytree_utils.FirstLeafNode(node)
- self._SetNumNewlines(leaf, self._GetNumNewlines(leaf))
+ _SetNumNewlines(leaf, self._GetNumNewlines(leaf))
self.last_was_class_or_function = False
super(_BlankLineCalculator, self).DefaultNodeVisit(node)
@@ -137,17 +139,17 @@ class _BlankLineCalculator(pytree_visitor.PyTreeVisitor):
# node as its only child.
self.Visit(node.children[index].children[0])
if not self.last_was_decorator:
- self._SetNumNewlines(node.children[index].children[0], _ONE_BLANK_LINE)
+ _SetNumNewlines(node.children[index].children[0], _ONE_BLANK_LINE)
index += 1
- if (index and node.children[index].lineno -
- 1 == node.children[index - 1].children[0].lineno):
- self._SetNumNewlines(node.children[index], _NO_BLANK_LINES)
+ if (index and node.children[index].lineno - 1
+ == node.children[index - 1].children[0].lineno):
+ _SetNumNewlines(node.children[index], _NO_BLANK_LINES)
else:
if self.last_comment_lineno + 1 == node.children[index].lineno:
num_newlines = _NO_BLANK_LINES
else:
num_newlines = self._GetNumNewlines(node)
- self._SetNumNewlines(node.children[index], num_newlines)
+ _SetNumNewlines(node.children[index], num_newlines)
return index
def _GetNumNewlines(self, node):
@@ -157,15 +159,16 @@ class _BlankLineCalculator(pytree_visitor.PyTreeVisitor):
return 1 + style.Get('BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION')
return _ONE_BLANK_LINE
- def _SetNumNewlines(self, node, num_newlines):
- pytree_utils.SetNodeAnnotation(node, pytree_utils.Annotation.NEWLINES,
- num_newlines)
-
def _IsTopLevel(self, node):
return (not (self.class_level or self.function_level) and
_StartsInZerothColumn(node))
+def _SetNumNewlines(node, num_newlines):
+ pytree_utils.SetNodeAnnotation(node, pytree_utils.Annotation.NEWLINES,
+ num_newlines)
+
+
def _StartsInZerothColumn(node):
return (pytree_utils.FirstLeafNode(node).column == 0 or
(_AsyncFunction(node) and node.prev_sibling.column == 0))
@@ -173,4 +176,4 @@ def _StartsInZerothColumn(node):
def _AsyncFunction(node):
return (py3compat.PY3 and node.prev_sibling and
- pytree_utils.NodeName(node.prev_sibling) == 'ASYNC')
+ node.prev_sibling.type == grammar_token.ASYNC)
diff --git a/yapf/yapflib/comment_splicer.py b/yapf/yapflib/comment_splicer.py
index af999d2..535711b 100644
--- a/yapf/yapflib/comment_splicer.py
+++ b/yapf/yapflib/comment_splicer.py
@@ -44,6 +44,7 @@ def SpliceComments(tree):
_AnnotateIndents(tree)
def _VisitNodeRec(node):
+ """Recursively visit each node to splice comments into the AST."""
# This loop may insert into node.children, so we'll iterate over a copy.
for child in node.children[:]:
if isinstance(child, pytree.Node):
@@ -119,9 +120,9 @@ def SpliceComments(tree):
for comment_column, comment_indent, comment_group in comment_groups:
ancestor_at_indent = _FindAncestorAtIndent(child, comment_indent)
if ancestor_at_indent.type == token.DEDENT:
- InsertNodes = pytree_utils.InsertNodesBefore # pylint: disable=invalid-name
+ InsertNodes = pytree_utils.InsertNodesBefore # pylint: disable=invalid-name # noqa
else:
- InsertNodes = pytree_utils.InsertNodesAfter # pylint: disable=invalid-name
+ InsertNodes = pytree_utils.InsertNodesAfter # pylint: disable=invalid-name # noqa
InsertNodes(
_CreateCommentsFromPrefix(
'\n'.join(comment_group) + '\n',
@@ -152,6 +153,16 @@ def SpliceComments(tree):
# parent to insert into. See comments above
# _STANDALONE_LINE_NODES for more details.
node_with_line_parent = _FindNodeWithStandaloneLineParent(child)
+
+ if pytree_utils.NodeName(
+ node_with_line_parent.parent) in {'funcdef', 'classdef'}:
+ # Keep a comment that's not attached to a function or class
+ # next to the object it is attached to.
+ comment_end = (
+ comment_lineno + comment_prefix.rstrip('\n').count('\n'))
+ if comment_end < node_with_line_parent.lineno - 1:
+ node_with_line_parent = node_with_line_parent.parent
+
pytree_utils.InsertNodesBefore(
_CreateCommentsFromPrefix(
comment_prefix, comment_lineno, 0, standalone=True),
@@ -177,8 +188,8 @@ def SpliceComments(tree):
rindex = (0 if '\n' not in comment_prefix.rstrip() else
comment_prefix.rstrip().rindex('\n') + 1)
comment_column = (
- len(comment_prefix[rindex:]) - len(
- comment_prefix[rindex:].lstrip()))
+ len(comment_prefix[rindex:]) -
+ len(comment_prefix[rindex:].lstrip()))
comments = _CreateCommentsFromPrefix(
comment_prefix,
comment_lineno,
@@ -250,7 +261,7 @@ def _CreateCommentsFromPrefix(comment_prefix,
# When splicing a standalone comment (i.e. a comment that appears on its own
# line, not on the same line with other code), it's important to insert it into
# an appropriate parent of the node it's attached to. An appropriate parent
-# is the first "standaline line node" in the parent chain of a node.
+# is the first "standalone line node" in the parent chain of a node.
_STANDALONE_LINE_NODES = frozenset([
'suite', 'if_stmt', 'while_stmt', 'for_stmt', 'try_stmt', 'with_stmt',
'funcdef', 'classdef', 'decorated', 'file_input'
diff --git a/yapf/yapflib/errors.py b/yapf/yapflib/errors.py
index 3946275..99e88d9 100644
--- a/yapf/yapflib/errors.py
+++ b/yapf/yapflib/errors.py
@@ -11,7 +11,30 @@
# 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.
-"""YAPF error object."""
+"""YAPF error objects."""
+
+from lib2to3.pgen2 import tokenize
+
+
+def FormatErrorMsg(e):
+ """Convert an exception into a standard format.
+
+ The standard error message format is:
+
+ <filename>:<lineno>:<column>: <msg>
+
+ Arguments:
+ e: An exception.
+
+ Returns:
+ A properly formatted error message string.
+ """
+ if isinstance(e, SyntaxError):
+ return '{}:{}:{}: {}'.format(e.filename, e.lineno, e.offset, e.msg)
+ if isinstance(e, tokenize.TokenError):
+ return '{}:{}:{}: {}'.format(e.filename, e.args[1][0], e.args[1][1],
+ e.args[0])
+ return '{}:{}:{}: {}'.format(e.args[1][0], e.args[1][1], e.args[1][2], e.msg)
class YapfError(Exception):
diff --git a/yapf/yapflib/file_resources.py b/yapf/yapflib/file_resources.py
index 6e7202d..972f483 100644
--- a/yapf/yapflib/file_resources.py
+++ b/yapf/yapflib/file_resources.py
@@ -32,16 +32,79 @@ LF = '\n'
CRLF = '\r\n'
-def GetDefaultStyleForDir(dirname):
+def _GetExcludePatternsFromYapfIgnore(filename):
+ """Get a list of file patterns to ignore from .yapfignore."""
+ ignore_patterns = []
+ if os.path.isfile(filename) and os.access(filename, os.R_OK):
+ with open(filename, 'r') as fd:
+ for line in fd:
+ if line.strip() and not line.startswith('#'):
+ ignore_patterns.append(line.strip())
+
+ if any(e.startswith('./') for e in ignore_patterns):
+ raise errors.YapfError('path in .yapfignore should not start with ./')
+
+ return ignore_patterns
+
+
+def _GetExcludePatternsFromPyprojectToml(filename):
+ """Get a list of file patterns to ignore from pyproject.toml."""
+ ignore_patterns = []
+ try:
+ import toml
+ except ImportError:
+ raise errors.YapfError(
+ "toml package is needed for using pyproject.toml as a "
+ "configuration file")
+
+ if os.path.isfile(filename) and os.access(filename, os.R_OK):
+ pyproject_toml = toml.load(filename)
+ ignore_patterns = pyproject_toml.get('tool',
+ {}).get('yapfignore',
+ {}).get('ignore_patterns', [])
+ if any(e.startswith('./') for e in ignore_patterns):
+ raise errors.YapfError('path in pyproject.toml should not start with ./')
+
+ return ignore_patterns
+
+
+def GetExcludePatternsForDir(dirname):
+ """Return patterns of files to exclude from ignorefile in a given directory.
+
+ Looks for .yapfignore in the directory dirname.
+
+ Arguments:
+ dirname: (unicode) The name of the directory.
+
+ Returns:
+ A List of file patterns to exclude if ignore file is found, otherwise empty
+ List.
+ """
+ ignore_patterns = []
+
+ yapfignore_file = os.path.join(dirname, '.yapfignore')
+ if os.path.exists(yapfignore_file):
+ ignore_patterns += _GetExcludePatternsFromYapfIgnore(yapfignore_file)
+
+ pyproject_toml_file = os.path.join(dirname, 'pyproject.toml')
+ if os.path.exists(pyproject_toml_file):
+ ignore_patterns += _GetExcludePatternsFromPyprojectToml(pyproject_toml_file)
+ return ignore_patterns
+
+
+def GetDefaultStyleForDir(dirname, default_style=style.DEFAULT_STYLE):
"""Return default style name for a given directory.
- Looks for .style.yapf or setup.cfg in the parent directories.
+ Looks for .style.yapf or setup.cfg or pyproject.toml in the parent
+ directories.
Arguments:
dirname: (unicode) The name of the directory.
+ default_style: The style to return if nothing is found. Defaults to the
+ global default style ('pep8') unless otherwise specified.
Returns:
- The filename if found, otherwise return the global default (pep8).
+ The filename if found, otherwise return the default style.
"""
dirname = os.path.abspath(dirname)
while True:
@@ -52,23 +115,47 @@ def GetDefaultStyleForDir(dirname):
# See if we have a setup.cfg file with a '[yapf]' section.
config_file = os.path.join(dirname, style.SETUP_CONFIG)
- if os.path.exists(config_file):
- with open(config_file) as fd:
+ try:
+ fd = open(config_file)
+ except IOError:
+ pass # It's okay if it's not there.
+ else:
+ with fd:
config = py3compat.ConfigParser()
config.read_file(fd)
if config.has_section('yapf'):
return config_file
- dirname = os.path.dirname(dirname)
+ # See if we have a pyproject.toml file with a '[tool.yapf]' section.
+ config_file = os.path.join(dirname, style.PYPROJECT_TOML)
+ try:
+ fd = open(config_file)
+ except IOError:
+ pass # It's okay if it's not there.
+ else:
+ with fd:
+ try:
+ import toml
+ except ImportError:
+ raise errors.YapfError(
+ "toml package is needed for using pyproject.toml as a "
+ "configuration file")
+
+ pyproject_toml = toml.load(config_file)
+ style_dict = pyproject_toml.get('tool', {}).get('yapf', None)
+ if style_dict is not None:
+ return config_file
+
if (not dirname or not os.path.basename(dirname) or
dirname == os.path.abspath(os.path.sep)):
break
+ dirname = os.path.dirname(dirname)
global_file = os.path.expanduser(style.GLOBAL_STYLE)
if os.path.exists(global_file):
return global_file
- return style.DEFAULT_STYLE
+ return default_style
def GetCommandLineFiles(command_line_file_list, recursive, exclude):
@@ -116,30 +203,44 @@ def _FindPythonFiles(filenames, recursive, exclude):
"""Find all Python files."""
if exclude and any(e.startswith('./') for e in exclude):
raise errors.YapfError("path in '--exclude' should not start with ./")
+ exclude = exclude and [e.rstrip("/" + os.path.sep) for e in exclude]
python_files = []
for filename in filenames:
if filename != '.' and exclude and IsIgnored(filename, exclude):
continue
if os.path.isdir(filename):
- if recursive:
- # TODO(morbo): Look into a version of os.walk that can handle recursion.
- excluded_dirs = []
- for dirpath, _, filelist in os.walk(filename):
- if dirpath != '.' and exclude and IsIgnored(dirpath, exclude):
- excluded_dirs.append(dirpath)
- continue
- elif any(dirpath.startswith(e) for e in excluded_dirs):
- continue
- for f in filelist:
- filepath = os.path.join(dirpath, f)
- if exclude and IsIgnored(filepath, exclude):
- continue
- if IsPythonFile(filepath):
- python_files.append(filepath)
- else:
+ if not recursive:
raise errors.YapfError(
"directory specified without '--recursive' flag: %s" % filename)
+
+ # TODO(morbo): Look into a version of os.walk that can handle recursion.
+ excluded_dirs = []
+ for dirpath, dirnames, filelist in os.walk(filename):
+ if dirpath != '.' and exclude and IsIgnored(dirpath, exclude):
+ excluded_dirs.append(dirpath)
+ continue
+ elif any(dirpath.startswith(e) for e in excluded_dirs):
+ continue
+ for f in filelist:
+ filepath = os.path.join(dirpath, f)
+ if exclude and IsIgnored(filepath, exclude):
+ continue
+ if IsPythonFile(filepath):
+ python_files.append(filepath)
+ # To prevent it from scanning the contents excluded folders, os.walk()
+ # lets you amend its list of child dirs `dirnames`. These edits must be
+ # made in-place instead of creating a modified copy of `dirnames`.
+ # list.remove() is slow and list.pop() is a headache. Instead clear
+ # `dirnames` then repopulate it.
+ dirnames_ = [dirnames.pop(0) for i in range(len(dirnames))]
+ for dirname in dirnames_:
+ dir_ = os.path.join(dirpath, dirname)
+ if IsIgnored(dir_, exclude):
+ excluded_dirs.append(dir_)
+ else:
+ dirnames.append(dirname)
+
elif os.path.isfile(filename):
python_files.append(filename)
@@ -148,10 +249,12 @@ def _FindPythonFiles(filenames, recursive, exclude):
def IsIgnored(path, exclude):
"""Return True if filename matches any patterns in exclude."""
- path = path.lstrip('/')
- while path.startswith('./'):
+ if exclude is None:
+ return False
+ path = path.lstrip(os.path.sep)
+ while path.startswith('.' + os.path.sep):
path = path[2:]
- return any(fnmatch.fnmatch(path, e.rstrip('/')) for e in exclude)
+ return any(fnmatch.fnmatch(path, e.rstrip(os.path.sep)) for e in exclude)
def IsPythonFile(filename):
diff --git a/yapf/yapflib/format_decision_state.py b/yapf/yapflib/format_decision_state.py
index bff8ea3..74d0861 100644
--- a/yapf/yapflib/format_decision_state.py
+++ b/yapf/yapflib/format_decision_state.py
@@ -27,32 +27,34 @@ through the code to commit the whitespace formatting.
"""
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 unwrapped_line
+from yapf.yapflib import subtypes
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 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.
- 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
applying to comprehensions.
+ param_list_stack: A stack (of ParameterListState) keeping track of
+ properties applying to function parameter lists.
ignore_stack_for_comparison: Ignore the stack of _ParenState for state
comparison.
+ column_limit: The column limit specified by the style.
"""
def __init__(self, line, first_indent):
@@ -62,7 +64,7 @@ class FormatDecisionState(object):
'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
@@ -73,9 +75,8 @@ class FormatDecisionState(object):
self.ignore_stack_for_comparison = False
self.stack = [_ParenState(first_indent, first_indent)]
self.comp_stack = []
+ self.param_list_stack = []
self.first_indent = first_indent
- self.newline = False
- self.previous = None
self.column_limit = style.Get('COLUMN_LIMIT')
def Clone(self):
@@ -89,10 +90,9 @@ class FormatDecisionState(object):
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]
+ new.param_list_stack = [state.Clone() for state in self.param_list_stack]
return new
def __eq__(self, other):
@@ -105,8 +105,9 @@ class FormatDecisionState(object):
self.line.depth == other.line.depth and
self.lowest_level_on_line == other.lowest_level_on_line and
(self.ignore_stack_for_comparison or
- other.ignore_stack_for_comparison or
- self.stack == other.stack and self.comp_stack == other.comp_stack))
+ other.ignore_stack_for_comparison or self.stack == other.stack and
+ self.comp_stack == other.comp_stack and
+ self.param_list_stack == other.param_list_stack))
def __ne__(self, other):
return not self == other
@@ -132,19 +133,17 @@ class FormatDecisionState(object):
current = self.next_token
previous = current.previous_token
- if current.is_pseudo_paren:
+ if current.is_pseudo:
return False
- if (not must_split and
- format_token.Subtype.DICTIONARY_KEY_PART in current.subtypes and
- format_token.Subtype.DICTIONARY_KEY not in current.subtypes and
+ if (not must_split and subtypes.DICTIONARY_KEY_PART in current.subtypes and
+ subtypes.DICTIONARY_KEY not in current.subtypes and
not style.Get('ALLOW_MULTILINE_DICTIONARY_KEYS')):
# In some situations, a dictionary may be multiline, but pylint doesn't
# like it. So don't allow it unless forced to.
return False
- if (not must_split and
- format_token.Subtype.DICTIONARY_VALUE in current.subtypes and
+ if (not must_split and subtypes.DICTIONARY_VALUE in current.subtypes and
not style.Get('ALLOW_SPLIT_BEFORE_DICT_VALUE')):
return False
@@ -157,7 +156,7 @@ class FormatDecisionState(object):
if not prev or prev.name not in {'NAME', 'DOT'}:
break
token = token.previous_token
- if token and format_token.Subtype.DICTIONARY_VALUE in token.subtypes:
+ if token and subtypes.DICTIONARY_VALUE in token.subtypes:
if not style.Get('ALLOW_SPLIT_BEFORE_DICT_VALUE'):
return False
@@ -171,7 +170,7 @@ class FormatDecisionState(object):
current = self.next_token
previous = current.previous_token
- if current.is_pseudo_paren:
+ if current.is_pseudo:
return False
if current.must_break_before:
@@ -183,10 +182,32 @@ class FormatDecisionState(object):
if style.Get('SPLIT_ALL_COMMA_SEPARATED_VALUES') and previous.value == ',':
return True
+ if (style.Get('SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES') and
+ previous.value == ','):
+ # Avoid breaking in a container that fits in the current line if possible
+ opening = _GetOpeningBracket(current)
+
+ # Can't find opening bracket, behave the same way as
+ # SPLIT_ALL_COMMA_SEPARATED_VALUES.
+ if not opening:
+ return True
+
+ if current.is_comment:
+ # Don't require splitting before a comment, since it may be related to
+ # the current line.
+ return False
+
+ # Allow the fallthrough code to handle the closing bracket.
+ if current != opening.matching_bracket:
+ # If the container doesn't fit in the current line, must split
+ return not self._ContainerFitsOnStartLine(opening)
+
if (self.stack[-1].split_before_closing_bracket and
- current.value in '}]' and style.Get('SPLIT_BEFORE_CLOSING_BRACKET')):
+ (current.value in '}]' and style.Get('SPLIT_BEFORE_CLOSING_BRACKET') or
+ current.value in '}])' and style.Get('INDENT_CLOSING_BRACKETS'))):
# Split before the closing bracket if we can.
- return current.node_split_penalty != split_penalty.UNBREAKABLE
+ if subtypes.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)):
@@ -202,9 +223,10 @@ class FormatDecisionState(object):
###########################################################################
# List Splitting
if (style.Get('DEDENT_CLOSING_BRACKETS') or
+ style.Get('INDENT_CLOSING_BRACKETS') or
style.Get('SPLIT_BEFORE_FIRST_ARGUMENT')):
bracket = current if current.ClosesScope() else previous
- if format_token.Subtype.SUBSCRIPT_BRACKET not in bracket.subtypes:
+ if subtypes.SUBSCRIPT_BRACKET not in bracket.subtypes:
if bracket.OpensScope():
if style.Get('COALESCE_BRACKETS'):
if current.OpensScope():
@@ -212,7 +234,7 @@ class FormatDecisionState(object):
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)
@@ -223,7 +245,8 @@ class FormatDecisionState(object):
self.stack[-1].split_before_closing_bracket = True
return True
- elif style.Get('DEDENT_CLOSING_BRACKETS') and current.ClosesScope():
+ elif (style.Get('DEDENT_CLOSING_BRACKETS') or
+ style.Get('INDENT_CLOSING_BRACKETS')) and current.ClosesScope():
# Split before and dedent the closing bracket.
return self.stack[-1].split_before_closing_bracket
@@ -244,8 +267,8 @@ class FormatDecisionState(object):
token = token.next_token
return False
- if (previous.value == '(' and not previous.is_pseudo_paren and
- not unwrapped_line.IsSurroundedByBrackets(previous)):
+ if (previous.value == '(' and not previous.is_pseudo and
+ not logical_line.IsSurroundedByBrackets(previous)):
pptoken = previous.previous_token
if (pptoken and not pptoken.is_name and not pptoken.is_keyword and
SurroundedByParens(current)):
@@ -277,7 +300,7 @@ class FormatDecisionState(object):
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,
@@ -287,11 +310,20 @@ class FormatDecisionState(object):
if not self._FitsOnLine(current, tok.matching_bracket):
return True
+ if (current.OpensScope() and previous.value == ',' and
+ 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 = 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):
+ return True
+
###########################################################################
# Dict/Set Splitting
if (style.Get('EACH_DICT_ENTRY_ON_SEPARATE_LINE') and
- format_token.Subtype.DICTIONARY_KEY in current.subtypes and
- not current.is_comment):
+ subtypes.DICTIONARY_KEY in current.subtypes and not current.is_comment):
# Place each dictionary entry onto its own line.
if previous.value == '{' and previous.previous_token:
opening = _GetOpeningBracket(previous.previous_token)
@@ -311,12 +343,12 @@ class FormatDecisionState(object):
return True
if (style.Get('SPLIT_BEFORE_DICT_SET_GENERATOR') and
- format_token.Subtype.DICT_SET_GENERATOR in current.subtypes):
+ subtypes.DICT_SET_GENERATOR in current.subtypes):
# Split before a dict/set generator.
return True
- if (format_token.Subtype.DICTIONARY_VALUE in current.subtypes or
- (previous.is_pseudo_paren and previous.value == '(' and
+ if (subtypes.DICTIONARY_VALUE in current.subtypes or
+ (previous.is_pseudo and previous.value == '(' and
not current.is_comment)):
# Split before the dictionary value if we can't fit every dictionary
# entry on its own line.
@@ -336,8 +368,7 @@ class FormatDecisionState(object):
###########################################################################
# 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):
+ subtypes.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
@@ -351,20 +382,22 @@ class FormatDecisionState(object):
# 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
+ # Don't split if not required
+ if (not style.Get('SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN') and
+ not style.Get('SPLIT_BEFORE_FIRST_ARGUMENT')):
+ return False
+
column = self.column - self.stack[-1].last_space
return column > style.Get('CONTINUATION_INDENT_WIDTH')
opening = _GetOpeningBracket(current)
if opening:
- arglist_length = (
- opening.matching_bracket.total_length - opening.total_length +
- self.stack[-1].indent)
- return arglist_length > self.column_limit
+ return not self._ContainerFitsOnStartLine(opening)
if (current.value not in '{)' and previous.value == '(' and
self._ArgumentListHasDictionaryEntry(current)):
@@ -407,14 +440,34 @@ class FormatDecisionState(object):
return True
pprevious = previous.previous_token
+
+ # 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 remaining arguments are
+ # indented too far:
+ #
+ # function_call({
+ # KEY_1: 'value one',
+ # KEY_2: 'value two',
+ # },
+ # default=False)
+ if (current.value == '{' and previous.value == '(' and pprevious and
+ pprevious.is_name):
+ dict_end = current.matching_bracket
+ next_token = dict_end.next_token
+ if next_token.value == ',' and not self._FitsOnLine(current, dict_end):
+ return True
+
if (current.is_name and pprevious and pprevious.is_name and
previous.value == '('):
+
if (not self._FitsOnLine(previous, previous.matching_bracket) and
_IsFunctionCallWithArguments(current)):
# There is a function call, with more than 1 argument, where the first
- # argument is itself a function call with arguments. In this specific
- # case, if we split after the first argument's opening '(', then the
- # formatting will look bad for the rest of the arguments. E.g.:
+ # argument is itself a function call with arguments that does not fit
+ # into the line. In this specific case, if we split after the first
+ # argument's opening '(', then the formatting will look bad for the
+ # rest of the arguments. E.g.:
#
# outer_function_call(inner_function_call(
# inner_arg1, inner_arg2),
@@ -422,11 +475,35 @@ class FormatDecisionState(object):
#
# Instead, enforce a split before that argument to keep things looking
# good.
- return True
+ if (style.Get('SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN') or
+ style.Get('SPLIT_BEFORE_FIRST_ARGUMENT')):
+ return True
+
+ opening = _GetOpeningBracket(current)
+ if (opening and opening.value == '(' and opening.previous_token and
+ (opening.previous_token.is_name or
+ opening.previous_token.value in {'*', '**'})):
+ is_func_call = False
+ opening = current
+ while opening:
+ if opening.value == '(':
+ is_func_call = True
+ break
+ if (not (opening.is_name or opening.value in {'*', '**'}) and
+ opening.value != '.'):
+ break
+ opening = opening.next_token
+
+ if is_func_call:
+ if (not self._FitsOnLine(current, opening.matching_bracket) or
+ (opening.matching_bracket.next_token and
+ opening.matching_bracket.next_token.value != ',' and
+ not opening.matching_bracket.next_token.ClosesScope())):
+ return True
if (previous.OpensScope() and not current.OpensScope() and
not current.is_comment and
- format_token.Subtype.SUBSCRIPT_BRACKET not in previous.subtypes):
+ subtypes.SUBSCRIPT_BRACKET not in previous.subtypes):
if pprevious and not pprevious.is_keyword and not pprevious.is_name:
# We want to split if there's a comment in the container.
token = current
@@ -474,7 +551,7 @@ class FormatDecisionState(object):
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
@@ -496,6 +573,8 @@ class FormatDecisionState(object):
Returns:
The penalty of splitting after the current token.
"""
+ self._PushParameterListState(newline)
+
penalty = 0
if newline:
penalty = self._AddTokenOnNewline(dry_run, must_split)
@@ -503,6 +582,7 @@ class FormatDecisionState(object):
self._AddTokenOnCurrentLine(dry_run)
penalty += self._CalculateComprehensionState(newline)
+ penalty += self._CalculateParameterListState(newline)
return self.MoveStateToNextToken() + penalty
@@ -519,6 +599,11 @@ class FormatDecisionState(object):
previous = current.previous_token
spaces = current.spaces_required_before
+ if isinstance(spaces, list):
+ # Don't set the value here, as we need to look at the lines near
+ # this one to determine the actual horizontal alignment value.
+ spaces = 0
+
if not dry_run:
current.AddWhitespacePrefix(newlines_before=0, spaces=spaces)
@@ -573,9 +658,10 @@ class FormatDecisionState(object):
if (previous.OpensScope() or
(previous.is_comment and previous.previous_token is not None and
previous.previous_token.OpensScope())):
- self.stack[-1].closing_scope_indent = max(
- 0, self.stack[-1].indent - style.Get('CONTINUATION_INDENT_WIDTH'))
-
+ dedent = (style.Get('CONTINUATION_INDENT_WIDTH'),
+ 0)[style.Get('INDENT_CLOSING_BRACKETS')]
+ self.stack[-1].closing_scope_indent = (
+ max(0, self.stack[-1].indent - dedent))
self.stack[-1].split_before_closing_bracket = True
# Calculate the split penalty.
@@ -585,7 +671,7 @@ class FormatDecisionState(object):
# Don't penalize for a must split.
return penalty
- if previous.is_pseudo_paren and previous.value == '(':
+ if previous.is_pseudo and previous.value == '(':
# Small penalty for splitting after a pseudo paren.
penalty += 50
@@ -634,7 +720,7 @@ class FormatDecisionState(object):
# If we encounter a closing bracket, we can remove a level from our
# parenthesis stack.
if len(self.stack) > 1 and current.ClosesScope():
- if format_token.Subtype.DICTIONARY_KEY_PART in current.subtypes:
+ if subtypes.DICTIONARY_KEY_PART in current.subtypes:
self.stack[-2].last_space = self.stack[-2].indent
else:
self.stack[-2].last_space = self.stack[-1].last_space
@@ -645,7 +731,7 @@ class FormatDecisionState(object):
if is_multiline_string:
# This is a multiline string. Only look at the first line.
self.column += len(current.value.split('\n')[0])
- elif not current.is_pseudo_paren:
+ elif not current.is_pseudo:
self.column += len(current.value)
self.next_token = self.next_token.next_token
@@ -653,7 +739,7 @@ class FormatDecisionState(object):
# Calculate the penalty for overflowing the column limit.
penalty = 0
if (not current.is_pylint_comment and not current.is_pytype_comment and
- self.column > self.column_limit):
+ not current.is_copybara_comment and self.column > self.column_limit):
excess_characters = self.column - self.column_limit
penalty += style.Get('SPLIT_PENALTY_EXCESS_CHARACTER') * excess_characters
@@ -692,13 +778,12 @@ class FormatDecisionState(object):
if newline:
top_of_stack.has_interior_split = True
- if (format_token.Subtype.COMP_EXPR in current.subtypes and
- format_token.Subtype.COMP_EXPR not in previous.subtypes):
+ if (subtypes.COMP_EXPR in current.subtypes and
+ subtypes.COMP_EXPR not in previous.subtypes):
self.comp_stack.append(object_state.ComprehensionState(current))
return penalty
- if (current.value == 'for' and
- format_token.Subtype.COMP_FOR in current.subtypes):
+ if current.value == 'for' and subtypes.COMP_FOR in current.subtypes:
if top_of_stack.for_token is not None:
# Treat nested comprehensions like normal comp_if expressions.
# Example:
@@ -722,8 +807,8 @@ class FormatDecisionState(object):
top_of_stack.HasTrivialExpr()):
penalty += split_penalty.CONNECTED
- if (format_token.Subtype.COMP_IF in current.subtypes and
- format_token.Subtype.COMP_IF not in previous.subtypes):
+ if (subtypes.COMP_IF in current.subtypes and
+ subtypes.COMP_IF not in previous.subtypes):
# Penalize breaking at comp_if when it doesn't match the newline structure
# in the rest of the comprehension.
if (style.Get('SPLIT_COMPLEX_COMPREHENSION') and
@@ -733,17 +818,135 @@ class FormatDecisionState(object):
return penalty
+ def _PushParameterListState(self, newline):
+ """Push a new parameter list state for a function definition.
+
+ Args:
+ newline: Whether the current token is to be added on a newline.
+ """
+ current = self.next_token
+ previous = current.previous_token
+
+ if _IsFunctionDefinition(previous):
+ first_param_column = previous.total_length + self.stack[-2].indent
+ self.param_list_stack.append(
+ object_state.ParameterListState(previous, newline,
+ first_param_column))
+
+ def _CalculateParameterListState(self, newline):
+ """Makes required changes to parameter list state.
+
+ Args:
+ newline: Whether the current token is to be added on a newline.
+
+ Returns:
+ The penalty for the token-newline combination given the current
+ parameter state.
+ """
+ current = self.next_token
+ previous = current.previous_token
+ penalty = 0
+
+ if _IsFunctionDefinition(previous):
+ first_param_column = previous.total_length + self.stack[-2].indent
+ if not newline:
+ param_list = self.param_list_stack[-1]
+ if param_list.parameters and param_list.has_typed_return:
+ last_param = param_list.parameters[-1].first_token
+ last_token = _LastTokenInLine(previous.matching_bracket)
+ total_length = last_token.total_length
+ total_length -= last_param.total_length - len(last_param.value)
+ if total_length + self.column > self.column_limit:
+ # If we need to split before the trailing code of a function
+ # definition with return types, then also split before the opening
+ # parameter so that the trailing bit isn't indented on a line by
+ # itself:
+ #
+ # def rrrrrrrrrrrrrrrrrrrrrr(ccccccccccccccccccccccc: Tuple[Text]
+ # ) -> List[Tuple[Text, Text]]:
+ # pass
+ penalty += split_penalty.VERY_STRONGLY_CONNECTED
+ return penalty
+
+ if first_param_column <= self.column:
+ # Make sure we don't split after the opening bracket if the
+ # continuation indent is greater than the opening bracket:
+ #
+ # a(
+ # b=1,
+ # c=2)
+ penalty += split_penalty.VERY_STRONGLY_CONNECTED
+ return penalty
+
+ if not self.param_list_stack:
+ return penalty
+
+ param_list = self.param_list_stack[-1]
+ if current == self.param_list_stack[-1].closing_bracket:
+ self.param_list_stack.pop() # We're done with this state.
+ if newline and param_list.has_typed_return:
+ if param_list.split_before_closing_bracket:
+ penalty -= split_penalty.STRONGLY_CONNECTED
+ elif param_list.LastParamFitsOnLine(self.column):
+ penalty += split_penalty.STRONGLY_CONNECTED
+
+ if (not newline and param_list.has_typed_return and
+ param_list.has_split_before_first_param):
+ # Prefer splitting before the closing bracket if there's a return type
+ # and we've already split before the first parameter.
+ penalty += split_penalty.STRONGLY_CONNECTED
+
+ return penalty
+
+ if not param_list.parameters:
+ return penalty
+
+ if newline:
+ if self._FitsOnLine(param_list.parameters[0].first_token,
+ _LastTokenInLine(param_list.closing_bracket)):
+ penalty += split_penalty.STRONGLY_CONNECTED
+
+ if (not newline and style.Get('SPLIT_BEFORE_NAMED_ASSIGNS') and
+ param_list.has_default_values and
+ current != param_list.parameters[0].first_token and
+ current != param_list.closing_bracket and
+ subtypes.PARAMETER_START in current.subtypes):
+ # If we want to split before parameters when there are named assigns,
+ # then add a penalty for not splitting.
+ penalty += split_penalty.STRONGLY_CONNECTED
+
+ return penalty
+
+ def _IndentWithContinuationAlignStyle(self, column):
+ if column == 0:
+ return column
+ align_style = style.Get('CONTINUATION_ALIGN_STYLE')
+ if align_style == 'FIXED':
+ return ((self.line.depth * style.Get('INDENT_WIDTH')) +
+ style.Get('CONTINUATION_INDENT_WIDTH'))
+ if align_style == 'VALIGN-RIGHT':
+ indent_width = style.Get('INDENT_WIDTH')
+ return indent_width * int((column + indent_width - 1) / indent_width)
+ return column
+
def _GetNewlineColumn(self):
"""Return the new column on the newline."""
current = self.next_token
previous = current.previous_token
top_of_stack = self.stack[-1]
- if current.spaces_required_before > 2 or self.line.disable:
+ if isinstance(current.spaces_required_before, list):
+ # Don't set the value here, as we need to look at the lines near
+ # this one to determine the actual horizontal alignment value.
+ return 0
+ elif current.spaces_required_before > 2 or self.line.disable:
return current.spaces_required_before
+ cont_aligned_indent = self._IndentWithContinuationAlignStyle(
+ top_of_stack.indent)
+
if current.OpensScope():
- return top_of_stack.indent if self.paren_level else self.first_indent
+ return cont_aligned_indent if self.paren_level else self.first_indent
if current.ClosesScope():
if (previous.OpensScope() or
@@ -754,29 +957,39 @@ class FormatDecisionState(object):
return top_of_stack.closing_scope_indent
if (previous and previous.is_string and current.is_string and
- format_token.Subtype.DICTIONARY_VALUE in current.subtypes):
+ subtypes.DICTIONARY_VALUE in current.subtypes):
return previous.column
if style.Get('INDENT_DICTIONARY_VALUE'):
- if previous and (previous.value == ':' or previous.is_pseudo_paren):
- if format_token.Subtype.DICTIONARY_VALUE in current.subtypes:
+ if previous and (previous.value == ':' or previous.is_pseudo):
+ if subtypes.DICTIONARY_VALUE in current.subtypes:
return top_of_stack.indent
- if (_IsCompoundStatement(self.line.first) and
- (not style.Get('DEDENT_CLOSING_BRACKETS') or
+ if (not self.param_list_stack and _IsCompoundStatement(self.line.first) and
+ (not (style.Get('DEDENT_CLOSING_BRACKETS') or
+ style.Get('INDENT_CLOSING_BRACKETS')) or
style.Get('SPLIT_BEFORE_FIRST_ARGUMENT'))):
token_indent = (
len(self.line.first.whitespace_prefix.split('\n')[-1]) +
style.Get('INDENT_WIDTH'))
if token_indent == top_of_stack.indent:
+ return token_indent + style.Get('CONTINUATION_INDENT_WIDTH')
+
+ if (self.param_list_stack and
+ not self.param_list_stack[-1].SplitBeforeClosingBracket(
+ top_of_stack.indent) and top_of_stack.indent
+ == ((self.line.depth + 1) * style.Get('INDENT_WIDTH'))):
+ if (subtypes.PARAMETER_START in current.subtypes or
+ (previous.is_comment and
+ subtypes.PARAMETER_START in previous.subtypes)):
return top_of_stack.indent + style.Get('CONTINUATION_INDENT_WIDTH')
- return top_of_stack.indent
+ return cont_aligned_indent
def _FitsOnLine(self, start, end):
"""Determines if line between start and end can fit on the current line."""
length = end.total_length - start.total_length
- if not start.is_pseudo_paren:
+ if not start.is_pseudo:
length += len(start.value)
return length + self.column <= self.column_limit
@@ -791,29 +1004,48 @@ class FormatDecisionState(object):
def ImplicitStringConcatenation(tok):
num_strings = 0
- if tok.is_pseudo_paren:
+ if tok.is_pseudo:
tok = tok.next_token
while tok.is_string:
num_strings += 1
tok = tok.next_token
return num_strings > 1
+ def DictValueIsContainer(opening, closing):
+ """Return true if the dictionary value is a container."""
+ if not opening or not closing:
+ return False
+ colon = opening.previous_token
+ while colon:
+ if not colon.is_pseudo:
+ break
+ colon = colon.previous_token
+ if not colon or colon.value != ':':
+ return False
+ key = colon.previous_token
+ if not key:
+ return False
+ return subtypes.DICTIONARY_KEY_PART in key.subtypes
+
closing = opening.matching_bracket
entry_start = opening.next_token
current = opening.next_token.next_token
while current and current != closing:
- if format_token.Subtype.DICTIONARY_KEY in current.subtypes:
+ if subtypes.DICTIONARY_KEY in current.subtypes:
prev = PreviousNonCommentToken(current)
- length = prev.total_length - entry_start.total_length
- length += len(entry_start.value)
- if length + self.stack[-2].indent >= self.column_limit:
- return False
+ if prev.value == ',':
+ prev = PreviousNonCommentToken(prev.previous_token)
+ if not DictValueIsContainer(prev.matching_bracket, prev):
+ length = prev.total_length - entry_start.total_length
+ length += len(entry_start.value)
+ if length + self.stack[-2].indent >= self.column_limit:
+ return False
entry_start = current
if current.OpensScope():
if ((current.value == '{' or
- (current.is_pseudo_paren and current.next_token.value == '{') and
- format_token.Subtype.DICTIONARY_VALUE in current.subtypes) or
+ (current.is_pseudo and current.next_token.value == '{') and
+ subtypes.DICTIONARY_VALUE in current.subtypes) or
ImplicitStringConcatenation(current)):
# A dictionary entry that cannot fit on a single line shouldn't matter
# to this calculation. If it can't fit on a single line, then the
@@ -825,7 +1057,7 @@ class FormatDecisionState(object):
while current:
if current == closing:
return True
- if format_token.Subtype.DICTIONARY_KEY in current.subtypes:
+ if subtypes.DICTIONARY_KEY in current.subtypes:
entry_start = current
break
current = current.next_token
@@ -834,8 +1066,8 @@ class FormatDecisionState(object):
else:
current = current.next_token
- # At this point, current is the closing bracket. Go back one to get the the
- # end of the dictionary entry.
+ # At this point, current is the closing bracket. Go back one to get the end
+ # of the dictionary entry.
current = PreviousNonCommentToken(current)
length = current.total_length - entry_start.total_length
length += len(entry_start.value)
@@ -855,6 +1087,11 @@ class FormatDecisionState(object):
token = token.next_token
return False
+ def _ContainerFitsOnStartLine(self, opening):
+ """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
+
_COMPOUND_STMTS = frozenset(
{'for', 'while', 'if', 'elif', 'with', 'except', 'def', 'class'})
@@ -884,29 +1121,22 @@ 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
return previous and previous.is_name
-def _GetLengthOfSubtype(token, subtype, exclude=None):
- current = token
- while (current.next_token and subtype in current.subtypes and
- (exclude is None or exclude not in current.subtypes)):
- current = current.next_token
- return current.total_length - token.total_length + 1
-
-
def _GetOpeningBracket(current):
"""Get the opening bracket containing the current token."""
- if current.matching_bracket and not current.is_pseudo_paren:
- return current.matching_bracket
+ if current.matching_bracket and not current.is_pseudo:
+ return current if current.OpensScope() else current.matching_bracket
+
while current:
if current.ClosesScope():
current = current.matching_bracket
- elif current.is_pseudo_paren:
+ elif current.is_pseudo:
current = current.previous_token
elif current.OpensScope():
return current
@@ -922,11 +1152,11 @@ def _LastTokenInLine(current):
def _IsFunctionDefinition(current):
prev = current.previous_token
- return (current.value == '(' and prev and
- format_token.Subtype.FUNC_DEF in prev.subtypes)
+ return current.value == '(' and prev and subtypes.FUNC_DEF in prev.subtypes
def _IsLastScopeInLine(current):
+ current = current.matching_bracket
while current:
current = current.next_token
if current and current.OpensScope():
@@ -942,10 +1172,7 @@ def _IsSingleElementTuple(token):
while token != close:
if token.value == ',':
num_commas += 1
- if token.OpensScope():
- token = token.matching_bracket
- else:
- token = token.next_token
+ token = token.matching_bracket if token.OpensScope() else token.next_token
return num_commas == 1
@@ -956,10 +1183,7 @@ def _ScopeHasNoCommas(token):
while token != close:
if token.value == ',':
return False
- if token.OpensScope():
- token = token.matching_bracket
- else:
- token = token.next_token
+ token = token.matching_bracket if token.OpensScope() else token.next_token
return True
@@ -973,6 +1197,7 @@ class _ParenState(object):
indent: The column position to which a specified parenthesis level needs to
be indented.
last_space: The column position of the last space on each level.
+ closing_scope_indent: The column position of the closing indentation.
split_before_closing_bracket: Whether a newline needs to be inserted before
the closing bracket. We only want to insert a newline before the closing
bracket if there also was a newline after the beginning left bracket.
diff --git a/yapf/yapflib/format_token.py b/yapf/yapflib/format_token.py
index 79dced4..487f3a9 100644
--- a/yapf/yapflib/format_token.py
+++ b/yapf/yapflib/format_token.py
@@ -24,58 +24,26 @@ from lib2to3.pgen2 import token
from yapf.yapflib import py3compat
from yapf.yapflib import pytree_utils
from yapf.yapflib import style
+from yapf.yapflib import subtypes
CONTINUATION = token.N_TOKENS
-class Subtype(object):
- """Subtype information about tokens.
-
- Gleaned from parsing the code. Helps determine the best formatting.
- """
- NONE = 0
- UNARY_OPERATOR = 1
- BINARY_OPERATOR = 2
- SUBSCRIPT_COLON = 3
- SUBSCRIPT_BRACKET = 4
- DEFAULT_OR_NAMED_ASSIGN = 5
- DEFAULT_OR_NAMED_ASSIGN_ARG_LIST = 6
- VARARGS_LIST = 7
- VARARGS_STAR = 8
- KWARGS_STAR_STAR = 9
- ASSIGN_OPERATOR = 10
- DICTIONARY_KEY = 11
- DICTIONARY_KEY_PART = 12
- DICTIONARY_VALUE = 13
- DICT_SET_GENERATOR = 14
- COMP_EXPR = 21
- COMP_FOR = 15
- COMP_IF = 16
- FUNC_DEF = 17
- DECORATOR = 18
- TYPED_NAME = 19
- TYPED_NAME_ARG_LIST = 20
-
-
-def _TabbedContinuationAlignPadding(spaces, align_style, tab_width,
- continuation_indent_width):
+def _TabbedContinuationAlignPadding(spaces, align_style, tab_width):
"""Build padding string for continuation alignment in tabbed indentation.
Arguments:
spaces: (int) The number of spaces to place before the token for alignment.
align_style: (str) The alignment style for continuation lines.
tab_width: (int) Number of columns of each tab character.
- continuation_indent_width: (int) Indent columns for line continuations.
Returns:
A padding string for alignment with style specified by align_style option.
"""
- if align_style == 'FIXED':
+ if align_style in ('FIXED', 'VALIGN-RIGHT'):
if spaces > 0:
- return '\t' * int(continuation_indent_width / tab_width)
+ return '\t' * int((spaces + tab_width - 1) / tab_width)
return ''
- elif align_style == 'VALIGN-RIGHT':
- return '\t' * int((spaces + tab_width - 1) / tab_width)
return ' ' * spaces
@@ -86,12 +54,15 @@ class FormatToken(object):
the code.
Attributes:
- 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.
+ node: The PyTree node this token represents.
+ 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
+ this is a list of those parameters.
container_opening: If the object is in a container, this points to its
opening bracket.
container_elements: If this is the start of a container, a list of the
@@ -103,12 +74,13 @@ 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.
- can_break_before: True if we're allowed to break before this token.
- must_break_before: True if we're required to break before this token.
- 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.
+ can_break_before: True if we're allowed to break before this token.
+ must_break_before: True if we're required to break before this token.
+ newlines: The number of newlines needed before this token.
"""
def __init__(self, node):
@@ -121,23 +93,44 @@ class FormatToken(object):
self.next_token = None
self.previous_token = None
self.matching_bracket = None
+ self.parameters = []
self.container_opening = None
self.container_elements = []
self.whitespace_prefix = ''
- self.can_break_before = False
- self.must_break_before = False
- self.total_length = 0 # TODO(morbo): Think up a better name.
+ self.total_length = 0
self.split_penalty = 0
+ self.can_break_before = False
+ self.must_break_before = pytree_utils.GetNodeAnnotation(
+ node, pytree_utils.Annotation.MUST_SPLIT, default=False)
+ self.newlines = pytree_utils.GetNodeAnnotation(
+ node, pytree_utils.Annotation.NEWLINES)
+ self.type = node.type
+ self.column = node.column
+ self.lineno = node.lineno
+ self.name = pytree_utils.NodeName(node)
+
+ self.spaces_required_before = 0
if self.is_comment:
self.spaces_required_before = style.Get('SPACES_BEFORE_COMMENT')
- else:
- self.spaces_required_before = 0
+ self.value = node.value
if self.is_continuation:
- self.value = self.node.value.rstrip()
- else:
- self.value = self.node.value
+ self.value = node.value.rstrip()
+
+ stypes = pytree_utils.GetNodeAnnotation(node,
+ pytree_utils.Annotation.SUBTYPE)
+ self.subtypes = {subtypes.NONE} if not stypes else stypes
+ self.is_pseudo = hasattr(node, 'is_pseudo') and node.is_pseudo
+
+ @property
+ def formatted_whitespace_prefix(self):
+ if style.Get('INDENT_BLANK_LINES'):
+ without_newlines = self.whitespace_prefix.lstrip('\n')
+ height = len(self.whitespace_prefix) - len(without_newlines)
+ if height:
+ return ('\n' + without_newlines) * height
+ return self.whitespace_prefix
def AddWhitespacePrefix(self, newlines_before, spaces=0, indent_level=0):
"""Register a token's whitespace prefix.
@@ -153,30 +146,30 @@ class FormatToken(object):
if newlines_before > 0:
indent_before = '\t' * indent_level + _TabbedContinuationAlignPadding(
spaces, style.Get('CONTINUATION_ALIGN_STYLE'),
- style.Get('INDENT_WIDTH'), style.Get('CONTINUATION_INDENT_WIDTH'))
+ style.Get('INDENT_WIDTH'))
else:
indent_before = '\t' * indent_level + ' ' * spaces
else:
- indent_before = (
- ' ' * indent_level * style.Get('INDENT_WIDTH') + ' ' * spaces)
+ indent_before = (' ' * indent_level * style.Get('INDENT_WIDTH') +
+ ' ' * spaces)
if self.is_comment:
comment_lines = [s.lstrip() for s in self.value.splitlines()]
- self.node.value = ('\n' + indent_before).join(comment_lines)
+ self.value = ('\n' + indent_before).join(comment_lines)
# Update our own value since we are changing node value
- self.value = self.node.value
+ self.value = self.value
if not self.whitespace_prefix:
- self.whitespace_prefix = (
- '\n' * (self.newlines or newlines_before) + indent_before)
+ self.whitespace_prefix = ('\n' * (self.newlines or newlines_before) +
+ indent_before)
else:
self.whitespace_prefix += indent_before
def AdjustNewlinesBefore(self, newlines_before):
"""Change the number of newlines before this token."""
- self.whitespace_prefix = (
- '\n' * newlines_before + self.whitespace_prefix.lstrip('\n'))
+ self.whitespace_prefix = ('\n' * newlines_before +
+ self.whitespace_prefix.lstrip('\n'))
def RetainHorizontalSpacing(self, first_column, depth):
"""Retains a token's horizontal spacing."""
@@ -184,7 +177,7 @@ class FormatToken(object):
if not previous:
return
- if previous.is_pseudo_paren:
+ if previous.is_pseudo:
previous = previous.previous_token
if not previous:
return
@@ -195,17 +188,17 @@ class FormatToken(object):
prev_lineno += previous.value.count('\n')
if (cur_lineno != prev_lineno or
- (previous.is_pseudo_paren and previous.value != ')' and
+ (previous.is_pseudo and previous.value != ')' and
cur_lineno != previous.previous_token.lineno)):
self.spaces_required_before = (
self.column - first_column + depth * style.Get('INDENT_WIDTH'))
return
- cur_column = self.node.column
+ cur_column = self.column
prev_column = previous.node.column
prev_len = len(previous.value)
- if previous.is_pseudo_paren and previous.value == ')':
+ if previous.is_pseudo and previous.value == ')':
prev_column -= 1
prev_len = 0
@@ -222,67 +215,65 @@ class FormatToken(object):
def ClosesScope(self):
return self.value in pytree_utils.CLOSING_BRACKETS
+ def AddSubtype(self, subtype):
+ self.subtypes.add(subtype)
+
def __repr__(self):
- msg = 'FormatToken(name={0}, value={1}'.format(self.name, self.value)
- msg += ', pseudo)' if self.is_pseudo_paren else ')'
+ msg = ('FormatToken(name={0}, value={1}, column={2}, lineno={3}, '
+ 'splitpenalty={4}'.format(
+ 'DOCSTRING' if self.is_docstring else self.name, self.value,
+ self.column, self.lineno, self.split_penalty))
+ msg += ', pseudo)' if self.is_pseudo else ')'
return msg
@property
- @py3compat.lru_cache()
def node_split_penalty(self):
"""Split penalty attached to the pytree node of this token."""
return pytree_utils.GetNodeAnnotation(
self.node, pytree_utils.Annotation.SPLIT_PENALTY, default=0)
@property
- def newlines(self):
- """The number of newlines needed before this token."""
- return pytree_utils.GetNodeAnnotation(self.node,
- pytree_utils.Annotation.NEWLINES)
-
- @property
- def must_split(self):
- """Return true if the token requires a split before it."""
- return pytree_utils.GetNodeAnnotation(self.node,
- pytree_utils.Annotation.MUST_SPLIT)
-
- @property
- def column(self):
- """The original column number of the node in the source."""
- return self.node.column
-
- @property
- def lineno(self):
- """The original line number of the node in the source."""
- return self.node.lineno
+ def is_binary_op(self):
+ """Token is a binary operator."""
+ return subtypes.BINARY_OPERATOR in self.subtypes
@property
@py3compat.lru_cache()
- def subtypes(self):
- """Extra type information for directing formatting."""
- value = pytree_utils.GetNodeAnnotation(self.node,
- pytree_utils.Annotation.SUBTYPE)
- return [Subtype.NONE] if value is None else value
+ def is_arithmetic_op(self):
+ """Token is an arithmetic operator."""
+ return self.value in frozenset({
+ '+', # Add
+ '-', # Subtract
+ '*', # Multiply
+ '@', # Matrix Multiply
+ '/', # Divide
+ '//', # Floor Divide
+ '%', # Modulo
+ '<<', # Left Shift
+ '>>', # Right Shift
+ '|', # Bitwise Or
+ '&', # Bitwise Add
+ '^', # Bitwise Xor
+ '**', # Power
+ })
@property
- @py3compat.lru_cache()
- def is_binary_op(self):
- """Token is a binary operator."""
- return Subtype.BINARY_OPERATOR in self.subtypes
+ def is_simple_expr(self):
+ """Token is an operator in a simple expression."""
+ return subtypes.SIMPLE_EXPRESSION in self.subtypes
@property
- @py3compat.lru_cache()
- def name(self):
- """A string representation of the node's name."""
- return pytree_utils.NodeName(self.node)
+ def is_subscript_colon(self):
+ """Token is a subscript colon."""
+ return subtypes.SUBSCRIPT_COLON in self.subtypes
@property
def is_comment(self):
- return self.node.type == token.COMMENT
+ return self.type == token.COMMENT
@property
def is_continuation(self):
- return self.node.type == CONTINUATION
+ return self.type == CONTINUATION
@property
@py3compat.lru_cache()
@@ -290,43 +281,31 @@ class FormatToken(object):
return keyword.iskeyword(self.value)
@property
- @py3compat.lru_cache()
def is_name(self):
- return self.node.type == token.NAME and not self.is_keyword
+ return self.type == token.NAME and not self.is_keyword
@property
def is_number(self):
- return self.node.type == token.NUMBER
+ return self.type == token.NUMBER
@property
def is_string(self):
- return self.node.type == token.STRING
+ return self.type == token.STRING
@property
- @py3compat.lru_cache()
def is_multiline_string(self):
- """A multiline string."""
- if py3compat.PY3:
- prefix = '('
- prefix += 'r|u|R|U|f|F|fr|Fr|fR|FR|rf|rF|Rf|RF' # strings
- prefix += '|b|B|br|Br|bR|BR|rb|rB|Rb|RB' # bytes
- prefix += ')?'
- else:
- prefix = '[uUbB]?[rR]?'
+ """Test if this string is a multiline string.
- regex = r'^{prefix}(?P<delim>"""|\'\'\').*(?P=delim)$'.format(prefix=prefix)
- return (self.is_string and
- re.match(regex, self.value, re.DOTALL) is not None)
+ Returns:
+ A multiline string always ends with triple quotes, so if it is a string
+ token, inspect the last 3 characters and return True if it is a triple
+ double or triple single quote mark.
+ """
+ return self.is_string and self.value.endswith(('"""', "'''"))
@property
- @py3compat.lru_cache()
def is_docstring(self):
- return self.is_multiline_string and not self.node.prev_sibling
-
- @property
- @py3compat.lru_cache()
- def is_pseudo_paren(self):
- return hasattr(self.node, 'is_pseudo') and self.node.is_pseudo
+ return self.is_string and self.previous_token is None
@property
def is_pylint_comment(self):
@@ -337,3 +316,8 @@ class FormatToken(object):
def is_pytype_comment(self):
return self.is_comment and re.match(r'#.*\bpytype:\s*(disable|enable)=',
self.value)
+
+ @property
+ def is_copybara_comment(self):
+ return self.is_comment and re.match(
+ r'#.*\bcopybara:\s*(strip|insert|replace)', self.value)
diff --git a/yapf/yapflib/identify_container.py b/yapf/yapflib/identify_container.py
index 5c5fc5b..888dbbb 100644
--- a/yapf/yapflib/identify_container.py
+++ b/yapf/yapflib/identify_container.py
@@ -19,6 +19,8 @@ to the opening bracket and vice-versa.
IdentifyContainers(): the main function exported by this module.
"""
+from lib2to3.pgen2 import token as grammar_token
+
from yapf.yapflib import pytree_utils
from yapf.yapflib import pytree_visitor
@@ -42,7 +44,7 @@ class _IdentifyContainers(pytree_visitor.PyTreeVisitor):
if len(node.children) != 3:
return
- if pytree_utils.NodeName(node.children[0]) != 'LPAR':
+ if node.children[0].type != grammar_token.LPAR:
return
if pytree_utils.NodeName(node.children[1]) == 'arglist':
@@ -59,7 +61,7 @@ class _IdentifyContainers(pytree_visitor.PyTreeVisitor):
if len(node.children) != 3:
return
- if pytree_utils.NodeName(node.children[0]) != 'LPAR':
+ if node.children[0].type != grammar_token.LPAR:
return
for child in node.children[1].children:
diff --git a/yapf/yapflib/line_joiner.py b/yapf/yapflib/line_joiner.py
index 84346c2..f0acd2f 100644
--- a/yapf/yapflib/line_joiner.py
+++ b/yapf/yapflib/line_joiner.py
@@ -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:
@@ -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:
@@ -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:
diff --git a/yapf/yapflib/unwrapped_line.py b/yapf/yapflib/logical_line.py
index 92b986e..5723440 100644
--- a/yapf/yapflib/unwrapped_line.py
+++ b/yapf/yapflib/logical_line.py
@@ -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
@@ -24,10 +24,13 @@ from yapf.yapflib import py3compat
from yapf.yapflib import pytree_utils
from yapf.yapflib import split_penalty
from yapf.yapflib import style
+from yapf.yapflib import subtypes
+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
@@ -38,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.
@@ -60,7 +63,7 @@ class UnwrappedLine(object):
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)
@@ -69,11 +72,24 @@ class UnwrappedLine(object):
prev_length = self.first.total_length
for token in self._tokens[1:]:
if (token.spaces_required_before == 0 and
- _SpaceRequiredBetween(prev_token, token)):
+ _SpaceRequiredBetween(prev_token, token, self.disable)):
token.spaces_required_before = 1
- tok_len = len(token.value) if not token.is_pseudo_paren else 0
- token.total_length = prev_length + tok_len + token.spaces_required_before
+ tok_len = len(token.value) if not token.is_pseudo else 0
+
+ spaces_required_before = token.spaces_required_before
+ if isinstance(spaces_required_before, list):
+ assert token.is_comment, token
+
+ # If here, we are looking at a comment token that appears on a line
+ # with other tokens (but because it is a comment, it is always the last
+ # token). Rather than specifying the actual number of spaces here,
+ # hard code a value of 0 and then set it later. This logic only works
+ # because this comment token is guaranteed to be the last token in the
+ # list.
+ spaces_required_before = 0
+
+ token.total_length = prev_length + tok_len + spaces_required_before
# The split penalty has to be computed before {must|can}_break_before,
# because these may use it for their decision.
@@ -90,25 +106,23 @@ class UnwrappedLine(object):
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:
- pytree_utils.SetNodeAnnotation(uwline.first.node,
- pytree_utils.Annotation.MUST_SPLIT, True)
- 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 #
@@ -169,8 +183,8 @@ class UnwrappedLine(object):
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(
+ '{0}({1!r})'.format(tok.name, tok.value) for tok in self._tokens)
+ return 'LogicalLine(depth={0}, tokens=[{1}])'.format(
self.depth, tokens_repr)
############################################################################
@@ -190,14 +204,32 @@ class UnwrappedLine(object):
@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
@property
+ def start(self):
+ """The start of the logical line.
+
+ Returns:
+ A tuple of the starting line number and column.
+ """
+ return (self.first.lineno, self.first.column)
+
+ @property
+ def end(self):
+ """The end of the logical line.
+
+ Returns:
+ A tuple of the ending line number and column.
+ """
+ return (self.last.lineno, self.last.column + len(self.last.value))
+
+ @property
def is_comment(self):
return self.first.is_comment
@@ -211,18 +243,56 @@ def _IsIdNumberStringToken(tok):
def _IsUnaryOperator(tok):
- return format_token.Subtype.UNARY_OPERATOR in tok.subtypes
+ return subtypes.UNARY_OPERATOR in tok.subtypes
+
+def _HasPrecedence(tok):
+ """Whether a binary operation has precedence within its context."""
+ node = tok.node
-def _SpaceRequiredBetween(left, right):
+ # We let ancestor be the statement surrounding the operation that tok is the
+ # operator in.
+ ancestor = node.parent.parent
+
+ while ancestor is not None:
+ # Search through the ancestor nodes in the parse tree for operators with
+ # lower precedence.
+ predecessor_type = pytree_utils.NodeName(ancestor)
+ if predecessor_type in ['arith_expr', 'term']:
+ # An ancestor "arith_expr" or "term" means we have found an operator
+ # with lower precedence than our tok.
+ return True
+ if predecessor_type != 'atom':
+ # We understand the context to look for precedence within as an
+ # arbitrary nesting of "arith_expr", "term", and "atom" nodes. If we
+ # leave this context we have not found a lower precedence operator.
+ return False
+ # Under normal usage we expect a complete parse tree to be available and
+ # we will return before we get an AttributeError from the root.
+ ancestor = ancestor.parent
+
+
+def _PriorityIndicatingNoSpace(tok):
+ """Whether to remove spaces around an operator due to precedence."""
+ if not tok.is_arithmetic_op or not tok.is_simple_expr:
+ # Limit space removal to highest priority arithmetic operators
+ return False
+ return _HasPrecedence(tok)
+
+
+def _IsSubscriptColonAndValuePair(token1, token2):
+ return (token1.is_number or token1.is_name) and token2.is_subscript_colon
+
+
+def _SpaceRequiredBetween(left, right, is_line_disabled):
"""Return True if a space is required between the left and right token."""
lval = left.value
rval = right.value
- if (left.is_pseudo_paren and _IsIdNumberStringToken(right) and
+ if (left.is_pseudo and _IsIdNumberStringToken(right) and
left.previous_token and _IsIdNumberStringToken(left.previous_token)):
# Space between keyword... tokens and pseudo parens.
return True
- if left.is_pseudo_paren or right.is_pseudo_paren:
+ if left.is_pseudo or right.is_pseudo:
# There should be a space after the ':' in a dictionary.
if left.OpensScope():
return True
@@ -240,6 +310,17 @@ def _SpaceRequiredBetween(left, right):
if lval == ',' and rval == ':':
# We do want a space between a comma and colon.
return True
+ if style.Get('SPACE_INSIDE_BRACKETS'):
+ # Supersede the "no space before a colon or comma" check.
+ if lval in pytree_utils.OPENING_BRACKETS and rval == ':':
+ return True
+ if rval in pytree_utils.CLOSING_BRACKETS and lval == ':':
+ return True
+ if (style.Get('SPACES_AROUND_SUBSCRIPT_COLON') and
+ (_IsSubscriptColonAndValuePair(left, right) or
+ _IsSubscriptColonAndValuePair(right, left))):
+ # Supersede the "never want a space before a colon or comma" check.
+ return True
if rval in ':,':
# Otherwise, we never want a space before a colon or comma.
return False
@@ -255,33 +336,43 @@ def _SpaceRequiredBetween(left, right):
if lval == '.' and rval == 'import':
# Space after the '.' in an import statement.
return True
- if (lval == '=' and rval == '.' and
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN not in left.subtypes):
+ if (lval == '=' and rval in {'.', ',,,'} and
+ subtypes.DEFAULT_OR_NAMED_ASSIGN not in left.subtypes):
# Space between equal and '.' as in "X = ...".
return True
+ if lval == ':' and rval in {'.', '...'}:
+ # Space between : and ...
+ return True
if ((right.is_keyword or right.is_name) and
(left.is_keyword or left.is_name)):
# Don't merge two keywords/identifiers.
return True
- if (format_token.Subtype.SUBSCRIPT_COLON in left.subtypes or
- format_token.Subtype.SUBSCRIPT_COLON in right.subtypes):
+ if (subtypes.SUBSCRIPT_COLON in left.subtypes or
+ subtypes.SUBSCRIPT_COLON in right.subtypes):
# A subscript shouldn't have spaces separating its colons.
return False
- if (format_token.Subtype.TYPED_NAME in left.subtypes or
- format_token.Subtype.TYPED_NAME in right.subtypes):
+ if (subtypes.TYPED_NAME in left.subtypes or
+ subtypes.TYPED_NAME in right.subtypes):
# A typed argument should have a space after the colon.
return True
if left.is_string:
if (rval == '=' and
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST in right.subtypes
- ):
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST in right.subtypes):
# If there is a type hint, then we don't want to add a space between the
# equal sign and the hint.
return False
- if rval not in '[)]}.':
+ if rval not in '[)]}.' and not right.is_binary_op:
# A string followed by something other than a subscript, closing bracket,
- # or dot should have a space after it.
+ # dot, or a binary op should have a space after it.
return True
+ if rval in pytree_utils.CLOSING_BRACKETS:
+ # A string followed by closing brackets should have a space after it
+ # depending on SPACE_INSIDE_BRACKETS. A string followed by opening
+ # brackets, however, should not.
+ return style.Get('SPACE_INSIDE_BRACKETS')
+ if subtypes.SUBSCRIPT_BRACKET in right.subtypes:
+ # It's legal to do this in Python: 'hello'[a]
+ return False
if left.is_binary_op and lval != '**' and _IsUnaryOperator(right):
# Space between the binary operator and the unary operator.
return True
@@ -295,31 +386,46 @@ def _SpaceRequiredBetween(left, right):
if lval == '**' or rval == '**':
# Space around the "power" operator.
return style.Get('SPACES_AROUND_POWER_OPERATOR')
- # Enforce spaces around binary operators except the blacklisted ones.
- blacklist = style.Get('NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS')
- return lval not in blacklist and rval not in blacklist
+ # Enforce spaces around binary operators except the blocked ones.
+ block_list = style.Get('NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS')
+ if lval in block_list or rval in block_list:
+ return False
+ if style.Get('ARITHMETIC_PRECEDENCE_INDICATION'):
+ if _PriorityIndicatingNoSpace(left) or _PriorityIndicatingNoSpace(right):
+ return False
+ else:
+ return True
+ else:
+ return True
if (_IsUnaryOperator(left) and lval != 'not' and
(right.is_name or right.is_number or rval == '(')):
# The previous token was a unary op. No space is desired between it and
# the current token.
return False
- if (format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in left.subtypes or
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in right.subtypes):
+ if (subtypes.DEFAULT_OR_NAMED_ASSIGN in left.subtypes and
+ subtypes.TYPED_NAME not in right.subtypes):
+ # A named argument or default parameter shouldn't have spaces around it.
+ return style.Get('SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN')
+ if (subtypes.DEFAULT_OR_NAMED_ASSIGN in right.subtypes and
+ subtypes.TYPED_NAME not in left.subtypes):
# A named argument or default parameter shouldn't have spaces around it.
return style.Get('SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN')
- if (format_token.Subtype.VARARGS_LIST in left.subtypes or
- format_token.Subtype.VARARGS_LIST in right.subtypes):
+ if (subtypes.VARARGS_LIST in left.subtypes or
+ subtypes.VARARGS_LIST in right.subtypes):
return False
- if (format_token.Subtype.VARARGS_STAR in left.subtypes or
- format_token.Subtype.KWARGS_STAR_STAR in left.subtypes):
+ if (subtypes.VARARGS_STAR in left.subtypes or
+ subtypes.KWARGS_STAR_STAR in left.subtypes):
# Don't add a space after a vararg's star or a keyword's star-star.
return False
- if lval == '@' and format_token.Subtype.DECORATOR in left.subtypes:
+ if lval == '@' and subtypes.DECORATOR in left.subtypes:
# Decorators shouldn't be separated from the 'at' sign.
return False
- if left.is_keyword and rval == '.' or lval == '.' and right.is_keyword:
+ if left.is_keyword and rval == '.':
+ # Add space between keywords and dots.
+ return lval not in {'None', 'print'}
+ if lval == '.' and right.is_keyword:
# Add space between keywords and dots.
- return lval != 'None'
+ return rval not in {'None', 'print'}
if lval == '.' or rval == '.':
# Don't place spaces between dots.
return False
@@ -327,53 +433,75 @@ def _SpaceRequiredBetween(left, right):
(lval == '{' and rval == '}')):
# Empty objects shouldn't be separated by spaces.
return False
+ if not is_line_disabled and (left.OpensScope() or right.ClosesScope()):
+ if (style.GetOrDefault('SPACES_AROUND_DICT_DELIMITERS', False) and (
+ (lval == '{' and _IsDictListTupleDelimiterTok(left, is_opening=True)) or
+ (rval == '}' and
+ _IsDictListTupleDelimiterTok(right, is_opening=False)))):
+ return True
+ if (style.GetOrDefault('SPACES_AROUND_LIST_DELIMITERS', False) and (
+ (lval == '[' and _IsDictListTupleDelimiterTok(left, is_opening=True)) or
+ (rval == ']' and
+ _IsDictListTupleDelimiterTok(right, is_opening=False)))):
+ return True
+ if (style.GetOrDefault('SPACES_AROUND_TUPLE_DELIMITERS', False) and (
+ (lval == '(' and _IsDictListTupleDelimiterTok(left, is_opening=True)) or
+ (rval == ')' and
+ _IsDictListTupleDelimiterTok(right, is_opening=False)))):
+ return True
if (lval in pytree_utils.OPENING_BRACKETS and
rval in pytree_utils.OPENING_BRACKETS):
- # Nested objects' opening brackets shouldn't be separated.
- return False
+ # Nested objects' opening brackets shouldn't be separated, unless enabled
+ # by SPACE_INSIDE_BRACKETS.
+ return style.Get('SPACE_INSIDE_BRACKETS')
if (lval in pytree_utils.CLOSING_BRACKETS and
rval in pytree_utils.CLOSING_BRACKETS):
- # Nested objects' closing brackets shouldn't be separated.
- return False
+ # Nested objects' closing brackets shouldn't be separated, unless enabled
+ # by SPACE_INSIDE_BRACKETS.
+ return style.Get('SPACE_INSIDE_BRACKETS')
if lval in pytree_utils.CLOSING_BRACKETS and rval in '([':
# A call, set, dictionary, or subscript that has a call or subscript after
# it shouldn't have a space between them.
return False
if lval in pytree_utils.OPENING_BRACKETS and _IsIdNumberStringToken(right):
- # Don't separate the opening bracket from the first item.
- return False
+ # Don't separate the opening bracket from the first item, unless enabled
+ # by SPACE_INSIDE_BRACKETS.
+ return style.Get('SPACE_INSIDE_BRACKETS')
if left.is_name and rval in '([':
# Don't separate a call or array access from the name.
return False
if rval in pytree_utils.CLOSING_BRACKETS:
- # Don't separate the closing bracket from the last item.
+ # Don't separate the closing bracket from the last item, unless enabled
+ # by SPACE_INSIDE_BRACKETS.
# FIXME(morbo): This might be too permissive.
- return False
+ return style.Get('SPACE_INSIDE_BRACKETS')
if lval == 'print' and rval == '(':
# Special support for the 'print' function.
return False
if lval in pytree_utils.OPENING_BRACKETS and _IsUnaryOperator(right):
- # Don't separate a unary operator from the opening bracket.
- return False
+ # Don't separate a unary operator from the opening bracket, unless enabled
+ # by SPACE_INSIDE_BRACKETS.
+ return style.Get('SPACE_INSIDE_BRACKETS')
if (lval in pytree_utils.OPENING_BRACKETS and
- (format_token.Subtype.VARARGS_STAR in right.subtypes or
- format_token.Subtype.KWARGS_STAR_STAR in right.subtypes)):
- # Don't separate a '*' or '**' from the opening bracket.
- return False
+ (subtypes.VARARGS_STAR in right.subtypes or
+ subtypes.KWARGS_STAR_STAR in right.subtypes)):
+ # Don't separate a '*' or '**' from the opening bracket, unless enabled
+ # by SPACE_INSIDE_BRACKETS.
+ return style.Get('SPACE_INSIDE_BRACKETS')
if rval == ';':
# Avoid spaces before a semicolon. (Why is there a semicolon?!)
return False
if lval == '(' and rval == 'await':
# Special support for the 'await' keyword. Don't separate the 'await'
- # keyword from an opening paren.
- return False
+ # keyword from an opening paren, unless enabled by SPACE_INSIDE_BRACKETS.
+ return style.Get('SPACE_INSIDE_BRACKETS')
return True
def _MustBreakBefore(prev_token, cur_token):
"""Return True if a line break is required before the current token."""
if prev_token.is_comment or (prev_token.previous_token and
- prev_token.is_pseudo_paren and
+ prev_token.is_pseudo and
prev_token.previous_token.is_comment):
# Must break if the previous token was a comment.
return True
@@ -383,8 +511,7 @@ def _MustBreakBefore(prev_token, cur_token):
# reasonable assumption, because otherwise they should have written them
# all on the same line, or with a '+'.
return True
- return pytree_utils.GetNodeAnnotation(
- cur_token.node, pytree_utils.Annotation.MUST_SPLIT, default=False)
+ return cur_token.must_break_before
def _CanBreakBefore(prev_token, cur_token):
@@ -415,15 +542,16 @@ def _CanBreakBefore(prev_token, cur_token):
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
- if format_token.Subtype.UNARY_OPERATOR in prev_token.subtypes:
+ if subtypes.UNARY_OPERATOR in prev_token.subtypes:
# Don't break after a unary token.
return False
+ if not style.Get('ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS'):
+ if (subtypes.DEFAULT_OR_NAMED_ASSIGN in cur_token.subtypes or
+ subtypes.DEFAULT_OR_NAMED_ASSIGN in prev_token.subtypes):
+ return False
return True
@@ -458,9 +586,36 @@ def IsSurroundedByBrackets(tok):
return None
+def _IsDictListTupleDelimiterTok(tok, is_opening):
+ assert tok
+
+ if tok.matching_bracket is None:
+ return False
+
+ if is_opening:
+ open_tok = tok
+ close_tok = tok.matching_bracket
+ else:
+ open_tok = tok.matching_bracket
+ close_tok = tok
+
+ # There must be something in between the tokens
+ if open_tok.next_token == close_tok:
+ return False
+
+ assert open_tok.next_token.node
+ assert open_tok.next_token.node.parent
+
+ return open_tok.next_token.node.parent.type in [
+ python_symbols.dictsetmaker,
+ python_symbols.listmaker,
+ python_symbols.testlist_gexp,
+ ]
+
+
_LOGICAL_OPERATORS = frozenset({'and', 'or'})
_BITWISE_OPERATORS = frozenset({'&', '|', '^'})
-_TERM_OPERATORS = frozenset({'*', '/', '%', '//'})
+_ARITHMETIC_OPERATORS = frozenset({'+', '-', '*', '/', '%', '//', '@'})
def _SplitPenalty(prev_token, cur_token):
@@ -499,21 +654,20 @@ def _SplitPenalty(prev_token, cur_token):
if cval in _BITWISE_OPERATORS:
return style.Get('SPLIT_PENALTY_BITWISE_OPERATOR')
- if (format_token.Subtype.COMP_FOR in cur_token.subtypes or
- format_token.Subtype.COMP_IF in cur_token.subtypes):
+ if (subtypes.COMP_FOR in cur_token.subtypes or
+ subtypes.COMP_IF in cur_token.subtypes):
# We don't mind breaking before the 'for' or 'if' of a list comprehension.
return 0
- if format_token.Subtype.UNARY_OPERATOR in prev_token.subtypes:
+ if subtypes.UNARY_OPERATOR in prev_token.subtypes:
# Try not to break after a unary operator.
return style.Get('SPLIT_PENALTY_AFTER_UNARY_OPERATOR')
if pval == ',':
# Breaking after a comma is fine, if need be.
return 0
- if prev_token.is_binary_op:
- # We would rather not split after an equality operator.
- return 20
- if (format_token.Subtype.VARARGS_STAR in prev_token.subtypes or
- format_token.Subtype.KWARGS_STAR_STAR in prev_token.subtypes):
+ if pval == '**' or cval == '**':
+ return split_penalty.STRONGLY_CONNECTED
+ if (subtypes.VARARGS_STAR in prev_token.subtypes or
+ subtypes.KWARGS_STAR_STAR in prev_token.subtypes):
# Don't split after a varargs * or kwargs **.
return split_penalty.UNBREAKABLE
if prev_token.OpensScope() and cval != '(':
@@ -525,8 +679,8 @@ def _SplitPenalty(prev_token, cur_token):
if cval == '=':
# Don't split before an assignment.
return split_penalty.UNBREAKABLE
- if (format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in prev_token.subtypes or
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in cur_token.subtypes):
+ if (subtypes.DEFAULT_OR_NAMED_ASSIGN in prev_token.subtypes or
+ subtypes.DEFAULT_OR_NAMED_ASSIGN in cur_token.subtypes):
# Don't break before or after an default or named assignment.
return split_penalty.UNBREAKABLE
if cval == '==':
@@ -535,6 +689,4 @@ def _SplitPenalty(prev_token, cur_token):
if cur_token.ClosesScope():
# Give a slight penalty for splitting before the closing scope.
return 100
- if pval in _TERM_OPERATORS or cval in _TERM_OPERATORS:
- return 50
return 0
diff --git a/yapf/yapflib/object_state.py b/yapf/yapflib/object_state.py
index dded7c4..07925ef 100644
--- a/yapf/yapflib/object_state.py
+++ b/yapf/yapflib/object_state.py
@@ -22,6 +22,11 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+from yapf.yapflib import format_token
+from yapf.yapflib import py3compat
+from yapf.yapflib import style
+from yapf.yapflib import subtypes
+
class ComprehensionState(object):
"""Maintains the state of list comprehension formatting decisions.
@@ -32,10 +37,12 @@ class ComprehensionState(object):
Attributes:
expr_token: The first token in the comprehension.
for_token: The first 'for' token of the comprehension.
+ opening_bracket: The opening bracket of the list comprehension.
+ closing_bracket: The closing bracket of the list comprehension.
has_split_at_for: Whether there is a newline immediately before the
- for_token.
+ for_token.
has_interior_split: Whether there is a newline within the comprehension.
- That is, a split somewhere after expr_token or before closing_bracket.
+ That is, a split somewhere after expr_token or before closing_bracket.
"""
def __init__(self, expr_token):
@@ -78,3 +85,149 @@ class ComprehensionState(object):
def __hash__(self, *args, **kwargs):
return hash((self.expr_token, self.for_token, self.has_split_at_for,
self.has_interior_split))
+
+
+class ParameterListState(object):
+ """Maintains the state of function parameter list formatting decisions.
+
+ Attributes:
+ opening_bracket: The opening bracket of the parameter list.
+ closing_bracket: The closing bracket of the parameter list.
+ has_typed_return: True if the function definition has a typed return.
+ ends_in_comma: True if the parameter list ends in a comma.
+ last_token: Returns the last token of the function declaration.
+ has_default_values: True if the parameters have default values.
+ has_split_before_first_param: Whether there is a newline before the first
+ parameter.
+ opening_column: The position of the opening parameter before a newline.
+ parameters: A list of parameter objects (Parameter).
+ split_before_closing_bracket: Split before the closing bracket. Sometimes
+ needed if the indentation would collide.
+ """
+
+ def __init__(self, opening_bracket, newline, opening_column):
+ self.opening_bracket = opening_bracket
+ self.has_split_before_first_param = newline
+ self.opening_column = opening_column
+ self.parameters = opening_bracket.parameters
+ self.split_before_closing_bracket = False
+
+ @property
+ def closing_bracket(self):
+ return self.opening_bracket.matching_bracket
+
+ @property
+ def has_typed_return(self):
+ return self.closing_bracket.next_token.value == '->'
+
+ @property
+ @py3compat.lru_cache()
+ def has_default_values(self):
+ return any(param.has_default_value for param in self.parameters)
+
+ @property
+ @py3compat.lru_cache()
+ def ends_in_comma(self):
+ if not self.parameters:
+ return False
+ return self.parameters[-1].last_token.next_token.value == ','
+
+ @property
+ @py3compat.lru_cache()
+ def last_token(self):
+ token = self.opening_bracket.matching_bracket
+ while not token.is_comment and token.next_token:
+ token = token.next_token
+ return token
+
+ @py3compat.lru_cache()
+ def LastParamFitsOnLine(self, indent):
+ """Return true if the last parameter fits on a single line."""
+ if not self.has_typed_return:
+ return False
+ if not self.parameters:
+ return True
+ total_length = self.last_token.total_length
+ last_param = self.parameters[-1].first_token
+ total_length -= last_param.total_length - len(last_param.value)
+ return total_length + indent <= style.Get('COLUMN_LIMIT')
+
+ @py3compat.lru_cache()
+ def SplitBeforeClosingBracket(self, indent):
+ """Return true if there's a split before the closing bracket."""
+ if style.Get('DEDENT_CLOSING_BRACKETS'):
+ return True
+ if self.ends_in_comma:
+ return True
+ if not self.parameters:
+ return False
+ total_length = self.last_token.total_length
+ last_param = self.parameters[-1].first_token
+ total_length -= last_param.total_length - len(last_param.value)
+ return total_length + indent > style.Get('COLUMN_LIMIT')
+
+ def Clone(self):
+ clone = ParameterListState(self.opening_bracket,
+ self.has_split_before_first_param,
+ self.opening_column)
+ clone.split_before_closing_bracket = self.split_before_closing_bracket
+ clone.parameters = [param.Clone() for param in self.parameters]
+ return clone
+
+ def __repr__(self):
+ return ('[opening_bracket::%s, has_split_before_first_param::%s, '
+ 'opening_column::%d]' %
+ (self.opening_bracket, self.has_split_before_first_param,
+ self.opening_column))
+
+ def __eq__(self, other):
+ return hash(self) == hash(other)
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self, *args, **kwargs):
+ return hash(
+ (self.opening_bracket, self.has_split_before_first_param,
+ self.opening_column, (hash(param) for param in self.parameters)))
+
+
+class Parameter(object):
+ """A parameter in a parameter list.
+
+ Attributes:
+ first_token: (format_token.FormatToken) First token of parameter.
+ last_token: (format_token.FormatToken) Last token of parameter.
+ has_default_value: (boolean) True if the parameter has a default value
+ """
+
+ def __init__(self, first_token, last_token):
+ self.first_token = first_token
+ self.last_token = last_token
+
+ @property
+ @py3compat.lru_cache()
+ def has_default_value(self):
+ """Returns true if the parameter has a default value."""
+ tok = self.first_token
+ while tok != self.last_token:
+ if subtypes.DEFAULT_OR_NAMED_ASSIGN in tok.subtypes:
+ return True
+ tok = tok.matching_bracket if tok.OpensScope() else tok.next_token
+ return False
+
+ def Clone(self):
+ return Parameter(self.first_token, self.last_token)
+
+ def __repr__(self):
+ return '[first_token::%s, last_token:%s]' % (self.first_token,
+ self.last_token)
+
+ def __eq__(self, other):
+ return hash(self) == hash(other)
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self, *args, **kwargs):
+ return hash((self.first_token, self.last_token))
diff --git a/yapf/yapflib/py3compat.py b/yapf/yapflib/py3compat.py
index c66d6c6..8f15476 100644
--- a/yapf/yapflib/py3compat.py
+++ b/yapf/yapflib/py3compat.py
@@ -13,20 +13,23 @@
# limitations under the License.
"""Utilities for Python2 / Python3 compatibility."""
+import codecs
import io
import os
import sys
PY3 = sys.version_info[0] >= 3
PY36 = sys.version_info[0] >= 3 and sys.version_info[1] >= 6
+PY37 = sys.version_info[0] >= 3 and sys.version_info[1] >= 7
+PY38 = sys.version_info[0] >= 3 and sys.version_info[1] >= 8
if PY3:
StringIO = io.StringIO
BytesIO = io.BytesIO
- import codecs
+ import codecs # noqa: F811
- def open_with_encoding(filename, mode, encoding, newline=''): # pylint: disable=unused-argument
+ def open_with_encoding(filename, mode, encoding, newline=''): # pylint: disable=unused-argument # noqa
return codecs.open(filename, mode=mode, encoding=encoding)
import functools
@@ -59,13 +62,13 @@ else:
return fake_wrapper
- range = xrange
+ range = xrange # noqa: F821
from itertools import ifilter
raw_input = raw_input
import ConfigParser as configparser
- CONFIGPARSER_BOOLEAN_STATES = configparser.ConfigParser._boolean_states # pylint: disable=protected-access
+ CONFIGPARSER_BOOLEAN_STATES = configparser.ConfigParser._boolean_states # pylint: disable=protected-access # noqa
def EncodeAndWriteToStdout(s, encoding='utf-8'):
@@ -116,3 +119,13 @@ class ConfigParser(configparser.ConfigParser):
def read_file(self, fp, source=None):
self.readfp(fp, filename=source)
+
+
+def removeBOM(source):
+ """Remove any Byte-order-Mark bytes from the beginning of a file."""
+ bom = codecs.BOM_UTF8
+ if PY3:
+ bom = bom.decode('utf-8')
+ if source.startswith(bom):
+ return source[len(bom):]
+ return source
diff --git a/yapf/yapflib/pytree_unwrapper.py b/yapf/yapflib/pytree_unwrapper.py
index 0d371ae..1b05b0e 100644
--- a/yapf/yapflib/pytree_unwrapper.py
+++ b/yapf/yapflib/pytree_unwrapper.py
@@ -11,13 +11,13 @@
# 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.
-"""PyTreeUnwrapper - produces a list of unwrapped lines from a pytree.
+"""PyTreeUnwrapper - produces a list of logical lines from a pytree.
-[for a description of what an unwrapped line is, see unwrapped_line.py]
+[for a description of what a logical line is, see logical_line.py]
This is a pytree visitor that goes over a parse tree and produces a list of
-UnwrappedLine containers from it, each with its own depth and containing all
-the tokens that could fit on the line if there were no maximal line-length
+LogicalLine containers from it, each with its own depth and containing all the
+tokens that could fit on the line if there were no maximal line-length
limitations.
Note: a precondition to running this visitor and obtaining correct results is
@@ -31,27 +31,30 @@ For most uses, the convenience function UnwrapPyTree should be sufficient.
from lib2to3 import pytree
from lib2to3.pgen2 import token as grammar_token
+from yapf.yapflib import format_token
+from yapf.yapflib import logical_line
+from yapf.yapflib import object_state
from yapf.yapflib import pytree_utils
from yapf.yapflib import pytree_visitor
from yapf.yapflib import split_penalty
from yapf.yapflib import style
-from yapf.yapflib import unwrapped_line
+from yapf.yapflib import subtypes
def UnwrapPyTree(tree):
- """Create and return a list of unwrapped lines from the given pytree.
+ """Create and return a list of logical lines from the given pytree.
Arguments:
- tree: the top-level pytree node to unwrap.
+ tree: the top-level pytree node to unwrap..
Returns:
- A list of UnwrappedLine objects.
+ A list of LogicalLine objects.
"""
unwrapper = PyTreeUnwrapper()
unwrapper.Visit(tree)
- uwlines = unwrapper.GetUnwrappedLines()
- uwlines.sort(key=lambda x: x.lineno)
- return uwlines
+ llines = unwrapper.GetLogicalLines()
+ llines.sort(key=lambda x: x.lineno)
+ return llines
# Grammar tokens considered as whitespace for the purpose of unwrapping.
@@ -77,39 +80,40 @@ class PyTreeUnwrapper(pytree_visitor.PyTreeVisitor):
"""
def __init__(self):
- # A list of all unwrapped lines finished visiting so far.
- self._unwrapped_lines = []
+ # A list of all logical lines finished visiting so far.
+ self._logical_lines = []
- # Builds up a "current" unwrapped line while visiting pytree nodes. Some
- # nodes will finish a line and start a new one.
- self._cur_unwrapped_line = unwrapped_line.UnwrappedLine(0)
+ # Builds up a "current" logical line while visiting pytree nodes. Some nodes
+ # will finish a line and start a new one.
+ self._cur_logical_line = logical_line.LogicalLine(0)
# Current indentation depth.
self._cur_depth = 0
- def GetUnwrappedLines(self):
+ def GetLogicalLines(self):
"""Fetch the result of the tree walk.
Note: only call this after visiting the whole tree.
Returns:
- A list of UnwrappedLine objects.
+ A list of LogicalLine objects.
"""
# Make sure the last line that was being populated is flushed.
self._StartNewLine()
- return self._unwrapped_lines
+ return self._logical_lines
def _StartNewLine(self):
"""Finish current line and start a new one.
- Place the currently accumulated line into the _unwrapped_lines list and
+ Place the currently accumulated line into the _logical_lines list and
start a new one.
"""
- if self._cur_unwrapped_line.tokens:
- self._unwrapped_lines.append(self._cur_unwrapped_line)
- _MatchBrackets(self._cur_unwrapped_line)
- _AdjustSplitPenalty(self._cur_unwrapped_line)
- self._cur_unwrapped_line = unwrapped_line.UnwrappedLine(self._cur_depth)
+ if self._cur_logical_line.tokens:
+ self._logical_lines.append(self._cur_logical_line)
+ _MatchBrackets(self._cur_logical_line)
+ _IdentifyParameterLists(self._cur_logical_line)
+ _AdjustSplitPenalty(self._cur_logical_line)
+ self._cur_logical_line = logical_line.LogicalLine(self._cur_depth)
_STMT_TYPES = frozenset({
'if_stmt',
@@ -148,7 +152,7 @@ class PyTreeUnwrapper(pytree_visitor.PyTreeVisitor):
"""Helper for visiting compound statements.
Python compound statements serve as containers for other statements. Thus,
- when we encounter a new compound statement we start a new unwrapped line.
+ when we encounter a new compound statement, we start a new logical line.
Arguments:
node: the node to visit.
@@ -202,7 +206,7 @@ class PyTreeUnwrapper(pytree_visitor.PyTreeVisitor):
for child in node.children:
index += 1
self.Visit(child)
- if pytree_utils.NodeName(child) == 'ASYNC':
+ if child.type == grammar_token.ASYNC:
break
for child in node.children[index].children:
self.Visit(child)
@@ -218,16 +222,17 @@ class PyTreeUnwrapper(pytree_visitor.PyTreeVisitor):
for child in node.children:
index += 1
self.Visit(child)
- if pytree_utils.NodeName(child) == 'ASYNC':
+ if child.type == grammar_token.ASYNC:
break
for child in node.children[index].children:
+ if child.type == grammar_token.NAME and child.value == 'else':
+ self._StartNewLine()
self.Visit(child)
def Visit_decorator(self, node): # pylint: disable=invalid-name
for child in node.children:
self.Visit(child)
- if (pytree_utils.NodeName(child) == 'COMMENT' and
- child == node.children[0]):
+ if child.type == grammar_token.COMMENT and child == node.children[0]:
self._StartNewLine()
def Visit_decorators(self, node): # pylint: disable=invalid-name
@@ -280,7 +285,7 @@ class PyTreeUnwrapper(pytree_visitor.PyTreeVisitor):
def DefaultLeafVisit(self, leaf):
"""Default visitor for tree leaves.
- A tree leaf is always just gets appended to the current unwrapped line.
+ A tree leaf is always just gets appended to the current logical line.
Arguments:
leaf: the leaf to visit.
@@ -289,13 +294,13 @@ class PyTreeUnwrapper(pytree_visitor.PyTreeVisitor):
self._StartNewLine()
elif leaf.type != grammar_token.COMMENT or leaf.value.strip():
# Add non-whitespace tokens and comments that aren't empty.
- self._cur_unwrapped_line.AppendNode(leaf)
+ self._cur_logical_line.AppendNode(leaf)
_BRACKET_MATCH = {')': '(', '}': '{', ']': '['}
-def _MatchBrackets(uwline):
+def _MatchBrackets(line):
"""Visit the node and match the brackets.
For every open bracket ('[', '{', or '('), find the associated closing bracket
@@ -303,10 +308,10 @@ def _MatchBrackets(uwline):
or close bracket.
Arguments:
- uwline: (UnwrappedLine) An unwrapped line.
+ line: (LogicalLine) A logical line.
"""
bracket_stack = []
- for token in uwline.tokens:
+ for token in line.tokens:
if token.value in pytree_utils.OPENING_BRACKETS:
bracket_stack.append(token)
elif token.value in pytree_utils.CLOSING_BRACKETS:
@@ -320,17 +325,50 @@ def _MatchBrackets(uwline):
token.container_opening = bracket
-def _AdjustSplitPenalty(uwline):
+def _IdentifyParameterLists(line):
+ """Visit the node to create a state for parameter lists.
+
+ For instance, a parameter is considered an "object" with its first and last
+ token uniquely identifying the object.
+
+ Arguments:
+ line: (LogicalLine) A logical line.
+ """
+ func_stack = []
+ param_stack = []
+ for tok in line.tokens:
+ # Identify parameter list objects.
+ if subtypes.FUNC_DEF in tok.subtypes:
+ assert tok.next_token.value == '('
+ func_stack.append(tok.next_token)
+ continue
+
+ if func_stack and tok.value == ')':
+ if tok == func_stack[-1].matching_bracket:
+ func_stack.pop()
+ continue
+
+ # Identify parameter objects.
+ if subtypes.PARAMETER_START in tok.subtypes:
+ param_stack.append(tok)
+
+ # Not "elif", a parameter could be a single token.
+ if param_stack and subtypes.PARAMETER_STOP in tok.subtypes:
+ start = param_stack.pop()
+ func_stack[-1].parameters.append(object_state.Parameter(start, tok))
+
+
+def _AdjustSplitPenalty(line):
"""Visit the node and adjust the split penalties if needed.
A token shouldn't be split if it's not within a bracket pair. Mark any token
that's not within a bracket pair as "unbreakable".
Arguments:
- uwline: (UnwrappedLine) An unwrapped line.
+ line: (LogicalLine) An logical line.
"""
bracket_level = 0
- for index, token in enumerate(uwline.tokens):
+ for index, token in enumerate(line.tokens):
if index and not bracket_level:
pytree_utils.SetNodeAnnotation(token.node,
pytree_utils.Annotation.SPLIT_PENALTY,
@@ -348,8 +386,7 @@ def _DetermineMustSplitAnnotation(node):
if not _ContainsComments(node):
token = next(node.parent.leaves())
if token.value == '(':
- if sum(1 for ch in node.children
- if pytree_utils.NodeName(ch) == 'COMMA') < 2:
+ if sum(1 for ch in node.children if ch.type == grammar_token.COMMA) < 2:
return
if (not isinstance(node.children[-1], pytree.Leaf) or
node.children[-1].value != ','):
diff --git a/yapf/yapflib/pytree_utils.py b/yapf/yapflib/pytree_utils.py
index 999ba88..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).
@@ -219,6 +223,18 @@ def _InsertNodeAt(new_node, target, after=False):
_NODE_ANNOTATION_PREFIX = '_yapf_annotation_'
+def CopyYapfAnnotations(src, dst):
+ """Copy all YAPF annotations from the source node to the destination node.
+
+ Arguments:
+ 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 --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/reformatter.py b/yapf/yapflib/reformatter.py
index 6539e68..b6e6a13 100644
--- a/yapf/yapflib/reformatter.py
+++ b/yapf/yapflib/reformatter.py
@@ -13,9 +13,8 @@
# limitations under the License.
"""Decide what the format for the code should be.
-The `unwrapped_line.UnwrappedLine`s are now ready to be formatted.
-UnwrappedLines that can be merged together are. The best formatting is returned
-as a string.
+The `logical_line.LogicalLine`s are now ready to be formatted. LogicalLInes that
+can be merged together are. The best formatting is returned as a string.
Reformat(): the main function exported by this module.
"""
@@ -36,11 +35,11 @@ from yapf.yapflib import style
from yapf.yapflib import verifier
-def Reformat(uwlines, verify=False, lines=None):
- """Reformat the unwrapped lines.
+def Reformat(llines, verify=False, lines=None):
+ """Reformat the logical lines.
Arguments:
- uwlines: (list of unwrapped_line.UnwrappedLine) Lines we want to format.
+ llines: (list of logical_line.LogicalLine) Lines we want to format.
verify: (bool) True if reformatted code should be verified for syntax.
lines: (set of int) The lines which can be modified or None if there is no
line range restriction.
@@ -49,66 +48,81 @@ def Reformat(uwlines, verify=False, lines=None):
A string representing the reformatted code.
"""
final_lines = []
- prev_uwline = None # The previous line.
+ prev_line = None # The previous line.
indent_width = style.Get('INDENT_WIDTH')
- for uwline in _SingleOrMergedLines(uwlines):
- first_token = uwline.first
- _FormatFirstToken(first_token, uwline.depth, prev_uwline, final_lines)
+ for lline in _SingleOrMergedLines(llines):
+ first_token = lline.first
+ _FormatFirstToken(first_token, lline.depth, prev_line, final_lines)
- indent_amt = indent_width * uwline.depth
- state = format_decision_state.FormatDecisionState(uwline, indent_amt)
+ indent_amt = indent_width * lline.depth
+ state = format_decision_state.FormatDecisionState(lline, indent_amt)
state.MoveStateToNextToken()
- if not uwline.disable:
- if uwline.first.is_comment:
- uwline.first.node.value = uwline.first.node.value.rstrip()
- elif uwline.last.is_comment:
- uwline.last.node.value = uwline.last.node.value.rstrip()
- if prev_uwline and prev_uwline.disable:
+ if not lline.disable:
+ if lline.first.is_comment:
+ lline.first.node.value = lline.first.node.value.rstrip()
+ elif lline.last.is_comment:
+ lline.last.node.value = lline.last.node.value.rstrip()
+ if prev_line and prev_line.disable:
# Keep the vertical spacing between a disabled and enabled formatting
# region.
- _RetainRequiredVerticalSpacingBetweenTokens(uwline.first,
- prev_uwline.last, lines)
- if any(tok.is_comment for tok in uwline.tokens):
- _RetainVerticalSpacingBeforeComments(uwline)
-
- if (_LineContainsI18n(uwline) or uwline.disable or
- _LineHasContinuationMarkers(uwline)):
- _RetainHorizontalSpacing(uwline)
- _RetainRequiredVerticalSpacing(uwline, prev_uwline, lines)
+ _RetainRequiredVerticalSpacingBetweenTokens(lline.first, prev_line.last,
+ lines)
+ if any(tok.is_comment for tok in lline.tokens):
+ _RetainVerticalSpacingBeforeComments(lline)
+
+ if lline.disable or _LineHasContinuationMarkers(lline):
+ _RetainHorizontalSpacing(lline)
+ _RetainRequiredVerticalSpacing(lline, prev_line, lines)
_EmitLineUnformatted(state)
- elif _CanPlaceOnSingleLine(uwline) and not any(tok.must_split
- for tok in uwline.tokens):
- # The unwrapped line fits on one line.
+
+ elif (_LineContainsPylintDisableLineTooLong(lline) or
+ _LineContainsI18n(lline)):
+ # Don't modify vertical spacing, but fix any horizontal spacing issues.
+ _RetainRequiredVerticalSpacing(lline, prev_line, lines)
+ _EmitLineUnformatted(state)
+
+ elif _CanPlaceOnSingleLine(lline) and not any(tok.must_break_before
+ for tok in lline.tokens):
+ # The logical line fits on one line.
while state.next_token:
state.AddTokenToState(newline=False, dry_run=False)
- else:
- if not _AnalyzeSolutionSpace(state):
- # Failsafe mode. If there isn't a solution to the line, then just emit
- # it as is.
- state = format_decision_state.FormatDecisionState(uwline, indent_amt)
- state.MoveStateToNextToken()
- _RetainHorizontalSpacing(uwline)
- _RetainRequiredVerticalSpacing(uwline, prev_uwline, None)
- _EmitLineUnformatted(state)
-
- final_lines.append(uwline)
- prev_uwline = uwline
+
+ elif not _AnalyzeSolutionSpace(state):
+ # Failsafe mode. If there isn't a solution to the line, then just emit
+ # it as is.
+ state = format_decision_state.FormatDecisionState(lline, indent_amt)
+ state.MoveStateToNextToken()
+ _RetainHorizontalSpacing(lline)
+ _RetainRequiredVerticalSpacing(lline, prev_line, None)
+ _EmitLineUnformatted(state)
+
+ final_lines.append(lline)
+ prev_line = lline
+
+ _AlignTrailingComments(final_lines)
return _FormatFinalLines(final_lines, verify)
-def _RetainHorizontalSpacing(uwline):
+def _RetainHorizontalSpacing(line):
"""Retain all horizontal spacing between tokens."""
- for tok in uwline.tokens:
- tok.RetainHorizontalSpacing(uwline.first.column, uwline.depth)
+ for tok in line.tokens:
+ tok.RetainHorizontalSpacing(line.first.column, line.depth)
-def _RetainRequiredVerticalSpacing(cur_uwline, prev_uwline, lines):
+def _RetainRequiredVerticalSpacing(cur_line, prev_line, lines):
+ """Retain all vertical spacing between lines."""
prev_tok = None
- if prev_uwline is not None:
- prev_tok = prev_uwline.last
- for cur_tok in cur_uwline.tokens:
+ if prev_line is not None:
+ prev_tok = prev_line.last
+
+ if cur_line.disable:
+ # After the first token we are acting on a single line. So if it is
+ # disabled we must not reformat.
+ lines = set()
+
+ for cur_tok in cur_line.tokens:
_RetainRequiredVerticalSpacingBetweenTokens(cur_tok, prev_tok, lines)
prev_tok = cur_tok
@@ -120,7 +134,7 @@ def _RetainRequiredVerticalSpacingBetweenTokens(cur_tok, prev_tok, lines):
if prev_tok.is_string:
prev_lineno = prev_tok.lineno + prev_tok.value.count('\n')
- elif prev_tok.is_pseudo_paren:
+ elif prev_tok.is_pseudo:
if not prev_tok.previous_token.is_multiline_string:
prev_lineno = prev_tok.previous_token.lineno
else:
@@ -133,14 +147,14 @@ def _RetainRequiredVerticalSpacingBetweenTokens(cur_tok, prev_tok, lines):
else:
cur_lineno = cur_tok.lineno
- if prev_tok.value.endswith('\\'):
+ if not prev_tok.is_comment and prev_tok.value.endswith('\\'):
prev_lineno += prev_tok.value.count('\n')
required_newlines = cur_lineno - prev_lineno
if cur_tok.is_comment and not prev_tok.is_comment:
# Don't adjust between a comment and non-comment.
pass
- elif lines and (cur_lineno in lines or prev_lineno in lines):
+ elif lines and lines.intersection(range(prev_lineno, cur_lineno + 1)):
desired_newlines = cur_tok.whitespace_prefix.count('\n')
whitespace_lines = range(prev_lineno + 1, cur_lineno)
deletable_lines = len(lines.intersection(whitespace_lines))
@@ -150,10 +164,10 @@ def _RetainRequiredVerticalSpacingBetweenTokens(cur_tok, prev_tok, lines):
cur_tok.AdjustNewlinesBefore(required_newlines)
-def _RetainVerticalSpacingBeforeComments(uwline):
+def _RetainVerticalSpacingBeforeComments(line):
"""Retain vertical spacing before comments."""
prev_token = None
- for tok in uwline.tokens:
+ for tok in line.tokens:
if tok.is_comment and prev_token:
if tok.lineno - tok.value.count('\n') - prev_token.lineno > 1:
tok.AdjustNewlinesBefore(ONE_BLANK_LINE)
@@ -173,7 +187,6 @@ def _EmitLineUnformatted(state):
state: (format_decision_state.FormatDecisionState) The format decision
state.
"""
- prev_lineno = None
while state.next_token:
previous_token = state.next_token.previous_token
previous_lineno = previous_token.lineno
@@ -184,67 +197,200 @@ def _EmitLineUnformatted(state):
if previous_token.is_continuation:
newline = False
else:
- newline = (
- prev_lineno is not None and state.next_token.lineno > previous_lineno)
+ newline = state.next_token.lineno > previous_lineno
- prev_lineno = state.next_token.lineno
state.AddTokenToState(newline=newline, dry_run=False)
-def _LineContainsI18n(uwline):
+def _LineContainsI18n(line):
"""Return true if there are i18n comments or function calls in the line.
I18n comments and pseudo-function calls are closely related. They cannot
be moved apart without breaking i18n.
Arguments:
- uwline: (unwrapped_line.UnwrappedLine) The line currently being formatted.
+ line: (logical_line.LogicalLine) The line currently being formatted.
Returns:
True if the line contains i18n comments or function calls. False otherwise.
"""
if style.Get('I18N_COMMENT'):
- for tok in uwline.tokens:
+ for tok in line.tokens:
if tok.is_comment and re.match(style.Get('I18N_COMMENT'), tok.value):
# Contains an i18n comment.
return True
if style.Get('I18N_FUNCTION_CALL'):
- length = len(uwline.tokens)
- index = 0
- while index < length - 1:
- if (uwline.tokens[index + 1].value == '(' and
- uwline.tokens[index].value in style.Get('I18N_FUNCTION_CALL')):
+ length = len(line.tokens)
+ for index in range(length - 1):
+ if (line.tokens[index + 1].value == '(' and
+ line.tokens[index].value in style.Get('I18N_FUNCTION_CALL')):
return True
- index += 1
-
return False
-def _LineHasContinuationMarkers(uwline):
+def _LineContainsPylintDisableLineTooLong(line):
+ """Return true if there is a "pylint: disable=line-too-long" comment."""
+ return re.search(r'\bpylint:\s+disable=line-too-long\b', line.last.value)
+
+
+def _LineHasContinuationMarkers(line):
"""Return true if the line has continuation markers in it."""
- return any(tok.is_continuation for tok in uwline.tokens)
+ return any(tok.is_continuation for tok in line.tokens)
-def _CanPlaceOnSingleLine(uwline):
- """Determine if the unwrapped line can go on a single line.
+def _CanPlaceOnSingleLine(line):
+ """Determine if the logical line can go on a single line.
Arguments:
- uwline: (unwrapped_line.UnwrappedLine) The line currently being formatted.
+ line: (logical_line.LogicalLine) The line currently being formatted.
Returns:
True if the line can or should be added to a single line. False otherwise.
"""
- indent_amt = style.Get('INDENT_WIDTH') * uwline.depth
- last = uwline.last
+ token_names = [x.name for x in line.tokens]
+ if (style.Get('FORCE_MULTILINE_DICT') and 'LBRACE' in token_names):
+ return False
+ indent_amt = style.Get('INDENT_WIDTH') * line.depth
+ last = line.last
last_index = -1
- if last.is_pylint_comment or last.is_pytype_comment:
+ if (last.is_pylint_comment or last.is_pytype_comment or
+ last.is_copybara_comment):
last = last.previous_token
last_index = -2
if last is None:
return True
return (last.total_length + indent_amt <= style.Get('COLUMN_LIMIT') and
- not any(tok.is_comment for tok in uwline.tokens[:last_index]))
+ not any(tok.is_comment for tok in line.tokens[:last_index]))
+
+
+def _AlignTrailingComments(final_lines):
+ """Align trailing comments to the same column."""
+ final_lines_index = 0
+ while final_lines_index < len(final_lines):
+ line = final_lines[final_lines_index]
+ assert line.tokens
+
+ processed_content = False
+
+ for tok in line.tokens:
+ if (tok.is_comment and isinstance(tok.spaces_required_before, list) and
+ tok.value.startswith('#')):
+ # All trailing comments and comments that appear on a line by themselves
+ # in this block should be indented at the same level. The block is
+ # terminated by an empty line or EOF. Enumerate through each line in
+ # the block and calculate the max line length. Once complete, use the
+ # first col value greater than that value and create the necessary for
+ # each line accordingly.
+ all_pc_line_lengths = [] # All pre-comment line lengths
+ max_line_length = 0
+
+ while True:
+ # EOF
+ if final_lines_index + len(all_pc_line_lengths) == len(final_lines):
+ break
+
+ this_line = final_lines[final_lines_index + len(all_pc_line_lengths)]
+
+ # Blank line - note that content is preformatted so we don't need to
+ # worry about spaces/tabs; a blank line will always be '\n\n'.
+ assert this_line.tokens
+ if (all_pc_line_lengths and
+ this_line.tokens[0].formatted_whitespace_prefix.startswith('\n\n')
+ ):
+ break
+
+ if this_line.disable:
+ all_pc_line_lengths.append([])
+ continue
+
+ # Calculate the length of each line in this logical line.
+ line_content = ''
+ pc_line_lengths = []
+
+ for line_tok in this_line.tokens:
+ whitespace_prefix = line_tok.formatted_whitespace_prefix
+
+ newline_index = whitespace_prefix.rfind('\n')
+ if newline_index != -1:
+ max_line_length = max(max_line_length, len(line_content))
+ line_content = ''
+
+ whitespace_prefix = whitespace_prefix[newline_index + 1:]
+
+ if line_tok.is_comment:
+ pc_line_lengths.append(len(line_content))
+ else:
+ line_content += '{}{}'.format(whitespace_prefix, line_tok.value)
+
+ if pc_line_lengths:
+ max_line_length = max(max_line_length, max(pc_line_lengths))
+
+ all_pc_line_lengths.append(pc_line_lengths)
+
+ # Calculate the aligned column value
+ max_line_length += 2
+
+ aligned_col = None
+ for potential_col in tok.spaces_required_before:
+ if potential_col > max_line_length:
+ aligned_col = potential_col
+ break
+
+ if aligned_col is None:
+ aligned_col = max_line_length
+
+ # Update the comment token values based on the aligned values
+ for all_pc_line_lengths_index, pc_line_lengths in enumerate(
+ all_pc_line_lengths):
+ if not pc_line_lengths:
+ continue
+
+ this_line = final_lines[final_lines_index + all_pc_line_lengths_index]
+
+ pc_line_length_index = 0
+ for line_tok in this_line.tokens:
+ if line_tok.is_comment:
+ assert pc_line_length_index < len(pc_line_lengths)
+ assert pc_line_lengths[pc_line_length_index] < aligned_col
+
+ # Note that there may be newlines embedded in the comments, so
+ # we need to apply a whitespace prefix to each line.
+ whitespace = ' ' * (
+ aligned_col - pc_line_lengths[pc_line_length_index] - 1)
+ pc_line_length_index += 1
+
+ line_content = []
+
+ for comment_line_index, comment_line in enumerate(
+ line_tok.value.split('\n')):
+ line_content.append('{}{}'.format(whitespace,
+ comment_line.strip()))
+
+ if comment_line_index == 0:
+ whitespace = ' ' * (aligned_col - 1)
+
+ line_content = '\n'.join(line_content)
+
+ # Account for initial whitespace already slated for the
+ # beginning of the line.
+ existing_whitespace_prefix = \
+ line_tok.formatted_whitespace_prefix.lstrip('\n')
+
+ if line_content.startswith(existing_whitespace_prefix):
+ line_content = line_content[len(existing_whitespace_prefix):]
+
+ line_tok.value = line_content
+
+ assert pc_line_length_index == len(pc_line_lengths)
+
+ final_lines_index += len(all_pc_line_lengths)
+
+ processed_content = True
+ break
+
+ if not processed_content:
+ final_lines_index += 1
def _FormatFinalLines(final_lines, verify):
@@ -253,15 +399,14 @@ def _FormatFinalLines(final_lines, verify):
for line in final_lines:
formatted_line = []
for tok in line.tokens:
- if not tok.is_pseudo_paren:
- formatted_line.append(tok.whitespace_prefix)
+ if not tok.is_pseudo:
+ formatted_line.append(tok.formatted_whitespace_prefix)
formatted_line.append(tok.value)
- else:
- if (not tok.next_token.whitespace_prefix.startswith('\n') and
+ elif (not tok.next_token.whitespace_prefix.startswith('\n') and
not tok.next_token.whitespace_prefix.startswith(' ')):
- if (tok.previous_token.value == ':' or
- tok.next_token.value not in ',}])'):
- formatted_line.append(' ')
+ if (tok.previous_token.value == ':' or
+ tok.next_token.value not in ',}])'):
+ formatted_line.append(' ')
formatted_code.append(''.join(formatted_line))
if verify:
@@ -340,10 +485,13 @@ def _AnalyzeSolutionSpace(initial_state):
if count > 10000:
node.state.ignore_stack_for_comparison = True
- if node.state in seen:
- continue
-
+ # Unconditionally add the state and check if it was present to avoid having
+ # to hash it twice in the common case (state hashing is expensive).
+ before_seen_count = len(seen)
seen.add(node.state)
+ # If seen didn't change size, the state was already present.
+ if before_seen_count == len(seen):
+ continue
# FIXME(morbo): Add a 'decision' element?
@@ -409,24 +557,38 @@ def _ReconstructPath(initial_state, current):
initial_state.AddTokenToState(newline=node.newline, dry_run=False)
-def _FormatFirstToken(first_token, indent_depth, prev_uwline, final_lines):
- """Format the first token in the unwrapped line.
+NESTED_DEPTH = []
+
- Add a newline and the required indent before the first token of the unwrapped
+def _FormatFirstToken(first_token, indent_depth, prev_line, final_lines):
+ """Format the first token in the logical line.
+
+ Add a newline and the required indent before the first token of the logical
line.
Arguments:
- first_token: (format_token.FormatToken) The first token in the unwrapped
- line.
+ first_token: (format_token.FormatToken) The first token in the logical line.
indent_depth: (int) The line's indentation depth.
- prev_uwline: (list of unwrapped_line.UnwrappedLine) The unwrapped line
- previous to this line.
- final_lines: (list of unwrapped_line.UnwrappedLine) The unwrapped lines
- that have already been processed.
+ prev_line: (list of logical_line.LogicalLine) The logical line previous to
+ this line.
+ final_lines: (list of logical_line.LogicalLine) The logical lines that have
+ already been processed.
"""
+ global NESTED_DEPTH
+ while NESTED_DEPTH and NESTED_DEPTH[-1] > indent_depth:
+ NESTED_DEPTH.pop()
+
+ first_nested = False
+ if _IsClassOrDef(first_token):
+ if not NESTED_DEPTH:
+ NESTED_DEPTH = [indent_depth]
+ elif NESTED_DEPTH[-1] < indent_depth:
+ first_nested = True
+ NESTED_DEPTH.append(indent_depth)
+
first_token.AddWhitespacePrefix(
- _CalculateNumberOfNewlines(first_token, indent_depth, prev_uwline,
- final_lines),
+ _CalculateNumberOfNewlines(first_token, indent_depth, prev_line,
+ final_lines, first_nested),
indent_level=indent_depth)
@@ -435,70 +597,82 @@ ONE_BLANK_LINE = 2
TWO_BLANK_LINES = 3
-def _IsClassOrDef(uwline):
- if uwline.first.value in {'class', 'def'}:
+def _IsClassOrDef(tok):
+ if tok.value in {'class', 'def', '@'}:
return True
-
- return [t.value for t in uwline.tokens[:2]] == ['async', 'def']
+ return (tok.next_token and tok.value == 'async' and
+ tok.next_token.value == 'def')
-def _CalculateNumberOfNewlines(first_token, indent_depth, prev_uwline,
- final_lines):
+def _CalculateNumberOfNewlines(first_token, indent_depth, prev_line,
+ final_lines, first_nested):
"""Calculate the number of newlines we need to add.
Arguments:
- first_token: (format_token.FormatToken) The first token in the unwrapped
+ first_token: (format_token.FormatToken) The first token in the logical
line.
indent_depth: (int) The line's indentation depth.
- prev_uwline: (list of unwrapped_line.UnwrappedLine) The unwrapped line
- previous to this line.
- final_lines: (list of unwrapped_line.UnwrappedLine) The unwrapped lines
- that have already been processed.
+ prev_line: (list of logical_line.LogicalLine) The logical line previous to
+ this line.
+ final_lines: (list of logical_line.LogicalLine) The logical lines that have
+ already been processed.
+ first_nested: (boolean) Whether this is the first nested class or function.
Returns:
The number of newlines needed before the first token.
"""
# TODO(morbo): Special handling for imports.
# TODO(morbo): Create a knob that can tune these.
- if prev_uwline is None:
+ if prev_line is None:
# The first line in the file. Don't add blank lines.
# FIXME(morbo): Is this correct?
if first_token.newlines is not None:
- pytree_utils.SetNodeAnnotation(first_token.node,
- pytree_utils.Annotation.NEWLINES, None)
+ first_token.newlines = None
return 0
if first_token.is_docstring:
- if (prev_uwline.first.value == 'class' and
+ if (prev_line.first.value == 'class' and
style.Get('BLANK_LINE_BEFORE_CLASS_DOCSTRING')):
# Enforce a blank line before a class's docstring.
return ONE_BLANK_LINE
- elif (prev_uwline.first.value.startswith('#') and
+ elif (prev_line.first.value.startswith('#') and
style.Get('BLANK_LINE_BEFORE_MODULE_DOCSTRING')):
# Enforce a blank line before a module's docstring.
return ONE_BLANK_LINE
# The docstring shouldn't have a newline before it.
return NO_BLANK_LINES
- prev_last_token = prev_uwline.last
+ if first_token.is_name and not indent_depth:
+ if prev_line.first.value in {'from', 'import'}:
+ # Support custom number of blank lines between top-level imports and
+ # variable definitions.
+ return 1 + style.Get(
+ 'BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES')
+
+ prev_last_token = prev_line.last
if prev_last_token.is_docstring:
if (not indent_depth and first_token.value in {'class', 'def', 'async'}):
# Separate a class or function from the module-level docstring with
# appropriate number of blank lines.
return 1 + style.Get('BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION')
+ if (first_nested and
+ not style.Get('BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF') and
+ _IsClassOrDef(first_token)):
+ first_token.newlines = None
+ return NO_BLANK_LINES
if _NoBlankLinesBeforeCurrentToken(prev_last_token.value, first_token,
prev_last_token):
return NO_BLANK_LINES
else:
return ONE_BLANK_LINE
- if first_token.value in {'class', 'def', 'async', '@'}:
+ if _IsClassOrDef(first_token):
# TODO(morbo): This can go once the blank line calculator is more
# sophisticated.
if not indent_depth:
# This is a top-level class or function.
is_inline_comment = prev_last_token.whitespace_prefix.count('\n') == 0
- if (not prev_uwline.disable and prev_last_token.is_comment and
+ if (not prev_line.disable and prev_last_token.is_comment and
not is_inline_comment):
# This token follows a non-inline comment.
if _NoBlankLinesBeforeCurrentToken(prev_last_token.value, first_token,
@@ -516,13 +690,12 @@ def _CalculateNumberOfNewlines(first_token, indent_depth, prev_uwline,
prev_last_token.AdjustNewlinesBefore(
1 + style.Get('BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION'))
if first_token.newlines is not None:
- pytree_utils.SetNodeAnnotation(
- first_token.node, pytree_utils.Annotation.NEWLINES, None)
+ first_token.newlines = None
return NO_BLANK_LINES
- elif _IsClassOrDef(prev_uwline):
- if not style.Get('BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'):
- pytree_utils.SetNodeAnnotation(first_token.node,
- pytree_utils.Annotation.NEWLINES, None)
+ elif _IsClassOrDef(prev_line.first):
+ if first_nested and not style.Get(
+ 'BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'):
+ first_token.newlines = None
return NO_BLANK_LINES
# Calculate how many newlines were between the original lines. We want to
@@ -542,11 +715,11 @@ def _CalculateNumberOfNewlines(first_token, indent_depth, prev_uwline,
return NO_BLANK_LINES
-def _SingleOrMergedLines(uwlines):
+def _SingleOrMergedLines(lines):
"""Generate the lines we want to format.
Arguments:
- uwlines: (list of unwrapped_line.UnwrappedLine) Lines we want to format.
+ lines: (list of logical_line.LogicalLine) Lines we want to format.
Yields:
Either a single line, if the current line cannot be merged with the
@@ -554,38 +727,37 @@ def _SingleOrMergedLines(uwlines):
"""
index = 0
last_was_merged = False
- while index < len(uwlines):
- if uwlines[index].disable:
- uwline = uwlines[index]
+ while index < len(lines):
+ if lines[index].disable:
+ line = lines[index]
index += 1
- while index < len(uwlines):
- column = uwline.last.column + 2
- if uwlines[index].lineno != uwline.lineno:
+ while index < len(lines):
+ column = line.last.column + 2
+ if lines[index].lineno != line.lineno:
break
- if uwline.last.value != ':':
+ if line.last.value != ':':
leaf = pytree.Leaf(
- type=token.SEMI, value=';', context=('', (uwline.lineno, column)))
- uwline.AppendToken(format_token.FormatToken(leaf))
- for tok in uwlines[index].tokens:
- uwline.AppendToken(tok)
+ type=token.SEMI, value=';', context=('', (line.lineno, column)))
+ line.AppendToken(format_token.FormatToken(leaf))
+ for tok in lines[index].tokens:
+ line.AppendToken(tok)
index += 1
- yield uwline
- elif line_joiner.CanMergeMultipleLines(uwlines[index:], last_was_merged):
+ yield line
+ elif line_joiner.CanMergeMultipleLines(lines[index:], last_was_merged):
# TODO(morbo): This splice is potentially very slow. Come up with a more
# performance-friendly way of determining if two lines can be merged.
- next_uwline = uwlines[index + 1]
- for tok in next_uwline.tokens:
- uwlines[index].AppendToken(tok)
- if (len(next_uwline.tokens) == 1 and
- next_uwline.first.is_multiline_string):
+ next_line = lines[index + 1]
+ for tok in next_line.tokens:
+ lines[index].AppendToken(tok)
+ if (len(next_line.tokens) == 1 and next_line.first.is_multiline_string):
# This may be a multiline shebang. In that case, we want to retain the
# formatting. Otherwise, it could mess up the shell script's syntax.
- uwlines[index].disable = True
- yield uwlines[index]
+ lines[index].disable = True
+ yield lines[index]
index += 2
last_was_merged = True
else:
- yield uwlines[index]
+ yield lines[index]
index += 1
last_was_merged = False
@@ -602,9 +774,8 @@ def _NoBlankLinesBeforeCurrentToken(text, cur_token, prev_token):
Arguments:
text: (unicode) The text of the docstring or comment before the current
token.
- cur_token: (format_token.FormatToken) The current token in the unwrapped
- line.
- prev_token: (format_token.FormatToken) The previous token in the unwrapped
+ cur_token: (format_token.FormatToken) The current token in the logical line.
+ prev_token: (format_token.FormatToken) The previous token in the logical
line.
Returns:
diff --git a/yapf/yapflib/split_penalty.py b/yapf/yapflib/split_penalty.py
index 416eda3..643ae24 100644
--- a/yapf/yapflib/split_penalty.py
+++ b/yapf/yapflib/split_penalty.py
@@ -16,21 +16,24 @@
import re
from lib2to3 import pytree
+from lib2to3.pgen2 import token as grammar_token
from yapf.yapflib import format_token
from yapf.yapflib import py3compat
from yapf.yapflib import pytree_utils
from yapf.yapflib import pytree_visitor
from yapf.yapflib import style
+from yapf.yapflib import subtypes
# 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
CONNECTED = 500
+TOGETHER = 100
OR_TEST = 1000
AND_TEST = 1100
@@ -46,7 +49,8 @@ TERM = 2000
FACTOR = 2100
POWER = 2200
ATOM = 2300
-ONE_ELEMENT_ARGUMENT = 2500
+ONE_ELEMENT_ARGUMENT = 500
+SUBSCRIPT = 6000
def ComputeSplitPenalties(tree):
@@ -64,6 +68,10 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
Split penalties are attached as annotations to tokens.
"""
+ def Visit(self, node):
+ if not hasattr(node, 'is_pseudo'): # Ignore pseudo tokens.
+ super(_SplitPenaltyAssigner, self).Visit(node)
+
def Visit_import_as_names(self, node): # pyline: disable=invalid-name
# import_as_names ::= import_as_name (',' import_as_name)* [',']
self.DefaultNodeVisit(node)
@@ -117,15 +125,15 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
allow_multiline_lambdas = style.Get('ALLOW_MULTILINE_LAMBDAS')
if not allow_multiline_lambdas:
for child in node.children:
- if pytree_utils.NodeName(child) == 'COMMENT':
+ if child.type == grammar_token.COMMENT:
if re.search(r'pylint:.*disable=.*\bg-long-lambda', child.value):
allow_multiline_lambdas = True
break
if allow_multiline_lambdas:
- _SetStronglyConnected(node)
+ _SetExpressionPenalty(node, STRONGLY_CONNECTED)
else:
- self._SetUnbreakableOnChildren(node)
+ _SetExpressionPenalty(node, VERY_STRONGLY_CONNECTED)
def Visit_parameters(self, node): # pylint: disable=invalid-name
# parameters ::= '(' [typedargslist] ')'
@@ -133,18 +141,25 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# Can't break before the opening paren of a parameter list.
_SetUnbreakable(node.children[0])
- if not style.Get('DEDENT_CLOSING_BRACKETS'):
+ if not (style.Get('INDENT_CLOSING_BRACKETS') or
+ style.Get('DEDENT_CLOSING_BRACKETS')):
_SetStronglyConnected(node.children[-1])
def Visit_arglist(self, node): # pylint: disable=invalid-name
# arglist ::= argument (',' argument)* [',']
+ if node.children[0].type == grammar_token.STAR:
+ # Python 3 treats a star expression as a specific expression type.
+ # Process it in that method.
+ self.Visit_star_expr(node)
+ return
+
self.DefaultNodeVisit(node)
- index = 1
- while index < len(node.children):
+
+ for index in py3compat.range(1, len(node.children)):
child = node.children[index]
if isinstance(child, pytree.Leaf) and child.value == ',':
_SetUnbreakable(child)
- index += 1
+
for child in node.children:
if pytree_utils.NodeName(child) == 'atom':
_IncreasePenalty(child, CONNECTED)
@@ -152,32 +167,34 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
def Visit_argument(self, node): # pylint: disable=invalid-name
# argument ::= test [comp_for] | test '=' test # Really [keyword '='] test
self.DefaultNodeVisit(node)
- index = 1
- while index < len(node.children) - 1:
+
+ for index in py3compat.range(1, len(node.children) - 1):
child = node.children[index]
if isinstance(child, pytree.Leaf) and child.value == '=':
_SetSplitPenalty(
pytree_utils.FirstLeafNode(node.children[index]), NAMED_ASSIGN)
_SetSplitPenalty(
pytree_utils.FirstLeafNode(node.children[index + 1]), NAMED_ASSIGN)
- index += 1
def Visit_tname(self, node): # pylint: disable=invalid-name
# tname ::= NAME [':' test]
self.DefaultNodeVisit(node)
- index = 1
- while index < len(node.children) - 1:
+
+ for index in py3compat.range(1, len(node.children) - 1):
child = node.children[index]
if isinstance(child, pytree.Leaf) and child.value == ':':
_SetSplitPenalty(
pytree_utils.FirstLeafNode(node.children[index]), NAMED_ASSIGN)
_SetSplitPenalty(
pytree_utils.FirstLeafNode(node.children[index + 1]), NAMED_ASSIGN)
- index += 1
def Visit_dotted_name(self, node): # pylint: disable=invalid-name
# dotted_name ::= NAME ('.' NAME)*
- self._SetUnbreakableOnChildren(node)
+ for child in node.children:
+ self.Visit(child)
+ start = 2 if hasattr(node.children[0], 'is_pseudo') else 1
+ for i in py3compat.range(start, len(node.children)):
+ _SetUnbreakable(node.children[i])
def Visit_dictsetmaker(self, node): # pylint: disable=invalid-name
# dictsetmaker ::= ( (test ':' test
@@ -185,7 +202,7 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# (test (comp_for | (',' test)* [','])) )
for child in node.children:
self.Visit(child)
- if pytree_utils.NodeName(child) == 'COLON':
+ if child.type == grammar_token.COLON:
# This is a key to a dictionary. We don't want to split the key if at
# all possible.
_SetStronglyConnected(child)
@@ -193,8 +210,11 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
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],
+ VERY_STRONGLY_CONNECTED if before else DOTTED_NAME)
+ _SetSplitPenalty(node.children[1],
+ DOTTED_NAME if before else VERY_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)
@@ -211,7 +231,7 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
_SetSplitPenalty(
pytree_utils.FirstLeafNode(node.children[1]),
ONE_ELEMENT_ARGUMENT)
- elif (pytree_utils.NodeName(node.children[0]) == 'LSQB' and
+ elif (node.children[0].type == grammar_token.LSQB and
len(node.children[1].children) > 2 and
(name.endswith('_test') or name.endswith('_expr'))):
_SetStronglyConnected(node.children[1].children[0])
@@ -230,13 +250,23 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
pytree_utils.FirstLeafNode(node.children[1].children[2]), 0)
# Don't split the ending bracket of a subscript list.
- _SetVeryStronglyConnected(node.children[-1])
+ _RecAnnotate(node.children[-1], pytree_utils.Annotation.SPLIT_PENALTY,
+ VERY_STRONGLY_CONNECTED)
elif name not in {
'arglist', 'argument', 'term', 'or_test', 'and_test', 'comparison',
'atom', 'power'
}:
# Don't split an argument list with one element if at all possible.
- _SetStronglyConnected(node.children[1], node.children[2])
+ stypes = pytree_utils.GetNodeAnnotation(
+ pytree_utils.FirstLeafNode(node), pytree_utils.Annotation.SUBTYPE)
+ if stypes and subtypes.SUBSCRIPT_BRACKET in stypes:
+ _IncreasePenalty(node, SUBSCRIPT)
+
+ # Bump up the split penalty for the first part of a subscript. We
+ # would rather not split there.
+ _IncreasePenalty(node.children[1], CONNECTED)
+ else:
+ _SetStronglyConnected(node.children[1], node.children[2])
if name == 'arglist':
_SetStronglyConnected(node.children[-1])
@@ -253,7 +283,9 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
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
@@ -265,20 +297,20 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
while prev_trailer_idx < len(node.children) - 1:
cur_trailer_idx = prev_trailer_idx + 1
cur_trailer = node.children[cur_trailer_idx]
- if pytree_utils.NodeName(cur_trailer) == 'trailer':
- # Now we know we have two trailers one after the other
- prev_trailer = node.children[prev_trailer_idx]
- if prev_trailer.children[-1].value != ')':
- # Set the previous node unbreakable if it's not a function call:
- # atom tr1() tr2
- # It may be necessary (though undesirable) to split up a previous
- # function call's parentheses to the next line.
- _SetStronglyConnected(prev_trailer.children[-1])
- _SetStronglyConnected(cur_trailer.children[0])
- prev_trailer_idx = cur_trailer_idx
- else:
+ if pytree_utils.NodeName(cur_trailer) != 'trailer':
break
+ # Now we know we have two trailers one after the other
+ prev_trailer = node.children[prev_trailer_idx]
+ if prev_trailer.children[-1].value != ')':
+ # Set the previous node unbreakable if it's not a function call:
+ # atom tr1() tr2
+ # It may be necessary (though undesirable) to split up a previous
+ # function call's parentheses to the next line.
+ _SetStronglyConnected(prev_trailer.children[-1])
+ _SetStronglyConnected(cur_trailer.children[0])
+ prev_trailer_idx = cur_trailer_idx
+
# We don't want to split before the last ')' of a function call. This also
# takes care of the special case of:
# atom tr1 tr2 ... trn
@@ -288,16 +320,17 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
break
if trailer.children[0].value in '([':
if len(trailer.children) > 2:
- subtypes = pytree_utils.GetNodeAnnotation(
+ stypes = pytree_utils.GetNodeAnnotation(
trailer.children[0], pytree_utils.Annotation.SUBTYPE)
- if subtypes and format_token.Subtype.SUBSCRIPT_BRACKET in subtypes:
+ if stypes and subtypes.SUBSCRIPT_BRACKET in stypes:
_SetStronglyConnected(
pytree_utils.FirstLeafNode(trailer.children[1]))
last_child_node = pytree_utils.LastLeafNode(trailer)
if last_child_node.value.strip().startswith('#'):
last_child_node = last_child_node.prev_sibling
- if not style.Get('DEDENT_CLOSING_BRACKETS'):
+ if not (style.Get('INDENT_CLOSING_BRACKETS') or
+ style.Get('DEDENT_CLOSING_BRACKETS')):
last = pytree_utils.LastLeafNode(last_child_node.prev_sibling)
if last.value != ',':
if last_child_node.value == ']':
@@ -310,9 +343,15 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# 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_subscriptlist(self, node): # pylint: disable=invalid-name
+ # subscriptlist ::= subscript (',' subscript)* [',']
+ self.DefaultNodeVisit(node)
+ _SetSplitPenalty(pytree_utils.FirstLeafNode(node), 0)
+ prev_child = None
+ for child in node.children:
+ if prev_child and prev_child.type == grammar_token.COMMA:
+ _SetSplitPenalty(pytree_utils.FirstLeafNode(child), 0)
+ prev_child = child
def Visit_subscript(self, node): # pylint: disable=invalid-name
# subscript ::= test | [test] ':' [test] [sliceop]
@@ -325,6 +364,10 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
_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 +375,15 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
_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)
@@ -369,8 +421,7 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# comparison ::= expr (comp_op expr)*
self.DefaultNodeVisit(node)
if len(node.children) == 3 and _StronglyConnectedCompOp(node):
- _SetSplitPenalty(
- pytree_utils.FirstLeafNode(node.children[1]), STRONGLY_CONNECTED)
+ _IncreasePenalty(node.children[1], VERY_STRONGLY_CONNECTED)
_SetSplitPenalty(
pytree_utils.FirstLeafNode(node.children[2]), STRONGLY_CONNECTED)
else:
@@ -385,27 +436,19 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# expr ::= xor_expr ('|' xor_expr)*
self.DefaultNodeVisit(node)
_IncreasePenalty(node, EXPR)
- index = 1
- while index < len(node.children) - 1:
- child = node.children[index]
- if isinstance(child, pytree.Leaf) and child.value == '|':
- if style.Get('SPLIT_BEFORE_BITWISE_OPERATOR'):
- _SetSplitPenalty(child, style.Get('SPLIT_PENALTY_BITWISE_OPERATOR'))
- else:
- _SetSplitPenalty(
- pytree_utils.FirstLeafNode(node.children[index + 1]),
- style.Get('SPLIT_PENALTY_BITWISE_OPERATOR'))
- index += 1
+ _SetBitwiseOperandPenalty(node, '|')
def Visit_xor_expr(self, node): # pylint: disable=invalid-name
# xor_expr ::= and_expr ('^' and_expr)*
self.DefaultNodeVisit(node)
_IncreasePenalty(node, XOR_EXPR)
+ _SetBitwiseOperandPenalty(node, '^')
def Visit_and_expr(self, node): # pylint: disable=invalid-name
# and_expr ::= shift_expr ('&' shift_expr)*
self.DefaultNodeVisit(node)
_IncreasePenalty(node, AND_EXPR)
+ _SetBitwiseOperandPenalty(node, '&')
def Visit_shift_expr(self, node): # pylint: disable=invalid-name
# shift_expr ::= arith_expr (('<<'|'>>') arith_expr)*
@@ -418,14 +461,7 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# arith_expr ::= term (('+'|'-') term)*
self.DefaultNodeVisit(node)
_IncreasePenalty(node, ARITH_EXPR)
-
- index = 1
- while index < len(node.children) - 1:
- child = node.children[index]
- if pytree_utils.NodeName(child) in self._ARITH_OPS:
- next_node = pytree_utils.FirstLeafNode(node.children[index + 1])
- _SetSplitPenalty(next_node, ARITH_EXPR)
- index += 1
+ _SetExpressionOperandPenalty(node, self._ARITH_OPS)
_TERM_OPS = frozenset({'STAR', 'AT', 'SLASH', 'PERCENT', 'DOUBLESLASH'})
@@ -433,14 +469,7 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# term ::= factor (('*'|'@'|'/'|'%'|'//') factor)*
self.DefaultNodeVisit(node)
_IncreasePenalty(node, TERM)
-
- index = 1
- while index < len(node.children) - 1:
- child = node.children[index]
- if pytree_utils.NodeName(child) in self._TERM_OPS:
- next_node = pytree_utils.FirstLeafNode(node.children[index + 1])
- _SetSplitPenalty(next_node, TERM)
- index += 1
+ _SetExpressionOperandPenalty(node, self._TERM_OPS)
def Visit_factor(self, node): # pyline: disable=invalid-name
# factor ::= ('+'|'-'|'~') factor | power
@@ -452,7 +481,8 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
# '[' [listmaker] ']' |
# '{' [dictsetmaker] '}')
self.DefaultNodeVisit(node)
- if node.children[0].value == '(':
+ if (node.children[0].value == '(' and
+ not hasattr(node.children[0], 'is_pseudo')):
if node.children[-1].value == ')':
if pytree_utils.NodeName(node.parent) == 'if_stmt':
_SetSplitPenalty(node.children[-1], STRONGLY_CONNECTED)
@@ -473,20 +503,9 @@ class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor):
prev_was_comma = True
else:
if prev_was_comma:
- _SetSplitPenalty(pytree_utils.FirstLeafNode(child), 0)
+ _SetSplitPenalty(pytree_utils.FirstLeafNode(child), TOGETHER)
prev_was_comma = False
- ############################################################################
- # Helper methods that set the annotations.
-
- def _SetUnbreakableOnChildren(self, node):
- """Set an UNBREAKABLE penalty annotation on children of node."""
- for child in node.children:
- self.Visit(child)
- start = 2 if hasattr(node.children[0], 'is_pseudo') else 1
- for i in py3compat.range(start, len(node.children)):
- _SetUnbreakable(node.children[i])
-
def _SetUnbreakable(node):
"""Set an UNBREAKABLE penalty annotation for the given node."""
@@ -500,13 +519,6 @@ def _SetStronglyConnected(*nodes):
STRONGLY_CONNECTED)
-def _SetVeryStronglyConnected(*nodes):
- """Set a VERY_STRONGLY_CONNECTED penalty annotation for the given nodes."""
- for node in nodes:
- _RecAnnotate(node, pytree_utils.Annotation.SPLIT_PENALTY,
- VERY_STRONGLY_CONNECTED)
-
-
def _SetExpressionPenalty(node, penalty):
"""Set a penalty annotation on children nodes."""
@@ -528,6 +540,30 @@ def _SetExpressionPenalty(node, penalty):
RecExpression(node, pytree_utils.FirstLeafNode(node))
+def _SetBitwiseOperandPenalty(node, op):
+ for index in py3compat.range(1, len(node.children) - 1):
+ child = node.children[index]
+ if isinstance(child, pytree.Leaf) and child.value == op:
+ if style.Get('SPLIT_BEFORE_BITWISE_OPERATOR'):
+ _SetSplitPenalty(child, style.Get('SPLIT_PENALTY_BITWISE_OPERATOR'))
+ else:
+ _SetSplitPenalty(
+ pytree_utils.FirstLeafNode(node.children[index + 1]),
+ style.Get('SPLIT_PENALTY_BITWISE_OPERATOR'))
+
+
+def _SetExpressionOperandPenalty(node, ops):
+ for index in py3compat.range(1, len(node.children) - 1):
+ child = node.children[index]
+ if pytree_utils.NodeName(child) in ops:
+ if style.Get('SPLIT_BEFORE_ARITHMETIC_OPERATOR'):
+ _SetSplitPenalty(child, style.Get('SPLIT_PENALTY_ARITHMETIC_OPERATOR'))
+ else:
+ _SetSplitPenalty(
+ pytree_utils.FirstLeafNode(node.children[index + 1]),
+ style.Get('SPLIT_PENALTY_ARITHMETIC_OPERATOR'))
+
+
def _IncreasePenalty(node, amt):
"""Increase a penalty annotation on children nodes."""
@@ -536,7 +572,7 @@ def _IncreasePenalty(node, amt):
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)
@@ -570,10 +606,13 @@ def _RecAnnotate(tree, annotate_name, annotate_value):
def _StronglyConnectedCompOp(op):
if (len(op.children[1].children) == 2 and
- pytree_utils.NodeName(op.children[1]) == 'comp_op' and
- pytree_utils.FirstLeafNode(op.children[1]).value == 'not' and
- pytree_utils.LastLeafNode(op.children[1]).value == 'in'):
- return True
+ pytree_utils.NodeName(op.children[1]) == 'comp_op'):
+ if (pytree_utils.FirstLeafNode(op.children[1]).value == 'not' and
+ pytree_utils.LastLeafNode(op.children[1]).value == 'in'):
+ return True
+ if (pytree_utils.FirstLeafNode(op.children[1]).value == 'is' and
+ pytree_utils.LastLeafNode(op.children[1]).value == 'not'):
+ return True
if (isinstance(op.children[1], pytree.Leaf) and
op.children[1].value in {'==', 'in'}):
return True
@@ -590,23 +629,3 @@ def _DecrementSplitPenalty(node, amt):
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 --git a/yapf/yapflib/style.py b/yapf/yapflib/style.py
index 6144246..233a64e 100644
--- a/yapf/yapflib/style.py
+++ b/yapf/yapflib/style.py
@@ -31,6 +31,11 @@ def Get(setting_name):
return _style[setting_name]
+def GetOrDefault(setting_name, default_value):
+ """Get a style setting or default value if the setting does not exist."""
+ return _style.get(setting_name, default_value)
+
+
def Help():
"""Return dict mapping style names to help strings."""
return _STYLE_HELP
@@ -59,8 +64,31 @@ _STYLE_HELP = dict(
'this is the second element of a tuple'):
value,
}"""),
+ ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS=textwrap.dedent("""\
+ Allow splitting before a default / named assignment in an argument list.
+ """),
ALLOW_SPLIT_BEFORE_DICT_VALUE=textwrap.dedent("""\
Allow splits before the dictionary value."""),
+ ARITHMETIC_PRECEDENCE_INDICATION=textwrap.dedent("""\
+ Let spacing indicate operator precedence. For example:
+
+ a = 1 * 2 + 3 / 4
+ b = 1 / 2 - 3 * 4
+ c = (1 + 2) * (3 - 4)
+ d = (1 - 2) / (3 + 4)
+ e = 1 * 2 - 3
+ f = 1 + 2 + 3 + 4
+
+ will be formatted as follows to indicate precedence:
+
+ a = 1*2 + 3/4
+ b = 1/2 - 3*4
+ c = (1+2) * (3-4)
+ d = (1-2) / (3+4)
+ e = 1*2 - 3
+ f = 1 + 2 + 3 + 4
+
+ """),
BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=textwrap.dedent("""\
Insert a blank line before a 'def' or 'class' immediately nested
within another 'def' or 'class'. For example:
@@ -76,6 +104,9 @@ _STYLE_HELP = dict(
BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION=textwrap.dedent("""\
Number of blank lines surrounding top-level function and class
definitions."""),
+ BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES=textwrap.dedent("""\
+ Number of blank lines between top-level imports and variable
+ definitions."""),
COALESCE_BRACKETS=textwrap.dedent("""\
Do not split consecutive brackets. Only relevant when
dedent_closing_brackets is set. For example:
@@ -100,16 +131,11 @@ _STYLE_HELP = dict(
- SPACE: Use spaces for continuation alignment. This is default behavior.
- FIXED: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns
- (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs) for continuation
- alignment.
- - LESS: Slightly left if cannot vertically align continuation lines with
- indent characters.
- - VALIGN-RIGHT: Vertically align continuation lines with indent
- characters. Slightly right (one more indent character) if cannot
- vertically align continuation lines with indent characters.
-
- For options FIXED, and VALIGN-RIGHT are only available when USE_TABS is
- enabled."""),
+ (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or
+ CONTINUATION_INDENT_WIDTH spaces) for continuation alignment.
+ - VALIGN-RIGHT: Vertically align continuation lines to multiple of
+ INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if
+ cannot vertically align continuation lines with indent characters."""),
CONTINUATION_INDENT_WIDTH=textwrap.dedent("""\
Indent width used for line continuations."""),
DEDENT_CLOSING_BRACKETS=textwrap.dedent("""\
@@ -128,12 +154,20 @@ _STYLE_HELP = dict(
transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
start_ts=now()-timedelta(days=3),
end_ts=now(),
- ) # <--- this bracket is dedented and on a separate line"""),
+ ) # <--- this bracket is dedented and on a separate line
+ """),
DISABLE_ENDING_COMMA_HEURISTIC=textwrap.dedent("""\
Disable the heuristic which places each list element on a separate line
if the list is comma-terminated."""),
EACH_DICT_ENTRY_ON_SEPARATE_LINE=textwrap.dedent("""\
Place each dictionary entry onto its own line."""),
+ FORCE_MULTILINE_DICT=textwrap.dedent("""\
+ Require multiline dictionary even if it would normally fit on one line.
+ For example:
+
+ config = {
+ 'key1': 'value1'
+ }"""),
I18N_COMMENT=textwrap.dedent("""\
The regex for an i18n comment. The presence of this comment stops
reformatting of that line, because the comments are required to be
@@ -142,6 +176,24 @@ _STYLE_HELP = dict(
The i18n function call names. The presence of this function stops
reformattting on that line, because the string it has cannot be moved
away from the i18n comment."""),
+ INDENT_CLOSING_BRACKETS=textwrap.dedent("""\
+ Put closing brackets on a separate line, indented, if the bracketed
+ expression can't fit in a single line. Applies to all kinds of brackets,
+ including function definitions and calls. For example:
+
+ config = {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ } # <--- this bracket is indented and on a separate line
+
+ time_series = self.remote_client.query_entity_counters(
+ entity='dev3246.region1',
+ key='dns.query_latency_tcp',
+ transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
+ start_ts=now()-timedelta(days=3),
+ end_ts=now(),
+ ) # <--- this bracket is indented and on a separate line
+ """),
INDENT_DICTIONARY_VALUE=textwrap.dedent("""\
Indent the dictionary value if it cannot fit on the same line as the
dictionary key. For example:
@@ -151,9 +203,12 @@ _STYLE_HELP = dict(
'value1',
'key2': value1 +
value2,
- }"""),
+ }
+ """),
INDENT_WIDTH=textwrap.dedent("""\
The number of columns to use for indentation."""),
+ INDENT_BLANK_LINES=textwrap.dedent("""\
+ Indent blank lines."""),
JOIN_MULTIPLE_LINES=textwrap.dedent("""\
Join short lines into one line. E.g., single line 'if' statements."""),
NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS=textwrap.dedent("""\
@@ -161,25 +216,112 @@ _STYLE_HELP = dict(
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
-
"""),
SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET=textwrap.dedent("""\
Insert a space between the ending comma and closing bracket of a list,
etc."""),
+ SPACE_INSIDE_BRACKETS=textwrap.dedent("""\
+ Use spaces inside brackets, braces, and parentheses. For example:
+
+ method_call( 1 )
+ my_dict[ 3 ][ 1 ][ get_index( *args, **kwargs ) ]
+ my_set = { 1, 2, 3 }
+ """),
SPACES_AROUND_POWER_OPERATOR=textwrap.dedent("""\
Use spaces around the power operator."""),
SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN=textwrap.dedent("""\
Use spaces around default or named assigns."""),
+ SPACES_AROUND_DICT_DELIMITERS=textwrap.dedent("""\
+ Adds a space after the opening '{' and before the ending '}' dict
+ delimiters.
+
+ {1: 2}
+
+ will be formatted as:
+
+ { 1: 2 }
+ """),
+ SPACES_AROUND_LIST_DELIMITERS=textwrap.dedent("""\
+ Adds a space after the opening '[' and before the ending ']' list
+ delimiters.
+
+ [1, 2]
+
+ will be formatted as:
+
+ [ 1, 2 ]
+ """),
+ SPACES_AROUND_SUBSCRIPT_COLON=textwrap.dedent("""\
+ Use spaces around the subscript / slice operator. For example:
+
+ my_list[1 : 10 : 2]
+ """),
+ SPACES_AROUND_TUPLE_DELIMITERS=textwrap.dedent("""\
+ Adds a space after the opening '(' and before the ending ')' tuple
+ delimiters.
+
+ (1, 2, 3)
+
+ will be formatted as:
+
+ ( 1, 2, 3 )
+ """),
SPACES_BEFORE_COMMENT=textwrap.dedent("""\
- The number of spaces required before a trailing comment."""),
+ The number of spaces required before a trailing comment.
+ This can be a single value (representing the number of spaces
+ before each trailing comment) or list of values (representing
+ alignment column values; trailing comments within a block will
+ be aligned to the first column value that is greater than the maximum
+ line length within the block). For example:
+
+ With spaces_before_comment=5:
+
+ 1 + 1 # Adding values
+
+ will be formatted as:
+
+ 1 + 1 # Adding values <-- 5 spaces between the end of the
+ # statement and comment
+
+ With spaces_before_comment=15, 20:
+
+ 1 + 1 # Adding values
+ two + two # More adding
+
+ longer_statement # This is a longer statement
+ short # This is a shorter statement
+
+ a_very_long_statement_that_extends_beyond_the_final_column # Comment
+ short # This is a shorter statement
+
+ will be formatted as:
+
+ 1 + 1 # Adding values <-- end of line comments in block
+ # aligned to col 15
+ two + two # More adding
+
+ longer_statement # This is a longer statement <-- end of line
+ # comments in block aligned to col 20
+ short # This is a shorter statement
+
+ a_very_long_statement_that_extends_beyond_the_final_column # Comment <-- the end of line comments are aligned based on the line length
+ short # This is a shorter statement
+
+ """), # noqa
SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED=textwrap.dedent("""\
Split before arguments if the argument list is terminated by a
comma."""),
SPLIT_ALL_COMMA_SEPARATED_VALUES=textwrap.dedent("""\
Split before arguments"""),
+ SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES=textwrap.dedent("""\
+ Split before arguments, but do not split all subexpressions recursively
+ (unless needed)."""),
+ SPLIT_BEFORE_ARITHMETIC_OPERATOR=textwrap.dedent("""\
+ Set to True to prefer splitting before '+', '-', '*', '/', '//', or '@'
+ rather than after."""),
SPLIT_BEFORE_BITWISE_OPERATOR=textwrap.dedent("""\
Set to True to prefer splitting before '&', '|' or '^' rather than
after."""),
@@ -194,6 +336,16 @@ _STYLE_HELP = dict(
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))
+ """), # noqa
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.
@@ -226,6 +378,9 @@ _STYLE_HELP = dict(
The penalty for splitting right after the opening bracket."""),
SPLIT_PENALTY_AFTER_UNARY_OPERATOR=textwrap.dedent("""\
The penalty for splitting the line after a unary operator."""),
+ SPLIT_PENALTY_ARITHMETIC_OPERATOR=textwrap.dedent("""\
+ The penalty of splitting the line around the '+', '-', '*', '/', '//',
+ ``%``, and '@' operators."""),
SPLIT_PENALTY_BEFORE_IF_EXPR=textwrap.dedent("""\
The penalty for splitting right before an if expression."""),
SPLIT_PENALTY_BITWISE_OPERATOR=textwrap.dedent("""\
@@ -237,7 +392,7 @@ _STYLE_HELP = dict(
SPLIT_PENALTY_EXCESS_CHARACTER=textwrap.dedent("""\
The penalty for characters over the column limit."""),
SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT=textwrap.dedent("""\
- The penalty incurred by adding a line split to the unwrapped line. The
+ 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=textwrap.dedent("""\
The penalty of splitting a list of "import as" names. For example:
@@ -250,7 +405,7 @@ _STYLE_HELP = dict(
from a_very_long_or_indented_module_name_yada_yad import (
long_argument_1, long_argument_2, long_argument_3)
- """),
+ """), # noqa
SPLIT_PENALTY_LOGICAL_OPERATOR=textwrap.dedent("""\
The penalty of splitting the line around the 'and' and 'or'
operators."""),
@@ -261,48 +416,64 @@ _STYLE_HELP = dict(
def CreatePEP8Style():
+ """Create the PEP8 formatting style."""
return dict(
ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT=True,
ALLOW_MULTILINE_LAMBDAS=False,
ALLOW_MULTILINE_DICTIONARY_KEYS=False,
+ ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS=True,
ALLOW_SPLIT_BEFORE_DICT_VALUE=True,
- BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=False,
+ ARITHMETIC_PRECEDENCE_INDICATION=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,
+ BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES=1,
COALESCE_BRACKETS=False,
COLUMN_LIMIT=79,
CONTINUATION_ALIGN_STYLE='SPACE',
CONTINUATION_INDENT_WIDTH=4,
DEDENT_CLOSING_BRACKETS=False,
+ INDENT_CLOSING_BRACKETS=False,
DISABLE_ENDING_COMMA_HEURISTIC=False,
EACH_DICT_ENTRY_ON_SEPARATE_LINE=True,
+ FORCE_MULTILINE_DICT=False,
I18N_COMMENT='',
I18N_FUNCTION_CALL='',
INDENT_DICTIONARY_VALUE=False,
INDENT_WIDTH=4,
+ INDENT_BLANK_LINES=False,
JOIN_MULTIPLE_LINES=True,
+ NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS=set(),
SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET=True,
+ SPACE_INSIDE_BRACKETS=False,
SPACES_AROUND_POWER_OPERATOR=False,
- NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS=set(),
SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN=False,
+ SPACES_AROUND_DICT_DELIMITERS=False,
+ SPACES_AROUND_LIST_DELIMITERS=False,
+ SPACES_AROUND_SUBSCRIPT_COLON=False,
+ SPACES_AROUND_TUPLE_DELIMITERS=False,
SPACES_BEFORE_COMMENT=2,
SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED=False,
SPLIT_ALL_COMMA_SEPARATED_VALUES=False,
+ SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES=False,
+ SPLIT_BEFORE_ARITHMETIC_OPERATOR=False,
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,
SPLIT_BEFORE_NAMED_ASSIGNS=True,
SPLIT_COMPLEX_COMPREHENSION=False,
- SPLIT_PENALTY_AFTER_OPENING_BRACKET=30,
+ SPLIT_PENALTY_AFTER_OPENING_BRACKET=300,
SPLIT_PENALTY_AFTER_UNARY_OPERATOR=10000,
+ SPLIT_PENALTY_ARITHMETIC_OPERATOR=300,
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,
@@ -311,13 +482,15 @@ def CreatePEP8Style():
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
style['I18N_COMMENT'] = r'#\..*'
style['I18N_FUNCTION_CALL'] = ['N_', '_']
+ style['JOIN_MULTIPLE_LINES'] = False
style['SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET'] = False
style['SPLIT_BEFORE_BITWISE_OPERATOR'] = False
style['SPLIT_BEFORE_DICT_SET_GENERATOR'] = False
@@ -327,22 +500,26 @@ def CreateGoogleStyle():
return style
-def CreateChromiumStyle():
+def CreateYapfStyle():
+ """Create the YAPF formatting style."""
style = CreateGoogleStyle()
style['ALLOW_MULTILINE_DICTIONARY_KEYS'] = True
- style['INDENT_DICTIONARY_VALUE'] = True
+ style['ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS'] = False
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
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
style['INDENT_DICTIONARY_VALUE'] = True
style['JOIN_MULTIPLE_LINES'] = False
style['SPACES_BEFORE_COMMENT'] = 2
@@ -356,16 +533,16 @@ def CreateFacebookStyle():
_STYLE_NAME_TO_FACTORY = dict(
pep8=CreatePEP8Style,
- chromium=CreateChromiumStyle,
google=CreateGoogleStyle,
facebook=CreateFacebookStyle,
+ yapf=CreateYapfStyle,
)
_DEFAULT_STYLE_TO_FACTORY = [
- (CreateChromiumStyle(), CreateChromiumStyle),
(CreateFacebookStyle(), CreateFacebookStyle),
(CreateGoogleStyle(), CreateGoogleStyle),
(CreatePEP8Style(), CreatePEP8Style),
+ (CreateYapfStyle(), CreateYapfStyle),
]
@@ -380,7 +557,7 @@ def _ContinuationAlignStyleStringConverter(s):
"""Option value converter for a continuation align style string."""
accepted_styles = ('SPACE', 'FIXED', 'VALIGN-RIGHT')
if s:
- r = s.upper()
+ r = s.strip('"\'').replace('_', '-').upper()
if r not in accepted_styles:
raise ValueError('unknown continuation align style: %r' % (s,))
else:
@@ -395,7 +572,9 @@ def _StringListConverter(s):
def _StringSetConverter(s):
"""Option value converter for a comma-separated set of strings."""
- return set(part.strip() for part in s.split(','))
+ if len(s) > 2 and s[0] in '"\'':
+ s = s[1:-1]
+ return {part.strip() for part in s.split(',')}
def _BoolConverter(s):
@@ -403,6 +582,22 @@ def _BoolConverter(s):
return py3compat.CONFIGPARSER_BOOLEAN_STATES[s.lower()]
+def _IntListConverter(s):
+ """Option value converter for a comma-separated list of integers."""
+ s = s.strip()
+ if s.startswith('[') and s.endswith(']'):
+ s = s[1:-1]
+
+ return [int(part.strip()) for part in s.split(',') if part.strip()]
+
+
+def _IntOrIntListConverter(s):
+ """Option value converter for an integer or list of integers."""
+ if len(s) > 2 and s[0] in '"\'':
+ s = s[1:-1]
+ return _IntListConverter(s) if ',' in s else int(s)
+
+
# Different style options need to have their values interpreted differently when
# read from the config file. This dict maps an option name to a "converter"
# function that accepts the string read for the option's value from the file and
@@ -414,33 +609,47 @@ _STYLE_OPTION_VALUE_CONVERTER = dict(
ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT=_BoolConverter,
ALLOW_MULTILINE_LAMBDAS=_BoolConverter,
ALLOW_MULTILINE_DICTIONARY_KEYS=_BoolConverter,
+ ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS=_BoolConverter,
ALLOW_SPLIT_BEFORE_DICT_VALUE=_BoolConverter,
+ ARITHMETIC_PRECEDENCE_INDICATION=_BoolConverter,
BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=_BoolConverter,
BLANK_LINE_BEFORE_CLASS_DOCSTRING=_BoolConverter,
BLANK_LINE_BEFORE_MODULE_DOCSTRING=_BoolConverter,
BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION=int,
+ BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES=int,
COALESCE_BRACKETS=_BoolConverter,
COLUMN_LIMIT=int,
CONTINUATION_ALIGN_STYLE=_ContinuationAlignStyleStringConverter,
CONTINUATION_INDENT_WIDTH=int,
DEDENT_CLOSING_BRACKETS=_BoolConverter,
+ INDENT_CLOSING_BRACKETS=_BoolConverter,
DISABLE_ENDING_COMMA_HEURISTIC=_BoolConverter,
EACH_DICT_ENTRY_ON_SEPARATE_LINE=_BoolConverter,
+ FORCE_MULTILINE_DICT=_BoolConverter,
I18N_COMMENT=str,
I18N_FUNCTION_CALL=_StringListConverter,
INDENT_DICTIONARY_VALUE=_BoolConverter,
INDENT_WIDTH=int,
+ INDENT_BLANK_LINES=_BoolConverter,
JOIN_MULTIPLE_LINES=_BoolConverter,
NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS=_StringSetConverter,
SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET=_BoolConverter,
+ SPACE_INSIDE_BRACKETS=_BoolConverter,
SPACES_AROUND_POWER_OPERATOR=_BoolConverter,
SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN=_BoolConverter,
- SPACES_BEFORE_COMMENT=int,
+ SPACES_AROUND_DICT_DELIMITERS=_BoolConverter,
+ SPACES_AROUND_LIST_DELIMITERS=_BoolConverter,
+ SPACES_AROUND_SUBSCRIPT_COLON=_BoolConverter,
+ SPACES_AROUND_TUPLE_DELIMITERS=_BoolConverter,
+ SPACES_BEFORE_COMMENT=_IntOrIntListConverter,
SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED=_BoolConverter,
SPLIT_ALL_COMMA_SEPARATED_VALUES=_BoolConverter,
+ SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES=_BoolConverter,
+ SPLIT_BEFORE_ARITHMETIC_OPERATOR=_BoolConverter,
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,
@@ -448,6 +657,7 @@ _STYLE_OPTION_VALUE_CONVERTER = dict(
SPLIT_COMPLEX_COMPREHENSION=_BoolConverter,
SPLIT_PENALTY_AFTER_OPENING_BRACKET=int,
SPLIT_PENALTY_AFTER_UNARY_OPERATOR=int,
+ SPLIT_PENALTY_ARITHMETIC_OPERATOR=int,
SPLIT_PENALTY_BEFORE_IF_EXPR=int,
SPLIT_PENALTY_BITWISE_OPERATOR=int,
SPLIT_PENALTY_COMPREHENSION=int,
@@ -489,6 +699,7 @@ def CreateStyleFromConfig(style_config):
if not def_style:
return _style
return _GLOBAL_STYLE_FACTORY()
+
if isinstance(style_config, dict):
config = _CreateConfigParserFromConfigDict(style_config)
elif isinstance(style_config, py3compat.basestring):
@@ -519,8 +730,12 @@ def _CreateConfigParserFromConfigString(config_string):
"Invalid style dict syntax: '{}'.".format(config_string))
config = py3compat.ConfigParser()
config.add_section('style')
- for key, value in re.findall(r'([a-zA-Z0-9_]+)\s*[:=]\s*([a-zA-Z0-9_]+)',
- config_string):
+ 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')', config_string): # yapf: disable
config.set('style', key, value)
return config
@@ -533,19 +748,40 @@ def _CreateConfigParserFromConfigFile(config_filename):
'"{0}" is not a valid style or file path'.format(config_filename))
with open(config_filename) as style_file:
config = py3compat.ConfigParser()
+ if config_filename.endswith(PYPROJECT_TOML):
+ try:
+ import toml
+ except ImportError:
+ raise errors.YapfError(
+ "toml package is needed for using pyproject.toml as a "
+ "configuration file")
+
+ pyproject_toml = toml.load(style_file)
+ style_dict = pyproject_toml.get("tool", {}).get("yapf", None)
+ if style_dict is None:
+ raise StyleConfigError(
+ 'Unable to find section [tool.yapf] in {0}'.format(config_filename))
+ config.add_section('style')
+ for k, v in style_dict.items():
+ config.set('style', k, str(v))
+ return config
+
config.read_file(style_file)
if config_filename.endswith(SETUP_CONFIG):
if not config.has_section('yapf'):
raise StyleConfigError(
'Unable to find section [yapf] in {0}'.format(config_filename))
- elif config_filename.endswith(LOCAL_STYLE):
- if not config.has_section('style'):
- raise StyleConfigError(
- 'Unable to find section [style] in {0}'.format(config_filename))
- else:
+ return config
+
+ if config_filename.endswith(LOCAL_STYLE):
if not config.has_section('style'):
raise StyleConfigError(
'Unable to find section [style] in {0}'.format(config_filename))
+ return config
+
+ if not config.has_section('style'):
+ raise StyleConfigError(
+ 'Unable to find section [style] in {0}'.format(config_filename))
return config
@@ -608,6 +844,10 @@ LOCAL_STYLE = '.style.yapf'
# specified in the '[yapf]' section.
SETUP_CONFIG = 'setup.cfg'
+# Style definition by local pyproject.toml file. Style should be specified
+# in the '[tool.yapf]' section.
+PYPROJECT_TOML = 'pyproject.toml'
+
# TODO(eliben): For now we're preserving the global presence of a style dict.
# Refactor this so that the style is passed around through yapf rather than
# being global.
diff --git a/yapf/yapflib/subtype_assigner.py b/yapf/yapflib/subtype_assigner.py
index 8bf3d8d..7b45586 100644
--- a/yapf/yapflib/subtype_assigner.py
+++ b/yapf/yapflib/subtype_assigner.py
@@ -11,28 +11,28 @@
# 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.
-"""Subtype assigner for lib2to3 trees.
+"""Subtype assigner for format tokens.
-This module assigns extra type information to the lib2to3 trees. This
-information is more specific than whether something is an operator or an
-identifier. For instance, it can specify if a node in the tree is part of a
-subscript.
+This module assigns extra type information to format tokens. This information is
+more specific than whether something is an operator or an identifier. For
+instance, it can specify if a node in the tree is part of a subscript.
AssignSubtypes(): the main function exported by this module.
Annotations:
- subtype: The subtype of a pytree token. See 'format_token' module for a list
- of subtypes.
+ subtype: The subtype of a pytree token. See 'subtypes' module for a list of
+ subtypes.
"""
from lib2to3 import pytree
-from lib2to3.pgen2 import token
+from lib2to3.pgen2 import token as grammar_token
from lib2to3.pygram import python_symbols as syms
from yapf.yapflib import format_token
from yapf.yapflib import pytree_utils
from yapf.yapflib import pytree_visitor
from yapf.yapflib import style
+from yapf.yapflib import subtypes
def AssignSubtypes(tree):
@@ -47,10 +47,10 @@ def AssignSubtypes(tree):
# Map tokens in argument lists to their respective subtype.
_ARGLIST_TOKEN_TO_SUBTYPE = {
- '=': format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN,
- ':': format_token.Subtype.TYPED_NAME,
- '*': format_token.Subtype.VARARGS_STAR,
- '**': format_token.Subtype.KWARGS_STAR_STAR,
+ '=': subtypes.DEFAULT_OR_NAMED_ASSIGN,
+ ':': subtypes.TYPED_NAME,
+ '*': subtypes.VARARGS_STAR,
+ '**': subtypes.KWARGS_STAR_STAR,
}
@@ -73,35 +73,31 @@ class _SubtypeAssigner(pytree_visitor.PyTreeVisitor):
for child in node.children:
if pytree_utils.NodeName(child) == 'comp_for':
comp_for = True
- _AppendFirstLeafTokenSubtype(child,
- format_token.Subtype.DICT_SET_GENERATOR)
- elif pytree_utils.NodeName(child) in ('COLON', 'DOUBLESTAR'):
+ _AppendFirstLeafTokenSubtype(child, subtypes.DICT_SET_GENERATOR)
+ elif child.type in (grammar_token.COLON, grammar_token.DOUBLESTAR):
dict_maker = True
if not comp_for and dict_maker:
last_was_colon = False
unpacking = False
for child in node.children:
- if pytree_utils.NodeName(child) == 'DOUBLESTAR':
- _AppendFirstLeafTokenSubtype(child,
- format_token.Subtype.KWARGS_STAR_STAR)
+ if child.type == grammar_token.DOUBLESTAR:
+ _AppendFirstLeafTokenSubtype(child, subtypes.KWARGS_STAR_STAR)
if last_was_colon:
if style.Get('INDENT_DICTIONARY_VALUE'):
_InsertPseudoParentheses(child)
else:
- _AppendFirstLeafTokenSubtype(child,
- format_token.Subtype.DICTIONARY_VALUE)
+ _AppendFirstLeafTokenSubtype(child, subtypes.DICTIONARY_VALUE)
elif (isinstance(child, pytree.Node) or
(not child.value.startswith('#') and child.value not in '{:,')):
# Mark the first leaf of a key entry as a DICTIONARY_KEY. We
# normally want to split before them if the dictionary cannot exist
# on a single line.
if not unpacking or pytree_utils.FirstLeafNode(child).value == '**':
- _AppendFirstLeafTokenSubtype(child,
- format_token.Subtype.DICTIONARY_KEY)
- _AppendSubtypeRec(child, format_token.Subtype.DICTIONARY_KEY_PART)
- last_was_colon = pytree_utils.NodeName(child) == 'COLON'
- if pytree_utils.NodeName(child) == 'DOUBLESTAR':
+ _AppendFirstLeafTokenSubtype(child, subtypes.DICTIONARY_KEY)
+ _AppendSubtypeRec(child, subtypes.DICTIONARY_KEY_PART)
+ last_was_colon = child.type == grammar_token.COLON
+ if child.type == grammar_token.DOUBLESTAR:
unpacking = True
elif last_was_colon:
unpacking = False
@@ -112,28 +108,28 @@ class _SubtypeAssigner(pytree_visitor.PyTreeVisitor):
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == '=':
- _AppendTokenSubtype(child, format_token.Subtype.ASSIGN_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.ASSIGN_OPERATOR)
def Visit_or_test(self, node): # pylint: disable=invalid-name
# or_test ::= and_test ('or' and_test)*
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == 'or':
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
def Visit_and_test(self, node): # pylint: disable=invalid-name
# and_test ::= not_test ('and' not_test)*
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == 'and':
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
def Visit_not_test(self, node): # pylint: disable=invalid-name
# not_test ::= 'not' not_test | comparison
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == 'not':
- _AppendTokenSubtype(child, format_token.Subtype.UNARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.UNARY_OPERATOR)
def Visit_comparison(self, node): # pylint: disable=invalid-name
# comparison ::= expr (comp_op expr)*
@@ -142,95 +138,104 @@ class _SubtypeAssigner(pytree_visitor.PyTreeVisitor):
self.Visit(child)
if (isinstance(child, pytree.Leaf) and
child.value in {'<', '>', '==', '>=', '<=', '<>', '!=', 'in', 'is'}):
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
elif pytree_utils.NodeName(child) == 'comp_op':
for grandchild in child.children:
- _AppendTokenSubtype(grandchild, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(grandchild, subtypes.BINARY_OPERATOR)
def Visit_star_expr(self, node): # pylint: disable=invalid-name
# star_expr ::= '*' expr
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == '*':
- _AppendTokenSubtype(child, format_token.Subtype.UNARY_OPERATOR)
- _AppendTokenSubtype(child, format_token.Subtype.VARARGS_STAR)
+ _AppendTokenSubtype(child, subtypes.UNARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.VARARGS_STAR)
def Visit_expr(self, node): # pylint: disable=invalid-name
# expr ::= xor_expr ('|' xor_expr)*
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == '|':
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
def Visit_xor_expr(self, node): # pylint: disable=invalid-name
# xor_expr ::= and_expr ('^' and_expr)*
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == '^':
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
def Visit_and_expr(self, node): # pylint: disable=invalid-name
# and_expr ::= shift_expr ('&' shift_expr)*
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == '&':
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
def Visit_shift_expr(self, node): # pylint: disable=invalid-name
# shift_expr ::= arith_expr (('<<'|'>>') arith_expr)*
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value in {'<<', '>>'}:
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
def Visit_arith_expr(self, node): # pylint: disable=invalid-name
# arith_expr ::= term (('+'|'-') term)*
for child in node.children:
self.Visit(child)
- if isinstance(child, pytree.Leaf) and child.value in '+-':
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ if _IsAExprOperator(child):
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
+
+ if _IsSimpleExpression(node):
+ for child in node.children:
+ if _IsAExprOperator(child):
+ _AppendTokenSubtype(child, subtypes.SIMPLE_EXPRESSION)
def Visit_term(self, node): # pylint: disable=invalid-name
- # term ::= factor (('*'|'/'|'%'|'//') factor)*
+ # term ::= factor (('*'|'/'|'%'|'//'|'@') factor)*
for child in node.children:
self.Visit(child)
- if (isinstance(child, pytree.Leaf) and
- child.value in {'*', '/', '%', '//'}):
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ if _IsMExprOperator(child):
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
+
+ if _IsSimpleExpression(node):
+ for child in node.children:
+ if _IsMExprOperator(child):
+ _AppendTokenSubtype(child, subtypes.SIMPLE_EXPRESSION)
def Visit_factor(self, node): # pylint: disable=invalid-name
# factor ::= ('+'|'-'|'~') factor | power
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value in '+-~':
- _AppendTokenSubtype(child, format_token.Subtype.UNARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.UNARY_OPERATOR)
def Visit_power(self, node): # pylint: disable=invalid-name
# power ::= atom trailer* ['**' factor]
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == '**':
- _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR)
+ _AppendTokenSubtype(child, subtypes.BINARY_OPERATOR)
def Visit_trailer(self, node): # pylint: disable=invalid-name
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value in '[]':
- _AppendTokenSubtype(child, format_token.Subtype.SUBSCRIPT_BRACKET)
+ _AppendTokenSubtype(child, subtypes.SUBSCRIPT_BRACKET)
def Visit_subscript(self, node): # pylint: disable=invalid-name
# subscript ::= test | [test] ':' [test] [sliceop]
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == ':':
- _AppendTokenSubtype(child, format_token.Subtype.SUBSCRIPT_COLON)
+ _AppendTokenSubtype(child, subtypes.SUBSCRIPT_COLON)
def Visit_sliceop(self, node): # pylint: disable=invalid-name
# sliceop ::= ':' [test]
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == ':':
- _AppendTokenSubtype(child, format_token.Subtype.SUBSCRIPT_COLON)
+ _AppendTokenSubtype(child, subtypes.SUBSCRIPT_COLON)
def Visit_argument(self, node): # pylint: disable=invalid-name
# argument ::=
@@ -243,32 +248,39 @@ class _SubtypeAssigner(pytree_visitor.PyTreeVisitor):
# | '*' test (',' argument)* [',' '**' test]
# | '**' test)
self._ProcessArgLists(node)
- _SetArgListSubtype(node, format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST)
+ _SetArgListSubtype(node, subtypes.DEFAULT_OR_NAMED_ASSIGN,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST)
def Visit_tname(self, node): # pylint: disable=invalid-name
self._ProcessArgLists(node)
- _SetArgListSubtype(node, format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST)
+ _SetArgListSubtype(node, subtypes.DEFAULT_OR_NAMED_ASSIGN,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST)
def Visit_decorator(self, node): # pylint: disable=invalid-name
# decorator ::=
# '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
for child in node.children:
if isinstance(child, pytree.Leaf) and child.value == '@':
- _AppendTokenSubtype(child, subtype=format_token.Subtype.DECORATOR)
+ _AppendTokenSubtype(child, subtype=subtypes.DECORATOR)
self.Visit(child)
def Visit_funcdef(self, node): # pylint: disable=invalid-name
# funcdef ::=
# 'def' NAME parameters ['->' test] ':' suite
for child in node.children:
- if pytree_utils.NodeName(child) == 'NAME' and child.value != 'def':
- _AppendTokenSubtype(child, format_token.Subtype.FUNC_DEF)
+ if child.type == grammar_token.NAME and child.value != 'def':
+ _AppendTokenSubtype(child, subtypes.FUNC_DEF)
break
for child in node.children:
self.Visit(child)
+ def Visit_parameters(self, node): # pylint: disable=invalid-name
+ # parameters ::= '(' [typedargslist] ')'
+ self._ProcessArgLists(node)
+ if len(node.children) > 2:
+ _AppendFirstLeafTokenSubtype(node.children[1], subtypes.PARAMETER_START)
+ _AppendLastLeafTokenSubtype(node.children[-2], subtypes.PARAMETER_STOP)
+
def Visit_typedargslist(self, node): # pylint: disable=invalid-name
# typedargslist ::=
# ((tfpdef ['=' test] ',')*
@@ -276,20 +288,32 @@ class _SubtypeAssigner(pytree_visitor.PyTreeVisitor):
# | '**' tname)
# | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
self._ProcessArgLists(node)
- _SetArgListSubtype(node, format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST)
+ _SetArgListSubtype(node, subtypes.DEFAULT_OR_NAMED_ASSIGN,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST)
tname = False
- for child in node.children:
+ if not node.children:
+ return
+
+ _AppendFirstLeafTokenSubtype(node.children[0], subtypes.PARAMETER_START)
+ _AppendLastLeafTokenSubtype(node.children[-1], subtypes.PARAMETER_STOP)
+
+ tname = pytree_utils.NodeName(node.children[0]) == 'tname'
+ for i in range(1, len(node.children)):
+ prev_child = node.children[i - 1]
+ child = node.children[i]
+ if prev_child.type == grammar_token.COMMA:
+ _AppendFirstLeafTokenSubtype(child, subtypes.PARAMETER_START)
+ elif child.type == grammar_token.COMMA:
+ _AppendLastLeafTokenSubtype(prev_child, subtypes.PARAMETER_STOP)
+
if pytree_utils.NodeName(child) == 'tname':
tname = True
- _SetArgListSubtype(child, format_token.Subtype.TYPED_NAME,
- format_token.Subtype.TYPED_NAME_ARG_LIST)
- if not isinstance(child, pytree.Leaf):
- continue
- if child.value == ',':
+ _SetArgListSubtype(child, subtypes.TYPED_NAME,
+ subtypes.TYPED_NAME_ARG_LIST)
+ elif child.type == grammar_token.COMMA:
tname = False
- elif child.value == '=' and tname:
- _AppendTokenSubtype(child, subtype=format_token.Subtype.TYPED_NAME)
+ elif child.type == grammar_token.EQUAL and tname:
+ _AppendTokenSubtype(child, subtype=subtypes.TYPED_NAME)
tname = False
def Visit_varargslist(self, node): # pylint: disable=invalid-name
@@ -302,24 +326,32 @@ class _SubtypeAssigner(pytree_visitor.PyTreeVisitor):
for child in node.children:
self.Visit(child)
if isinstance(child, pytree.Leaf) and child.value == '=':
- _AppendTokenSubtype(child, format_token.Subtype.VARARGS_LIST)
+ _AppendTokenSubtype(child, subtypes.VARARGS_LIST)
def Visit_comp_for(self, node): # pylint: disable=invalid-name
# comp_for ::= 'for' exprlist 'in' testlist_safe [comp_iter]
- _AppendSubtypeRec(node, format_token.Subtype.COMP_FOR)
+ _AppendSubtypeRec(node, subtypes.COMP_FOR)
# Mark the previous node as COMP_EXPR unless this is a nested comprehension
# as these will have the outer comprehension as their previous node.
attr = pytree_utils.GetNodeAnnotation(node.parent,
pytree_utils.Annotation.SUBTYPE)
- if not attr or format_token.Subtype.COMP_FOR not in attr:
- _AppendSubtypeRec(node.parent.children[0], format_token.Subtype.COMP_EXPR)
+ if not attr or subtypes.COMP_FOR not in attr:
+ _AppendSubtypeRec(node.parent.children[0], subtypes.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)
+ _AppendSubtypeRec(node, subtypes.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:
@@ -327,8 +359,7 @@ class _SubtypeAssigner(pytree_visitor.PyTreeVisitor):
if isinstance(child, pytree.Leaf):
_AppendTokenSubtype(
child,
- subtype=_ARGLIST_TOKEN_TO_SUBTYPE.get(child.value,
- format_token.Subtype.NONE))
+ subtype=_ARGLIST_TOKEN_TO_SUBTYPE.get(child.value, subtypes.NONE))
def _SetArgListSubtype(node, node_subtype, list_subtype):
@@ -337,20 +368,24 @@ def _SetArgListSubtype(node, node_subtype, list_subtype):
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):
@@ -367,6 +402,14 @@ def _AppendFirstLeafTokenSubtype(node, subtype):
_AppendFirstLeafTokenSubtype(node.children[0], subtype)
+def _AppendLastLeafTokenSubtype(node, subtype):
+ """Append the last leaf token's subtypes."""
+ if isinstance(node, pytree.Leaf):
+ _AppendTokenSubtype(node, subtype)
+ return
+ _AppendLastLeafTokenSubtype(node.children[-1], subtype)
+
+
def _AppendSubtypeRec(node, subtype, force=True):
"""Append the leafs in the node to the given subtype."""
if isinstance(node, pytree.Leaf):
@@ -380,18 +423,24 @@ def _InsertPseudoParentheses(node):
"""Insert pseudo parentheses so that dicts can be formatted correctly."""
comment_node = None
if isinstance(node, pytree.Node):
- if node.children[-1].type == token.COMMENT:
+ if node.children[-1].type == grammar_token.COMMENT:
comment_node = node.children[-1].clone()
node.children[-1].remove()
first = pytree_utils.FirstLeafNode(node)
last = pytree_utils.LastLeafNode(node)
- if first == last and first.type == token.COMMENT:
+ if first == last and first.type == grammar_token.COMMENT:
# 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()
@@ -400,17 +449,19 @@ def _InsertPseudoParentheses(node):
last = pytree_utils.LastLeafNode(node)
lparen = pytree.Leaf(
- token.LPAR, u'(', context=('', (first.get_lineno(), first.column - 1)))
+ grammar_token.LPAR,
+ u'(',
+ context=('', (first.get_lineno(), first.column - 1)))
last_lineno = last.get_lineno()
- if last.type == token.STRING and '\n' in last.value:
+ if last.type == grammar_token.STRING and '\n' in last.value:
last_lineno += last.value.count('\n')
- if last.type == token.STRING and '\n' in last.value:
+ if last.type == grammar_token.STRING and '\n' in last.value:
last_column = len(last.value.split('\n')[-1]) + 1
else:
last_column = last.column + len(last.value) + 1
rparen = pytree.Leaf(
- token.RPAR, u')', context=('', (last_lineno, last_column)))
+ grammar_token.RPAR, u')', context=('', (last_lineno, last_column)))
lparen.is_pseudo = True
rparen.is_pseudo = True
@@ -420,9 +471,25 @@ def _InsertPseudoParentheses(node):
node.append_child(rparen)
if comment_node:
node.append_child(comment_node)
- _AppendFirstLeafTokenSubtype(node, format_token.Subtype.DICTIONARY_VALUE)
+ _AppendFirstLeafTokenSubtype(node, subtypes.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)
+ _AppendFirstLeafTokenSubtype(clone, subtypes.DICTIONARY_VALUE)
+
+
+def _IsAExprOperator(node):
+ return isinstance(node, pytree.Leaf) and node.value in {'+', '-'}
+
+
+def _IsMExprOperator(node):
+ return isinstance(node,
+ pytree.Leaf) and node.value in {'*', '/', '%', '//', '@'}
+
+
+def _IsSimpleExpression(node):
+ """A node with only leafs as children."""
+ return all(isinstance(child, pytree.Leaf) for child in node.children)
diff --git a/yapf/yapflib/subtypes.py b/yapf/yapflib/subtypes.py
new file mode 100644
index 0000000..b4b7efe
--- /dev/null
+++ b/yapf/yapflib/subtypes.py
@@ -0,0 +1,40 @@
+# Copyright 2021 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+"""Token subtypes used to improve formatting."""
+
+NONE = 0
+UNARY_OPERATOR = 1
+BINARY_OPERATOR = 2
+SUBSCRIPT_COLON = 3
+SUBSCRIPT_BRACKET = 4
+DEFAULT_OR_NAMED_ASSIGN = 5
+DEFAULT_OR_NAMED_ASSIGN_ARG_LIST = 6
+VARARGS_LIST = 7
+VARARGS_STAR = 8
+KWARGS_STAR_STAR = 9
+ASSIGN_OPERATOR = 10
+DICTIONARY_KEY = 11
+DICTIONARY_KEY_PART = 12
+DICTIONARY_VALUE = 13
+DICT_SET_GENERATOR = 14
+COMP_EXPR = 15
+COMP_FOR = 16
+COMP_IF = 17
+FUNC_DEF = 18
+DECORATOR = 19
+TYPED_NAME = 20
+TYPED_NAME_ARG_LIST = 21
+SIMPLE_EXPRESSION = 22
+PARAMETER_START = 23
+PARAMETER_STOP = 24
diff --git a/yapf/yapflib/yapf_api.py b/yapf/yapflib/yapf_api.py
index 282dea3..09c31bc 100644
--- a/yapf/yapflib/yapf_api.py
+++ b/yapf/yapflib/yapf_api.py
@@ -37,10 +37,12 @@ import re
import sys
from lib2to3.pgen2 import parse
+from lib2to3.pgen2 import tokenize
from yapf.yapflib import blank_line_calculator
from yapf.yapflib import comment_splicer
from yapf.yapflib import continuation_splicer
+from yapf.yapflib import errors
from yapf.yapflib import file_resources
from yapf.yapflib import identify_container
from yapf.yapflib import py3compat
@@ -63,9 +65,18 @@ def FormatFile(filename,
Arguments:
filename: (unicode) The file to reformat.
+ 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.
+ print_diff: (bool) Instead of returning the reformatted source, return a
+ diff that turns the formatted source into reformatter source.
+ verify: (bool) True if reformatted code should be verified for syntax.
in_place: (bool) If True, write the reformatted code back to the file.
logger: (io streamer) A stream to output logging.
- remaining arguments: see comment at the top of this module.
Returns:
Tuple of (reformatted_code, encoding, changed). reformatted_code is None if
@@ -91,7 +102,7 @@ def FormatFile(filename,
verify=verify)
if reformatted_source.rstrip('\n'):
lines = reformatted_source.rstrip('\n').split('\n')
- reformatted_source = newline.join(line for line in lines) + newline
+ reformatted_source = newline.join(iter(lines)) + newline
if in_place:
if original_source and original_source != reformatted_source:
file_resources.WriteReformattedCode(filename, reformatted_source,
@@ -101,6 +112,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)
+
+ llines = pytree_unwrapper.UnwrapPyTree(tree)
+ for lline in llines:
+ lline.CalculateFormattingInformation()
+
+ lines = _LineRangesToSet(lines)
+ _MarkLinesToFormat(llines, lines)
+ return reformatter.Reformat(_SplitSemicolons(llines), verify, lines)
+
+
def FormatCode(unformatted_source,
filename='<unknown>',
style_config=None,
@@ -114,39 +164,29 @@ def FormatCode(unformatted_source,
Arguments:
unformatted_source: (unicode) The code to format.
filename: (unicode) The name of the file being reformatted.
- remaining arguments: see comment at the top of this module.
+ 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.
+ print_diff: (bool) Instead of returning the reformatted source, return a
+ diff that turns the formatted source into reformatter source.
+ verify: (bool) True if reformatted code should be verified for syntax.
Returns:
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
+ except Exception as e:
+ e.filename = filename
+ raise errors.YapfError(errors.FormatErrorMsg(e))
- # 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
@@ -155,7 +195,7 @@ def FormatCode(unformatted_source,
unformatted_source, reformatted_source, filename=filename)
if print_diff:
- return code_diff, code_diff.strip() != '' # pylint: disable=g-explicit-bool-comparison
+ return code_diff, code_diff.strip() != '' # pylint: disable=g-explicit-bool-comparison # noqa
return reformatted_source, True
@@ -198,16 +238,24 @@ def ReadFile(filename, logger=None):
line_ending = file_resources.LineEnding(lines)
source = '\n'.join(line.rstrip('\r\n') for line in lines) + '\n'
return source, line_ending, encoding
- except IOError as err: # pragma: no cover
+ except IOError as e: # pragma: no cover
+ if logger:
+ logger(e)
+ e.args = (e.args[0], (filename, e.args[1][1], e.args[1][2], e.args[1][3]))
+ raise
+ except UnicodeDecodeError as e: # pragma: no cover
if logger:
- logger(err)
+ logger('Could not parse %s! Consider excluding this file with --exclude.',
+ filename)
+ logger(e)
+ e.args = (e.args[0], (filename, e.args[1][1], e.args[1][2], e.args[1][3]))
raise
-def _SplitSemicolons(uwlines):
+def _SplitSemicolons(lines):
res = []
- for uwline in uwlines:
- res.extend(uwline.Split())
+ for line in lines:
+ res.extend(line.Split())
return res
@@ -228,25 +276,27 @@ def _LineRangesToSet(line_ranges):
return line_set
-def _MarkLinesToFormat(uwlines, lines):
+def _MarkLinesToFormat(llines, lines):
"""Skip sections of code that we shouldn't reformat."""
if lines:
- for uwline in uwlines:
+ for uwline in llines:
uwline.disable = not lines.intersection(
range(uwline.lineno, uwline.last.lineno + 1))
# Now go through the lines and disable any lines explicitly marked as
# disabled.
index = 0
- while index < len(uwlines):
- uwline = uwlines[index]
+ while index < len(llines):
+ uwline = llines[index]
if uwline.is_comment:
if _DisableYAPF(uwline.first.value.strip()):
index += 1
- while index < len(uwlines):
- uwline = uwlines[index]
- if uwline.is_comment and _EnableYAPF(uwline.first.value.strip()):
- break
+ while index < len(llines):
+ uwline = llines[index]
+ line = uwline.first.value.strip()
+ if uwline.is_comment and _EnableYAPF(line):
+ if not _DisableYAPF(line):
+ break
uwline.disable = True
index += 1
elif re.search(DISABLE_PATTERN, uwline.last.value.strip(), re.IGNORECASE):
diff --git a/yapftests/blank_line_calculator_test.py b/yapftests/blank_line_calculator_test.py
index 2a27a2f..18fa83e 100644
--- a/yapftests/blank_line_calculator_test.py
+++ b/yapftests/blank_line_calculator_test.py
@@ -27,7 +27,7 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
@classmethod
def setUpClass(cls):
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testDecorators(self):
unformatted_code = textwrap.dedent("""\
@@ -41,8 +41,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
def foo():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testComplexDecorators(self):
unformatted_code = textwrap.dedent("""\
@@ -77,8 +77,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
def method(self):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testCodeAfterFunctionsAndClasses(self):
unformatted_code = textwrap.dedent("""\
@@ -122,8 +122,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
except Error as error:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testCommentSpacing(self):
unformatted_code = textwrap.dedent("""\
@@ -188,8 +188,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
# comment
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testCommentBeforeMethod(self):
code = textwrap.dedent("""\
@@ -199,8 +199,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
def f(self):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testCommentsBeforeClassDefs(self):
code = textwrap.dedent('''\
@@ -212,8 +212,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
class Foo(object):
pass
''')
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testCommentsBeforeDecorator(self):
code = textwrap.dedent("""\
@@ -222,8 +222,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
def a():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
# Hello world
@@ -233,8 +233,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
def a():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testCommentsAfterDecorator(self):
code = textwrap.dedent("""\
@@ -249,9 +249,9 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
# reason="https://github.com/pypa/setuptools/issues/706")
def test_unicode_filename_in_sdist(self, sdist_unicode, tmpdir, monkeypatch):
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testInnerClasses(self):
unformatted_code = textwrap.dedent("""\
@@ -274,8 +274,8 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
class DeployAPIHTTPError(Error):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testLinesOnRangeBoundary(self):
unformatted_code = textwrap.dedent(u"""\
@@ -300,15 +300,12 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
def B(): # 4
pass # 5
-
def C():
pass
def D(): # 9
pass # 10
-
-
def E():
pass
""")
@@ -350,6 +347,76 @@ class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest):
self.assertCodeEqual(expected_formatted_code, code)
self.assertFalse(changed)
+ def testLinesRangeRemove(self):
+ unformatted_code = textwrap.dedent(u"""\
+ def A():
+ pass
+
+
+
+ def B(): # 6
+ pass # 7
+
+
+
+
+ def C():
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent(u"""\
+ def A():
+ pass
+
+
+ def B(): # 6
+ pass # 7
+
+
+
+
+ def C():
+ pass
+ """)
+ code, changed = yapf_api.FormatCode(unformatted_code, lines=[(5, 9)])
+ self.assertCodeEqual(expected_formatted_code, code)
+ self.assertTrue(changed)
+
+ def testLinesRangeRemoveSome(self):
+ unformatted_code = textwrap.dedent(u"""\
+ def A():
+ pass
+
+
+
+
+ def B(): # 7
+ pass # 8
+
+
+
+
+ def C():
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent(u"""\
+ def A():
+ pass
+
+
+
+ def B(): # 7
+ pass # 8
+
+
+
+
+ def C():
+ pass
+ """)
+ code, changed = yapf_api.FormatCode(unformatted_code, lines=[(6, 9)])
+ self.assertCodeEqual(expected_formatted_code, code)
+ self.assertTrue(changed)
+
if __name__ == '__main__':
unittest.main()
diff --git a/yapftests/file_resources_test.py b/yapftests/file_resources_test.py
index 70cea46..31184c4 100644
--- a/yapftests/file_resources_test.py
+++ b/yapftests/file_resources_test.py
@@ -36,12 +36,118 @@ def _restore_working_dir():
os.chdir(curdir)
+@contextlib.contextmanager
+def _exists_mocked_in_module(module, mock_implementation):
+ unmocked_exists = getattr(module, 'exists')
+ setattr(module, 'exists', mock_implementation)
+ try:
+ yield
+ finally:
+ setattr(module, 'exists', unmocked_exists)
+
+
+class GetExcludePatternsForDir(unittest.TestCase):
+
+ def setUp(self): # pylint: disable=g-missing-super-call
+ self.test_tmpdir = tempfile.mkdtemp()
+
+ def tearDown(self): # pylint: disable=g-missing-super-call
+ shutil.rmtree(self.test_tmpdir)
+
+ def test_get_exclude_file_patterns_from_yapfignore(self):
+ local_ignore_file = os.path.join(self.test_tmpdir, '.yapfignore')
+ ignore_patterns = ['temp/**/*.py', 'temp2/*.py']
+ with open(local_ignore_file, 'w') as f:
+ f.writelines('\n'.join(ignore_patterns))
+
+ self.assertEqual(
+ sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
+ sorted(ignore_patterns))
+
+ def test_get_exclude_file_patterns_from_yapfignore_with_wrong_syntax(self):
+ local_ignore_file = os.path.join(self.test_tmpdir, '.yapfignore')
+ ignore_patterns = ['temp/**/*.py', './wrong/syntax/*.py']
+ with open(local_ignore_file, 'w') as f:
+ f.writelines('\n'.join(ignore_patterns))
+
+ with self.assertRaises(errors.YapfError):
+ file_resources.GetExcludePatternsForDir(self.test_tmpdir)
+
+ def test_get_exclude_file_patterns_from_pyproject(self):
+ try:
+ import toml
+ except ImportError:
+ return
+ local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
+ ignore_patterns = ['temp/**/*.py', 'temp2/*.py']
+ with open(local_ignore_file, 'w') as f:
+ f.write('[tool.yapfignore]\n')
+ f.write('ignore_patterns=[')
+ f.writelines('\n,'.join(['"{}"'.format(p) for p in ignore_patterns]))
+ f.write(']')
+
+ self.assertEqual(
+ sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
+ sorted(ignore_patterns))
+
+ @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
+ def test_get_exclude_file_patterns_from_pyproject_with_wrong_syntax(self):
+ try:
+ import toml
+ except ImportError:
+ return
+ local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
+ ignore_patterns = ['temp/**/*.py', './wrong/syntax/*.py']
+ with open(local_ignore_file, 'w') as f:
+ f.write('[tool.yapfignore]\n')
+ f.write('ignore_patterns=[')
+ f.writelines('\n,'.join(['"{}"'.format(p) for p in ignore_patterns]))
+ f.write(']')
+
+ with self.assertRaises(errors.YapfError):
+ file_resources.GetExcludePatternsForDir(self.test_tmpdir)
+
+ def test_get_exclude_file_patterns_from_pyproject_no_ignore_section(self):
+ try:
+ import toml
+ except ImportError:
+ return
+ local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
+ ignore_patterns = []
+ open(local_ignore_file, 'w').close()
+
+ self.assertEqual(
+ sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
+ sorted(ignore_patterns))
+
+ def test_get_exclude_file_patterns_from_pyproject_ignore_section_empty(self):
+ try:
+ import toml
+ except ImportError:
+ return
+ local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
+ ignore_patterns = []
+ with open(local_ignore_file, 'w') as f:
+ f.write('[tool.yapfignore]\n')
+
+ self.assertEqual(
+ sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
+ sorted(ignore_patterns))
+
+ def test_get_exclude_file_patterns_with_no_config_files(self):
+ ignore_patterns = []
+
+ self.assertEqual(
+ sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
+ sorted(ignore_patterns))
+
+
class GetDefaultStyleForDirTest(unittest.TestCase):
- def setUp(self):
+ def setUp(self): # pylint: disable=g-missing-super-call
self.test_tmpdir = tempfile.mkdtemp()
- def tearDown(self):
+ def tearDown(self): # pylint: disable=g-missing-super-call
shutil.rmtree(self.test_tmpdir)
def test_no_local_style(self):
@@ -49,6 +155,12 @@ class GetDefaultStyleForDirTest(unittest.TestCase):
style_name = file_resources.GetDefaultStyleForDir(test_file)
self.assertEqual(style_name, 'pep8')
+ def test_no_local_style_custom_default(self):
+ test_file = os.path.join(self.test_tmpdir, 'file.py')
+ style_name = file_resources.GetDefaultStyleForDir(
+ test_file, default_style='custom-default')
+ self.assertEqual(style_name, 'custom-default')
+
def test_with_local_style(self):
# Create an empty .style.yapf file in test_tmpdir
style_file = os.path.join(self.test_tmpdir, '.style.yapf')
@@ -62,6 +174,63 @@ class GetDefaultStyleForDirTest(unittest.TestCase):
self.assertEqual(style_file,
file_resources.GetDefaultStyleForDir(test_filename))
+ def test_setup_config(self):
+ # An empty setup.cfg file should not be used
+ setup_config = os.path.join(self.test_tmpdir, 'setup.cfg')
+ open(setup_config, 'w').close()
+
+ test_dir = os.path.join(self.test_tmpdir, 'dir1')
+ style_name = file_resources.GetDefaultStyleForDir(test_dir)
+ self.assertEqual(style_name, 'pep8')
+
+ # One with a '[yapf]' section should be used
+ with open(setup_config, 'w') as f:
+ f.write('[yapf]\n')
+ self.assertEqual(setup_config,
+ file_resources.GetDefaultStyleForDir(test_dir))
+
+ def test_pyproject_toml(self):
+ # An empty pyproject.toml file should not be used
+ try:
+ import toml
+ except ImportError:
+ return
+
+ pyproject_toml = os.path.join(self.test_tmpdir, 'pyproject.toml')
+ open(pyproject_toml, 'w').close()
+
+ test_dir = os.path.join(self.test_tmpdir, 'dir1')
+ style_name = file_resources.GetDefaultStyleForDir(test_dir)
+ self.assertEqual(style_name, 'pep8')
+
+ # One with a '[tool.yapf]' section should be used
+ with open(pyproject_toml, 'w') as f:
+ f.write('[tool.yapf]\n')
+ self.assertEqual(pyproject_toml,
+ file_resources.GetDefaultStyleForDir(test_dir))
+
+ def test_local_style_at_root(self):
+ # Test behavior of files located on the root, and under root.
+ rootdir = os.path.abspath(os.path.sep)
+ test_dir_at_root = os.path.join(rootdir, 'dir1')
+ test_dir_under_root = os.path.join(rootdir, 'dir1', 'dir2')
+
+ # Fake placing only a style file at the root by mocking `os.path.exists`.
+ style_file = os.path.join(rootdir, '.style.yapf')
+
+ def mock_exists_implementation(path):
+ return path == style_file
+
+ with _exists_mocked_in_module(file_resources.os.path,
+ mock_exists_implementation):
+ # Both files should find the style file at the root.
+ default_style_at_root = file_resources.GetDefaultStyleForDir(
+ test_dir_at_root)
+ self.assertEqual(style_file, default_style_at_root)
+ default_style_under_root = file_resources.GetDefaultStyleForDir(
+ test_dir_under_root)
+ self.assertEqual(style_file, default_style_under_root)
+
def _touch_files(filenames):
for name in filenames:
@@ -70,13 +239,13 @@ def _touch_files(filenames):
class GetCommandLineFilesTest(unittest.TestCase):
- def setUp(self):
+ def setUp(self): # pylint: disable=g-missing-super-call
self.test_tmpdir = tempfile.mkdtemp()
self.old_dir = os.getcwd()
- def tearDown(self):
- shutil.rmtree(self.test_tmpdir)
+ def tearDown(self): # pylint: disable=g-missing-super-call
os.chdir(self.old_dir)
+ shutil.rmtree(self.test_tmpdir)
def _make_test_dir(self, name):
fullpath = os.path.normpath(os.path.join(self.test_tmpdir, name))
@@ -91,11 +260,13 @@ class GetCommandLineFilesTest(unittest.TestCase):
_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 +295,9 @@ class GetCommandLineFilesTest(unittest.TestCase):
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 +312,9 @@ class GetCommandLineFilesTest(unittest.TestCase):
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 +331,9 @@ class GetCommandLineFilesTest(unittest.TestCase):
]
_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,24 +398,26 @@ class GetCommandLineFilesTest(unittest.TestCase):
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'])
+ self.assertEqual(
+ found, ['test3/foo/bar/bas/xxx/testfile3.py'.replace("/", os.path.sep)])
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'])
+ self.assertEqual(
+ found, ['./test2/testinner/testfile2.py'.replace("/", os.path.sep)])
def test_find_with_excluded_current_dir(self):
with self.assertRaises(errors.YapfError):
@@ -251,10 +426,10 @@ class GetCommandLineFilesTest(unittest.TestCase):
class IsPythonFileTest(unittest.TestCase):
- def setUp(self):
+ def setUp(self): # pylint: disable=g-missing-super-call
self.test_tmpdir = tempfile.mkdtemp()
- def tearDown(self):
+ def tearDown(self): # pylint: disable=g-missing-super-call
shutil.rmtree(self.test_tmpdir)
def test_with_py_extension(self):
@@ -305,7 +480,7 @@ class IsIgnoredTest(unittest.TestCase):
def test_trailing_slash(self):
self.assertTrue(file_resources.IsIgnored('z', ['z']))
- self.assertTrue(file_resources.IsIgnored('z', ['z/']))
+ self.assertTrue(file_resources.IsIgnored('z', ['z' + os.path.sep]))
class BufferedByteStream(object):
@@ -324,11 +499,11 @@ class BufferedByteStream(object):
class WriteReformattedCodeTest(unittest.TestCase):
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
cls.test_tmpdir = tempfile.mkdtemp()
@classmethod
- def tearDownClass(cls):
+ def tearDownClass(cls): # pylint: disable=g-missing-super-call
shutil.rmtree(cls.test_tmpdir)
def test_write_to_file(self):
@@ -350,7 +525,7 @@ class WriteReformattedCodeTest(unittest.TestCase):
self.assertEqual(stream.getvalue(), s)
def test_write_encoded_to_stdout(self):
- s = '\ufeff# -*- coding: utf-8 -*-\nresult = "passed"\n' # pylint: disable=anomalous-unicode-escape-in-string
+ s = '\ufeff# -*- coding: utf-8 -*-\nresult = "passed"\n' # pylint: disable=anomalous-unicode-escape-in-string # noqa
stream = BufferedByteStream() if py3compat.PY3 else py3compat.StringIO()
with utils.stdout_redirector(stream):
file_resources.WriteReformattedCode(
@@ -358,5 +533,33 @@ class WriteReformattedCodeTest(unittest.TestCase):
self.assertEqual(stream.getvalue(), s)
+class LineEndingTest(unittest.TestCase):
+
+ def test_line_ending_linefeed(self):
+ lines = ['spam\n', 'spam\n']
+ actual = file_resources.LineEnding(lines)
+ self.assertEqual(actual, '\n')
+
+ def test_line_ending_carriage_return(self):
+ lines = ['spam\r', 'spam\r']
+ actual = file_resources.LineEnding(lines)
+ self.assertEqual(actual, '\r')
+
+ def test_line_ending_combo(self):
+ lines = ['spam\r\n', 'spam\r\n']
+ actual = file_resources.LineEnding(lines)
+ self.assertEqual(actual, '\r\n')
+
+ def test_line_ending_weighted(self):
+ lines = [
+ 'spam\n',
+ 'spam\n',
+ 'spam\r',
+ 'spam\r\n',
+ ]
+ actual = file_resources.LineEnding(lines)
+ self.assertEqual(actual, '\n')
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/yapftests/format_decision_state_test.py b/yapftests/format_decision_state_test.py
index 6122960..9d62267 100644
--- a/yapftests/format_decision_state_test.py
+++ b/yapftests/format_decision_state_test.py
@@ -17,9 +17,9 @@ import textwrap
import unittest
from yapf.yapflib import format_decision_state
+from yapf.yapflib import logical_line
from yapf.yapflib import pytree_utils
from yapf.yapflib import style
-from yapf.yapflib import unwrapped_line
from yapftests import yapf_test_helper
@@ -28,19 +28,19 @@ class FormatDecisionStateTest(yapf_test_helper.YAPFTest):
@classmethod
def setUpClass(cls):
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testSimpleFunctionDefWithNoSplitting(self):
code = textwrap.dedent(r"""
def f(a, b):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- uwline = unwrapped_line.UnwrappedLine(0, _FilterLine(uwlines[0]))
- uwline.CalculateFormattingInformation()
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ lline = logical_line.LogicalLine(0, _FilterLine(llines[0]))
+ lline.CalculateFormattingInformation()
# Add: 'f'
- state = format_decision_state.FormatDecisionState(uwline, 0)
+ state = format_decision_state.FormatDecisionState(lline, 0)
state.MoveStateToNextToken()
self.assertEqual('f', state.next_token.value)
self.assertFalse(state.CanSplit(False))
@@ -89,12 +89,12 @@ class FormatDecisionStateTest(yapf_test_helper.YAPFTest):
def f(a, b):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- uwline = unwrapped_line.UnwrappedLine(0, _FilterLine(uwlines[0]))
- uwline.CalculateFormattingInformation()
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ lline = logical_line.LogicalLine(0, _FilterLine(llines[0]))
+ lline.CalculateFormattingInformation()
# Add: 'f'
- state = format_decision_state.FormatDecisionState(uwline, 0)
+ state = format_decision_state.FormatDecisionState(lline, 0)
state.MoveStateToNextToken()
self.assertEqual('f', state.next_token.value)
self.assertFalse(state.CanSplit(False))
@@ -133,10 +133,10 @@ class FormatDecisionStateTest(yapf_test_helper.YAPFTest):
self.assertEqual(repr(state), repr(clone))
-def _FilterLine(uwline):
- """Filter out nonsemantic tokens from the UnwrappedLines."""
+def _FilterLine(lline):
+ """Filter out nonsemantic tokens from the LogicalLines."""
return [
- ft for ft in uwline.tokens
+ ft for ft in lline.tokens
if ft.name not in pytree_utils.NONSEMANTIC_TOKENS
]
diff --git a/yapftests/format_token_test.py b/yapftests/format_token_test.py
index 7dfb82a..e324983 100644
--- a/yapftests/format_token_test.py
+++ b/yapftests/format_token_test.py
@@ -26,40 +26,40 @@ class TabbedContinuationAlignPaddingTest(unittest.TestCase):
def testSpace(self):
align_style = 'SPACE'
- pad = format_token._TabbedContinuationAlignPadding(0, align_style, 2, 4)
+ pad = format_token._TabbedContinuationAlignPadding(0, align_style, 2)
self.assertEqual(pad, '')
- pad = format_token._TabbedContinuationAlignPadding(2, align_style, 2, 4)
+ pad = format_token._TabbedContinuationAlignPadding(2, align_style, 2)
self.assertEqual(pad, ' ' * 2)
- pad = format_token._TabbedContinuationAlignPadding(5, align_style, 2, 4)
+ pad = format_token._TabbedContinuationAlignPadding(5, align_style, 2)
self.assertEqual(pad, ' ' * 5)
def testFixed(self):
align_style = 'FIXED'
- pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4, 8)
+ pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4)
self.assertEqual(pad, '')
- pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4, 8)
- self.assertEqual(pad, '\t' * 2)
+ pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4)
+ self.assertEqual(pad, '\t')
- pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4, 8)
+ pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4)
self.assertEqual(pad, '\t' * 2)
def testVAlignRight(self):
align_style = 'VALIGN-RIGHT'
- pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4, 8)
+ pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4)
self.assertEqual(pad, '')
- pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4, 8)
+ pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4)
self.assertEqual(pad, '\t')
- pad = format_token._TabbedContinuationAlignPadding(4, align_style, 4, 8)
+ pad = format_token._TabbedContinuationAlignPadding(4, align_style, 4)
self.assertEqual(pad, '\t')
- pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4, 8)
+ pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4)
self.assertEqual(pad, '\t' * 2)
@@ -67,11 +67,15 @@ class FormatTokenTest(unittest.TestCase):
def testSimple(self):
tok = format_token.FormatToken(pytree.Leaf(token.STRING, "'hello world'"))
- self.assertEqual("FormatToken(name=STRING, value='hello world')", str(tok))
+ self.assertEqual(
+ "FormatToken(name=DOCSTRING, value='hello world', column=0, "
+ "lineno=0, splitpenalty=0)", str(tok))
self.assertTrue(tok.is_string)
tok = format_token.FormatToken(pytree.Leaf(token.COMMENT, '# A comment'))
- self.assertEqual('FormatToken(name=COMMENT, value=# A comment)', str(tok))
+ self.assertEqual(
+ 'FormatToken(name=COMMENT, value=# A comment, column=0, '
+ 'lineno=0, splitpenalty=0)', str(tok))
self.assertTrue(tok.is_comment)
def testIsMultilineString(self):
diff --git a/yapftests/line_joiner_test.py b/yapftests/line_joiner_test.py
index 6501bc8..2eaf164 100644
--- a/yapftests/line_joiner_test.py
+++ b/yapftests/line_joiner_test.py
@@ -29,14 +29,14 @@ class LineJoinerTest(yapf_test_helper.YAPFTest):
style.SetGlobalStyle(style.CreatePEP8Style())
def _CheckLineJoining(self, code, join_lines):
- """Check that the given UnwrappedLines are joined as expected.
+ """Check that the given LogicalLines are joined as expected.
Arguments:
code: The code to check to see if we can join it.
join_lines: True if we expect the lines to be joined.
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(line_joiner.CanMergeMultipleLines(uwlines), join_lines)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(line_joiner.CanMergeMultipleLines(llines), join_lines)
def testSimpleSingleLineStatement(self):
code = textwrap.dedent(u"""\
@@ -74,7 +74,7 @@ class LineJoinerTest(yapf_test_helper.YAPFTest):
def testOverColumnLimit(self):
code = textwrap.dedent(u"""\
if instance(bbbbbbbbbbbbbbbbbbbbbbbbb, int): cccccccccccccccccccccccccc = ddddddddddddddddddddd
- """)
+ """) # noqa
self._CheckLineJoining(code, join_lines=False)
diff --git a/yapftests/unwrapped_line_test.py b/yapftests/logical_line_test.py
index 90be1a1..6876efe 100644
--- a/yapftests/unwrapped_line_test.py
+++ b/yapftests/logical_line_test.py
@@ -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.
-"""Tests for yapf.unwrapped_line."""
+"""Tests for yapf.logical_line."""
import textwrap
import unittest
@@ -20,62 +20,62 @@ from lib2to3 import pytree
from lib2to3.pgen2 import token
from yapf.yapflib import format_token
+from yapf.yapflib import logical_line
from yapf.yapflib import split_penalty
-from yapf.yapflib import unwrapped_line
from yapftests import yapf_test_helper
-class UnwrappedLineBasicTest(unittest.TestCase):
+class LogicalLineBasicTest(unittest.TestCase):
def testConstruction(self):
toks = _MakeFormatTokenList([(token.DOT, '.'), (token.VBAR, '|')])
- uwl = unwrapped_line.UnwrappedLine(20, toks)
- self.assertEqual(20, uwl.depth)
- self.assertEqual(['DOT', 'VBAR'], [tok.name for tok in uwl.tokens])
+ lline = logical_line.LogicalLine(20, toks)
+ self.assertEqual(20, lline.depth)
+ self.assertEqual(['DOT', 'VBAR'], [tok.name for tok in lline.tokens])
def testFirstLast(self):
toks = _MakeFormatTokenList([(token.DOT, '.'), (token.LPAR, '('),
(token.VBAR, '|')])
- uwl = unwrapped_line.UnwrappedLine(20, toks)
- self.assertEqual(20, uwl.depth)
- self.assertEqual('DOT', uwl.first.name)
- self.assertEqual('VBAR', uwl.last.name)
+ lline = logical_line.LogicalLine(20, toks)
+ self.assertEqual(20, lline.depth)
+ self.assertEqual('DOT', lline.first.name)
+ self.assertEqual('VBAR', lline.last.name)
def testAsCode(self):
toks = _MakeFormatTokenList([(token.DOT, '.'), (token.LPAR, '('),
(token.VBAR, '|')])
- uwl = unwrapped_line.UnwrappedLine(2, toks)
- self.assertEqual(' . ( |', uwl.AsCode())
+ lline = logical_line.LogicalLine(2, toks)
+ self.assertEqual(' . ( |', lline.AsCode())
def testAppendToken(self):
- uwl = unwrapped_line.UnwrappedLine(0)
- uwl.AppendToken(_MakeFormatTokenLeaf(token.LPAR, '('))
- uwl.AppendToken(_MakeFormatTokenLeaf(token.RPAR, ')'))
- self.assertEqual(['LPAR', 'RPAR'], [tok.name for tok in uwl.tokens])
+ lline = logical_line.LogicalLine(0)
+ lline.AppendToken(_MakeFormatTokenLeaf(token.LPAR, '('))
+ lline.AppendToken(_MakeFormatTokenLeaf(token.RPAR, ')'))
+ self.assertEqual(['LPAR', 'RPAR'], [tok.name for tok in lline.tokens])
def testAppendNode(self):
- uwl = unwrapped_line.UnwrappedLine(0)
- uwl.AppendNode(pytree.Leaf(token.LPAR, '('))
- uwl.AppendNode(pytree.Leaf(token.RPAR, ')'))
- self.assertEqual(['LPAR', 'RPAR'], [tok.name for tok in uwl.tokens])
+ lline = logical_line.LogicalLine(0)
+ lline.AppendNode(pytree.Leaf(token.LPAR, '('))
+ lline.AppendNode(pytree.Leaf(token.RPAR, ')'))
+ self.assertEqual(['LPAR', 'RPAR'], [tok.name for tok in lline.tokens])
-class UnwrappedLineFormattingInformationTest(yapf_test_helper.YAPFTest):
+class LogicalLineFormattingInformationTest(yapf_test_helper.YAPFTest):
def testFuncDef(self):
code = textwrap.dedent(r"""
def f(a, b):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
- f = uwlines[0].tokens[1]
+ f = llines[0].tokens[1]
self.assertFalse(f.can_break_before)
self.assertFalse(f.must_break_before)
self.assertEqual(f.split_penalty, split_penalty.UNBREAKABLE)
- lparen = uwlines[0].tokens[2]
+ lparen = llines[0].tokens[2]
self.assertFalse(lparen.can_break_before)
self.assertFalse(lparen.must_break_before)
self.assertEqual(lparen.split_penalty, split_penalty.UNBREAKABLE)
diff --git a/yapftests/main_test.py b/yapftests/main_test.py
index 138853c..c83b8b6 100644
--- a/yapftests/main_test.py
+++ b/yapftests/main_test.py
@@ -21,6 +21,8 @@ import yapf
from yapf.yapflib import py3compat
+from yapftests import yapf_test_helper
+
class IO(object):
"""IO is a thin wrapper around StringIO.
@@ -83,11 +85,11 @@ def patched_input(code):
yapf.py3compat.raw_input = orig_raw_import
-class RunMainTest(unittest.TestCase):
+class RunMainTest(yapf_test_helper.YAPFTest):
def testShouldHandleYapfError(self):
"""run_main should handle YapfError and sys.exit(1)."""
- expected_message = 'yapf: Input filenames did not match any python files\n'
+ expected_message = 'yapf: input filenames did not match any python files\n'
sys.argv = ['yapf', 'foo.c']
with captured_output() as (out, err):
with self.assertRaises(SystemExit):
@@ -96,11 +98,11 @@ class RunMainTest(unittest.TestCase):
self.assertEqual(err.getvalue(), expected_message)
-class MainTest(unittest.TestCase):
+class MainTest(yapf_test_helper.YAPFTest):
def testNoPythonFilesMatched(self):
- with self.assertRaisesRegexp(yapf.errors.YapfError,
- 'did not match any python files'):
+ with self.assertRaisesRegex(yapf.errors.YapfError,
+ 'did not match any python files'):
yapf.main(['yapf', 'foo.c'])
def testEchoInput(self):
@@ -112,19 +114,19 @@ class MainTest(unittest.TestCase):
self.assertEqual(out.getvalue(), code)
def testEchoInputWithStyle(self):
- code = 'def f(a = 1):\n return 2*a\n'
- chromium_code = 'def f(a=1):\n return 2 * a\n'
+ code = 'def f(a = 1\n\n):\n return 2*a\n'
+ yapf_code = 'def f(a=1):\n return 2 * a\n'
with patched_input(code):
with captured_output() as (out, _):
- ret = yapf.main(['-', '--style=chromium'])
+ ret = yapf.main(['-', '--style=yapf'])
self.assertEqual(ret, 0)
- self.assertEqual(out.getvalue(), chromium_code)
+ self.assertEqual(out.getvalue(), yapf_code)
def testEchoBadInput(self):
bad_syntax = ' a = 1\n'
with patched_input(bad_syntax):
with captured_output() as (_, _):
- with self.assertRaisesRegexp(SyntaxError, 'unexpected indent'):
+ with self.assertRaisesRegex(yapf.errors.YapfError, 'unexpected indent'):
yapf.main([])
def testHelp(self):
@@ -135,10 +137,3 @@ class MainTest(unittest.TestCase):
self.assertIn('indent_width=4', help_message)
self.assertIn('The number of spaces required before a trailing comment.',
help_message)
-
- def testVersion(self):
- with captured_output() as (out, _):
- ret = yapf.main(['-', '--version'])
- self.assertEqual(ret, 0)
- version = 'yapf {}\n'.format(yapf.__version__)
- self.assertEqual(version, out.getvalue())
diff --git a/yapftests/pytree_unwrapper_test.py b/yapftests/pytree_unwrapper_test.py
index f95f366..b6ab809 100644
--- a/yapftests/pytree_unwrapper_test.py
+++ b/yapftests/pytree_unwrapper_test.py
@@ -23,22 +23,22 @@ from yapftests import yapf_test_helper
class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
- def _CheckUnwrappedLines(self, uwlines, list_of_expected):
- """Check that the given UnwrappedLines match expectations.
+ def _CheckLogicalLines(self, llines, list_of_expected):
+ """Check that the given LogicalLines match expectations.
Args:
- uwlines: list of UnwrappedLine
+ llines: list of LogicalLine
list_of_expected: list of (depth, values) pairs. Non-semantic tokens are
filtered out from the expected values.
"""
actual = []
- for uwl in uwlines:
+ for lline in llines:
filtered_values = [
ft.value
- for ft in uwl.tokens
+ for ft in lline.tokens
if ft.name not in pytree_utils.NONSEMANTIC_TOKENS
]
- actual.append((uwl.depth, filtered_values))
+ actual.append((lline.depth, filtered_values))
self.assertEqual(list_of_expected, actual)
@@ -48,8 +48,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
# a comment
y = 2
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['x', '=', '1']),
(0, ['# a comment']),
(0, ['y', '=', '2']),
@@ -60,8 +60,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
y = (1 +
x)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['y', '=', '(', '1', '+', 'x', ')']),
])
@@ -70,8 +70,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
x = 1 # a comment
y = 2
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['x', '=', '1', '# a comment']),
(0, ['y', '=', '2']),
])
@@ -82,8 +82,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
x = 1
y = 2
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['if', 'foo', ':']),
(1, ['x', '=', '1']),
(1, ['y', '=', '2']),
@@ -96,8 +96,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
x = 1
y = 2
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['# c1']),
(0, ['if', 'foo', ':', '# c2']),
(1, ['x', '=', '1']),
@@ -112,8 +112,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
# c3
y = 2
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['if', 'foo', ':']),
(1, ['# c1']),
(1, ['x', '=', '1', '# c2']),
@@ -131,8 +131,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
# c3
z = 1
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['if', 'x', ':']),
(1, ['x', '=', '1', '# c1']),
(0, ['elif', 'y', ':', '# c2']),
@@ -151,8 +151,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
j = 1
k = 1
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['if', 'x', ':']),
(1, ['x', '=', '1', '# c1']),
(1, ['while', 't', ':']),
@@ -167,8 +167,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
# c2
x = 1
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['while', 'x', '>', '1', ':', '# c1']),
(1, ['# c2']),
(1, ['x', '=', '1']),
@@ -187,8 +187,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
finally:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['try', ':']),
(1, ['pass']),
(0, ['except', ':']),
@@ -207,8 +207,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
# c2
return x
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['def', 'foo', '(', 'x', ')', ':', '# c1']),
(1, ['# c2']),
(1, ['return', 'x']),
@@ -224,8 +224,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
# c4
return x
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['def', 'foo', '(', 'x', ')', ':', '# c1']),
(1, ['# c2']),
(1, ['return', 'x']),
@@ -240,8 +240,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
# c2
p = 1
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['class', 'Klass', ':', '# c1']),
(1, ['# c2']),
(1, ['p', '=', '1']),
@@ -251,8 +251,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
code = textwrap.dedent(r"""
def f(): return 37
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['def', 'f', '(', ')', ':']),
(1, ['return', '37']),
])
@@ -265,8 +265,8 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
def f():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [
(0, ['# Comment #1']),
(0, ['# Comment #2']),
(0, ['def', 'f', '(', ')', ':']),
@@ -281,48 +281,48 @@ class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
'c', # hello world
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckUnwrappedLines(uwlines, [(0, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckLogicalLines(llines, [(0, [
'a', '=', '[', "'a'", ',', "'b'", ',', "'c'", ',', '# hello world', ']'
])])
class MatchBracketsTest(yapf_test_helper.YAPFTest):
- def _CheckMatchingBrackets(self, uwlines, list_of_expected):
+ def _CheckMatchingBrackets(self, llines, list_of_expected):
"""Check that the tokens have the expected matching bracket.
Arguments:
- uwlines: list of UnwrappedLine.
+ llines: list of LogicalLine.
list_of_expected: list of (index, index) pairs. The matching brackets at
the indexes need to match. Non-semantic tokens are filtered out from the
expected values.
"""
actual = []
- for uwl in uwlines:
+ for lline in llines:
filtered_values = [(ft, ft.matching_bracket)
- for ft in uwl.tokens
+ for ft in lline.tokens
if ft.name not in pytree_utils.NONSEMANTIC_TOKENS]
if filtered_values:
actual.append(filtered_values)
for index, bracket_list in enumerate(list_of_expected):
- uwline = actual[index]
+ lline = actual[index]
if not bracket_list:
- for value in uwline:
+ for value in lline:
self.assertIsNone(value[1])
else:
for open_bracket, close_bracket in bracket_list:
- self.assertEqual(uwline[open_bracket][0], uwline[close_bracket][1])
- self.assertEqual(uwline[close_bracket][0], uwline[open_bracket][1])
+ self.assertEqual(lline[open_bracket][0], lline[close_bracket][1])
+ self.assertEqual(lline[close_bracket][0], lline[open_bracket][1])
def testFunctionDef(self):
code = textwrap.dedent("""\
def foo(a, b=['w','d'], c=[42, 37]):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckMatchingBrackets(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckMatchingBrackets(llines, [
[(2, 20), (7, 11), (15, 19)],
[],
])
@@ -333,8 +333,8 @@ class MatchBracketsTest(yapf_test_helper.YAPFTest):
def foo(a, b, c):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckMatchingBrackets(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckMatchingBrackets(llines, [
[(2, 3)],
[(2, 8)],
[],
@@ -345,8 +345,8 @@ class MatchBracketsTest(yapf_test_helper.YAPFTest):
class A(B, C, D):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckMatchingBrackets(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckMatchingBrackets(llines, [
[(2, 8)],
[],
])
diff --git a/yapftests/reformatter_basic_test.py b/yapftests/reformatter_basic_test.py
index a3de63d..5037f11 100644
--- a/yapftests/reformatter_basic_test.py
+++ b/yapftests/reformatter_basic_test.py
@@ -16,6 +16,7 @@
import textwrap
import unittest
+from yapf.yapflib import py3compat
from yapf.yapflib import reformatter
from yapf.yapflib import style
@@ -26,7 +27,7 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
@classmethod
def setUpClass(cls):
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testSplittingAllArgs(self):
style.SetGlobalStyle(
@@ -34,7 +35,7 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
'{split_all_comma_separated_values: true, column_limit: 40}'))
unformatted_code = textwrap.dedent("""\
responseDict = {"timestamp": timestamp, "someValue": value, "whatever": 120}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
responseDict = {
"timestamp": timestamp,
@@ -42,10 +43,24 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
"whatever": 120
}
""")
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ unformatted_code = textwrap.dedent("""\
+ yes = { 'yes': 'no', 'no': 'yes', }
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ yes = {
+ 'yes': 'no',
+ 'no': 'yes',
+ }
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
def foo(long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def foo(long_arg,
really_long_arg,
@@ -53,11 +68,80 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
cant_keep_all_these_args):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
foo_tuple = [long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args]
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ foo_tuple = [
+ long_arg,
+ really_long_arg,
+ really_really_long_arg,
+ cant_keep_all_these_args
+ ]
""")
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+ unformatted_code = textwrap.dedent("""\
+ foo_tuple = [short, arg]
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ foo_tuple = [short, arg]
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+ # There is a test for split_all_top_level_comma_separated_values, with
+ # different expected value
+ unformatted_code = textwrap.dedent("""\
+ someLongFunction(this_is_a_very_long_parameter,
+ abc=(a, this_will_just_fit_xxxxxxx))
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ someLongFunction(
+ this_is_a_very_long_parameter,
+ abc=(a,
+ this_will_just_fit_xxxxxxx))
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testSplittingTopLevelAllArgs(self):
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{split_all_top_level_comma_separated_values: true, '
+ 'column_limit: 40}'))
+ # Works the same way as split_all_comma_separated_values
+ unformatted_code = textwrap.dedent("""\
+ responseDict = {"timestamp": timestamp, "someValue": value, "whatever": 120}
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ responseDict = {
+ "timestamp": timestamp,
+ "someValue": value,
+ "whatever": 120
+ }
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+ # Works the same way as split_all_comma_separated_values
+ unformatted_code = textwrap.dedent("""\
+ def foo(long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args):
+ pass
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def foo(long_arg,
+ really_long_arg,
+ really_really_long_arg,
+ cant_keep_all_these_args):
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+ # Works the same way as split_all_comma_separated_values
+ unformatted_code = textwrap.dedent("""\
+ foo_tuple = [long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args]
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
foo_tuple = [
long_arg,
@@ -66,16 +150,79 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
cant_keep_all_these_args
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+ # Works the same way as split_all_comma_separated_values
unformatted_code = textwrap.dedent("""\
foo_tuple = [short, arg]
""")
expected_formatted_code = textwrap.dedent("""\
foo_tuple = [short, arg]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+ # There is a test for split_all_comma_separated_values, with different
+ # expected value
+ unformatted_code = textwrap.dedent("""\
+ someLongFunction(this_is_a_very_long_parameter,
+ abc=(a, this_will_just_fit_xxxxxxx))
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ someLongFunction(
+ this_is_a_very_long_parameter,
+ abc=(a, this_will_just_fit_xxxxxxx))
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ actual_formatted_code = reformatter.Reformat(llines)
+ self.assertEqual(40, len(actual_formatted_code.splitlines()[-1]))
+ self.assertCodeEqual(expected_formatted_code, actual_formatted_code)
+
+ unformatted_code = textwrap.dedent("""\
+ someLongFunction(this_is_a_very_long_parameter,
+ abc=(a, this_will_not_fit_xxxxxxxxx))
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ someLongFunction(
+ this_is_a_very_long_parameter,
+ abc=(a,
+ this_will_not_fit_xxxxxxxxx))
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ # Exercise the case where there's no opening bracket (for a, b)
+ unformatted_code = textwrap.dedent("""\
+ a, b = f(
+ a_very_long_parameter, yet_another_one, and_another)
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ a, b = f(
+ a_very_long_parameter, yet_another_one, and_another)
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ # Don't require splitting before comments.
+ unformatted_code = textwrap.dedent("""\
+ KO = {
+ 'ABC': Abc, # abc
+ 'DEF': Def, # def
+ 'LOL': Lol, # wtf
+ 'GHI': Ghi,
+ 'JKL': Jkl,
+ }
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ KO = {
+ 'ABC': Abc, # abc
+ 'DEF': Def, # def
+ 'LOL': Lol, # wtf
+ 'GHI': Ghi,
+ 'JKL': Jkl,
+ }
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSimpleFunctionsWithTrailingComments(self):
unformatted_code = textwrap.dedent("""\
@@ -103,8 +250,97 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testBlankLinesBetweenTopLevelImportsAndVariables(self):
+ unformatted_code = textwrap.dedent("""\
+ import foo as bar
+ VAR = 'baz'
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ import foo as bar
+
+ VAR = 'baz'
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ unformatted_code = textwrap.dedent("""\
+ import foo as bar
+
+ VAR = 'baz'
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ import foo as bar
+
+
+ VAR = 'baz'
+ """)
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: yapf, '
+ 'blank_lines_between_top_level_imports_and_variables: 2}'))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ unformatted_code = textwrap.dedent("""\
+ import foo as bar
+ # Some comment
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ import foo as bar
+ # Some comment
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ unformatted_code = textwrap.dedent("""\
+ import foo as bar
+ class Baz():
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ import foo as bar
+
+
+ class Baz():
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ unformatted_code = textwrap.dedent("""\
+ import foo as bar
+ def foobar():
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ import foo as bar
+
+
+ def foobar():
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ unformatted_code = textwrap.dedent("""\
+ def foobar():
+ from foo import Bar
+ Bar.baz()
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ def foobar():
+ from foo import Bar
+ Bar.baz()
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testBlankLinesAtEndOfFile(self):
unformatted_code = textwrap.dedent("""\
@@ -117,9 +353,9 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
expected_formatted_code = textwrap.dedent("""\
def foobar(): # foo
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
x = { 'a':37,'b':42,
@@ -129,9 +365,48 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
""")
expected_formatted_code = textwrap.dedent("""\
x = {'a': 37, 'b': 42, 'c': 927}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testIndentBlankLines(self):
+ unformatted_code = textwrap.dedent("""\
+ class foo(object):
+
+ def foobar(self):
+
+ pass
+
+ def barfoo(self, x, y): # bar
+
+ if x:
+
+ return y
+
+
+ def bar():
+
+ return 0
+ """)
+ expected_formatted_code = """\
+class foo(object):\n \n def foobar(self):\n \n pass\n \n def barfoo(self, x, y): # bar\n \n if x:\n \n return y\n\n\ndef bar():\n \n return 0
+""" # noqa
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: yapf, indent_blank_lines: true}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ unformatted_code, expected_formatted_code = (expected_formatted_code,
+ unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testMultipleUgliness(self):
unformatted_code = textwrap.dedent("""\
@@ -170,8 +445,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
def f(a):
return 37 + -+a[42 - x:y**3]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testComments(self):
unformatted_code = textwrap.dedent("""\
@@ -223,27 +498,25 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
class Qux(object):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSingleComment(self):
code = textwrap.dedent("""\
# Thing 1
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testCommentsWithTrailingSpaces(self):
unformatted_code = textwrap.dedent("""\
- # Thing 1
- # Thing 2
- """)
+ # Thing 1 \n# Thing 2 \n""")
expected_formatted_code = textwrap.dedent("""\
# Thing 1
# Thing 2
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testCommentsInDataLiteral(self):
code = textwrap.dedent("""\
@@ -259,8 +532,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
# Ending comment.
})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testEndingWhitespaceAfterSimpleStatement(self):
code = textwrap.dedent("""\
@@ -268,8 +541,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
# Thing 1
# Thing 2
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testDocstrings(self):
unformatted_code = textwrap.dedent('''\
@@ -306,8 +579,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
print('hello {}'.format('world'))
return 42
''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDocstringAndMultilineComment(self):
unformatted_code = textwrap.dedent('''\
@@ -341,8 +614,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
# comment
pass
''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testMultilineDocstringAndMultilineComment(self):
unformatted_code = textwrap.dedent('''\
@@ -394,8 +667,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
# comment
pass
''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testTupleCommaBeforeLastParen(self):
unformatted_code = textwrap.dedent("""\
@@ -404,8 +677,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
expected_formatted_code = textwrap.dedent("""\
a = (1,)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoBreakOutsideOfBracket(self):
# FIXME(morbo): How this is formatted is not correct. But it's syntactically
@@ -419,9 +692,9 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
def f():
assert port >= minimum, 'Unexpected port %d when minimum was %d.' % (port,
minimum)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testBlankLinesBeforeDecorators(self):
unformatted_code = textwrap.dedent("""\
@@ -441,8 +714,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
def x(self):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testCommentBetweenDecorators(self):
unformatted_code = textwrap.dedent("""\
@@ -459,8 +732,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
def x(self):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testListComprehension(self):
unformatted_code = textwrap.dedent("""\
@@ -472,8 +745,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
def given(y):
[k for k in () if k in y]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testListComprehensionPreferOneLine(self):
unformatted_code = textwrap.dedent("""\
@@ -489,22 +762,22 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
long_var_name + 1 for long_var_name in () if long_var_name == 2
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testListComprehensionPreferOneLineOverArithmeticSplit(self):
unformatted_code = textwrap.dedent("""\
def given(used_identifiers):
return (sum(len(identifier)
for identifier in used_identifiers) / len(used_identifiers))
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def given(used_identifiers):
return (sum(len(identifier) for identifier in used_identifiers) /
len(used_identifiers))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testListComprehensionPreferThreeLinesForLineWrap(self):
unformatted_code = textwrap.dedent("""\
@@ -522,8 +795,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
if long_var_name == 2 and number_two == 3
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testListComprehensionPreferNoBreakForTrivialExpression(self):
unformatted_code = textwrap.dedent("""\
@@ -540,8 +813,8 @@ class BasicReformatterTest(yapf_test_helper.YAPFTest):
if long_var_name == 2 and number_two == 3
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testOpeningAndClosingBrackets(self):
unformatted_code = """\
@@ -558,8 +831,8 @@ foo((
3,
))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSingleLineFunctions(self):
unformatted_code = textwrap.dedent("""\
@@ -569,8 +842,8 @@ foo((
def foo():
return 42
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoQueueSeletionInMiddleOfLine(self):
# If the queue isn't properly constructed, then a token in the middle of the
@@ -578,13 +851,13 @@ foo((
# one are then splatted at the end of the line with no formatting.
unformatted_code = """\
find_symbol(node.type) + "< " + " ".join(find_pattern(n) for n in node.child) + " >"
-"""
+""" # noqa
expected_formatted_code = """\
find_symbol(node.type) + "< " + " ".join(
find_pattern(n) for n in node.child) + " >"
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoSpacesBetweenSubscriptsAndCalls(self):
unformatted_code = textwrap.dedent("""\
@@ -593,8 +866,8 @@ find_symbol(node.type) + "< " + " ".join(
expected_formatted_code = textwrap.dedent("""\
aaaaaaaaaa = bbbbbbbb.ccccccccc()[42](a, 2)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoSpacesBetweenOpeningBracketAndStartingOperator(self):
# Unary operator.
@@ -604,8 +877,8 @@ find_symbol(node.type) + "< " + " ".join(
expected_formatted_code = textwrap.dedent("""\
aaaaaaaaaa = bbbbbbbb.ccccccccc[-1](-42)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
# Varargs and kwargs.
unformatted_code = textwrap.dedent("""\
@@ -616,8 +889,8 @@ find_symbol(node.type) + "< " + " ".join(
aaaaaaaaaa = bbbbbbbb.ccccccccc(*varargs)
aaaaaaaaaa = bbbbbbbb.ccccccccc(**kwargs)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testMultilineCommentReformatted(self):
unformatted_code = textwrap.dedent("""\
@@ -632,8 +905,8 @@ find_symbol(node.type) + "< " + " ".join(
# comment.
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDictionaryMakerFormatting(self):
unformatted_code = textwrap.dedent("""\
@@ -643,7 +916,7 @@ find_symbol(node.type) + "< " + " ".join(
'yield_stmt': 'import_stmt', lambda: 'global_stmt': 'exec_stmt', 'assert_stmt':
'if_stmt', 'while_stmt': 'for_stmt',
})
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
_PYTHON_STATEMENTS = frozenset({
lambda x, y: 'simple_stmt': 'small_stmt',
@@ -657,8 +930,8 @@ find_symbol(node.type) + "< " + " ".join(
'while_stmt': 'for_stmt',
})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSimpleMultilineCode(self):
unformatted_code = textwrap.dedent("""\
@@ -674,9 +947,9 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
vvvvvvvvv)
aaaaaaaaaaaaaa.bbbbbbbbbbbbbb.ccccccc(zzzzzzzzzzzz, xxxxxxxxxxx, yyyyyyyyyyyy,
vvvvvvvvv)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testMultilineComment(self):
code = textwrap.dedent("""\
@@ -688,8 +961,15 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
# Yo man.
a = 42
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testSpaceBetweenStringAndParentheses(self):
+ code = textwrap.dedent("""\
+ b = '0' ('hello')
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testMultilineString(self):
code = textwrap.dedent("""\
@@ -703,8 +983,8 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
a = 42
''')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent('''\
def f():
@@ -714,7 +994,7 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
<b>Residence: </b>"""+palace["Winter"]+"""<br>
</body>
</html>"""
- ''')
+ ''') # noqa
expected_formatted_code = textwrap.dedent('''\
def f():
email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br>
@@ -723,9 +1003,9 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
<b>Residence: </b>""" + palace["Winter"] + """<br>
</body>
</html>"""
- ''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ ''') # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSimpleMultilineWithComments(self):
code = textwrap.dedent("""\
@@ -736,8 +1016,8 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
# Whoa! A normal comment!!
pass # Another trailing comment
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testMatchingParenSplittingMatching(self):
unformatted_code = textwrap.dedent("""\
@@ -750,8 +1030,8 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
raise RuntimeError('unable to find insertion point for target node',
(target,))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testContinuationIndent(self):
unformatted_code = textwrap.dedent('''\
@@ -775,9 +1055,9 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
child,
subtype=_ARGLIST_TOKEN_TO_SUBTYPE.get(child.value,
format_token.Subtype.NONE))
- ''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ ''') # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testTrailingCommaAndBracket(self):
unformatted_code = textwrap.dedent('''\
@@ -794,21 +1074,21 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
42,
]
''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testI18n(self):
code = textwrap.dedent("""\
N_('Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.') # A comment is here.
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
foo('Fake function call') #. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testI18nCommentsInDataLiteral(self):
code = textwrap.dedent("""\
@@ -821,8 +1101,8 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
'snork': 'bar#.*=\\\\0',
})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testClosingBracketIndent(self):
code = textwrap.dedent('''\
@@ -833,9 +1113,9 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
xxxxxxxxxxxxxxxxxxxxx(
yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb'):
pass
- ''')
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ ''') # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testClosingBracketsInlinedInCall(self):
unformatted_code = textwrap.dedent("""\
@@ -866,8 +1146,8 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
"porkporkpork": 5,
})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testLineWrapInForExpression(self):
code = textwrap.dedent("""\
@@ -879,8 +1159,8 @@ xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv)
node.pre_order())):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testFunctionCallContinuationLine(self):
code = """\
@@ -893,8 +1173,8 @@ class foo:
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(
cccc, ddddddddddddddddddddddddddddddddddddd))]
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testI18nNonFormatting(self):
code = textwrap.dedent("""\
@@ -904,17 +1184,17 @@ class foo:
#. Error message indicating an invalid e-mail address.
message=N_('Please check your email address.'), **kwargs):
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNoSpaceBetweenUnaryOpAndOpeningParen(self):
code = textwrap.dedent("""\
if ~(a or b):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testCommentBeforeFuncDef(self):
code = textwrap.dedent("""\
@@ -931,8 +1211,8 @@ class foo:
bbbbbbbbbbbbbbb=False):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testExcessLineCountWithDefaultKeywords(self):
unformatted_code = textwrap.dedent("""\
@@ -956,16 +1236,16 @@ class foo:
hhhhhhhhhhhhh=hhhhhhhhhhhhh,
iiiiiii=iiiiiiiiiiiiii)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSpaceAfterNotOperator(self):
code = textwrap.dedent("""\
if not (this and that):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNoPenaltySplitting(self):
code = textwrap.dedent("""\
@@ -977,8 +1257,8 @@ class foo:
for f in os.listdir(filename)
if IsPythonFile(os.path.join(filename, f)))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testExpressionPenalties(self):
code = textwrap.dedent("""\
@@ -988,8 +1268,8 @@ class foo:
(left.value == '{' and right.value == '}')):
return False
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testLineDepthOfSingleLineStatement(self):
unformatted_code = textwrap.dedent("""\
@@ -1011,8 +1291,8 @@ class foo:
with open(a) as fd:
a = fd.read()
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplitListWithTerminatingComma(self):
unformatted_code = textwrap.dedent("""\
@@ -1034,8 +1314,8 @@ class foo:
lambda a, b: 37,
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplitListWithInterspersedComments(self):
code = textwrap.dedent("""\
@@ -1053,15 +1333,15 @@ class foo:
lambda a, b: 37 # lambda
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testRelativeImportStatements(self):
code = textwrap.dedent("""\
from ... import bork
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testSingleLineList(self):
# A list on a single line should prefer to remain contiguous.
@@ -1074,9 +1354,9 @@ class foo:
expected_formatted_code = textwrap.dedent("""\
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = aaaaaaaaaaa(
("...", "."), "..", "..............................................")
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testBlankLinesBeforeFunctionsNotInColumnZero(self):
unformatted_code = textwrap.dedent("""\
@@ -1108,9 +1388,9 @@ class foo:
pass
except:
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoKeywordArgumentBreakage(self):
code = textwrap.dedent("""\
@@ -1121,8 +1401,8 @@ class foo:
cccccccccccccccccccc=True):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testTrailerOnSingleLine(self):
code = """\
@@ -1131,8 +1411,8 @@ urlpatterns = patterns('', url(r'^$', 'homepage_view'),
url(r'^/login/$', 'logout_view'),
url(r'^/user/(?P<username>\\w+)/$', 'profile_view'))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testIfConditionalParens(self):
code = textwrap.dedent("""\
@@ -1144,8 +1424,8 @@ urlpatterns = patterns('', url(r'^$', 'homepage_view'),
child.value in substatement_names):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testContinuationMarkers(self):
code = textwrap.dedent("""\
@@ -1154,24 +1434,24 @@ urlpatterns = patterns('', url(r'^$', 'homepage_view'),
"ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis "\\
"sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. "\\
"Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet"
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
from __future__ import nested_scopes, generators, division, absolute_import, with_statement, \\
print_function, unicode_literals
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
if aaaaaaaaa == 42 and bbbbbbbbbbbbbb == 42 and \\
cccccccc == 42:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testCommentsWithContinuationMarkers(self):
code = textwrap.dedent("""\
@@ -1181,8 +1461,8 @@ urlpatterns = patterns('', url(r'^$', 'homepage_view'),
key2=arg)\\
.fn3()
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testMultipleContinuationMarkers(self):
code = textwrap.dedent("""\
@@ -1190,8 +1470,8 @@ urlpatterns = patterns('', url(r'^$', 'homepage_view'),
\\
some_thing()
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testContinuationMarkerAfterStringWithContinuation(self):
code = """\
@@ -1199,8 +1479,8 @@ s = 'foo \\
bar' \\
.format()
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testEmptyContainers(self):
code = textwrap.dedent("""\
@@ -1208,33 +1488,32 @@ s = 'foo \\
'output_dirs', [],
'Lorem ipsum dolor sit amet, consetetur adipiscing elit. Donec a diam lectus. '
'Sed sit amet ipsum mauris. Maecenas congue.')
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testSplitStringsIfSurroundedByParens(self):
unformatted_code = textwrap.dedent("""\
a = foo.bar({'xxxxxxxxxxxxxxxxxxxxxxx' 'yyyyyyyyyyyyyyyyyyyyyyyyyy': baz[42]} + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbb' 'cccccccccccccccccccccccccccccccc' 'ddddddddddddddddddddddddddddd')
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
- a = foo.bar({
- 'xxxxxxxxxxxxxxxxxxxxxxx'
- 'yyyyyyyyyyyyyyyyyyyyyyyyyy': baz[42]
- } + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ a = foo.bar({'xxxxxxxxxxxxxxxxxxxxxxx'
+ 'yyyyyyyyyyyyyyyyyyyyyyyyyy': baz[42]} +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
'bbbbbbbbbbbbbbbbbbbbbbbbbb'
'cccccccccccccccccccccccccccccccc'
'ddddddddddddddddddddddddddddd')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
a = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' \
'bbbbbbbbbbbbbbbbbbbbbbbbbb' 'cccccccccccccccccccccccccccccccc' \
'ddddddddddddddddddddddddddddd'
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testMultilineShebang(self):
code = textwrap.dedent("""\
@@ -1253,16 +1532,16 @@ s = 'foo \\
assert os.environ['FOO'] == '123'
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNoSplittingAroundTermOperators(self):
code = textwrap.dedent("""\
a_very_long_function_call_yada_yada_etc_etc_etc(long_arg1,
long_arg2 / long_arg3)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNoSplittingWithinSubscriptList(self):
code = textwrap.dedent("""\
@@ -1271,8 +1550,8 @@ s = 'foo \\
'someotherlongkey': 2
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testExcessCharacters(self):
code = textwrap.dedent("""\
@@ -1282,9 +1561,9 @@ s = 'foo \\
self.write(s=[
'%s%s %s' % ('many of really', 'long strings', '+ just makes up 81')
])
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
def _():
@@ -1292,7 +1571,7 @@ s = 'foo \\
if True:
if contract == allow_contract and attr_dict.get(if_attribute) == has_value:
return True
- """)
+ """) # noqa
expected_code = textwrap.dedent("""\
def _():
if True:
@@ -1301,8 +1580,8 @@ s = 'foo \\
if_attribute) == has_value:
return True
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
def testDictSetGenerator(self):
code = textwrap.dedent("""\
@@ -1312,8 +1591,8 @@ s = 'foo \\
if variable != 37
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testUnaryOpInDictionaryValue(self):
code = textwrap.dedent("""\
@@ -1323,8 +1602,8 @@ s = 'foo \\
print(beta[-1])
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testUnaryNotOperator(self):
code = textwrap.dedent("""\
@@ -1334,44 +1613,44 @@ s = 'foo \\
if True:
remote_checksum = self.get_checksum(conn, tmp, dest, inject,
not directory_prepended, source)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
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
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ 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
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testFunctionCallInDict(self):
code = "a = {'a': b(c=d, **e)}\n"
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testFunctionCallInNestedDict(self):
code = "a = {'a': {'a': {'a': b(c=d, **e)}}}\n"
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testUnbreakableNot(self):
code = textwrap.dedent("""\
def test():
if not "Foooooooooooooooooooooooooooooo" or "Foooooooooooooooooooooooooooooo" == "Foooooooooooooooooooooooooooooo":
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testSplitListWithComment(self):
code = textwrap.dedent("""\
@@ -1381,8 +1660,8 @@ s = 'foo \\
'c' # hello world
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testOverColumnLimit(self):
unformatted_code = textwrap.dedent("""\
@@ -1394,7 +1673,7 @@ s = 'foo \\
('aaaaaaaaaaaaa', 'bbbb'): 'ccccccccccccccccccccccccccccccccccccccccccc',
('aaaaaaaaaaaaa', 'bbbb'): 'ccccccccccccccccccccccccccccccccccccccccccc',
}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class Test:
@@ -1408,8 +1687,8 @@ s = 'foo \\
'ccccccccccccccccccccccccccccccccccccccccccc',
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testEndingComment(self):
code = textwrap.dedent("""\
@@ -1417,9 +1696,9 @@ s = 'foo \\
a="something",
b="something requiring comment which is quite long", # comment about b (pushes line over 79)
c="something else, about which comment doesn't make sense")
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testContinuationSpaceRetention(self):
code = textwrap.dedent("""\
@@ -1429,8 +1708,8 @@ s = 'foo \\
fn2(arg)
))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testIfExpressionWithFunctionCall(self):
code = textwrap.dedent("""\
@@ -1441,8 +1720,8 @@ s = 'foo \\
bbbbbbbbbbbbbbbbbbbbb=bbbbbbbbbbbbbbbbbb):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testUnformattedAfterMultilineString(self):
code = textwrap.dedent("""\
@@ -1452,8 +1731,8 @@ s = 'foo \\
TEST
''' % (input_fname, output_fname)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNoSpacesAroundKeywordDefaultValues(self):
code = textwrap.dedent("""\
@@ -1463,23 +1742,23 @@ s = 'foo \\
}
json = request.get_json(silent=True) or {}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNoSplittingBeforeEndingSubscriptBracket(self):
unformatted_code = textwrap.dedent("""\
if True:
if True:
status = cf.describe_stacks(StackName=stackname)[u'Stacks'][0][u'StackStatus']
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if True:
if True:
status = cf.describe_stacks(
StackName=stackname)[u'Stacks'][0][u'StackStatus']
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoSplittingOnSingleArgument(self):
unformatted_code = textwrap.dedent("""\
@@ -1499,9 +1778,9 @@ s = 'foo \\
xxxxxxxxxxxxxx = (
re.search(r'(\\d+\\.\\d+\\.\\d+\\.)\\d+', aaaaaaa.bbbbbbbbbbbb).group(a.b) +
re.search(r'\\d+\\.\\d+\\.\\d+\\.(\\d+)', ccccccc).group(c.d))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingArraysSensibly(self):
unformatted_code = textwrap.dedent("""\
@@ -1509,7 +1788,7 @@ s = 'foo \\
while True:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = list['bbbbbbbbbbbbbbbbbbbbbbbbb'].split(',')
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = list('bbbbbbbbbbbbbbbbbbbbbbbbb').split(',')
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
while True:
while True:
@@ -1518,8 +1797,8 @@ s = 'foo \\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = list(
'bbbbbbbbbbbbbbbbbbbbbbbbb').split(',')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testComprehensionForAndIf(self):
unformatted_code = textwrap.dedent("""\
@@ -1527,16 +1806,16 @@ s = 'foo \\
def __repr__(self):
tokens_repr = ','.join(['{0}({1!r})'.format(tok.name, tok.value) for tok in self._tokens])
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class f:
def __repr__(self):
tokens_repr = ','.join(
['{0}({1!r})'.format(tok.name, tok.value) for tok in self._tokens])
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testFunctionCallArguments(self):
unformatted_code = textwrap.dedent("""\
@@ -1559,9 +1838,9 @@ s = 'foo \\
pytree_utils.InsertNodesBefore(
_CreateCommentsFromPrefix(
comment_prefix, comment_lineno, comment_column, standalone=True))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testBinaryOperators(self):
unformatted_code = textwrap.dedent("""\
@@ -1572,8 +1851,8 @@ s = 'foo \\
a = b**37
c = (20**-3) / (_GRID_ROWS**(code_length - 10))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
def f():
@@ -1584,16 +1863,16 @@ s = 'foo \\
current.value in ']}'):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testContiguousList(self):
code = textwrap.dedent("""\
[retval1, retval2] = a_very_long_function(argument_1, argument2, argument_3,
argument_4)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testArgsAndKwargsFormatting(self):
code = textwrap.dedent("""\
@@ -1603,8 +1882,8 @@ s = 'foo \\
*d,
**e)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
def foo():
@@ -1614,8 +1893,8 @@ s = 'foo \\
zzz='a third long string')
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testCommentColumnLimitOverflow(self):
code = textwrap.dedent("""\
@@ -1627,103 +1906,108 @@ s = 'foo \\
# side_effect=[(157031694470475), (157031694470475),],
)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testMultilineLambdas(self):
- try:
- style.SetGlobalStyle(
- style.CreateStyleFromConfig(
- '{based_on_style: chromium, allow_multiline_lambdas: true}'))
- unformatted_code = textwrap.dedent("""\
- class SomeClass(object):
- do_something = True
+ unformatted_code = textwrap.dedent("""\
+ class SomeClass(object):
+ do_something = True
- def succeeded(self, dddddddddddddd):
- d = defer.succeed(None)
+ def succeeded(self, dddddddddddddd):
+ d = defer.succeed(None)
- if self.do_something:
- d.addCallback(lambda _: self.aaaaaa.bbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccccc(dddddddddddddd))
- return d
- """)
- expected_formatted_code = textwrap.dedent("""\
- class SomeClass(object):
- do_something = True
+ if self.do_something:
+ d.addCallback(lambda _: self.aaaaaa.bbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccccc(dddddddddddddd))
+ return d
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ class SomeClass(object):
+ do_something = True
- def succeeded(self, dddddddddddddd):
- d = defer.succeed(None)
+ def succeeded(self, dddddddddddddd):
+ d = defer.succeed(None)
- if self.do_something:
- d.addCallback(lambda _: self.aaaaaa.bbbbbbbbbbbbbbbb.
- cccccccccccccccccccccccccccccccc(dddddddddddddd))
- return d
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ if self.do_something:
+ d.addCallback(lambda _: self.aaaaaa.bbbbbbbbbbbbbbbb.
+ cccccccccccccccccccccccccccccccc(dddddddddddddd))
+ return d
+ """)
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: yapf, allow_multiline_lambdas: true}'))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testMultilineDictionaryKeys(self):
+ unformatted_code = textwrap.dedent("""\
+ MAP_WITH_LONG_KEYS = {
+ ('lorem ipsum', 'dolor sit amet'):
+ 1,
+ ('consectetur adipiscing elit.', 'Vestibulum mauris justo, ornare eget dolor eget'):
+ 2,
+ ('vehicula convallis nulla. Vestibulum dictum nisl in malesuada finibus.',):
+ 3
+ }
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ MAP_WITH_LONG_KEYS = {
+ ('lorem ipsum', 'dolor sit amet'):
+ 1,
+ ('consectetur adipiscing elit.',
+ 'Vestibulum mauris justo, ornare eget dolor eget'):
+ 2,
+ ('vehicula convallis nulla. Vestibulum dictum nisl in malesuada finibus.',):
+ 3
+ }
+ """) # noqa
+
try:
style.SetGlobalStyle(
- style.CreateStyleFromConfig('{based_on_style: chromium, '
+ style.CreateStyleFromConfig('{based_on_style: yapf, '
'allow_multiline_dictionary_keys: true}'))
- unformatted_code = textwrap.dedent("""\
- MAP_WITH_LONG_KEYS = {
- ('lorem ipsum', 'dolor sit amet'):
- 1,
- ('consectetur adipiscing elit.', 'Vestibulum mauris justo, ornare eget dolor eget'):
- 2,
- ('vehicula convallis nulla. Vestibulum dictum nisl in malesuada finibus.',):
- 3
- }
- """)
- expected_formatted_code = textwrap.dedent("""\
- MAP_WITH_LONG_KEYS = {
- ('lorem ipsum', 'dolor sit amet'):
- 1,
- ('consectetur adipiscing elit.',
- 'Vestibulum mauris justo, ornare eget dolor eget'):
- 2,
- ('vehicula convallis nulla. Vestibulum dictum nisl in malesuada finibus.',):
- 3
- }
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testStableDictionaryFormatting(self):
+ code = textwrap.dedent("""\
+ class A(object):
+
+ def method(self):
+ filters = {
+ 'expressions': [{
+ 'field': {
+ 'search_field': {
+ 'user_field': 'latest_party__number_of_guests'
+ },
+ }
+ }]
+ }
+ """) # noqa
+
try:
style.SetGlobalStyle(
- style.CreateStyleFromConfig(
- '{based_on_style: pep8, indent_width: 2, '
- 'continuation_indent_width: 4, indent_dictionary_value: True}'))
- code = textwrap.dedent("""\
- class A(object):
- def method(self):
- filters = {
- 'expressions': [{
- 'field': {
- 'search_field': {
- 'user_field': 'latest_party__number_of_guests'
- },
- }
- }]
- }
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- reformatted_code = reformatter.Reformat(uwlines)
+ style.CreateStyleFromConfig('{based_on_style: pep8, indent_width: 2, '
+ 'continuation_indent_width: 4, '
+ 'indent_dictionary_value: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(code, reformatted_code)
- uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
- reformatted_code = reformatter.Reformat(uwlines)
+ llines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(code, reformatted_code)
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testStableInlinedDictionaryFormatting(self):
try:
@@ -1732,7 +2016,7 @@ s = 'foo \\
def _():
url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format(
value, urllib.urlencode({'action': 'update', 'parameter': value}))
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _():
url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format(
@@ -1742,15 +2026,15 @@ s = 'foo \\
}))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- reformatted_code = reformatter.Reformat(uwlines)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(expected_formatted_code, reformatted_code)
- uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
- reformatted_code = reformatter.Reformat(uwlines)
+ llines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(expected_formatted_code, reformatted_code)
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testDontSplitKeywordValueArguments(self):
unformatted_code = textwrap.dedent("""\
@@ -1763,18 +2047,18 @@ s = 'foo \\
_connect.execute(
_games.update().where(_games.c.gid == gid).values(scored=True))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDontAddBlankLineAfterMultilineString(self):
code = textwrap.dedent("""\
- query = '''SELECT id
- FROM table
+ query = '''SELECT id
+ FROM table
WHERE day in {}'''
days = ",".join(days)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testFormattingListComprehensions(self):
code = textwrap.dedent("""\
@@ -1786,11 +2070,25 @@ s = 'foo \\
x for x, y in self._heap_this_is_very_long if x.route[0] == choice
]
self._heap = [x for x in self._heap if x.route and x.route[0] == choice]
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNoSplittingWhenBinPacking(self):
+ code = textwrap.dedent("""\
+ a_very_long_function_name(
+ long_argument_name_1=1,
+ long_argument_name_2=2,
+ long_argument_name_3=3,
+ long_argument_name_4=4,
+ )
+
+ a_very_long_function_name(
+ long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3,
+ long_argument_name_4=4
+ )
+ """) # noqa
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
@@ -1798,28 +2096,16 @@ s = 'foo \\
'continuation_indent_width: 4, indent_dictionary_value: True, '
'dedent_closing_brackets: True, '
'split_before_named_assigns: False}'))
- code = textwrap.dedent("""\
- a_very_long_function_name(
- long_argument_name_1=1,
- long_argument_name_2=2,
- long_argument_name_3=3,
- long_argument_name_4=4,
- )
- a_very_long_function_name(
- long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3,
- long_argument_name_4=4
- )
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- reformatted_code = reformatter.Reformat(uwlines)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(code, reformatted_code)
- uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
- reformatted_code = reformatter.Reformat(uwlines)
+ llines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(code, reformatted_code)
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testNotSplittingAfterSubscript(self):
unformatted_code = textwrap.dedent("""\
@@ -1832,8 +2118,8 @@ s = 'foo \\
c == d['eeeeee']).ffffff():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingOneArgumentList(self):
unformatted_code = textwrap.dedent("""\
@@ -1844,7 +2130,7 @@ s = 'foo \\
if True:
if True:
boxes[id_] = np.concatenate((points.min(axis=0), qoints.max(axis=0)))
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _():
if True:
@@ -1852,11 +2138,11 @@ s = 'foo \\
if True:
if True:
if True:
- boxes[id_] = np.concatenate((points.min(axis=0),
- qoints.max(axis=0)))
+ boxes[id_] = np.concatenate(
+ (points.min(axis=0), qoints.max(axis=0)))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingBeforeFirstElementListArgument(self):
unformatted_code = textwrap.dedent("""\
@@ -1871,7 +2157,7 @@ s = 'foo \\
clue for clue in combination if not clue == Verifier.UNMATCHED
), constraints, InvestigationResult.OR
)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class _():
@@ -1883,64 +2169,66 @@ s = 'foo \\
return cls._create_investigation_result(
(clue for clue in combination if not clue == Verifier.UNMATCHED),
constraints, InvestigationResult.OR)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingArgumentsTerminatedByComma(self):
- try:
- style.SetGlobalStyle(
- style.CreateStyleFromConfig(
- '{based_on_style: chromium, '
- 'split_arguments_when_comma_terminated: True}'))
- unformatted_code = textwrap.dedent("""\
- function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3)
+ unformatted_code = textwrap.dedent("""\
+ function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3)
- function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3,)
+ function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3,)
- a_very_long_function_name(long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3, long_argument_name_4=4)
+ a_very_long_function_name(long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3, long_argument_name_4=4)
- a_very_long_function_name(long_argument_name_1, long_argument_name_2, long_argument_name_3, long_argument_name_4,)
+ a_very_long_function_name(long_argument_name_1, long_argument_name_2, long_argument_name_3, long_argument_name_4,)
- r =f0 (1, 2,3,)
- """)
- expected_formatted_code = textwrap.dedent("""\
- function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3)
+ r =f0 (1, 2,3,)
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3)
- function_name(
- argument_name_1=1,
- argument_name_2=2,
- argument_name_3=3,
- )
+ function_name(
+ argument_name_1=1,
+ argument_name_2=2,
+ argument_name_3=3,
+ )
- a_very_long_function_name(
- long_argument_name_1=1,
- long_argument_name_2=2,
- long_argument_name_3=3,
- long_argument_name_4=4)
-
- a_very_long_function_name(
- long_argument_name_1,
- long_argument_name_2,
- long_argument_name_3,
- long_argument_name_4,
- )
+ a_very_long_function_name(
+ long_argument_name_1=1,
+ long_argument_name_2=2,
+ long_argument_name_3=3,
+ long_argument_name_4=4)
+
+ a_very_long_function_name(
+ long_argument_name_1,
+ long_argument_name_2,
+ long_argument_name_3,
+ long_argument_name_4,
+ )
- r = f0(
- 1,
- 2,
- 3,
- )
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- reformatted_code = reformatter.Reformat(uwlines)
+ r = f0(
+ 1,
+ 2,
+ 3,
+ )
+ """)
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: yapf, '
+ 'split_arguments_when_comma_terminated: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(expected_formatted_code, reformatted_code)
- uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
- reformatted_code = reformatter.Reformat(uwlines)
+ llines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(expected_formatted_code, reformatted_code)
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testImportAsList(self):
code = textwrap.dedent("""\
@@ -1948,8 +2236,8 @@ s = 'foo \\
from toto import titi, tata, tutu
from toto import (titi, tata, tutu)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testDictionaryValuesOnOwnLines(self):
unformatted_code = textwrap.dedent("""\
@@ -1999,9 +2287,9 @@ s = 'foo \\
'jjjjjjjjjjjjjjjjjjjjjjjjjj':
Check('QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ', '=', False),
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDictionaryOnOwnLine(self):
unformatted_code = textwrap.dedent("""\
@@ -2013,9 +2301,9 @@ s = 'foo \\
expected_formatted_code = textwrap.dedent("""\
doc = test_utils.CreateTestDocumentViaController(
content={'a': 'b'}, branch_key=branch.key, collection_key=collection.key)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
doc = test_utils.CreateTestDocumentViaController(
@@ -2031,8 +2319,8 @@ s = 'foo \\
collection_key=collection.key,
collection_key2=collection.key2)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNestedListsInDictionary(self):
unformatted_code = textwrap.dedent("""\
@@ -2063,7 +2351,7 @@ s = 'foo \\
'cccccccccc': ('^21109', # PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP.
),
}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
_A = {
'cccccccccc': ('^^1',),
@@ -2098,8 +2386,8 @@ s = 'foo \\
),
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNestedDictionary(self):
unformatted_code = textwrap.dedent("""\
@@ -2125,9 +2413,9 @@ s = 'foo \\
},
]
breadcrumbs = [{'name': 'Admin', 'url': url_for(".home")}, {'title': title}]
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDictionaryElementsOnOneLine(self):
code = textwrap.dedent("""\
@@ -2143,22 +2431,22 @@ s = 'foo \\
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)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testNotInParams(self):
unformatted_code = textwrap.dedent("""\
list("a long line to break the line. a long line to break the brk a long lin", not True)
- """)
+ """) # noqa
expected_code = textwrap.dedent("""\
list("a long line to break the line. a long line to break the brk a long lin",
not True)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
def testNamedAssignNotAtEndOfLine(self):
unformatted_code = textwrap.dedent("""\
@@ -2175,8 +2463,8 @@ s = 'foo \\
filename, mode='w', encoding=encoding) as fd:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
def testBlankLineBeforeClassDocstring(self):
unformatted_code = textwrap.dedent('''\
@@ -2200,41 +2488,43 @@ s = 'foo \\
def __init__(self):
pass
''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
- try:
- style.SetGlobalStyle(
- style.CreateStyleFromConfig(
- '{based_on_style: chromium, '
- 'blank_line_before_class_docstring: True}'))
- unformatted_code = textwrap.dedent('''\
- class A:
+ unformatted_code = textwrap.dedent('''\
+ class A:
- """Does something.
+ """Does something.
- Also, here are some details.
- """
+ Also, here are some details.
+ """
- def __init__(self):
- pass
- ''')
- expected_formatted_code = textwrap.dedent('''\
- class A:
+ def __init__(self):
+ pass
+ ''')
+ expected_formatted_code = textwrap.dedent('''\
+ class A:
- """Does something.
+ """Does something.
- Also, here are some details.
- """
+ Also, here are some details.
+ """
- def __init__(self):
- pass
- ''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ def __init__(self):
+ pass
+ ''')
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: yapf, '
+ 'blank_line_before_class_docstring: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testBlankLineBeforeModuleDocstring(self):
unformatted_code = textwrap.dedent('''\
@@ -2256,15 +2546,10 @@ s = 'foo \\
def foobar():
pass
''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
- try:
- style.SetGlobalStyle(
- style.CreateStyleFromConfig(
- '{based_on_style: pep8, '
- 'blank_line_before_module_docstring: True}'))
- unformatted_code = textwrap.dedent('''\
+ unformatted_code = textwrap.dedent('''\
#!/usr/bin/env python
# -*- coding: utf-8 name> -*-
"""Some module docstring."""
@@ -2272,8 +2557,8 @@ s = 'foo \\
def foobar():
pass
- ''')
- expected_formatted_code = textwrap.dedent('''\
+ ''')
+ expected_formatted_code = textwrap.dedent('''\
#!/usr/bin/env python
# -*- coding: utf-8 name> -*-
@@ -2282,12 +2567,19 @@ s = 'foo \\
def foobar():
pass
- ''')
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ ''')
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: pep8, '
+ 'blank_line_before_module_docstring: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testTupleCohesion(self):
unformatted_code = textwrap.dedent("""\
@@ -2301,15 +2593,15 @@ s = 'foo \\
an_extremely_long_variable_name,
('a string that may be too long %s' % 'M15'))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
def testSubscriptExpression(self):
code = textwrap.dedent("""\
foo = d[not a]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testListWithFunctionCalls(self):
unformatted_code = textwrap.dedent("""\
@@ -2335,8 +2627,8 @@ s = 'foo \\
zzz='a third long string')
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
def testEllipses(self):
unformatted_code = textwrap.dedent("""\
@@ -2347,128 +2639,156 @@ s = 'foo \\
X = ...
Y = X if ... else X
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertEqual(expected_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
+
+ 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,
+ },
+}
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
def testSplittingBeforeFirstArgumentOnFunctionCall(self):
"""Tests split_before_first_argument on a function call."""
+ unformatted_code = textwrap.dedent("""\
+ a_very_long_function_name("long string with formatting {0:s}".format(
+ "mystring"))
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ a_very_long_function_name(
+ "long string with formatting {0:s}".format("mystring"))
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
- '{based_on_style: chromium, split_before_first_argument: True}'))
- unformatted_code = textwrap.dedent("""\
- a_very_long_function_name("long string with formatting {0:s}".format(
- "mystring"))
- """)
- expected_formatted_code = textwrap.dedent("""\
- a_very_long_function_name(
- "long string with formatting {0:s}".format("mystring"))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ '{based_on_style: yapf, split_before_first_argument: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testSplittingBeforeFirstArgumentOnFunctionDefinition(self):
"""Tests split_before_first_argument on a function definition."""
+ unformatted_code = textwrap.dedent("""\
+ def _GetNumberOfSecondsFromElements(year, month, day, hours,
+ minutes, seconds, microseconds):
+ return
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ def _GetNumberOfSecondsFromElements(
+ year, month, day, hours, minutes, seconds, microseconds):
+ return
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
- '{based_on_style: chromium, split_before_first_argument: True}'))
- unformatted_code = textwrap.dedent("""\
- def _GetNumberOfSecondsFromElements(year, month, day, hours,
- minutes, seconds, microseconds):
- return
- """)
- expected_formatted_code = textwrap.dedent("""\
- def _GetNumberOfSecondsFromElements(
- year, month, day, hours, minutes, seconds, microseconds):
- return
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ '{based_on_style: yapf, split_before_first_argument: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testSplittingBeforeFirstArgumentOnCompoundStatement(self):
"""Tests split_before_first_argument on a compound statement."""
+ unformatted_code = textwrap.dedent("""\
+ if (long_argument_name_1 == 1 or
+ long_argument_name_2 == 2 or
+ long_argument_name_3 == 3 or
+ long_argument_name_4 == 4):
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ if (long_argument_name_1 == 1 or long_argument_name_2 == 2 or
+ long_argument_name_3 == 3 or long_argument_name_4 == 4):
+ pass
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
- '{based_on_style: chromium, split_before_first_argument: True}'))
- unformatted_code = textwrap.dedent("""\
- if (long_argument_name_1 == 1 or
- long_argument_name_2 == 2 or
- long_argument_name_3 == 3 or
- long_argument_name_4 == 4):
- pass
- """)
- expected_formatted_code = textwrap.dedent("""\
- if (long_argument_name_1 == 1 or long_argument_name_2 == 2 or
- long_argument_name_3 == 3 or long_argument_name_4 == 4):
- pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ '{based_on_style: yapf, split_before_first_argument: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testCoalesceBracketsOnDict(self):
"""Tests coalesce_brackets on a dictionary."""
+ unformatted_code = textwrap.dedent("""\
+ date_time_values = (
+ {
+ u'year': year,
+ u'month': month,
+ u'day_of_month': day_of_month,
+ u'hours': hours,
+ u'minutes': minutes,
+ u'seconds': seconds
+ }
+ )
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ date_time_values = ({
+ u'year': year,
+ u'month': month,
+ u'day_of_month': day_of_month,
+ u'hours': hours,
+ u'minutes': minutes,
+ u'seconds': seconds
+ })
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
- '{based_on_style: chromium, coalesce_brackets: True}'))
- unformatted_code = textwrap.dedent("""\
- date_time_values = (
- {
- u'year': year,
- u'month': month,
- u'day_of_month': day_of_month,
- u'hours': hours,
- u'minutes': minutes,
- u'seconds': seconds
- }
- )
- """)
- expected_formatted_code = textwrap.dedent("""\
- date_time_values = ({
- u'year': year,
- u'month': month,
- u'day_of_month': day_of_month,
- u'hours': hours,
- u'minutes': minutes,
- u'seconds': seconds
- })
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ '{based_on_style: yapf, coalesce_brackets: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testSplitAfterComment(self):
+ code = textwrap.dedent("""\
+ if __name__ == "__main__":
+ with another_resource:
+ account = {
+ "validUntil":
+ int(time() + (6 * 7 * 24 * 60 * 60)) # in 6 weeks time
+ }
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
- '{based_on_style: chromium, coalesce_brackets: True, '
+ '{based_on_style: yapf, coalesce_brackets: True, '
'dedent_closing_brackets: true}'))
- code = textwrap.dedent("""\
- if __name__ == "__main__":
- with another_resource:
- account = {
- "validUntil":
- int(time() + (6 * 7 * 24 * 60 * 60)) # in 6 weeks time
- }
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
+ @unittest.skipUnless(not py3compat.PY3, 'Requires Python 2.7')
def testAsyncAsNonKeyword(self):
try:
style.SetGlobalStyle(style.CreatePEP8Style())
@@ -2479,30 +2799,341 @@ s = 'foo \\
class A(object):
+
def foo(self):
async.run()
-
- def bar(self):
- pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines, verify=False))
+
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testDisableEndingCommaHeuristic(self):
+ code = textwrap.dedent("""\
+ x = [1, 2, 3, 4, 5, 6, 7,]
+ """)
+
try:
style.SetGlobalStyle(
- style.CreateStyleFromConfig('{based_on_style: chromium,'
+ style.CreateStyleFromConfig('{based_on_style: yapf,'
' disable_ending_comma_heuristic: True}'))
- code = """\
-x = [1, 2, 3, 4, 5, 6, 7,]
-"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testDedentClosingBracketsWithTypeAnnotationExceedingLineLength(self):
+ unformatted_code = textwrap.dedent("""\
+ def function(first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None:
+ pass
+
+
+ def function(first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None:
+ pass
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def function(
+ first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None
+ ) -> None:
+ pass
+
+
+ def function(
+ first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None
+ ) -> None:
+ pass
+ """) # noqa
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{based_on_style: yapf,'
+ ' dedent_closing_brackets: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testIndentClosingBracketsWithTypeAnnotationExceedingLineLength(self):
+ unformatted_code = textwrap.dedent("""\
+ def function(first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None:
+ pass
+
+
+ def function(first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None:
+ pass
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def function(
+ first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None
+ ) -> None:
+ pass
+
+
+ def function(
+ first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None
+ ) -> None:
+ pass
+ """) # noqa
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{based_on_style: yapf,'
+ ' indent_closing_brackets: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testIndentClosingBracketsInFunctionCall(self):
+ unformatted_code = textwrap.dedent("""\
+ def function(first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None, third_and_final_argument=True):
+ pass
+
+
+ def function(first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_and_last_argument=None):
+ pass
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def function(
+ first_argument_xxxxxxxxxxxxxxxx=(0,),
+ second_argument=None,
+ third_and_final_argument=True
+ ):
+ pass
+
+
+ def function(
+ first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_and_last_argument=None
+ ):
+ pass
+ """) # noqa
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{based_on_style: yapf,'
+ ' indent_closing_brackets: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testIndentClosingBracketsInTuple(self):
+ unformatted_code = textwrap.dedent("""\
+ def function():
+ some_var = ('a long element', 'another long element', 'short element', 'really really long element')
+ return True
+
+ def function():
+ some_var = ('a couple', 'small', 'elemens')
+ return False
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def function():
+ some_var = (
+ 'a long element', 'another long element', 'short element',
+ 'really really long element'
+ )
+ return True
+
+
+ def function():
+ some_var = ('a couple', 'small', 'elemens')
+ return False
+ """) # noqa
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{based_on_style: yapf,'
+ ' indent_closing_brackets: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testIndentClosingBracketsInList(self):
+ unformatted_code = textwrap.dedent("""\
+ def function():
+ some_var = ['a long element', 'another long element', 'short element', 'really really long element']
+ return True
+
+ def function():
+ some_var = ['a couple', 'small', 'elemens']
+ return False
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def function():
+ some_var = [
+ 'a long element', 'another long element', 'short element',
+ 'really really long element'
+ ]
+ return True
+
+
+ def function():
+ some_var = ['a couple', 'small', 'elemens']
+ return False
+ """)
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{based_on_style: yapf,'
+ ' indent_closing_brackets: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testIndentClosingBracketsInDict(self):
+ unformatted_code = textwrap.dedent("""\
+ def function():
+ some_var = {1: ('a long element', 'and another really really long element that is really really amazingly long'), 2: 'another long element', 3: 'short element', 4: 'really really long element'}
+ return True
+
+ def function():
+ some_var = {1: 'a couple', 2: 'small', 3: 'elemens'}
+ return False
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def function():
+ some_var = {
+ 1:
+ (
+ 'a long element',
+ 'and another really really long element that is really really amazingly long'
+ ),
+ 2: 'another long element',
+ 3: 'short element',
+ 4: 'really really long element'
+ }
+ return True
+
+
+ def function():
+ some_var = {1: 'a couple', 2: 'small', 3: 'elemens'}
+ return False
+ """) # noqa
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{based_on_style: yapf,'
+ ' indent_closing_brackets: True}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testMultipleDictionariesInList(self):
+ unformatted_code = textwrap.dedent("""\
+ class A:
+ def b():
+ d = {
+ "123456": [
+ {
+ "12": "aa"
+ },
+ {
+ "12": "bb"
+ },
+ {
+ "12": "cc",
+ "1234567890": {
+ "1234567": [{
+ "12": "dd",
+ "12345": "text 1"
+ }, {
+ "12": "ee",
+ "12345": "text 2"
+ }]
+ }
+ }
+ ]
+ }
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ class A:
+
+ def b():
+ d = {
+ "123456": [{
+ "12": "aa"
+ }, {
+ "12": "bb"
+ }, {
+ "12": "cc",
+ "1234567890": {
+ "1234567": [{
+ "12": "dd",
+ "12345": "text 1"
+ }, {
+ "12": "ee",
+ "12345": "text 2"
+ }]
+ }
+ }]
+ }
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testForceMultilineDict_True(self):
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{force_multiline_dict: true}'))
+ unformatted_code = textwrap.dedent(
+ "responseDict = {'childDict': {'spam': 'eggs'}}\n")
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ actual = reformatter.Reformat(llines)
+ expected = textwrap.dedent("""\
+ responseDict = {
+ 'childDict': {
+ 'spam': 'eggs'
+ }
+ }
+ """)
+ self.assertCodeEqual(expected, actual)
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testForceMultilineDict_False(self):
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{force_multiline_dict: false}'))
+ unformatted_code = textwrap.dedent("""\
+ responseDict = {'childDict': {'spam': 'eggs'}}
+ """)
+ expected_formatted_code = unformatted_code
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ @unittest.skipUnless(py3compat.PY38, 'Requires Python 3.8')
+ def testWalrus(self):
+ unformatted_code = textwrap.dedent("""\
+ if (x := len([1]*1000)>100):
+ print(f'{x} is pretty big' )
+ """)
+ expected = textwrap.dedent("""\
+ if (x := len([1] * 1000) > 100):
+ print(f'{x} is pretty big')
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected, reformatter.Reformat(llines))
if __name__ == '__main__':
diff --git a/yapftests/reformatter_buganizer_test.py b/yapftests/reformatter_buganizer_test.py
index 6a1c781..b3de8f9 100644
--- a/yapftests/reformatter_buganizer_test.py
+++ b/yapftests/reformatter_buganizer_test.py
@@ -26,7 +26,392 @@ class BuganizerFixes(yapf_test_helper.YAPFTest):
@classmethod
def setUpClass(cls):
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
+
+ def testB137580392(self):
+ code = """\
+def _create_testing_simulator_and_sink(
+) -> Tuple[_batch_simulator:_batch_simulator.BatchSimulator,
+ _batch_simulator.SimulationSink]:
+ pass
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB73279849(self):
+ unformatted_code = """\
+class A:
+ def _(a):
+ return 'hello' [ a ]
+"""
+ expected_formatted_code = """\
+class A:
+ def _(a):
+ return 'hello'[a]
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testB122455211(self):
+ unformatted_code = """\
+_zzzzzzzzzzzzzzzzzzzz = Union[sssssssssssssssssssss.pppppppppppppppp,
+ sssssssssssssssssssss.pppppppppppppppppppppppppppp]
+"""
+ expected_formatted_code = """\
+_zzzzzzzzzzzzzzzzzzzz = Union[
+ sssssssssssssssssssss.pppppppppppppppp,
+ sssssssssssssssssssss.pppppppppppppppppppppppppppp]
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testB119300344(self):
+ code = """\
+def _GenerateStatsEntries(
+ process_id: Text,
+ timestamp: Optional[rdfvalue.RDFDatetime] = None
+) -> Sequence[stats_values.StatsStoreEntry]:
+ pass
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB132886019(self):
+ code = """\
+X = {
+ 'some_dict_key':
+ frozenset([
+ # pylint: disable=line-too-long
+ '//this/path/is/really/too/long/for/this/line/and/probably/should/be/split',
+ ]),
+}
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB26521719(self):
+ code = """\
+class _():
+
+ def _(self):
+ self.stubs.Set(some_type_of_arg, 'ThisIsAStringArgument',
+ lambda *unused_args, **unused_kwargs: fake_resolver)
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB122541552(self):
+ code = """\
+# pylint: disable=g-explicit-bool-comparison,singleton-comparison
+_QUERY = account.Account.query(account.Account.enabled == True)
+# pylint: enable=g-explicit-bool-comparison,singleton-comparison
+
+
+def _():
+ pass
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB124415889(self):
+ code = """\
+class _():
+
+ def run_queue_scanners():
+ return xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
+ {
+ components.NAME.FNOR: True,
+ components.NAME.DEVO: True,
+ },
+ default=False)
+
+ def modules_to_install():
+ modules = DeepCopy(GetDef({}))
+ modules.update({
+ 'xxxxxxxxxxxxxxxxxxxx':
+ GetDef('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', None),
+ })
+ return modules
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB73166511(self):
+ code = """\
+def _():
+ if min_std is not None:
+ groundtruth_age_variances = tf.maximum(groundtruth_age_variances,
+ min_std**2)
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB118624921(self):
+ code = """\
+def _():
+ function_call(
+ alert_name='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+ time_delta='1h',
+ alert_level='bbbbbbbb',
+ metric='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
+ bork=foo)
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB35417079(self):
+ code = """\
+class _():
+
+ def _():
+ X = (
+ _ares_label_prefix +
+ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' # pylint: disable=line-too-long
+ 'PyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyType' # pytype: disable=attribute-error
+ 'CopybaraCopybaraCopybaraCopybaraCopybaraCopybaraCopybaraCopybaraCopybara' # copybara:strip
+ )
+""" # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB120047670(self):
+ unformatted_code = """\
+X = {
+ 'NO_PING_COMPONENTS': [
+ 79775, # Releases / FOO API
+ 79770, # Releases / BAZ API
+ 79780], # Releases / MUX API
+
+ 'PING_BLOCKED_BUGS': False,
+}
+"""
+ expected_formatted_code = """\
+X = {
+ 'NO_PING_COMPONENTS': [
+ 79775, # Releases / FOO API
+ 79770, # Releases / BAZ API
+ 79780
+ ], # Releases / MUX API
+ 'PING_BLOCKED_BUGS': False,
+}
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testB120245013(self):
+ unformatted_code = """\
+class Foo(object):
+ def testNoAlertForShortPeriod(self, rutabaga):
+ self.targets[:][streamz_path,self._fillInOtherFields(streamz_path, {streamz_field_of_interest:True})] = series.Counter('1s', '+ 500x10000')
+""" # noqa
+ expected_formatted_code = """\
+class Foo(object):
+
+ def testNoAlertForShortPeriod(self, rutabaga):
+ self.targets[:][
+ streamz_path,
+ self._fillInOtherFields(streamz_path, {streamz_field_of_interest: True}
+ )] = series.Counter('1s', '+ 500x10000')
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testB117841880(self):
+ code = """\
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(
+ aaaaaaaaaaaaaaaaaaa: AnyStr,
+ bbbbbbbbbbbb: Optional[Sequence[AnyStr]] = None,
+ cccccccccc: AnyStr = cst.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD,
+ dddddddddd: Sequence[SliceDimension] = (),
+ eeeeeeeeeeee: AnyStr = cst.DEFAULT_CONTROL_NAME,
+ ffffffffffffffffffff: Optional[Callable[[pd.DataFrame],
+ pd.DataFrame]] = None,
+ gggggggggggggg: ooooooooooooo = ooooooooooooo()
+) -> pd.DataFrame:
+ pass
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB111764402(self):
+ unformatted_code = """\
+x = self.stubs.stub(video_classification_map, 'read_video_classifications', (lambda external_ids, **unused_kwargs: {external_id: self._get_serving_classification('video') for external_id in external_ids}))
+""" # noqa
+ expected_formatted_code = """\
+x = self.stubs.stub(video_classification_map, 'read_video_classifications',
+ (lambda external_ids, **unused_kwargs: {
+ external_id: self._get_serving_classification('video')
+ for external_id in external_ids
+ }))
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testB116825060(self):
+ code = """\
+result_df = pd.DataFrame({LEARNED_CTR_COLUMN: learned_ctr},
+ index=df_metrics.index)
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB112711217(self):
+ code = """\
+def _():
+ stats['moderated'] = ~stats.moderation_reason.isin(
+ approved_moderation_reasons)
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ 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})
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ 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
+""" # noqa
+ 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
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ 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
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB120771563(self):
+ code = """\
+class A:
+
+ def b():
+ d = {
+ "123456": [{
+ "12": "aa"
+ }, {
+ "12": "bb"
+ }, {
+ "12": "cc",
+ "1234567890": {
+ "1234567": [{
+ "12": "dd",
+ "12345": "text 1"
+ }, {
+ "12": "ee",
+ "12345": "text 2"
+ }]
+ }
+ }]
+ }
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ 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)
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testB113210278(self):
+ unformatted_code = """\
+def _():
+ aaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc(\
+eeeeeeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffffffffffffffffffffff.\
+ggggggggggggggggggggggggggggggggg.hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh())
+""" # noqa
+ expected_formatted_code = """\
+def _():
+ aaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc(
+ eeeeeeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffffffffffffffffffffff
+ .ggggggggggggggggggggggggggggggggg.hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh())
+""" # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB77923341(self):
code = """\
@@ -34,9 +419,9 @@ def f():
if (aaaaaaaaaaaaaa.bbbbbbbbbbbb.ccccc <= 0 and # pytype: disable=attribute-error
ddddddddddd.eeeeeeeee == constants.FFFFFFFFFFFFFF):
raise "yo"
-"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+""" # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB77329955(self):
code = """\
@@ -53,8 +438,8 @@ class _():
def _():
pass
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB65197969(self):
unformatted_code = """\
@@ -72,8 +457,8 @@ class _():
seconds=max(float(time_scale), small_interval) *
1.41**min(num_attempts, 9))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB65546221(self):
unformatted_code = """\
@@ -99,8 +484,8 @@ SUPPORTED_PLATFORMS = (
"debian-9-stretch",
)
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB30500455(self):
unformatted_code = """\
@@ -108,7 +493,7 @@ INITIAL_SYMTAB = dict([(name, 'exception#' + name) for name in INITIAL_EXCEPTION
] * [(name, 'type#' + name) for name in INITIAL_TYPES] + [
(name, 'function#' + name) for name in INITIAL_FUNCTIONS
] + [(name, 'const#' + name) for name in INITIAL_CONSTS])
-"""
+""" # noqa
expected_formatted_code = """\
INITIAL_SYMTAB = dict(
[(name, 'exception#' + name) for name in INITIAL_EXCEPTIONS] *
@@ -116,8 +501,8 @@ INITIAL_SYMTAB = dict(
[(name, 'function#' + name) for name in INITIAL_FUNCTIONS] +
[(name, 'const#' + name) for name in INITIAL_CONSTS])
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB38343525(self):
code = """\
@@ -128,8 +513,8 @@ INITIAL_SYMTAB = dict(
def f():
print 1
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB37099651(self):
unformatted_code = """\
@@ -138,7 +523,7 @@ _MEMCACHE = lazy.MakeLazy(
lambda: function.call.mem.clients(FLAGS.some_flag_thingy, default_namespace=_LAZY_MEM_NAMESPACE, allow_pickle=True)
# pylint: enable=g-long-lambda
)
-"""
+""" # noqa
expected_formatted_code = """\
_MEMCACHE = lazy.MakeLazy(
# pylint: disable=g-long-lambda
@@ -149,8 +534,8 @@ _MEMCACHE = lazy.MakeLazy(
# pylint: enable=g-long-lambda
)
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB33228502(self):
unformatted_code = """\
@@ -166,7 +551,7 @@ def _():
| m.Window(m.Delta('1h'))
| m.Join('successes', 'total')
| m.Point(m.VAL['successes'] / m.VAL['total']))))
-"""
+""" # noqa
expected_formatted_code = """\
def _():
success_rate_stream_table = module.Precompute(
@@ -187,8 +572,8 @@ def _():
| m.Join('successes', 'total')
| m.Point(m.VAL['successes'] / m.VAL['total']))))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB30394228(self):
code = """\
@@ -200,8 +585,8 @@ class _():
alert.Format(alert.body, alert=alert, threshold=threshold),
alert.html_formatting)
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB65246454(self):
unformatted_code = """\
@@ -220,8 +605,8 @@ class _():
self.assertEqual({i.id for i in successful_instances},
{i.id for i in self._statuses.successful_instances})
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB67935450(self):
unformatted_code = """\
@@ -261,8 +646,8 @@ def _():
m.Cond(m.VAL['start'] != 0, m.VAL['start'],
m.TimestampMicros() / 1000000L)))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB66011084(self):
unformatted_code = """\
@@ -293,19 +678,19 @@ X = {
]),
}
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB67455376(self):
unformatted_code = """\
sponge_ids.extend(invocation.id() for invocation in self._client.GetInvocationsByLabels(labels))
-"""
+""" # noqa
expected_formatted_code = """\
sponge_ids.extend(invocation.id()
for invocation in self._client.GetInvocationsByLabels(labels))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB35210351(self):
unformatted_code = """\
@@ -334,8 +719,8 @@ def _():
GetTheAlertToIt('the_title_to_the_thing_here'),
GetNotificationTemplate('your_email_here')))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB34774905(self):
unformatted_code = """\
@@ -363,15 +748,15 @@ x = [
astn=None))
]
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB65176185(self):
code = """\
xx = zip(*[(a, b) for (a, b, c) in yy])
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB35210166(self):
unformatted_code = """\
@@ -379,7 +764,7 @@ def _():
query = (
m.Fetch(n.Raw('monarch.BorgTask', '/proc/container/memory/usage'), { 'borg_user': borguser, 'borg_job': jobname })
| o.Window(m.Align('5m')) | p.GroupBy(['borg_user', 'borg_job', 'borg_cell'], q.Mean()))
-"""
+""" # noqa
expected_formatted_code = """\
def _():
query = (
@@ -391,8 +776,8 @@ def _():
| o.Window(m.Align('5m'))
| p.GroupBy(['borg_user', 'borg_job', 'borg_cell'], q.Mean()))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB32167774(self):
unformatted_code = """\
@@ -418,8 +803,8 @@ X = (
'is_compilation',
)
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB66912275(self):
unformatted_code = """\
@@ -430,7 +815,7 @@ def _():
region=region,
forwardingRule=rule_name,
body={'fingerprint': base64.urlsafe_b64encode('invalid_fingerprint')}).execute()
-"""
+""" # noqa
expected_formatted_code = """\
def _():
with self.assertRaisesRegexp(errors.HttpError, 'Invalid'):
@@ -442,8 +827,8 @@ def _():
'fingerprint': base64.urlsafe_b64encode('invalid_fingerprint')
}).execute()
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB67312284(self):
code = """\
@@ -452,29 +837,29 @@ def _():
[u'to be published 2', u'to be published 1', u'to be published 0'],
[el.text for el in page.first_column_tds])
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB65241516(self):
unformatted_code = """\
checkpoint_files = gfile.Glob(os.path.join(TrainTraceDir(unit_key, "*", "*"), embedding_model.CHECKPOINT_FILENAME + "-*"))
-"""
+""" # noqa
expected_formatted_code = """\
checkpoint_files = gfile.Glob(
os.path.join(
TrainTraceDir(unit_key, "*", "*"),
embedding_model.CHECKPOINT_FILENAME + "-*"))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB37460004(self):
code = textwrap.dedent("""\
assert all(s not in (_SENTINEL, None) for s in nested_schemas
), 'Nested schemas should never contain None/_SENTINEL'
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB36806207(self):
code = """\
@@ -492,8 +877,8 @@ def _():
"%.1f%%" % (np.max(linearity_values["rot_discontinuity"]) * 100.0)
]]
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB36215507(self):
code = textwrap.dedent("""\
@@ -506,8 +891,8 @@ def _():
*(qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq),
**(qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB35212469(self):
unformatted_code = textwrap.dedent("""\
@@ -518,7 +903,7 @@ def _():
('/some/path/to/a/file/that/is/needed/by/this/process')
}
}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _():
X = {
@@ -527,24 +912,24 @@ def _():
('/some/path/to/a/file/that/is/needed/by/this/process')
}
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB31063453(self):
unformatted_code = textwrap.dedent("""\
def _():
while ((not mpede_proc) or ((time_time() - last_modified) < FLAGS_boot_idle_timeout)):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _():
while ((not mpede_proc) or
((time_time() - last_modified) < FLAGS_boot_idle_timeout)):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB35021894(self):
unformatted_code = textwrap.dedent("""\
@@ -557,7 +942,7 @@ def _():
'read': 'name/some-type-of-very-long-name-for-reading-perms',
'modify': 'name/some-other-type-of-very-long-name-for-modifying'
})
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _():
labelacl = Env(
@@ -569,20 +954,20 @@ def _():
'read': 'name/some-type-of-very-long-name-for-reading-perms',
'modify': 'name/some-other-type-of-very-long-name-for-modifying'
})
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB34682902(self):
unformatted_code = textwrap.dedent("""\
logging.info("Mean angular velocity norm: %.3f", np.linalg.norm(np.mean(ang_vel_arr, axis=0)))
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
logging.info("Mean angular velocity norm: %.3f",
np.linalg.norm(np.mean(ang_vel_arr, axis=0)))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB33842726(self):
unformatted_code = textwrap.dedent("""\
@@ -594,11 +979,11 @@ def _():
expected_formatted_code = textwrap.dedent("""\
class _():
def _():
- hints.append(('hg tag -f -l -r %s %s # %s' % (short(
- ctx.node()), candidatetag, firstline))[:78])
+ hints.append(('hg tag -f -l -r %s %s # %s' %
+ (short(ctx.node()), candidatetag, firstline))[:78])
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB32931780(self):
unformatted_code = textwrap.dedent("""\
@@ -631,7 +1016,7 @@ def _():
'this is an entry',
}
}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
environments = {
'prod': {
@@ -658,9 +1043,9 @@ def _():
'.....': 'this is an entry',
}
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB33047408(self):
code = textwrap.dedent("""\
@@ -673,8 +1058,8 @@ def _():
'order': 'ASCENDING'
})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB32714745(self):
code = textwrap.dedent("""\
@@ -703,8 +1088,8 @@ def _():
'dirty': False,
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB32737279(self):
unformatted_code = textwrap.dedent("""\
@@ -720,8 +1105,8 @@ def _():
'value'
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB32570937(self):
code = textwrap.dedent("""\
@@ -731,8 +1116,8 @@ def _():
job_message.mall not in ('*', job_name)):
return False
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB31937033(self):
code = textwrap.dedent("""\
@@ -740,9 +1125,9 @@ def _():
def __init__(self, metric, fields_cb=None):
self._fields_cb = fields_cb or (lambda *unused_args, **unused_kwargs: {})
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB31911533(self):
code = """\
@@ -757,8 +1142,8 @@ class _():
def _():
pass
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB31847238(self):
unformatted_code = textwrap.dedent("""\
@@ -769,7 +1154,7 @@ class _():
def xxxxx(self, yyyyy, zzzzzzzzzzzzzz=None): # A normal comment that runs over the column limit.
return 1
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class _():
@@ -777,26 +1162,27 @@ class _():
return 1
def xxxxx(
- self, yyyyy,
+ self,
+ yyyyy,
zzzzzzzzzzzzzz=None): # A normal comment that runs over the column limit.
return 1
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB30760569(self):
unformatted_code = textwrap.dedent("""\
{'1234567890123456789012345678901234567890123456789012345678901234567890':
'1234567890123456789012345678901234567890'}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
{
'1234567890123456789012345678901234567890123456789012345678901234567890':
'1234567890123456789012345678901234567890'
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB26034238(self):
unformatted_code = textwrap.dedent("""\
@@ -804,7 +1190,7 @@ class _():
def Function(self):
thing.Scrape('/aaaaaaaaa/bbbbbbbbbb/ccccc/dddd/eeeeeeeeeeeeee/ffffffffffffff').AndReturn(42)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class Thing:
@@ -813,8 +1199,8 @@ class _():
'/aaaaaaaaa/bbbbbbbbbb/ccccc/dddd/eeeeeeeeeeeeee/ffffffffffffff'
).AndReturn(42)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB30536435(self):
unformatted_code = textwrap.dedent("""\
@@ -834,8 +1220,8 @@ class _():
bbbbbbbbb.usage, ccccccccc.within,
imports.ddddddddddddddddddd(name_item.ffffffffffffffff)))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB30442148(self):
unformatted_code = textwrap.dedent("""\
@@ -845,11 +1231,11 @@ class _():
""")
expected_formatted_code = textwrap.dedent("""\
def lulz():
- 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))
+ return (some_long_module_name.SomeLongClassName.some_long_attribute_name
+ .some_long_method_name())
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB26868213(self):
unformatted_code = textwrap.dedent("""\
@@ -866,7 +1252,7 @@ class _():
'lllllllllllll': None, # use the default
}
}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _():
xxxxxxxxxxxxxxxxxxx = {
@@ -884,8 +1270,8 @@ class _():
}
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB30173198(self):
code = textwrap.dedent("""\
@@ -894,20 +1280,20 @@ class _():
def _():
self.assertFalse(
evaluation_runner.get_larps_in_eval_set('these_arent_the_larps'))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB29908765(self):
code = textwrap.dedent("""\
class _():
def __repr__(self):
- return '<session %s on %s>' % (self._id,
- self._stub._stub.rpc_channel().target()) # pylint:disable=protected-access
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ return '<session %s on %s>' % (
+ self._id, self._stub._stub.rpc_channel().target()) # pylint:disable=protected-access
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB30087362(self):
code = textwrap.dedent("""\
@@ -919,8 +1305,8 @@ class _():
# This is another comment
foo()
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB30087363(self):
code = textwrap.dedent("""\
@@ -931,24 +1317,24 @@ class _():
elif True:
foo()
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB29093579(self):
unformatted_code = textwrap.dedent("""\
def _():
_xxxxxxxxxxxxxxx(aaaaaaaa, bbbbbbbbbbbbbb.cccccccccc[
dddddddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffff])
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _():
_xxxxxxxxxxxxxxx(
aaaaaaaa,
- bbbbbbbbbbbbbb.cccccccccc[dddddddddddddddddddddddddddd.
- eeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffff])
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ bbbbbbbbbbbbbb.cccccccccc[dddddddddddddddddddddddddddd
+ .eeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffff])
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB26382315(self):
code = textwrap.dedent("""\
@@ -959,8 +1345,8 @@ class _():
def foo():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB27616132(self):
unformatted_code = textwrap.dedent("""\
@@ -982,8 +1368,8 @@ class _():
mock.call(100, start_cursor=cursor_2),
])
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB27590179(self):
unformatted_code = textwrap.dedent("""\
@@ -995,7 +1381,7 @@ class _():
False:
self.bbb.cccccccccc(ddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee)
})
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if True:
if True:
@@ -1005,23 +1391,23 @@ class _():
False:
self.bbb.cccccccccc(ddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee)
})
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB27266946(self):
unformatted_code = textwrap.dedent("""\
def _():
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = (self.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccccccccc)
- """)
+ """) # noqa
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))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB25505359(self):
code = textwrap.dedent("""\
@@ -1035,8 +1421,8 @@ class _():
}]
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB25324261(self):
code = textwrap.dedent("""\
@@ -1044,8 +1430,8 @@ class _():
for ddd in eeeeee.fffffffffff.gggggggggggggggg
for cccc in ddd.specification)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB25136704(self):
code = textwrap.dedent("""\
@@ -1056,16 +1442,16 @@ class _():
'xxxxxx': 'yyyyyy'
}] = cccccc.ddd('1m', '10x1+1')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB25165602(self):
code = textwrap.dedent("""\
def f():
ids = {u: i for u, i in zip(self.aaaaa, xrange(42, 42 + len(self.aaaaaa)))}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB25157123(self):
code = textwrap.dedent("""\
@@ -1073,8 +1459,8 @@ class _():
FairlyLongMethodName([relatively_long_identifier_for_a_list],
another_argument_with_a_long_identifier)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB25136820(self):
unformatted_code = textwrap.dedent("""\
@@ -1093,8 +1479,8 @@ class _():
'$bbbbbbbbbbbbbbbbbbbbbbbb',
})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB25131481(self):
unformatted_code = textwrap.dedent("""\
@@ -1102,7 +1488,7 @@ class _():
'materialize': lambda x: some_type_of_function('materialize ' + x.command_def),
'#': lambda x: x # do nothing
})
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
APPARENT_ACTIONS = (
'command_type',
@@ -1112,9 +1498,9 @@ class _():
'#':
lambda x: x # do nothing
})
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB23445244(self):
unformatted_code = textwrap.dedent("""\
@@ -1127,7 +1513,7 @@ class _():
"PPPPPPPPPPPPPPPPPPPPP":
FLAGS.aaaaaaaaaaaaaa + FLAGS.bbbbbbbbbbbbbbbbbbb,
})
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def foo():
if True:
@@ -1139,9 +1525,9 @@ class _():
"PPPPPPPPPPPPPPPPPPPPP":
FLAGS.aaaaaaaaaaaaaa + FLAGS.bbbbbbbbbbbbbbbbbbb,
})
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB20559654(self):
unformatted_code = textwrap.dedent("""\
@@ -1161,8 +1547,8 @@ class _():
aaaaaaaaaaa=True,
bbbbbbbb=None)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB23943842(self):
unformatted_code = textwrap.dedent("""\
@@ -1199,30 +1585,30 @@ class _():
}
})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB20551180(self):
unformatted_code = textwrap.dedent("""\
def foo():
if True:
return (struct.pack('aaaa', bbbbbbbbbb, ccccccccccccccc, dddddddd) + eeeeeee)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def foo():
if True:
- return (
- struct.pack('aaaa', bbbbbbbbbb, ccccccccccccccc, dddddddd) + eeeeeee)
+ return (struct.pack('aaaa', bbbbbbbbbb, ccccccccccccccc, dddddddd) +
+ eeeeeee)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB23944849(self):
unformatted_code = textwrap.dedent("""\
class A(object):
def xxxxxxxxx(self, aaaaaaa, bbbbbbb=ccccccccccc, dddddd=300, eeeeeeeeeeeeee=None, fffffffffffffff=0):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class A(object):
@@ -1234,15 +1620,15 @@ class _():
fffffffffffffff=0):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB23935890(self):
unformatted_code = textwrap.dedent("""\
class F():
def functioni(self, aaaaaaa, bbbbbbb, cccccc, dddddddddddddd, eeeeeeeeeeeeeee):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class F():
@@ -1250,8 +1636,8 @@ class _():
eeeeeeeeeeeeeee):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB28414371(self):
code = textwrap.dedent("""\
@@ -1274,9 +1660,9 @@ class _():
| m.ggggggg(bbbbbbbbbbbbbbb))
| m.jjjj()
| m.ppppp(m.vvv[0] + m.vvv[1]))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB20127686(self):
code = textwrap.dedent("""\
@@ -1292,69 +1678,73 @@ class _():
| m.ggggggg(self.gggggggg))
| m.jjjj()
| m.ppppp(m.VAL[0] / m.VAL[1]))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB20016122(self):
+ unformatted_code = textwrap.dedent("""\
+ from a_very_long_or_indented_module_name_yada_yada import (long_argument_1,
+ long_argument_2)
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ from a_very_long_or_indented_module_name_yada_yada import (
+ long_argument_1, long_argument_2)
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
- '{based_on_style: pep8, split_penalty_import_names: 35}'))
- unformatted_code = textwrap.dedent("""\
- from a_very_long_or_indented_module_name_yada_yada import (long_argument_1,
- long_argument_2)
- """)
- expected_formatted_code = textwrap.dedent("""\
- from a_very_long_or_indented_module_name_yada_yada import (
- long_argument_1, long_argument_2)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ '{based_on_style: pep8, split_penalty_import_names: 350}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
+ code = textwrap.dedent("""\
+ class foo():
+
+ def __eq__(self, other):
+ return (isinstance(other, type(self))
+ and self.xxxxxxxxxxx == other.xxxxxxxxxxx
+ and self.xxxxxxxx == other.xxxxxxxx
+ and self.aaaaaaaaaaaa == other.aaaaaaaaaaaa
+ and self.bbbbbbbbbbb == other.bbbbbbbbbbb
+ and self.ccccccccccccccccc == other.ccccccccccccccccc
+ and self.ddddddddddddddddddddddd == other.ddddddddddddddddddddddd
+ and self.eeeeeeeeeeee == other.eeeeeeeeeeee
+ and self.ffffffffffffff == other.time_completed
+ and self.gggggg == other.gggggg and self.hhh == other.hhh
+ and len(self.iiiiiiii) == len(other.iiiiiiii)
+ and all(jjjjjjj in other.iiiiiiii for jjjjjjj in self.iiiiiiii))
+ """) # noqa
+
try:
style.SetGlobalStyle(
- style.CreateStyleFromConfig('{based_on_style: chromium, '
+ style.CreateStyleFromConfig('{based_on_style: yapf, '
'split_before_logical_operator: True}'))
- code = textwrap.dedent("""\
- class foo():
-
- def __eq__(self, other):
- return (isinstance(other, type(self))
- and self.xxxxxxxxxxx == other.xxxxxxxxxxx
- and self.xxxxxxxx == other.xxxxxxxx
- and self.aaaaaaaaaaaa == other.aaaaaaaaaaaa
- and self.bbbbbbbbbbb == other.bbbbbbbbbbb
- and self.ccccccccccccccccc == other.ccccccccccccccccc
- and self.ddddddddddddddddddddddd == other.ddddddddddddddddddddddd
- and self.eeeeeeeeeeee == other.eeeeeeeeeeee
- and self.ffffffffffffff == other.time_completed
- and self.gggggg == other.gggggg and self.hhh == other.hhh
- and len(self.iiiiiiii) == len(other.iiiiiiii)
- and all(jjjjjjj in other.iiiiiiii for jjjjjjj in self.iiiiiiii))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testB22527411(self):
unformatted_code = textwrap.dedent("""\
def f():
if True:
aaaaaa.bbbbbbbbbbbbbbbbbbbb[-1].cccccccccccccc.ddd().eeeeeeee(ffffffffffffff)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def f():
if True:
aaaaaa.bbbbbbbbbbbbbbbbbbbb[-1].cccccccccccccc.ddd().eeeeeeee(
ffffffffffffff)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB20849933(self):
unformatted_code = textwrap.dedent("""\
@@ -1372,9 +1762,9 @@ class _():
'xxx':
'%s/cccccc/ddddddddddddddddddd.jar' % (eeeeee.FFFFFFFFFFFFFFFFFF),
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB20813997(self):
code = textwrap.dedent("""\
@@ -1382,8 +1772,8 @@ class _():
myarray = numpy.zeros((2, 2, 2))
print(myarray[:, 1, :])
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB20605036(self):
code = textwrap.dedent("""\
@@ -1395,9 +1785,9 @@ class _():
'dddddddddddddddddddddddddddddddddddddddddd',
}
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB20562732(self):
code = textwrap.dedent("""\
@@ -1408,8 +1798,8 @@ class _():
'Second item',
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB20128830(self):
code = textwrap.dedent("""\
@@ -1428,8 +1818,8 @@ class _():
},
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB20073838(self):
code = textwrap.dedent("""\
@@ -1444,18 +1834,18 @@ class _():
class_0_count=class_0_count,
class_1_name=self.class_1_name,
class_1_count=class_1_count))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB19626808(self):
code = textwrap.dedent("""\
if True:
aaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbb(
'ccccccccccc', ddddddddd='eeeee').fffffffff([ggggggggggggggggggggg])
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB19547210(self):
code = textwrap.dedent("""\
@@ -1468,8 +1858,8 @@ class _():
xxxxxxxxxxxx.yyyyyyyyyyyyyy.zzzzzzzz):
continue
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB19377034(self):
code = textwrap.dedent("""\
@@ -1478,8 +1868,8 @@ class _():
bbbbbbbbbbbbbbb.start >= bbbbbbbbbbbbbbb.end):
return False
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB19372573(self):
code = textwrap.dedent("""\
@@ -1490,20 +1880,22 @@ class _():
if c: break
return 0
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
+
try:
style.SetGlobalStyle(style.CreatePEP8Style())
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
finally:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
def testB19353268(self):
code = textwrap.dedent("""\
a = {1, 2, 3}[x]
b = {'foo': 42, 'bar': 37}['foo']
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB19287512(self):
unformatted_code = textwrap.dedent("""\
@@ -1515,7 +1907,7 @@ class _():
fffffffffff=(aaaaaaa.bbbbbbbb.ccccccc.dddddddddddddddddddd
.Mmmmmmmmmmmmmmmmmm(-1, 'permission error'))):
self.assertRaises(nnnnnnnnnnnnnnnn.ooooo, ppppp.qqqqqqqqqqqqqqqqq)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class Foo(object):
@@ -1526,9 +1918,9 @@ class _():
aaaaaaa.bbbbbbbb.ccccccc.dddddddddddddddddddd.Mmmmmmmmmmmmmmmmmm(
-1, 'permission error'))):
self.assertRaises(nnnnnnnnnnnnnnnn.ooooo, ppppp.qqqqqqqqqqqqqqqqq)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB19194420(self):
code = textwrap.dedent("""\
@@ -1536,8 +1928,8 @@ class _():
'long argument goes here that causes the line to break',
lambda arg2=0.5: arg2)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB19073499(self):
code = """\
@@ -1548,8 +1940,8 @@ instance = (
'fnord': 6
}))
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB18257115(self):
code = textwrap.dedent("""\
@@ -1558,8 +1950,8 @@ instance = (
self._Test(aaaa, bbbbbbb.cccccccccc, dddddddd, eeeeeeeeeee,
[ffff, ggggggggggg, hhhhhhhhhhhh, iiiiii, jjjj])
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB18256666(self):
code = textwrap.dedent("""\
@@ -1576,8 +1968,8 @@ instance = (
},
llllllllll=mmmmmm.nnnnnnnnnnnnnnnn)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB18256826(self):
code = textwrap.dedent("""\
@@ -1595,8 +1987,8 @@ instance = (
elif False:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB18255697(self):
code = textwrap.dedent("""\
@@ -1606,8 +1998,8 @@ instance = (
'YYYYYYYYYYYYYYYY': ['zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'],
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testB17534869(self):
unformatted_code = textwrap.dedent("""\
@@ -1620,8 +2012,8 @@ instance = (
self.assertLess(
abs(time.time() - aaaa.bbbbbbbbbbb(datetime.datetime.now())), 1)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB17489866(self):
unformatted_code = textwrap.dedent("""\
@@ -1636,12 +2028,10 @@ instance = (
if True:
if True:
return aaaa.bbbbbbbbb(
- ccccccc=dddddddddddddd({
- ('eeee', 'ffffffff'): str(j)
- }))
+ ccccccc=dddddddddddddd({('eeee', 'ffffffff'): str(j)}))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB17133019(self):
unformatted_code = textwrap.dedent("""\
@@ -1664,9 +2054,9 @@ instance = (
os.path.join(aaaaa.bbbbb.ccccccccccc, DDDDDDDDDDDDDDD,
"eeeeeeeee ffffffffff"), "rb") as gggggggggggggggggggg:
print(gggggggggggggggggggg)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB17011869(self):
unformatted_code = textwrap.dedent("""\
@@ -1692,8 +2082,8 @@ instance = (
'DDDDDDDD': 0.4811
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB16783631(self):
unformatted_code = textwrap.dedent("""\
@@ -1702,22 +2092,22 @@ instance = (
eeeeeeeee=self.fffffffffffff
)as gggg:
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if True:
with aaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccc(
ddddddddddddd, eeeeeeeee=self.fffffffffffff) as gggg:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB16572361(self):
unformatted_code = textwrap.dedent("""\
def foo(self):
def bar(my_dict_name):
self.my_dict_name['foo-bar-baz-biz-boo-baa-baa'].IncrementBy.assert_called_once_with('foo_bar_baz_boo')
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def foo(self):
@@ -1725,9 +2115,9 @@ instance = (
self.my_dict_name[
'foo-bar-baz-biz-boo-baa-baa'].IncrementBy.assert_called_once_with(
'foo_bar_baz_boo')
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB15884241(self):
unformatted_code = textwrap.dedent("""\
@@ -1735,7 +2125,7 @@ instance = (
if 1:
for row in AAAA:
self.create(aaaaaaaa="/aaa/bbbb/cccc/dddddd/eeeeeeeeeeeeeeeeeeeeeeeeee/%s" % row [0].replace(".foo", ".bar"), aaaaa=bbb[1], ccccc=bbb[2], dddd=bbb[3], eeeeeeeeeee=[s.strip() for s in bbb[4].split(",")], ffffffff=[s.strip() for s in bbb[5].split(",")], gggggg=bbb[6])
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if 1:
if 1:
@@ -1749,9 +2139,9 @@ instance = (
eeeeeeeeeee=[s.strip() for s in bbb[4].split(",")],
ffffffff=[s.strip() for s in bbb[5].split(",")],
gggggg=bbb[6])
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB15697268(self):
unformatted_code = textwrap.dedent("""\
@@ -1761,8 +2151,8 @@ 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]
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def main(unused_argv):
ARBITRARY_CONSTANT_A = 10
@@ -1772,39 +2162,40 @@ 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)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
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)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ unformatted_code = """\
+if True:
+ if True:
+ if True:
+ print(("Return code was %d" + (", and the process timed out." if did_time_out else ".")) % errorcode)
+""" # noqa
+ 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)
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB15542157(self):
unformatted_code = textwrap.dedent("""\
aaaaaaaaaaaa = bbbb.ccccccccccccccc(dddddd.eeeeeeeeeeeeee, ffffffffffffffffff, gggggg.hhhhhhhhhhhhhhhhh)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
aaaaaaaaaaaa = bbbb.ccccccccccccccc(dddddd.eeeeeeeeeeeeee, ffffffffffffffffff,
gggggg.hhhhhhhhhhhhhhhhh)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB15438132(self):
unformatted_code = textwrap.dedent("""\
@@ -1822,7 +2213,7 @@ instance = (
iiiiiiiiiiiiiiiiiii.jjjjjjjjjj.kkkkkkk,
lllll.mm),
nnnnnnnnnn=ooooooo.pppppppppp)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if aaaaaaa.bbbbbbbbbb:
cccccc.dddddddddd(eeeeeeeeeee=fffffffffffff.gggggggggggggggggg)
@@ -1837,9 +2228,9 @@ instance = (
dddddddddddd=eeeeeeeeeeeeeeeeeee.fffffffffffffffff(
gggggg.hh, iiiiiiiiiiiiiiiiiii.jjjjjjjjjj.kkkkkkk, lllll.mm),
nnnnnnnnnn=ooooooo.pppppppppp)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB14468247(self):
unformatted_code = """\
@@ -1853,8 +2244,8 @@ call(
b=2,
)
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB14406499(self):
unformatted_code = textwrap.dedent("""\
@@ -1865,21 +2256,21 @@ parameter_5, parameter_6): pass
def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5,
parameter_6):
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB13900309(self):
unformatted_code = textwrap.dedent("""\
self.aaaaaaaaaaa( # A comment in the middle of it all.
948.0/3600, self.bbb.ccccccccccccccccccccc(dddddddddddddddd.eeee, True))
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
self.aaaaaaaaaaa( # A comment in the middle of it all.
948.0 / 3600, self.bbb.ccccccccccccccccccccc(dddddddddddddddd.eeee, True))
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
code = textwrap.dedent("""\
aaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccc(
@@ -1887,38 +2278,38 @@ parameter_5, parameter_6): pass
CCCCCCC).ddddddddd( # Look! A comment is here.
AAAAAAAA - (20 * 60 - 5))
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc().dddddddddddddddddddddddddd(1, 2, 3, 4)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc(
).dddddddddddddddddddddddddd(1, 2, 3, 4)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc(x).dddddddddddddddddddddddddd(1, 2, 3, 4)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc(
x).dddddddddddddddddddddddddd(1, 2, 3, 4)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
aaaaaaaaaaaaaaaaaaaaaaaa(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).dddddddddddddddddddddddddd(1, 2, 3, 4)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
aaaaaaaaaaaaaaaaaaaaaaaa(
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).dddddddddddddddddddddddddd(1, 2, 3, 4)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
aaaaaaaaaaaaaaaaaaaaaaaa().bbbbbbbbbbbbbbbbbbbbbbbb().ccccccccccccccccccc().\
@@ -1929,8 +2320,8 @@ dddddddddddddddddd().eeeeeeeeeeeeeeeeeeeee().fffffffffffffffff().ggggggggggggggg
).dddddddddddddddddd().eeeeeeeeeeeeeeeeeeeee().fffffffffffffffff(
).gggggggggggggggggg()
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testB67935687(self):
code = textwrap.dedent("""\
@@ -1938,8 +2329,8 @@ dddddddddddddddddd().eeeeeeeeeeeeeeeeeeeee().fffffffffffffffff().ggggggggggggggg
Raw('monarch.BorgTask', '/union/row_operator_action_delay'),
{'borg_user': self.borg_user})
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
shelf_renderer.expand_text = text.translate_to_unicode(
@@ -1948,11 +2339,11 @@ dddddddddddddddddd().eeeeeeeeeeeeeeeeeeeee().fffffffffffffffff().ggggggggggggggg
})
""")
expected_formatted_code = textwrap.dedent("""\
- shelf_renderer.expand_text = text.translate_to_unicode(
- expand_text % {'creator': creator})
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ shelf_renderer.expand_text = text.translate_to_unicode(expand_text %
+ {'creator': creator})
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
if __name__ == '__main__':
diff --git a/yapftests/reformatter_facebook_test.py b/yapftests/reformatter_facebook_test.py
index 289aa85..c61f32b 100644
--- a/yapftests/reformatter_facebook_test.py
+++ b/yapftests/reformatter_facebook_test.py
@@ -38,8 +38,8 @@ class TestsForFacebookStyle(yapf_test_helper.YAPFTest):
def overly_long_function_name(just_one_arg, **kwargs):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDedentClosingBracket(self):
unformatted_code = textwrap.dedent("""\
@@ -53,9 +53,9 @@ class TestsForFacebookStyle(yapf_test_helper.YAPFTest):
first_argument_on_the_same_line, second_argument_makes_the_line_too_long
):
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testBreakAfterOpeningBracketIfContentsTooBig(self):
unformatted_code = textwrap.dedent("""\
@@ -70,8 +70,8 @@ v, w, x, y, z
):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDedentClosingBracketWithComments(self):
unformatted_code = textwrap.dedent("""\
@@ -91,8 +91,8 @@ v, w, x, y, z
):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDedentImportAsNames(self):
code = textwrap.dedent("""\
@@ -103,8 +103,8 @@ v, w, x, y, z
SOME_CONSTANT_NUMBER3,
)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testDedentTestListGexp(self):
unformatted_code = textwrap.dedent("""\
@@ -141,8 +141,8 @@ v, w, x, y, z
) as exception:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testBrokenIdempotency(self):
# TODO(ambv): The following behaviour should be fixed.
@@ -151,7 +151,7 @@ v, w, x, y, z
pass
except (IOError, OSError, LookupError, RuntimeError, OverflowError) as exception:
pass
- """)
+ """) # noqa
pass1_code = textwrap.dedent("""\
try:
pass
@@ -160,8 +160,8 @@ v, w, x, y, z
) as exception:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(pass0_code)
- self.assertCodeEqual(pass1_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(pass0_code)
+ self.assertCodeEqual(pass1_code, reformatter.Reformat(llines))
pass2_code = textwrap.dedent("""\
try:
@@ -171,8 +171,8 @@ v, w, x, y, z
) as exception:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(pass1_code)
- self.assertCodeEqual(pass2_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(pass1_code)
+ self.assertCodeEqual(pass2_code, reformatter.Reformat(llines))
def testIfExprHangingIndent(self):
unformatted_code = textwrap.dedent("""\
@@ -194,22 +194,22 @@ v, w, x, y, z
):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSimpleDedenting(self):
unformatted_code = textwrap.dedent("""\
if True:
self.assertEqual(result.reason_not_added, "current preflight is still running")
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if True:
self.assertEqual(
result.reason_not_added, "current preflight is still running"
)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDedentingWithSubscripts(self):
unformatted_code = textwrap.dedent("""\
@@ -220,7 +220,7 @@ v, w, x, y, z
if clues_lists:
return cls.single_constraint_not(clues_lists, effect, constraints[0], constraint_manager)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class Foo:
class Bar:
@@ -230,9 +230,9 @@ v, w, x, y, z
return cls.single_constraint_not(
clues_lists, effect, constraints[0], constraint_manager
)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testDedentingCallsWithInnerLists(self):
code = textwrap.dedent("""\
@@ -241,9 +241,9 @@ v, w, x, y, z
cls.effect_clues = {
'effect': Clue((cls.effect_time, 'apache_host'), effect_line, 40)
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testDedentingListComprehension(self):
unformatted_code = textwrap.dedent("""\
@@ -283,7 +283,7 @@ v, w, x, y, z
('localhost', os.path.join(path, 'node_1.log'), super_parser),
('localhost', os.path.join(path, 'node_2.log'), super_parser)
]
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
class Foo():
def _pack_results_for_constraint_or():
@@ -319,9 +319,9 @@ v, w, x, y, z
('localhost', os.path.join(path, 'node_1.log'), super_parser),
('localhost', os.path.join(path, 'node_2.log'), super_parser)
]
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testMustSplitDedenting(self):
code = textwrap.dedent("""\
@@ -331,9 +331,9 @@ v, w, x, y, z
effect_line_offset, line_content,
LineSource('localhost', xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testDedentIfConditional(self):
code = textwrap.dedent("""\
@@ -346,8 +346,8 @@ v, w, x, y, z
):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testDedentSet(self):
code = textwrap.dedent("""\
@@ -362,8 +362,8 @@ v, w, x, y, z
]
)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testDedentingInnerScope(self):
code = textwrap.dedent("""\
@@ -374,13 +374,13 @@ v, w, x, y, z
(clue for clue in combination if not clue == Verifier.UNMATCHED),
constraints, InvestigationResult.OR
)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- reformatted_code = reformatter.Reformat(uwlines)
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(code, reformatted_code)
- uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
- reformatted_code = reformatter.Reformat(uwlines)
+ llines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
self.assertCodeEqual(code, reformatted_code)
def testCommentWithNewlinesInPrefix(self):
@@ -388,8 +388,8 @@ v, w, x, y, z
def foo():
if 0:
return False
-
-
+
+
#a deadly comment
elif 1:
return True
@@ -401,7 +401,7 @@ v, w, x, y, z
def foo():
if 0:
return False
-
+
#a deadly comment
elif 1:
return True
@@ -409,14 +409,14 @@ v, w, x, y, z
print(foo())
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testIfStmtClosingBracket(self):
unformatted_code = """\
if (isinstance(value , (StopIteration , StopAsyncIteration )) and exc.__cause__ is value_asdfasdfasdfasdfsafsafsafdasfasdfs):
return False
-"""
+""" # noqa
expected_formatted_code = """\
if (
isinstance(value, (StopIteration, StopAsyncIteration)) and
@@ -424,8 +424,8 @@ if (
):
return False
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
if __name__ == '__main__':
diff --git a/yapftests/reformatter_pep8_test.py b/yapftests/reformatter_pep8_test.py
index a6f736f..acc218d 100644
--- a/yapftests/reformatter_pep8_test.py
+++ b/yapftests/reformatter_pep8_test.py
@@ -16,6 +16,7 @@
import textwrap
import unittest
+from yapf.yapflib import py3compat
from yapf.yapflib import reformatter
from yapf.yapflib import style
@@ -25,7 +26,7 @@ from yapftests import yapf_test_helper
class TestsForPEP8Style(yapf_test_helper.YAPFTest):
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
style.SetGlobalStyle(style.CreatePEP8Style())
def testIndent4(self):
@@ -37,8 +38,8 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
if a + b:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSingleLineIfStatements(self):
code = textwrap.dedent("""\
@@ -46,23 +47,48 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
elif False: b = 42
else: c = 42
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
- 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))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testBlankBetweenDefsInClass(self):
+ unformatted_code = textwrap.dedent('''\
+ class TestClass:
+ def __init__(self):
+ self.running = False
+ def run(self):
+ """Override in subclass"""
+ def is_running(self):
+ return self.running
+ ''')
+ expected_formatted_code = textwrap.dedent('''\
+ class TestClass:
+
+ def __init__(self):
+ self.running = False
+
+ def run(self):
+ """Override in subclass"""
+
+ def is_running(self):
+ return self.running
+ ''')
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSingleWhiteBeforeTrailingComment(self):
unformatted_code = textwrap.dedent("""\
@@ -73,8 +99,8 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
if a + b: # comment
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSpaceBetweenEndingCommandAndClosingBracket(self):
unformatted_code = textwrap.dedent("""\
@@ -85,8 +111,8 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
expected_formatted_code = textwrap.dedent("""\
a = (1, )
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testContinuedNonOutdentedLine(self):
code = textwrap.dedent("""\
@@ -95,8 +121,8 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
) != self.geom_type and not self.geom_type == 'GEOMETRY':
ror(code='om_type')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testWrappingPercentExpressions(self):
unformatted_code = textwrap.dedent("""\
@@ -106,7 +132,7 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxx.yyy + 1)
zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxxxxxx + 1)
zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxxxxxx + 1)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def f():
if True:
@@ -119,8 +145,8 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxx + 1,
xxxxxxxxxxxxxxxxxxxxx + 1)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testAlignClosingBracketWithVisualIndentation(self):
unformatted_code = textwrap.dedent("""\
@@ -135,8 +161,8 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
'baz' # second comment
)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
def f():
@@ -146,30 +172,31 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb'
):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def f():
+
def g():
while (xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa'
and xxxxxxxxxxxxxxxxxxxx(
yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb'):
pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testIndentSizeChanging(self):
unformatted_code = textwrap.dedent("""\
if True:
runtime_mins = (program_end_time - program_start_time).total_seconds() / 60.0
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if True:
- runtime_mins = (
- program_end_time - program_start_time).total_seconds() / 60.0
+ runtime_mins = (program_end_time -
+ program_start_time).total_seconds() / 60.0
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testHangingIndentCollision(self):
unformatted_code = textwrap.dedent("""\
@@ -185,13 +212,15 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
for connection in itertools.chain(branch.contact, branch.address, morestuff.andmore.andmore.andmore.andmore.andmore.andmore.andmore):
dosomething(connection)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if (aaaaaaaaaaaaaa + bbbbbbbbbbbbbbbb == ccccccccccccccccc and xxxxxxxxxxxxx
or yyyyyyyyyyyyyyyyy):
pass
- elif (xxxxxxxxxxxxxxx(
- aaaaaaaaaaa, bbbbbbbbbbbbbb, cccccccccccc, dddddddddd=None)):
+ elif (xxxxxxxxxxxxxxx(aaaaaaaaaaa,
+ bbbbbbbbbbbbbb,
+ cccccccccccc,
+ dddddddddd=None)):
pass
@@ -204,9 +233,9 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
branch.contact, branch.address,
morestuff.andmore.andmore.andmore.andmore.andmore.andmore.andmore):
dosomething(connection)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingBeforeLogicalOperator(self):
try:
@@ -221,7 +250,7 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
update.message.supergroup_chat_created or update.message.channel_chat_created
or update.message.migrate_to_chat_id or update.message.migrate_from_chat_id or
update.message.pinned_message)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def foo():
return bool(
@@ -234,10 +263,10 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
or update.message.migrate_to_chat_id
or update.message.migrate_from_chat_id
or update.message.pinned_message)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
@@ -246,15 +275,15 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
if True:
if True:
keys.append(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) # may be unassigned.
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
if True:
if True:
keys.append(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) # may be unassigned.
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingBeforeFirstArgument(self):
try:
@@ -264,7 +293,7 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
unformatted_code = textwrap.dedent("""\
a_very_long_function_name(long_argument_name_1=1, long_argument_name_2=2,
long_argument_name_3=3, long_argument_name_4=4)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
a_very_long_function_name(
long_argument_name_1=1,
@@ -272,9 +301,9 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
long_argument_name_3=3,
long_argument_name_4=4)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
@@ -282,14 +311,14 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
unformatted_code = textwrap.dedent("""\
def foo():
df = df[(df['campaign_status'] == 'LIVE') & (df['action_status'] == 'LIVE')]
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def foo():
df = df[(df['campaign_status'] == 'LIVE')
& (df['action_status'] == 'LIVE')]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplitListsAndDictSetMakersIfCommaTerminated(self):
unformatted_code = textwrap.dedent("""\
@@ -308,24 +337,26 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
"context_processors",
]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
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
)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testUnaryOperator(self):
unformatted_code = textwrap.dedent("""\
@@ -340,8 +371,8 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
if -3 < x < 3:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoSplitBeforeDictValue(self):
try:
@@ -359,7 +390,7 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
'description': _("Lorem ipsum dolor met sit amet elit, si vis pacem para bellum "
"elites nihi very long string."),
}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
some_dict = {
'title': _("I am example data"),
@@ -368,31 +399,31 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
"elites nihi very long string."
),
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
X = {'a': 1, 'b': 2, 'key': this_is_a_function_call_that_goes_over_the_column_limit_im_pretty_sure()}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
X = {
'a': 1,
'b': 2,
'key': this_is_a_function_call_that_goes_over_the_column_limit_im_pretty_sure()
}
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
attrs = {
'category': category,
'role': forms.ModelChoiceField(label=_("Role"), required=False, queryset=category_roles, initial=selected_role, empty_label=_("No access"),),
}
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
attrs = {
'category': category,
@@ -405,9 +436,9 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
),
}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
unformatted_code = textwrap.dedent("""\
css_class = forms.CharField(
@@ -415,7 +446,7 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
required=False,
help_text=_("Optional CSS class used to customize this category appearance from templates."),
)
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
css_class = forms.CharField(
label=_("CSS class"),
@@ -424,13 +455,496 @@ class TestsForPEP8Style(yapf_test_helper.YAPFTest):
"Optional CSS class used to customize this category appearance from templates."
),
)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreatePEP8Style())
+
+ def testBitwiseOperandSplitting(self):
+ unformatted_code = """\
+def _():
+ include_values = np.where(
+ (cdffile['Quality_Flag'][:] >= 5) & (
+ cdffile['Day_Night_Flag'][:] == 1) & (
+ cdffile['Longitude'][:] >= select_lon - radius) & (
+ cdffile['Longitude'][:] <= select_lon + radius) & (
+ cdffile['Latitude'][:] >= select_lat - radius) & (
+ cdffile['Latitude'][:] <= select_lat + radius))
+"""
+ expected_code = """\
+def _():
+ include_values = np.where(
+ (cdffile['Quality_Flag'][:] >= 5) & (cdffile['Day_Night_Flag'][:] == 1)
+ & (cdffile['Longitude'][:] >= select_lon - radius)
+ & (cdffile['Longitude'][:] <= select_lon + radius)
+ & (cdffile['Latitude'][:] >= select_lat - radius)
+ & (cdffile['Latitude'][:] <= select_lat + radius))
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertEqual(expected_code, reformatter.Reformat(llines))
+
+ def testNoBlankLinesOnlyForFirstNestedObject(self):
+ unformatted_code = '''\
+class Demo:
+ """
+ Demo docs
+ """
+ def foo(self):
+ """
+ foo docs
+ """
+ def bar(self):
+ """
+ bar docs
+ """
+'''
+ expected_code = '''\
+class Demo:
+ """
+ Demo docs
+ """
+
+ def foo(self):
+ """
+ foo docs
+ """
+
+ def bar(self):
+ """
+ bar docs
+ """
+'''
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertEqual(expected_code, reformatter.Reformat(llines))
+
+ def testSplitBeforeArithmeticOperators(self):
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: pep8, split_before_arithmetic_operator: true}'))
+
+ unformatted_code = """\
+def _():
+ raise ValueError('This is a long message that ends with an argument: ' + str(42))
+""" # noqa
+ expected_formatted_code = """\
+def _():
+ raise ValueError('This is a long message that ends with an argument: '
+ + str(42))
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
+ def testListSplitting(self):
+ unformatted_code = """\
+foo([(1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,1),
+ (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,1),
+ (1,10), (1,11), (1, 10), (1,11), (10,11)])
+"""
+ expected_code = """\
+foo([(1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1),
+ (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 10), (1, 11), (1, 10),
+ (1, 11), (10, 11)])
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_code, reformatter.Reformat(llines))
+
+ def testNoBlankLineBeforeNestedFuncOrClass(self):
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: pep8, '
+ 'blank_line_before_nested_class_or_def: false}'))
+
+ unformatted_code = '''\
+def normal_function():
+ """Return the nested function."""
+
+ def nested_function():
+ """Do nothing just nest within."""
+
+ @nested(klass)
+ class nested_class():
+ pass
+
+ pass
+
+ return nested_function
+'''
+ expected_formatted_code = '''\
+def normal_function():
+ """Return the nested function."""
+ def nested_function():
+ """Do nothing just nest within."""
+ @nested(klass)
+ class nested_class():
+ pass
+
+ pass
+
+ return nested_function
+'''
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreatePEP8Style())
+
+ def testParamListIndentationCollision1(self):
+ unformatted_code = textwrap.dedent("""\
+class _():
+
+ def __init__(self, title: Optional[str], diffs: Collection[BinaryDiff] = (), charset: Union[Type[AsciiCharset], Type[LineCharset]] = AsciiCharset, preprocess: Callable[[str], str] = identity,
+ # TODO(somebody): Make this a Literal type.
+ justify: str = 'rjust'):
+ self._cs = charset
+ self._preprocess = preprocess
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+class _():
+
+ def __init__(
+ self,
+ title: Optional[str],
+ diffs: Collection[BinaryDiff] = (),
+ charset: Union[Type[AsciiCharset],
+ Type[LineCharset]] = AsciiCharset,
+ preprocess: Callable[[str], str] = identity,
+ # TODO(somebody): Make this a Literal type.
+ justify: str = 'rjust'):
+ self._cs = charset
+ self._preprocess = preprocess
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testParamListIndentationCollision2(self):
+ code = textwrap.dedent("""\
+ def simple_pass_function_with_an_extremely_long_name_and_some_arguments(
+ argument0, argument1):
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testParamListIndentationCollision3(self):
+ code = textwrap.dedent("""\
+ def func1(
+ arg1,
+ arg2,
+ ) -> None:
+ pass
+
+
+ def func2(
+ arg1,
+ arg2,
+ ):
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testTwoWordComparisonOperators(self):
+ unformatted_code = textwrap.dedent("""\
+ _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl is not ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj)
+ _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl not in {ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj})
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl
+ is not ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj)
+ _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl
+ not in {ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj})
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ @unittest.skipUnless(not py3compat.PY3, 'Requires Python 2.7')
+ def testAsyncAsNonKeyword(self):
+ # In Python 2, async may be used as a non-keyword identifier.
+ code = textwrap.dedent("""\
+ from util import async
+
+
+ class A(object):
+
+ def foo(self):
+ async.run()
+
+ def bar(self):
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines, verify=False))
+
+ def testStableInlinedDictionaryFormatting(self):
+ unformatted_code = textwrap.dedent("""\
+ def _():
+ url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format(
+ value, urllib.urlencode({'action': 'update', 'parameter': value}))
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def _():
+ url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format(
+ value, urllib.urlencode({
+ 'action': 'update',
+ 'parameter': value
+ }))
+ """)
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
+ self.assertCodeEqual(expected_formatted_code, reformatted_code)
+
+ llines = yapf_test_helper.ParseAndUnwrap(reformatted_code)
+ reformatted_code = reformatter.Reformat(llines)
+ self.assertCodeEqual(expected_formatted_code, reformatted_code)
+
+ @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
+ def testSpaceBetweenColonAndElipses(self):
+ style.SetGlobalStyle(style.CreatePEP8Style())
+ code = textwrap.dedent("""\
+ class MyClass(ABC):
+
+ place: ...
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines, verify=False))
+
+ @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
+ def testSpaceBetweenDictColonAndElipses(self):
+ style.SetGlobalStyle(style.CreatePEP8Style())
+ unformatted_code = textwrap.dedent("""\
+ {0:"...", 1:...}
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ {0: "...", 1: ...}
+ """)
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+
+class TestsForSpacesInsideBrackets(yapf_test_helper.YAPFTest):
+ """Test the SPACE_INSIDE_BRACKETS style option."""
+ unformatted_code = textwrap.dedent("""\
+ foo()
+ foo(1)
+ foo(1,2)
+ foo((1,))
+ foo((1, 2))
+ foo((1, 2,))
+ foo(bar['baz'][0])
+ set1 = {1, 2, 3}
+ dict1 = {1: 1, foo: 2, 3: bar}
+ dict2 = {
+ 1: 1,
+ foo: 2,
+ 3: bar,
+ }
+ dict3[3][1][get_index(*args,**kwargs)]
+ dict4[3][1][get_index(**kwargs)]
+ x = dict5[4](foo(*args))
+ a = list1[:]
+ b = list2[slice_start:]
+ c = list3[slice_start:slice_end]
+ d = list4[slice_start:slice_end:]
+ e = list5[slice_start:slice_end:slice_step]
+ # Print gets special handling
+ print(set2)
+ compound = ((10+3)/(5-2**(6+x)))
+ string_idx = "mystring"[3]
+ """)
+
+ def testEnabled(self):
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{space_inside_brackets: True}'))
+
+ expected_formatted_code = textwrap.dedent("""\
+ foo()
+ foo( 1 )
+ foo( 1, 2 )
+ foo( ( 1, ) )
+ foo( ( 1, 2 ) )
+ foo( (
+ 1,
+ 2,
+ ) )
+ foo( bar[ 'baz' ][ 0 ] )
+ set1 = { 1, 2, 3 }
+ dict1 = { 1: 1, foo: 2, 3: bar }
+ dict2 = {
+ 1: 1,
+ foo: 2,
+ 3: bar,
+ }
+ dict3[ 3 ][ 1 ][ get_index( *args, **kwargs ) ]
+ dict4[ 3 ][ 1 ][ get_index( **kwargs ) ]
+ x = dict5[ 4 ]( foo( *args ) )
+ a = list1[ : ]
+ b = list2[ slice_start: ]
+ c = list3[ slice_start:slice_end ]
+ d = list4[ slice_start:slice_end: ]
+ e = list5[ slice_start:slice_end:slice_step ]
+ # Print gets special handling
+ print( set2 )
+ compound = ( ( 10 + 3 ) / ( 5 - 2**( 6 + x ) ) )
+ string_idx = "mystring"[ 3 ]
+ """)
+
+ llines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testDefault(self):
+ style.SetGlobalStyle(style.CreatePEP8Style())
+
+ expected_formatted_code = textwrap.dedent("""\
+ foo()
+ foo(1)
+ foo(1, 2)
+ foo((1, ))
+ foo((1, 2))
+ foo((
+ 1,
+ 2,
+ ))
+ foo(bar['baz'][0])
+ set1 = {1, 2, 3}
+ dict1 = {1: 1, foo: 2, 3: bar}
+ dict2 = {
+ 1: 1,
+ foo: 2,
+ 3: bar,
+ }
+ dict3[3][1][get_index(*args, **kwargs)]
+ dict4[3][1][get_index(**kwargs)]
+ x = dict5[4](foo(*args))
+ a = list1[:]
+ b = list2[slice_start:]
+ c = list3[slice_start:slice_end]
+ d = list4[slice_start:slice_end:]
+ e = list5[slice_start:slice_end:slice_step]
+ # Print gets special handling
+ print(set2)
+ compound = ((10 + 3) / (5 - 2**(6 + x)))
+ string_idx = "mystring"[3]
+ """)
+
+ llines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
+ def testAwait(self):
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{space_inside_brackets: True}'))
+ unformatted_code = textwrap.dedent("""\
+ import asyncio
+ import time
+
+ @print_args
+ async def slow_operation():
+ await asyncio.sleep(1)
+ # print("Slow operation {} complete".format(n))
+ async def main():
+ start = time.time()
+ if (await get_html()):
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ import asyncio
+ import time
+
+
+ @print_args
+ async def slow_operation():
+ await asyncio.sleep( 1 )
+
+ # print("Slow operation {} complete".format(n))
+ async def main():
+ start = time.time()
+ if ( await get_html() ):
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+
+class TestsForSpacesAroundSubscriptColon(yapf_test_helper.YAPFTest):
+ """Test the SPACES_AROUND_SUBSCRIPT_COLON style option."""
+ unformatted_code = textwrap.dedent("""\
+ a = list1[ : ]
+ b = list2[ slice_start: ]
+ c = list3[ slice_start:slice_end ]
+ d = list4[ slice_start:slice_end: ]
+ e = list5[ slice_start:slice_end:slice_step ]
+ a1 = list1[ : ]
+ b1 = list2[ 1: ]
+ c1 = list3[ 1:20 ]
+ d1 = list4[ 1:20: ]
+ e1 = list5[ 1:20:3 ]
+ """)
+
+ def testEnabled(self):
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{spaces_around_subscript_colon: True}'))
+ expected_formatted_code = textwrap.dedent("""\
+ a = list1[:]
+ b = list2[slice_start :]
+ c = list3[slice_start : slice_end]
+ d = list4[slice_start : slice_end :]
+ e = list5[slice_start : slice_end : slice_step]
+ a1 = list1[:]
+ b1 = list2[1 :]
+ c1 = list3[1 : 20]
+ d1 = list4[1 : 20 :]
+ e1 = list5[1 : 20 : 3]
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testWithSpaceInsideBrackets(self):
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig('{'
+ 'spaces_around_subscript_colon: true, '
+ 'space_inside_brackets: true,'
+ '}'))
+ expected_formatted_code = textwrap.dedent("""\
+ a = list1[ : ]
+ b = list2[ slice_start : ]
+ c = list3[ slice_start : slice_end ]
+ d = list4[ slice_start : slice_end : ]
+ e = list5[ slice_start : slice_end : slice_step ]
+ a1 = list1[ : ]
+ b1 = list2[ 1 : ]
+ c1 = list3[ 1 : 20 ]
+ d1 = list4[ 1 : 20 : ]
+ e1 = list5[ 1 : 20 : 3 ]
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testDefault(self):
+ style.SetGlobalStyle(style.CreatePEP8Style())
+ expected_formatted_code = textwrap.dedent("""\
+ a = list1[:]
+ b = list2[slice_start:]
+ c = list3[slice_start:slice_end]
+ d = list4[slice_start:slice_end:]
+ e = list5[slice_start:slice_end:slice_step]
+ a1 = list1[:]
+ b1 = list2[1:]
+ c1 = list3[1:20]
+ d1 = list4[1:20:]
+ e1 = list5[1:20:3]
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
if __name__ == '__main__':
unittest.main()
diff --git a/yapftests/reformatter_python3_test.py b/yapftests/reformatter_python3_test.py
index 9be6528..b5d68e8 100644
--- a/yapftests/reformatter_python3_test.py
+++ b/yapftests/reformatter_python3_test.py
@@ -29,14 +29,14 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
"""Test a few constructs that are new Python 3 syntax."""
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
style.SetGlobalStyle(style.CreatePEP8Style())
def testTypedNames(self):
unformatted_code = textwrap.dedent("""\
def x(aaaaaaaaaaaaaaa:int,bbbbbbbbbbbbbbbb:str,ccccccccccccccc:dict,eeeeeeeeeeeeee:set={1, 2, 3})->bool:
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def x(aaaaaaaaaaaaaaa: int,
bbbbbbbbbbbbbbbb: str,
@@ -44,8 +44,21 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
eeeeeeeeeeeeee: set = {1, 2, 3}) -> bool:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
+
+ def testTypedNameWithLongNamedArg(self):
+ unformatted_code = textwrap.dedent("""\
+ def func(arg=long_function_call_that_pushes_the_line_over_eighty_characters()) -> ReturnType:
+ pass
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def func(arg=long_function_call_that_pushes_the_line_over_eighty_characters()
+ ) -> ReturnType:
+ pass
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testKeywordOnlyArgSpecifier(self):
unformatted_code = textwrap.dedent("""\
@@ -56,8 +69,8 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
def foo(a, *, kw):
return a + kw
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
@unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
def testPEP448ParameterExpansion(self):
@@ -73,8 +86,8 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
{**{**x}, **x}
{'a': 1, **kw, 'b': 3, **kw2}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testAnnotations(self):
unformatted_code = textwrap.dedent("""\
@@ -85,14 +98,14 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
def foo(a: list, b: "bar") -> dict:
return a + b
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testExecAsNonKeyword(self):
unformatted_code = 'methods.exec( sys.modules[name])\n'
expected_formatted_code = 'methods.exec(sys.modules[name])\n'
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testAsyncFunctions(self):
if sys.version_info[1] < 5:
@@ -113,41 +126,45 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
if (await get_html()):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines, verify=False))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines, verify=False))
def testNoSpacesAroundPowerOperator(self):
+ unformatted_code = textwrap.dedent("""\
+ a**b
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ a ** b
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
'{based_on_style: pep8, SPACES_AROUND_POWER_OPERATOR: True}'))
- unformatted_code = textwrap.dedent("""\
- a**b
- """)
- expected_formatted_code = textwrap.dedent("""\
- a ** b
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
def testSpacesAroundDefaultOrNamedAssign(self):
+ unformatted_code = textwrap.dedent("""\
+ f(a=5)
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ f(a = 5)
+ """)
+
try:
style.SetGlobalStyle(
style.CreateStyleFromConfig(
'{based_on_style: pep8, '
'SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN: True}'))
- unformatted_code = textwrap.dedent("""\
- f(a=5)
- """)
- expected_formatted_code = textwrap.dedent("""\
- f(a = 5)
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
@@ -168,8 +185,8 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
def foo2(x: 'int' = 42):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testMatrixMultiplication(self):
unformatted_code = textwrap.dedent("""\
@@ -178,15 +195,15 @@ class TestsForPython3Code(yapf_test_helper.YAPFTest):
expected_formatted_code = textwrap.dedent("""\
a = b @ c
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testNoneKeyword(self):
code = """\
None.__ne__()
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testAsyncWithPrecedingComment(self):
if sys.version_info[1] < 5:
@@ -213,19 +230,20 @@ None.__ne__()
async def foo():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testAsyncFunctionsNested(self):
if sys.version_info[1] < 5:
return
code = textwrap.dedent("""\
async def outer():
+
async def inner():
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testKeepTypesIntact(self):
if sys.version_info[1] < 5:
@@ -235,15 +253,15 @@ None.__ne__()
self, *args: Optional[automation_converter.PyiCollectionAbc]) -> List[
automation_converter.PyiCollectionAbc]:
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def _ReduceAbstractContainers(
- self, *args: Optional[automation_converter.PyiCollectionAbc]
+ self, *args: Optional[automation_converter.PyiCollectionAbc]
) -> List[automation_converter.PyiCollectionAbc]:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testContinuationIndentWithAsync(self):
if sys.version_info[1] < 5:
@@ -260,22 +278,14 @@ None.__ne__()
r"ws://a_really_long_long_long_long_long_long_url") as ws:
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testSplittingArguments(self):
if sys.version_info[1] < 5:
return
- try:
- style.SetGlobalStyle(
- style.CreateStyleFromConfig(
- '{based_on_style: pep8, '
- 'dedent_closing_brackets: true, '
- 'coalesce_brackets: false, '
- 'space_between_ending_comma_and_closing_bracket: false, '
- 'split_arguments_when_comma_terminated: true, '
- 'split_before_first_argument: true}'))
- unformatted_code = """\
+
+ unformatted_code = """\
async def open_file(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None):
pass
@@ -287,36 +297,36 @@ def open_file(file, mode='r', buffering=-1, encoding=None, errors=None, newline=
def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None):
pass
-"""
- expected_formatted_code = """\
+""" # noqa
+ expected_formatted_code = """\
async def open_file(
- file,
- mode='r',
- buffering=-1,
- encoding=None,
- errors=None,
- newline=None,
- closefd=True,
- opener=None
+ file,
+ mode='r',
+ buffering=-1,
+ encoding=None,
+ errors=None,
+ newline=None,
+ closefd=True,
+ opener=None
):
pass
async def run_sync_in_worker_thread(
- sync_fn, *args, cancellable=False, limiter=None
+ sync_fn, *args, cancellable=False, limiter=None
):
pass
def open_file(
- file,
- mode='r',
- buffering=-1,
- encoding=None,
- errors=None,
- newline=None,
- closefd=True,
- opener=None
+ file,
+ mode='r',
+ buffering=-1,
+ encoding=None,
+ errors=None,
+ newline=None,
+ closefd=True,
+ opener=None
):
pass
@@ -324,9 +334,20 @@ def open_file(
def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None):
pass
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+
+ try:
+ style.SetGlobalStyle(
+ style.CreateStyleFromConfig(
+ '{based_on_style: pep8, '
+ 'dedent_closing_brackets: true, '
+ 'coalesce_brackets: false, '
+ 'space_between_ending_comma_and_closing_bracket: false, '
+ 'split_arguments_when_comma_terminated: true, '
+ 'split_before_first_argument: true}'))
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
@@ -345,14 +366,15 @@ class Foo:
"""
expected_formatted_code = """\
class Foo:
+
def foo(self):
foofoofoofoofoofoofoofoo('foofoofoofoofoo', {
'foo': 'foo',
**foofoofoo
})
"""
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
def testMultilineFormatString(self):
if sys.version_info[1] < 6:
@@ -364,8 +386,8 @@ class Foo:
# yapf: enable
"""
# https://github.com/google/yapf/issues/513
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
def testEllipses(self):
if sys.version_info[1] < 6:
@@ -375,8 +397,76 @@ def dirichlet(x12345678901234567890123456789012345678901234567890=...) -> None:
return
"""
# https://github.com/google/yapf/issues/533
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self.assertCodeEqual(code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testFunctionTypedReturnNextLine(self):
+ code = """\
+def _GenerateStatsEntries(
+ process_id: Text,
+ timestamp: Optional[ffffffff.FFFFFFFFFFF] = None
+) -> Sequence[ssssssssssss.SSSSSSSSSSSSSSS]:
+ pass
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testFunctionTypedReturnSameLine(self):
+ code = """\
+def rrrrrrrrrrrrrrrrrrrrrr(
+ ccccccccccccccccccccccc: Tuple[Text, Text]) -> List[Tuple[Text, Text]]:
+ pass
+"""
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testAsyncForElseNotIndentedInsideBody(self):
+ if sys.version_info[1] < 5:
+ return
+ code = textwrap.dedent("""\
+ async def fn():
+ async for message in websocket:
+ for i in range(10):
+ pass
+ else:
+ pass
+ else:
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testForElseInAsyncNotMixedWithAsyncFor(self):
+ if sys.version_info[1] < 5:
+ return
+ code = textwrap.dedent("""\
+ async def fn():
+ for i in range(10):
+ pass
+ else:
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines))
+
+ def testParameterListIndentationConflicts(self):
+ unformatted_code = textwrap.dedent("""\
+ def raw_message( # pylint: disable=too-many-arguments
+ self, text, user_id=1000, chat_type='private', forward_date=None, forward_from=None):
+ pass
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ def raw_message( # pylint: disable=too-many-arguments
+ self,
+ text,
+ user_id=1000,
+ chat_type='private',
+ forward_date=None,
+ forward_from=None):
+ pass
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
if __name__ == '__main__':
diff --git a/yapftests/reformatter_style_config_test.py b/yapftests/reformatter_style_config_test.py
index 5afd805..c5726cb 100644
--- a/yapftests/reformatter_style_config_test.py
+++ b/yapftests/reformatter_style_config_test.py
@@ -29,7 +29,7 @@ class TestsForStyleConfig(yapf_test_helper.YAPFTest):
def testSetGlobalStyle(self):
try:
- style.SetGlobalStyle(style.CreateChromiumStyle())
+ style.SetGlobalStyle(style.CreateYapfStyle())
unformatted_code = textwrap.dedent(u"""\
for i in range(5):
print('bar')
@@ -38,9 +38,9 @@ class TestsForStyleConfig(yapf_test_helper.YAPFTest):
for i in range(5):
print('bar')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
style.DEFAULT_STYLE = self.current_style
@@ -53,10 +53,10 @@ class TestsForStyleConfig(yapf_test_helper.YAPFTest):
for i in range(5):
print('bar')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
- def testOperatorStyle(self):
+ def testOperatorNoSpaceStyle(self):
try:
sympy_style = style.CreatePEP8Style()
sympy_style['NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS'] = \
@@ -64,14 +64,131 @@ class TestsForStyleConfig(yapf_test_helper.YAPFTest):
style.SetGlobalStyle(sympy_style)
unformatted_code = textwrap.dedent("""\
a = 1+2 * 3 - 4 / 5
+ b = '0' * 1
""")
expected_formatted_code = textwrap.dedent("""\
a = 1 + 2*3 - 4/5
+ b = '0'*1
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines))
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreatePEP8Style())
+ style.DEFAULT_STYLE = self.current_style
+
+ def testOperatorPrecedenceStyle(self):
+ try:
+ pep8_with_precedence = style.CreatePEP8Style()
+ pep8_with_precedence['ARITHMETIC_PRECEDENCE_INDICATION'] = True
+ style.SetGlobalStyle(pep8_with_precedence)
+ unformatted_code = textwrap.dedent("""\
+ 1+2
+ (1 + 2) * (3 - (4 / 5))
+ a = 1 * 2 + 3 / 4
+ b = 1 / 2 - 3 * 4
+ c = (1 + 2) * (3 - 4)
+ d = (1 - 2) / (3 + 4)
+ e = 1 * 2 - 3
+ f = 1 + 2 + 3 + 4
+ g = 1 * 2 * 3 * 4
+ h = 1 + 2 - 3 + 4
+ i = 1 * 2 / 3 * 4
+ j = (1 * 2 - 3) + 4
+ k = (1 * 2 * 3) + (4 * 5 * 6 * 7 * 8)
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ 1 + 2
+ (1+2) * (3 - (4/5))
+ a = 1*2 + 3/4
+ b = 1/2 - 3*4
+ c = (1+2) * (3-4)
+ d = (1-2) / (3+4)
+ e = 1*2 - 3
+ f = 1 + 2 + 3 + 4
+ g = 1 * 2 * 3 * 4
+ h = 1 + 2 - 3 + 4
+ i = 1 * 2 / 3 * 4
+ j = (1*2 - 3) + 4
+ k = (1*2*3) + (4*5*6*7*8)
+ """)
+
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ self.assertCodeEqual(expected_formatted_code,
+ reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreatePEP8Style())
+ style.DEFAULT_STYLE = self.current_style
+
+ def testNoSplitBeforeFirstArgumentStyle1(self):
+ try:
+ pep8_no_split_before_first = style.CreatePEP8Style()
+ pep8_no_split_before_first['SPLIT_BEFORE_FIRST_ARGUMENT'] = False
+ pep8_no_split_before_first['SPLIT_BEFORE_NAMED_ASSIGNS'] = False
+ style.SetGlobalStyle(pep8_no_split_before_first)
+ formatted_code = textwrap.dedent("""\
+ # Example from in-code MustSplit comments
+ foo = outer_function_call(fitting_inner_function_call(inner_arg1, inner_arg2),
+ outer_arg1, outer_arg2)
+
+ foo = outer_function_call(
+ not_fitting_inner_function_call(inner_arg1, inner_arg2), outer_arg1,
+ outer_arg2)
+
+ # Examples Issue#424
+ a_super_long_version_of_print(argument1, argument2, argument3, argument4,
+ argument5, argument6, argument7)
+
+ CREDS_FILE = os.path.join(os.path.expanduser('~'),
+ 'apis/super-secret-admin-creds.json')
+
+ # Examples Issue#556
+ i_take_a_lot_of_params(arg1, param1=very_long_expression1(),
+ param2=very_long_expression2(),
+ param3=very_long_expression3(),
+ param4=very_long_expression4())
+
+ # Examples Issue#590
+ plt.plot(numpy.linspace(0, 1, 10), numpy.linspace(0, 1, 10), marker="x",
+ color="r")
+
+ plt.plot(veryverylongvariablename, veryverylongvariablename, marker="x",
+ color="r")
+ """) # noqa
+ llines = yapf_test_helper.ParseAndUnwrap(formatted_code)
+ self.assertCodeEqual(formatted_code, reformatter.Reformat(llines))
+ finally:
+ style.SetGlobalStyle(style.CreatePEP8Style())
+ style.DEFAULT_STYLE = self.current_style
+
+ def testNoSplitBeforeFirstArgumentStyle2(self):
+ try:
+ pep8_no_split_before_first = style.CreatePEP8Style()
+ pep8_no_split_before_first['SPLIT_BEFORE_FIRST_ARGUMENT'] = False
+ pep8_no_split_before_first['SPLIT_BEFORE_NAMED_ASSIGNS'] = True
+ style.SetGlobalStyle(pep8_no_split_before_first)
+ formatted_code = textwrap.dedent("""\
+ # Examples Issue#556
+ i_take_a_lot_of_params(arg1,
+ param1=very_long_expression1(),
+ param2=very_long_expression2(),
+ param3=very_long_expression3(),
+ param4=very_long_expression4())
+
+ # Examples Issue#590
+ plt.plot(numpy.linspace(0, 1, 10),
+ numpy.linspace(0, 1, 10),
+ marker="x",
+ color="r")
+
+ plt.plot(veryverylongvariablename,
+ veryverylongvariablename,
+ marker="x",
+ color="r")
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(formatted_code)
+ self.assertCodeEqual(formatted_code, reformatter.Reformat(llines))
finally:
style.SetGlobalStyle(style.CreatePEP8Style())
style.DEFAULT_STYLE = self.current_style
diff --git a/yapftests/reformatter_verify_test.py b/yapftests/reformatter_verify_test.py
index 1b3d5b0..33ba3a6 100644
--- a/yapftests/reformatter_verify_test.py
+++ b/yapftests/reformatter_verify_test.py
@@ -36,10 +36,10 @@ class TestVerifyNoVerify(yapf_test_helper.YAPFTest):
class ABC(metaclass=type):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
with self.assertRaises(verifier.InternalError):
- reformatter.Reformat(uwlines, verify=True)
- reformatter.Reformat(uwlines) # verify should be False by default.
+ reformatter.Reformat(llines, verify=True)
+ reformatter.Reformat(llines) # verify should be False by default.
def testNoVerify(self):
unformatted_code = textwrap.dedent("""\
@@ -50,9 +50,9 @@ class TestVerifyNoVerify(yapf_test_helper.YAPFTest):
class ABC(metaclass=type):
pass
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines, verify=False))
+ reformatter.Reformat(llines, verify=False))
def testVerifyFutureImport(self):
unformatted_code = textwrap.dedent("""\
@@ -64,9 +64,9 @@ class TestVerifyNoVerify(yapf_test_helper.YAPFTest):
if __name__ == "__main__":
call_my_function(print)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
with self.assertRaises(verifier.InternalError):
- reformatter.Reformat(uwlines, verify=True)
+ reformatter.Reformat(llines, verify=True)
expected_formatted_code = textwrap.dedent("""\
from __future__ import print_function
@@ -79,12 +79,12 @@ class TestVerifyNoVerify(yapf_test_helper.YAPFTest):
if __name__ == "__main__":
call_my_function(print)
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
+ llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines, verify=False))
+ reformatter.Reformat(llines, verify=False))
def testContinuationLineShouldBeDistinguished(self):
- unformatted_code = textwrap.dedent("""\
+ code = textwrap.dedent("""\
class Foo(object):
def bar(self):
@@ -92,16 +92,8 @@ class TestVerifyNoVerify(yapf_test_helper.YAPFTest):
self.generators + self.next_batch) == 1:
pass
""")
- expected_formatted_code = textwrap.dedent("""\
- class Foo(object):
- def bar(self):
- if self.solo_generator_that_is_long is None and len(
- self.generators + self.next_batch) == 1:
- pass
- """)
- uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
- self.assertCodeEqual(expected_formatted_code,
- reformatter.Reformat(uwlines, verify=False))
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self.assertCodeEqual(code, reformatter.Reformat(llines, verify=False))
if __name__ == '__main__':
diff --git a/yapftests/split_penalty_test.py b/yapftests/split_penalty_test.py
index 7d500da..4d55129 100644
--- a/yapftests/split_penalty_test.py
+++ b/yapftests/split_penalty_test.py
@@ -22,6 +22,9 @@ from lib2to3 import pytree
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 @@ DOTTED_NAME = split_penalty.DOTTED_NAME
STRONGLY_CONNECTED = split_penalty.STRONGLY_CONNECTED
-class SplitPenaltyTest(unittest.TestCase):
+class SplitPenaltyTest(yapf_test_helper.YAPFTest):
+
+ @classmethod
+ def setUpClass(cls):
+ style.SetGlobalStyle(style.CreateYapfStyle())
def _ParseAndComputePenalties(self, code, dumptree=False):
"""Parses the code and computes split penalties.
@@ -133,11 +140,11 @@ class SplitPenaltyTest(unittest.TestCase):
tree = self._ParseAndComputePenalties(code)
self._CheckPenalties(tree, [
('lambda', None),
- ('a', UNBREAKABLE),
- (',', UNBREAKABLE),
- ('b', UNBREAKABLE),
- (':', UNBREAKABLE),
- ('None', UNBREAKABLE),
+ ('a', VERY_STRONGLY_CONNECTED),
+ (',', VERY_STRONGLY_CONNECTED),
+ ('b', VERY_STRONGLY_CONNECTED),
+ (':', VERY_STRONGLY_CONNECTED),
+ ('None', VERY_STRONGLY_CONNECTED),
])
# Test dotted names.
@@ -174,9 +181,9 @@ class SplitPenaltyTest(unittest.TestCase):
('y', None),
('(', UNBREAKABLE),
('lambda', STRONGLY_CONNECTED),
- ('a', UNBREAKABLE),
- (':', UNBREAKABLE),
- ('23', UNBREAKABLE),
+ ('a', VERY_STRONGLY_CONNECTED),
+ (':', VERY_STRONGLY_CONNECTED),
+ ('23', VERY_STRONGLY_CONNECTED),
(')', VERY_STRONGLY_CONNECTED),
(':', STRONGLY_CONNECTED),
('37', None),
@@ -198,7 +205,7 @@ class SplitPenaltyTest(unittest.TestCase):
('foo', STRONGLY_CONNECTED),
('if', 0),
('a', STRONGLY_CONNECTED),
- ('.', UNBREAKABLE),
+ ('.', VERY_STRONGLY_CONNECTED),
('x', DOTTED_NAME),
('==', STRONGLY_CONNECTED),
('37', STRONGLY_CONNECTED),
@@ -224,9 +231,9 @@ class SplitPenaltyTest(unittest.TestCase):
tree = self._ParseAndComputePenalties(code)
self._CheckPenalties(tree, [
('foo', None),
- ('.', UNBREAKABLE),
+ ('.', VERY_STRONGLY_CONNECTED),
('bar', DOTTED_NAME),
- ('.', STRONGLY_CONNECTED),
+ ('.', VERY_STRONGLY_CONNECTED),
('baz', DOTTED_NAME),
('(', STRONGLY_CONNECTED),
('1', None),
diff --git a/yapftests/style_test.py b/yapftests/style_test.py
index 7f4a465..8a37f95 100644
--- a/yapftests/style_test.py
+++ b/yapftests/style_test.py
@@ -14,6 +14,7 @@
# limitations under the License.
"""Tests for yapf.style."""
+import os
import shutil
import tempfile
import textwrap
@@ -22,19 +23,31 @@ import unittest
from yapf.yapflib import style
from yapftests import utils
+from yapftests import yapf_test_helper
-class UtilsTest(unittest.TestCase):
+class UtilsTest(yapf_test_helper.YAPFTest):
def testContinuationAlignStyleStringConverter(self):
- self.assertEqual(style._ContinuationAlignStyleStringConverter(''), 'SPACE')
- self.assertEqual(
- style._ContinuationAlignStyleStringConverter('space'), 'SPACE')
- self.assertEqual(
- style._ContinuationAlignStyleStringConverter('fixed'), 'FIXED')
- self.assertEqual(
- style._ContinuationAlignStyleStringConverter('valign-right'),
- 'VALIGN-RIGHT')
+ for cont_align_space in ('', 'space', '"space"', '\'space\''):
+ self.assertEqual(
+ style._ContinuationAlignStyleStringConverter(cont_align_space),
+ 'SPACE')
+ for cont_align_fixed in ('fixed', '"fixed"', '\'fixed\''):
+ self.assertEqual(
+ style._ContinuationAlignStyleStringConverter(cont_align_fixed),
+ 'FIXED')
+ for cont_align_valignright in (
+ 'valign-right',
+ '"valign-right"',
+ '\'valign-right\'',
+ 'valign_right',
+ '"valign_right"',
+ '\'valign_right\'',
+ ):
+ self.assertEqual(
+ style._ContinuationAlignStyleStringConverter(cont_align_valignright),
+ 'VALIGN-RIGHT')
with self.assertRaises(ValueError) as ctx:
style._ContinuationAlignStyleStringConverter('blahblah')
self.assertIn("unknown continuation align style: 'blahblah'",
@@ -53,30 +66,36 @@ class UtilsTest(unittest.TestCase):
self.assertEqual(style._BoolConverter('false'), False)
self.assertEqual(style._BoolConverter('0'), False)
+ def testIntListConverter(self):
+ self.assertEqual(style._IntListConverter('1, 2, 3'), [1, 2, 3])
+ self.assertEqual(style._IntListConverter('[ 1, 2, 3 ]'), [1, 2, 3])
+ self.assertEqual(style._IntListConverter('[ 1, 2, 3, ]'), [1, 2, 3])
-def _LooksLikeChromiumStyle(cfg):
- return (cfg['INDENT_WIDTH'] == 2 and
- cfg['BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'])
+ def testIntOrIntListConverter(self):
+ self.assertEqual(style._IntOrIntListConverter('10'), 10)
+ self.assertEqual(style._IntOrIntListConverter('1, 2, 3'), [1, 2, 3])
def _LooksLikeGoogleStyle(cfg):
- return (cfg['INDENT_WIDTH'] == 4 and
- cfg['BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'])
+ return cfg['COLUMN_LIMIT'] == 80 and cfg['SPLIT_COMPLEX_COMPREHENSION']
def _LooksLikePEP8Style(cfg):
- return (cfg['INDENT_WIDTH'] == 4 and
- not cfg['BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'])
+ return cfg['COLUMN_LIMIT'] == 79
def _LooksLikeFacebookStyle(cfg):
- return cfg['INDENT_WIDTH'] == 4 and cfg['DEDENT_CLOSING_BRACKETS']
+ return cfg['DEDENT_CLOSING_BRACKETS']
+
+def _LooksLikeYapfStyle(cfg):
+ return cfg['SPLIT_BEFORE_DOT']
-class PredefinedStylesByNameTest(unittest.TestCase):
+
+class PredefinedStylesByNameTest(yapf_test_helper.YAPFTest):
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
style.SetGlobalStyle(style.CreatePEP8Style())
def testDefault(self):
@@ -94,10 +113,10 @@ class PredefinedStylesByNameTest(unittest.TestCase):
cfg = style.CreateStyleFromConfig(google_name)
self.assertTrue(_LooksLikeGoogleStyle(cfg))
- def testChromiumByName(self):
- for chromium_name in ('chromium', 'Chromium', 'CHROMIUM'):
- cfg = style.CreateStyleFromConfig(chromium_name)
- self.assertTrue(_LooksLikeChromiumStyle(cfg))
+ def testYapfByName(self):
+ for yapf_name in ('yapf', 'YAPF'):
+ cfg = style.CreateStyleFromConfig(yapf_name)
+ self.assertTrue(_LooksLikeYapfStyle(cfg))
def testFacebookByName(self):
for fb_name in ('facebook', 'FACEBOOK', 'Facebook'):
@@ -105,15 +124,15 @@ class PredefinedStylesByNameTest(unittest.TestCase):
self.assertTrue(_LooksLikeFacebookStyle(cfg))
-class StyleFromFileTest(unittest.TestCase):
+class StyleFromFileTest(yapf_test_helper.YAPFTest):
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
cls.test_tmpdir = tempfile.mkdtemp()
style.SetGlobalStyle(style.CreatePEP8Style())
@classmethod
- def tearDownClass(cls):
+ def tearDownClass(cls): # pylint: disable=g-missing-super-call
shutil.rmtree(cls.test_tmpdir)
def testDefaultBasedOnStyle(self):
@@ -137,17 +156,6 @@ class StyleFromFileTest(unittest.TestCase):
self.assertTrue(_LooksLikePEP8Style(cfg))
self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 40)
- def testDefaultBasedOnChromiumStyle(self):
- cfg = textwrap.dedent(u'''\
- [style]
- based_on_style = chromium
- continuation_indent_width = 30
- ''')
- with utils.TempFileContents(self.test_tmpdir, cfg) as filepath:
- cfg = style.CreateStyleFromConfig(filepath)
- self.assertTrue(_LooksLikeChromiumStyle(cfg))
- self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 30)
-
def testDefaultBasedOnGoogleStyle(self):
cfg = textwrap.dedent(u'''\
[style]
@@ -173,30 +181,30 @@ class StyleFromFileTest(unittest.TestCase):
def testBoolOptionValue(self):
cfg = textwrap.dedent(u'''\
[style]
- based_on_style = chromium
+ based_on_style = pep8
SPLIT_BEFORE_NAMED_ASSIGNS=False
split_before_logical_operator = true
''')
with utils.TempFileContents(self.test_tmpdir, cfg) as filepath:
cfg = style.CreateStyleFromConfig(filepath)
- self.assertTrue(_LooksLikeChromiumStyle(cfg))
+ self.assertTrue(_LooksLikePEP8Style(cfg))
self.assertEqual(cfg['SPLIT_BEFORE_NAMED_ASSIGNS'], False)
self.assertEqual(cfg['SPLIT_BEFORE_LOGICAL_OPERATOR'], True)
def testStringListOptionValue(self):
cfg = textwrap.dedent(u'''\
[style]
- based_on_style = chromium
+ based_on_style = pep8
I18N_FUNCTION_CALL = N_, V_, T_
''')
with utils.TempFileContents(self.test_tmpdir, cfg) as filepath:
cfg = style.CreateStyleFromConfig(filepath)
- self.assertTrue(_LooksLikeChromiumStyle(cfg))
+ self.assertTrue(_LooksLikePEP8Style(cfg))
self.assertEqual(cfg['I18N_FUNCTION_CALL'], ['N_', 'V_', 'T_'])
def testErrorNoStyleFile(self):
- with self.assertRaisesRegexp(style.StyleConfigError,
- 'is not a valid style or file path'):
+ with self.assertRaisesRegex(style.StyleConfigError,
+ 'is not a valid style or file path'):
style.CreateStyleFromConfig('/8822/xyznosuchfile')
def testErrorNoStyleSection(self):
@@ -205,8 +213,8 @@ class StyleFromFileTest(unittest.TestCase):
indent_width=2
''')
with utils.TempFileContents(self.test_tmpdir, cfg) as filepath:
- with self.assertRaisesRegexp(style.StyleConfigError,
- 'Unable to find section'):
+ with self.assertRaisesRegex(style.StyleConfigError,
+ 'Unable to find section'):
style.CreateStyleFromConfig(filepath)
def testErrorUnknownStyleOption(self):
@@ -216,15 +224,45 @@ class StyleFromFileTest(unittest.TestCase):
hummus=2
''')
with utils.TempFileContents(self.test_tmpdir, cfg) as filepath:
- with self.assertRaisesRegexp(style.StyleConfigError,
- 'Unknown style option'):
+ with self.assertRaisesRegex(style.StyleConfigError,
+ 'Unknown style option'):
style.CreateStyleFromConfig(filepath)
+ def testPyprojectTomlNoYapfSection(self):
+ try:
+ import toml
+ except ImportError:
+ return
-class StyleFromDict(unittest.TestCase):
+ filepath = os.path.join(self.test_tmpdir, 'pyproject.toml')
+ _ = open(filepath, 'w')
+ with self.assertRaisesRegex(style.StyleConfigError,
+ 'Unable to find section'):
+ style.CreateStyleFromConfig(filepath)
+
+ def testPyprojectTomlParseYapfSection(self):
+ try:
+ import toml
+ except ImportError:
+ return
+
+ cfg = textwrap.dedent(u'''\
+ [tool.yapf]
+ based_on_style = "pep8"
+ continuation_indent_width = 40
+ ''')
+ filepath = os.path.join(self.test_tmpdir, 'pyproject.toml')
+ with open(filepath, 'w') as f:
+ f.write(cfg)
+ cfg = style.CreateStyleFromConfig(filepath)
+ self.assertTrue(_LooksLikePEP8Style(cfg))
+ self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 40)
+
+
+class StyleFromDict(yapf_test_helper.YAPFTest):
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
style.SetGlobalStyle(style.CreatePEP8Style())
def testDefaultBasedOnStyle(self):
@@ -234,22 +272,22 @@ class StyleFromDict(unittest.TestCase):
'blank_line_before_nested_class_or_def': True
}
cfg = style.CreateStyleFromConfig(config_dict)
- self.assertTrue(_LooksLikeChromiumStyle(cfg))
+ self.assertTrue(_LooksLikePEP8Style(cfg))
self.assertEqual(cfg['INDENT_WIDTH'], 2)
def testDefaultBasedOnStyleBadDict(self):
- self.assertRaisesRegexp(style.StyleConfigError, 'Unknown style option',
- style.CreateStyleFromConfig,
- {'based_on_styl': 'pep8'})
- self.assertRaisesRegexp(style.StyleConfigError, 'not a valid',
- style.CreateStyleFromConfig,
- {'INDENT_WIDTH': 'FOUR'})
+ self.assertRaisesRegex(style.StyleConfigError, 'Unknown style option',
+ style.CreateStyleFromConfig,
+ {'based_on_styl': 'pep8'})
+ self.assertRaisesRegex(style.StyleConfigError, 'not a valid',
+ style.CreateStyleFromConfig,
+ {'INDENT_WIDTH': 'FOUR'})
-class StyleFromCommandLine(unittest.TestCase):
+class StyleFromCommandLine(yapf_test_helper.YAPFTest):
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
style.SetGlobalStyle(style.CreatePEP8Style())
def testDefaultBasedOnStyle(self):
@@ -257,7 +295,7 @@ class StyleFromCommandLine(unittest.TestCase):
'{based_on_style: pep8,'
' indent_width: 2,'
' blank_line_before_nested_class_or_def: True}')
- self.assertTrue(_LooksLikeChromiumStyle(cfg))
+ self.assertTrue(_LooksLikePEP8Style(cfg))
self.assertEqual(cfg['INDENT_WIDTH'], 2)
def testDefaultBasedOnStyleNotStrict(self):
@@ -265,7 +303,7 @@ class StyleFromCommandLine(unittest.TestCase):
'{based_on_style : pep8'
' ,indent_width=2'
' blank_line_before_nested_class_or_def:True}')
- self.assertTrue(_LooksLikeChromiumStyle(cfg))
+ self.assertTrue(_LooksLikePEP8Style(cfg))
self.assertEqual(cfg['INDENT_WIDTH'], 2)
def testDefaultBasedOnExplicitlyUnicodeTypeString(self):
@@ -277,17 +315,15 @@ class StyleFromCommandLine(unittest.TestCase):
self.assertIsInstance(cfg, dict)
def testDefaultBasedOnStyleBadString(self):
- self.assertRaisesRegexp(style.StyleConfigError, 'Unknown style option',
- style.CreateStyleFromConfig,
- '{based_on_styl: pep8}')
- self.assertRaisesRegexp(style.StyleConfigError, 'not a valid',
- style.CreateStyleFromConfig, '{INDENT_WIDTH: FOUR}')
- self.assertRaisesRegexp(style.StyleConfigError, 'Invalid style dict',
- style.CreateStyleFromConfig,
- '{based_on_style: pep8')
+ self.assertRaisesRegex(style.StyleConfigError, 'Unknown style option',
+ style.CreateStyleFromConfig, '{based_on_styl: pep8}')
+ self.assertRaisesRegex(style.StyleConfigError, 'not a valid',
+ style.CreateStyleFromConfig, '{INDENT_WIDTH: FOUR}')
+ self.assertRaisesRegex(style.StyleConfigError, 'Invalid style dict',
+ style.CreateStyleFromConfig, '{based_on_style: pep8')
-class StyleHelp(unittest.TestCase):
+class StyleHelp(yapf_test_helper.YAPFTest):
def testHelpKeys(self):
settings = sorted(style.Help())
diff --git a/yapftests/subtype_assigner_test.py b/yapftests/subtype_assigner_test.py
index 8daead9..145a96e 100644
--- a/yapftests/subtype_assigner_test.py
+++ b/yapftests/subtype_assigner_test.py
@@ -18,24 +18,25 @@ import unittest
from yapf.yapflib import format_token
from yapf.yapflib import pytree_utils
+from yapf.yapflib import subtypes
from yapftests import yapf_test_helper
class SubtypeAssignerTest(yapf_test_helper.YAPFTest):
- def _CheckFormatTokenSubtypes(self, uwlines, list_of_expected):
- """Check that the tokens in the UnwrappedLines have the expected subtypes.
+ def _CheckFormatTokenSubtypes(self, llines, list_of_expected):
+ """Check that the tokens in the LogicalLines have the expected subtypes.
Args:
- uwlines: list of UnwrappedLine.
+ llines: list of LogicalLine.
list_of_expected: list of (name, subtype) pairs. Non-semantic tokens are
filtered out from the expected values.
"""
actual = []
- for uwl in uwlines:
+ for lline in llines:
filtered_values = [(ft.value, ft.subtypes)
- for ft in uwl.tokens
+ for ft in lline.tokens
if ft.name not in pytree_utils.NONSEMANTIC_TOKENS]
if filtered_values:
actual.append(filtered_values)
@@ -43,140 +44,222 @@ class SubtypeAssignerTest(yapf_test_helper.YAPFTest):
self.assertEqual(list_of_expected, actual)
def testFuncDefDefaultAssign(self):
+ self.maxDiff = None # pylint: disable=invalid-name
code = textwrap.dedent(r"""
def foo(a=37, *b, **c):
return -x[:42]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckFormatTokenSubtypes(uwlines, [
- [('def', [format_token.Subtype.NONE]),
- ('foo', {format_token.Subtype.FUNC_DEF}),
- ('(', [format_token.Subtype.NONE]),
- ('a', {format_token.Subtype.NONE,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- ('=', {format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- ('37', {format_token.Subtype.NONE,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- (',', {format_token.Subtype.NONE}),
- ('*', {format_token.Subtype.VARARGS_STAR,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- ('b', {format_token.Subtype.NONE,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- (',', {format_token.Subtype.NONE}),
- ('**', {format_token.Subtype.KWARGS_STAR_STAR,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- ('c', {format_token.Subtype.NONE,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- (')', [format_token.Subtype.NONE]),
- (':', [format_token.Subtype.NONE])],
- [('return', [format_token.Subtype.NONE]),
- ('-', {format_token.Subtype.UNARY_OPERATOR}),
- ('x', [format_token.Subtype.NONE]),
- ('[', {format_token.Subtype.SUBSCRIPT_BRACKET}),
- (':', {format_token.Subtype.SUBSCRIPT_COLON}),
- ('42', [format_token.Subtype.NONE]),
- (']', {format_token.Subtype.SUBSCRIPT_BRACKET})],
- ]) # yapf: disable
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [
+ [
+ ('def', {subtypes.NONE}),
+ ('foo', {subtypes.FUNC_DEF}),
+ ('(', {subtypes.NONE}),
+ ('a', {
+ subtypes.NONE,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ subtypes.PARAMETER_START,
+ }),
+ ('=', {
+ subtypes.DEFAULT_OR_NAMED_ASSIGN,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ ('37', {
+ subtypes.NONE,
+ subtypes.PARAMETER_STOP,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ (',', {subtypes.NONE}),
+ ('*', {
+ subtypes.PARAMETER_START,
+ subtypes.VARARGS_STAR,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ ('b', {
+ subtypes.NONE,
+ subtypes.PARAMETER_STOP,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ (',', {subtypes.NONE}),
+ ('**', {
+ subtypes.PARAMETER_START,
+ subtypes.KWARGS_STAR_STAR,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ ('c', {
+ subtypes.NONE,
+ subtypes.PARAMETER_STOP,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ (')', {subtypes.NONE}),
+ (':', {subtypes.NONE}),
+ ],
+ [
+ ('return', {subtypes.NONE}),
+ ('-', {subtypes.UNARY_OPERATOR}),
+ ('x', {subtypes.NONE}),
+ ('[', {subtypes.SUBSCRIPT_BRACKET}),
+ (':', {subtypes.SUBSCRIPT_COLON}),
+ ('42', {subtypes.NONE}),
+ (']', {subtypes.SUBSCRIPT_BRACKET}),
+ ],
+ ])
def testFuncCallWithDefaultAssign(self):
code = textwrap.dedent(r"""
foo(x, a='hello world')
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckFormatTokenSubtypes(uwlines, [
- [('foo', [format_token.Subtype.NONE]),
- ('(', [format_token.Subtype.NONE]),
- ('x', {format_token.Subtype.NONE,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- (',', {format_token.Subtype.NONE}),
- ('a', {format_token.Subtype.NONE,
- format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST}),
- ('=', {format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN}),
- ("'hello world'", {format_token.Subtype.NONE}),
- (')', [format_token.Subtype.NONE])],
- ]) # yapf: disable
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [
+ [
+ ('foo', {subtypes.NONE}),
+ ('(', {subtypes.NONE}),
+ ('x', {
+ subtypes.NONE,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ (',', {subtypes.NONE}),
+ ('a', {
+ subtypes.NONE,
+ subtypes.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST,
+ }),
+ ('=', {subtypes.DEFAULT_OR_NAMED_ASSIGN}),
+ ("'hello world'", {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ],
+ ])
def testSetComprehension(self):
code = textwrap.dedent("""\
def foo(strs):
return {s.lower() for s in strs}
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckFormatTokenSubtypes(uwlines, [
- [('def', [format_token.Subtype.NONE]),
- ('foo', {format_token.Subtype.FUNC_DEF}),
- ('(', [format_token.Subtype.NONE]),
- ('strs', [format_token.Subtype.NONE]),
- (')', [format_token.Subtype.NONE]),
- (':', [format_token.Subtype.NONE])],
- [('return', [format_token.Subtype.NONE]),
- ('{', [format_token.Subtype.NONE]),
- ('s', {format_token.Subtype.COMP_EXPR}),
- ('.', {format_token.Subtype.COMP_EXPR}),
- ('lower', {format_token.Subtype.COMP_EXPR}),
- ('(', {format_token.Subtype.COMP_EXPR}),
- (')', {format_token.Subtype.COMP_EXPR}),
- ('for', {format_token.Subtype.DICT_SET_GENERATOR,
- format_token.Subtype.COMP_FOR}),
- ('s', {format_token.Subtype.COMP_FOR}),
- ('in', {format_token.Subtype.COMP_FOR}),
- ('strs', {format_token.Subtype.COMP_FOR}),
- ('}', [format_token.Subtype.NONE])]
- ]) # yapf: disable
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [
+ [
+ ('def', {subtypes.NONE}),
+ ('foo', {subtypes.FUNC_DEF}),
+ ('(', {subtypes.NONE}),
+ ('strs', {
+ subtypes.NONE,
+ subtypes.PARAMETER_START,
+ subtypes.PARAMETER_STOP,
+ }),
+ (')', {subtypes.NONE}),
+ (':', {subtypes.NONE}),
+ ],
+ [
+ ('return', {subtypes.NONE}),
+ ('{', {subtypes.NONE}),
+ ('s', {subtypes.COMP_EXPR}),
+ ('.', {subtypes.COMP_EXPR}),
+ ('lower', {subtypes.COMP_EXPR}),
+ ('(', {subtypes.COMP_EXPR}),
+ (')', {subtypes.COMP_EXPR}),
+ ('for', {
+ subtypes.DICT_SET_GENERATOR,
+ subtypes.COMP_FOR,
+ }),
+ ('s', {subtypes.COMP_FOR}),
+ ('in', {subtypes.COMP_FOR}),
+ ('strs', {subtypes.COMP_FOR}),
+ ('}', {subtypes.NONE}),
+ ],
+ ])
def testUnaryNotOperator(self):
code = textwrap.dedent("""\
not a
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckFormatTokenSubtypes(uwlines, [
- [('not', {format_token.Subtype.UNARY_OPERATOR}),
- ('a', [format_token.Subtype.NONE])]
- ]) # yapf: disable
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [[('not', {subtypes.UNARY_OPERATOR}),
+ ('a', {subtypes.NONE})]])
def testBitwiseOperators(self):
code = textwrap.dedent("""\
x = ((a | (b ^ 3) & c) << 3) >> 1
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckFormatTokenSubtypes(uwlines, [
- [('x', [format_token.Subtype.NONE]),
- ('=', {format_token.Subtype.ASSIGN_OPERATOR}),
- ('(', [format_token.Subtype.NONE]),
- ('(', [format_token.Subtype.NONE]),
- ('a', [format_token.Subtype.NONE]),
- ('|', {format_token.Subtype.BINARY_OPERATOR}),
- ('(', [format_token.Subtype.NONE]),
- ('b', [format_token.Subtype.NONE]),
- ('^', {format_token.Subtype.BINARY_OPERATOR}),
- ('3', [format_token.Subtype.NONE]),
- (')', [format_token.Subtype.NONE]),
- ('&', {format_token.Subtype.BINARY_OPERATOR}),
- ('c', [format_token.Subtype.NONE]),
- (')', [format_token.Subtype.NONE]),
- ('<<', {format_token.Subtype.BINARY_OPERATOR}),
- ('3', [format_token.Subtype.NONE]),
- (')', [format_token.Subtype.NONE]),
- ('>>', {format_token.Subtype.BINARY_OPERATOR}),
- ('1', [format_token.Subtype.NONE]),],
- ]) # yapf: disable
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [
+ [
+ ('x', {subtypes.NONE}),
+ ('=', {subtypes.ASSIGN_OPERATOR}),
+ ('(', {subtypes.NONE}),
+ ('(', {subtypes.NONE}),
+ ('a', {subtypes.NONE}),
+ ('|', {subtypes.BINARY_OPERATOR}),
+ ('(', {subtypes.NONE}),
+ ('b', {subtypes.NONE}),
+ ('^', {subtypes.BINARY_OPERATOR}),
+ ('3', {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ('&', {subtypes.BINARY_OPERATOR}),
+ ('c', {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ('<<', {subtypes.BINARY_OPERATOR}),
+ ('3', {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ('>>', {subtypes.BINARY_OPERATOR}),
+ ('1', {subtypes.NONE}),
+ ],
+ ])
+
+ def testArithmeticOperators(self):
+ code = textwrap.dedent("""\
+ x = ((a + (b - 3) * (1 % c) @ d) / 3) // 1
+ """)
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [
+ [
+ ('x', {subtypes.NONE}),
+ ('=', {subtypes.ASSIGN_OPERATOR}),
+ ('(', {subtypes.NONE}),
+ ('(', {subtypes.NONE}),
+ ('a', {subtypes.NONE}),
+ ('+', {subtypes.BINARY_OPERATOR}),
+ ('(', {subtypes.NONE}),
+ ('b', {subtypes.NONE}),
+ ('-', {
+ subtypes.BINARY_OPERATOR,
+ subtypes.SIMPLE_EXPRESSION,
+ }),
+ ('3', {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ('*', {subtypes.BINARY_OPERATOR}),
+ ('(', {subtypes.NONE}),
+ ('1', {subtypes.NONE}),
+ ('%', {
+ subtypes.BINARY_OPERATOR,
+ subtypes.SIMPLE_EXPRESSION,
+ }),
+ ('c', {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ('@', {subtypes.BINARY_OPERATOR}),
+ ('d', {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ('/', {subtypes.BINARY_OPERATOR}),
+ ('3', {subtypes.NONE}),
+ (')', {subtypes.NONE}),
+ ('//', {subtypes.BINARY_OPERATOR}),
+ ('1', {subtypes.NONE}),
+ ],
+ ])
def testSubscriptColon(self):
code = textwrap.dedent("""\
x[0:42:1]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckFormatTokenSubtypes(uwlines, [
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [
[
- ('x', [format_token.Subtype.NONE]),
- ('[', {format_token.Subtype.SUBSCRIPT_BRACKET}),
- ('0', [format_token.Subtype.NONE]),
- (':', {format_token.Subtype.SUBSCRIPT_COLON}),
- ('42', [format_token.Subtype.NONE]),
- (':', {format_token.Subtype.SUBSCRIPT_COLON}),
- ('1', [format_token.Subtype.NONE]),
- (']', {format_token.Subtype.SUBSCRIPT_BRACKET}),
+ ('x', {subtypes.NONE}),
+ ('[', {subtypes.SUBSCRIPT_BRACKET}),
+ ('0', {subtypes.NONE}),
+ (':', {subtypes.SUBSCRIPT_COLON}),
+ ('42', {subtypes.NONE}),
+ (':', {subtypes.SUBSCRIPT_COLON}),
+ ('1', {subtypes.NONE}),
+ (']', {subtypes.SUBSCRIPT_BRACKET}),
],
])
@@ -184,16 +267,20 @@ class SubtypeAssignerTest(yapf_test_helper.YAPFTest):
code = textwrap.dedent("""\
[a, *b]
""")
- uwlines = yapf_test_helper.ParseAndUnwrap(code)
- self._CheckFormatTokenSubtypes(uwlines, [
- [('[', [format_token.Subtype.NONE]),
- ('a', [format_token.Subtype.NONE]),
- (',', [format_token.Subtype.NONE]),
- ('*', {format_token.Subtype.UNARY_OPERATOR,
- format_token.Subtype.VARARGS_STAR}),
- ('b', [format_token.Subtype.NONE]),
- (']', [format_token.Subtype.NONE]),],
- ]) # yapf: disable
+ llines = yapf_test_helper.ParseAndUnwrap(code)
+ self._CheckFormatTokenSubtypes(llines, [
+ [
+ ('[', {subtypes.NONE}),
+ ('a', {subtypes.NONE}),
+ (',', {subtypes.NONE}),
+ ('*', {
+ subtypes.UNARY_OPERATOR,
+ subtypes.VARARGS_STAR,
+ }),
+ ('b', {subtypes.NONE}),
+ (']', {subtypes.NONE}),
+ ],
+ ])
if __name__ == '__main__':
diff --git a/yapftests/yapf_test.py b/yapftests/yapf_test.py
index 6df28b6..2330f4e 100644
--- a/yapftests/yapf_test.py
+++ b/yapftests/yapf_test.py
@@ -24,11 +24,15 @@ import tempfile
import textwrap
import unittest
+from lib2to3.pgen2 import tokenize
+
+from yapf.yapflib import errors
from yapf.yapflib import py3compat
from yapf.yapflib import style
from yapf.yapflib import yapf_api
from yapftests import utils
+from yapftests import yapf_test_helper
ROOT_DIR = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
@@ -36,12 +40,12 @@ ROOT_DIR = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
YAPF_BINARY = [sys.executable, '-m', 'yapf', '--verify', '--no-local-style']
-class FormatCodeTest(unittest.TestCase):
+class FormatCodeTest(yapf_test_helper.YAPFTest):
def _Check(self, unformatted_code, expected_formatted_code):
formatted_code, _ = yapf_api.FormatCode(
- unformatted_code, style_config='chromium')
- self.assertEqual(expected_formatted_code, formatted_code)
+ unformatted_code, style_config='yapf')
+ self.assertCodeEqual(expected_formatted_code, formatted_code)
def testSimple(self):
unformatted_code = textwrap.dedent("""\
@@ -59,13 +63,19 @@ class FormatCodeTest(unittest.TestCase):
""")
self._Check(unformatted_code, expected_formatted_code)
+ @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
+ def testPrintAfterPeriod(self):
+ unformatted_code = textwrap.dedent("""a.print\n""")
+ expected_formatted_code = textwrap.dedent("""a.print\n""")
+ self._Check(unformatted_code, expected_formatted_code)
+
class FormatFileTest(unittest.TestCase):
- def setUp(self):
+ def setUp(self): # pylint: disable=g-missing-super-call
self.test_tmpdir = tempfile.mkdtemp()
- def tearDown(self):
+ def tearDown(self): # pylint: disable=g-missing-super-call
shutil.rmtree(self.test_tmpdir)
def assertCodeEqual(self, expected_code, code):
@@ -87,7 +97,7 @@ class FormatFileTest(unittest.TestCase):
if True:
pass
""")
- expected_formatted_code_chromium = textwrap.dedent(u"""\
+ expected_formatted_code_yapf = textwrap.dedent(u"""\
if True:
pass
""")
@@ -95,9 +105,8 @@ class FormatFileTest(unittest.TestCase):
formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
self.assertCodeEqual(expected_formatted_code_pep8, formatted_code)
- formatted_code, _, _ = yapf_api.FormatFile(
- filepath, style_config='chromium')
- self.assertCodeEqual(expected_formatted_code_chromium, formatted_code)
+ formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
+ self.assertCodeEqual(expected_formatted_code_yapf, formatted_code)
def testDisableLinesPattern(self):
unformatted_code = textwrap.dedent(u"""\
@@ -187,6 +196,19 @@ class FormatFileTest(unittest.TestCase):
formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
self.assertCodeEqual(code, formatted_code)
+ def testEnabledDisabledSameComment(self):
+ code = textwrap.dedent(u"""\
+ # yapf: disable
+ a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee)
+ # yapf: enable
+ # yapf: disable
+ a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee)
+ # yapf: enable
+ """) # noqa
+ with utils.TempFileContents(self.test_tmpdir, code) as filepath:
+ formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
+ self.assertCodeEqual(code, formatted_code)
+
def testFormatFileLinesSelection(self):
unformatted_code = textwrap.dedent(u"""\
if a: b
@@ -224,7 +246,7 @@ class FormatFileTest(unittest.TestCase):
""")
with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
diff, _, _ = yapf_api.FormatFile(filepath, print_diff=True)
- self.assertTrue(u'+ pass' in diff)
+ self.assertIn(u'+ pass', diff)
def testFormatFileInPlace(self):
unformatted_code = u'True==False\n'
@@ -340,8 +362,7 @@ class FormatFileTest(unittest.TestCase):
]
""")
with utils.TempFileContents(self.test_tmpdir, code) as filepath:
- formatted_code, _, _ = yapf_api.FormatFile(
- filepath, style_config='chromium')
+ formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
self.assertCodeEqual(code, formatted_code)
def testDisabledWithPrecedingText(self):
@@ -360,15 +381,13 @@ class FormatFileTest(unittest.TestCase):
]
""")
with utils.TempFileContents(self.test_tmpdir, code) as filepath:
- formatted_code, _, _ = yapf_api.FormatFile(
- filepath, style_config='chromium')
+ formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
self.assertCodeEqual(code, formatted_code)
def testCRLFLineEnding(self):
code = u'class _():\r\n pass\r\n'
with utils.TempFileContents(self.test_tmpdir, code) as filepath:
- formatted_code, _, _ = yapf_api.FormatFile(
- filepath, style_config='chromium')
+ formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
self.assertCodeEqual(code, formatted_code)
@@ -376,11 +395,11 @@ class CommandLineTest(unittest.TestCase):
"""Test how calling yapf from the command line acts."""
@classmethod
- def setUpClass(cls):
+ def setUpClass(cls): # pylint: disable=g-missing-super-call
cls.test_tmpdir = tempfile.mkdtemp()
@classmethod
- def tearDownClass(cls):
+ def tearDownClass(cls): # pylint: disable=g-missing-super-call
shutil.rmtree(cls.test_tmpdir)
def assertYapfReformats(self,
@@ -406,10 +425,12 @@ class CommandLineTest(unittest.TestCase):
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env)
- reformatted_code, stderrdata = p.communicate(unformatted.encode('utf-8'))
+ reformatted_code, stderrdata = p.communicate(
+ unformatted.encode('utf-8-sig'))
self.assertEqual(stderrdata, b'')
self.assertMultiLineEqual(reformatted_code.decode('utf-8'), expected)
+ @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
def testUnicodeEncodingPipedToFile(self):
unformatted_code = textwrap.dedent(u"""\
def foo():
@@ -480,7 +501,7 @@ class CommandLineTest(unittest.TestCase):
""")
self.assertYapfReformats(unformatted_code, expected_formatted_code)
- def testSetChromiumStyle(self):
+ def testSetYapfStyle(self):
unformatted_code = textwrap.dedent("""\
def foo(): # trail
x = 37
@@ -492,9 +513,9 @@ class CommandLineTest(unittest.TestCase):
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
- extra_options=['--style=chromium'])
+ extra_options=['--style=yapf'])
- def testSetCustomStyleBasedOnChromium(self):
+ def testSetCustomStyleBasedOnYapf(self):
unformatted_code = textwrap.dedent("""\
def foo(): # trail
x = 37
@@ -505,8 +526,27 @@ class CommandLineTest(unittest.TestCase):
""")
style_file = textwrap.dedent(u'''\
[style]
- based_on_style = chromium
- SPACES_BEFORE_COMMENT = 4
+ based_on_style = yapf
+ spaces_before_comment = 4
+ ''')
+ with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath:
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=['--style={0}'.format(stylepath)])
+
+ def testSetCustomStyleSpacesBeforeComment(self):
+ unformatted_code = textwrap.dedent("""\
+ a_very_long_statement_that_extends_way_beyond # Comment
+ short # This is a shorter statement
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ a_very_long_statement_that_extends_way_beyond # Comment
+ short # This is a shorter statement
+ """) # noqa
+ style_file = textwrap.dedent(u'''\
+ [style]
+ spaces_before_comment = 15, 20
''')
with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath:
self.assertYapfReformats(
@@ -538,7 +578,8 @@ class CommandLineTest(unittest.TestCase):
try:
subprocess.check_call(YAPF_BINARY + ['--diff', filepath], stdout=out)
except subprocess.CalledProcessError as e:
- self.assertEqual(e.returncode, 1) # Indicates the text changed.
+ # Indicates the text changed.
+ self.assertEqual(e.returncode, 1) # pylint: disable=g-assert-in-except # noqa
def testReformattingSpecificLines(self):
unformatted_code = textwrap.dedent("""\
@@ -550,7 +591,7 @@ class CommandLineTest(unittest.TestCase):
def g():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def h():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
@@ -561,7 +602,7 @@ class CommandLineTest(unittest.TestCase):
def g():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
pass
- """)
+ """) # noqa
# TODO(ambv): the `expected_formatted_code` here is not PEP8 compliant,
# raising "E129 visually indented line with same indent as next logical
# line" with flake8.
@@ -601,7 +642,7 @@ class CommandLineTest(unittest.TestCase):
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
pass
# yapf: enable
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def h():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
@@ -614,7 +655,7 @@ class CommandLineTest(unittest.TestCase):
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
pass
# yapf: enable
- """)
+ """) # noqa
self.assertYapfReformats(unformatted_code, expected_formatted_code)
def testReformattingSkippingToEndOfFile(self):
@@ -634,7 +675,7 @@ class CommandLineTest(unittest.TestCase):
xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) ==
'bbbbbbb'):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def h():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
@@ -653,7 +694,7 @@ class CommandLineTest(unittest.TestCase):
xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) ==
'bbbbbbb'):
pass
- """)
+ """) # noqa
self.assertYapfReformats(unformatted_code, expected_formatted_code)
def testReformattingSkippingSingleLine(self):
@@ -665,7 +706,7 @@ class CommandLineTest(unittest.TestCase):
def g():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def h():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
@@ -676,7 +717,7 @@ class CommandLineTest(unittest.TestCase):
def g():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable
pass
- """)
+ """) # noqa
self.assertYapfReformats(unformatted_code, expected_formatted_code)
def testDisableWholeDataStructure(self):
@@ -697,12 +738,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
@@ -718,7 +761,7 @@ class CommandLineTest(unittest.TestCase):
def g():
if (xxxxxxxxxxxx.yyyyyyyy (zzzzzzzzzzzzz [0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def h():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
@@ -729,7 +772,7 @@ class CommandLineTest(unittest.TestCase):
def g():
if (xxxxxxxxxxxx.yyyyyyyy (zzzzzzzzzzzzz [0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable
pass
- """)
+ """) # noqa
self.assertYapfReformats(unformatted_code, expected_formatted_code)
def testRetainingVerticalWhitespace(self):
@@ -744,7 +787,7 @@ class CommandLineTest(unittest.TestCase):
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
pass
- """)
+ """) # noqa
expected_formatted_code = textwrap.dedent("""\
def h():
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
@@ -757,7 +800,7 @@ class CommandLineTest(unittest.TestCase):
if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
pass
- """)
+ """) # noqa
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
@@ -812,6 +855,28 @@ class CommandLineTest(unittest.TestCase):
self.assertYapfReformats(
unformatted_code, unformatted_code, extra_options=['--lines', '2-2'])
+ def testVerticalSpacingWithCommentWithContinuationMarkers(self):
+ unformatted_code = """\
+# \\
+# \\
+# \\
+
+x = {
+}
+"""
+ expected_formatted_code = """\
+# \\
+# \\
+# \\
+
+x = {
+}
+"""
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=['--lines', '1-1'])
+
def testRetainingSemicolonsWhenSpecifyingLines(self):
unformatted_code = textwrap.dedent("""\
a = line_to_format
@@ -821,8 +886,6 @@ class CommandLineTest(unittest.TestCase):
""")
expected_formatted_code = textwrap.dedent("""\
a = line_to_format
-
-
def f():
x = y + 42; z = n * 42
if True: a += 1 ; b += 1 ; c += 1
@@ -842,11 +905,9 @@ class CommandLineTest(unittest.TestCase):
<b>Residence: </b>"""+palace["Winter"]+"""<br>
</body>
</html>"""
- ''')
+ ''') # noqa
expected_formatted_code = textwrap.dedent('''\
foo = 42
-
-
def f():
email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br>
<b>Czar: </b>"""+despot["Nicholas"]+"""<br>
@@ -854,7 +915,7 @@ class CommandLineTest(unittest.TestCase):
<b>Residence: </b>"""+palace["Winter"]+"""<br>
</body>
</html>"""
- ''')
+ ''') # noqa
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
@@ -950,12 +1011,36 @@ class CommandLineTest(unittest.TestCase):
'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff),
gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
iiiii = jjjjjjjjjjjjjj.iiiii
- """)
+ """) # noqa
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
extra_options=['--lines', '4-7'])
+ def testRetainVerticalFormattingBetweenDisabledLines(self):
+ unformatted_code = textwrap.dedent("""\
+ class A(object):
+ def aaaaaaaaaaaaa(self):
+ pass
+
+
+ def bbbbbbbbbbbbb(self): # 5
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ class A(object):
+ def aaaaaaaaaaaaa(self):
+ pass
+
+
+ def bbbbbbbbbbbbb(self): # 5
+ pass
+ """)
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=['--lines', '4-4'])
+
def testFormatLinesSpecifiedInMiddleOfExpression(self):
unformatted_code = textwrap.dedent("""\
class A(object):
@@ -976,7 +1061,7 @@ class CommandLineTest(unittest.TestCase):
'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff),
gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
iiiii = jjjjjjjjjjjjjj.iiiii
- """)
+ """) # noqa
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
@@ -1046,7 +1131,7 @@ class CommandLineTest(unittest.TestCase):
first_argument_on_the_same_line, second_argument_makes_the_line_too_long
):
pass
- """)
+ """) # noqa
self.assertYapfReformats(
unformatted_code,
expected_formatted_fb_code,
@@ -1087,20 +1172,19 @@ class CommandLineTest(unittest.TestCase):
def testPseudoParenSpaces(self):
unformatted_code = textwrap.dedent("""\
- def foo():
+ def foo():
def bar():
return {msg_id: author for author, msg_id in reader}
""")
expected_formatted_code = textwrap.dedent("""\
def foo():
-
def bar():
return {msg_id: author for author, msg_id in reader}
""")
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
- extra_options=['--lines', '1-1', '--style', 'chromium'])
+ extra_options=['--lines', '1-1', '--style', 'yapf'])
def testMultilineCommentFormattingDisabled(self):
unformatted_code = textwrap.dedent("""\
@@ -1134,7 +1218,7 @@ class CommandLineTest(unittest.TestCase):
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
- extra_options=['--lines', '1-1', '--style', 'chromium'])
+ extra_options=['--lines', '1-1', '--style', 'yapf'])
def testTrailingCommentsWithDisabledFormatting(self):
unformatted_code = textwrap.dedent("""\
@@ -1154,7 +1238,7 @@ class CommandLineTest(unittest.TestCase):
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
- extra_options=['--lines', '1-1', '--style', 'chromium'])
+ extra_options=['--lines', '1-1', '--style', 'yapf'])
def testUseTabs(self):
unformatted_code = """\
@@ -1166,10 +1250,10 @@ def foo_function():
def foo_function():
if True:
pass
-"""
+""" # noqa: W191,E101
style_contents = u"""\
[style]
-based_on_style = chromium
+based_on_style = yapf
USE_TABS = true
INDENT_WIDTH=1
"""
@@ -1190,10 +1274,10 @@ def f():
'hello',
'world',
]
-"""
+""" # noqa: W191,E101
style_contents = u"""\
[style]
-based_on_style = chromium
+based_on_style = yapf
USE_TABS = true
INDENT_WIDTH=1
"""
@@ -1209,16 +1293,16 @@ def foo_function(arg1, arg2, arg3):
return ['hello', 'world',]
"""
expected_formatted_code = """\
-def foo_function(arg1, arg2,
- arg3):
+def foo_function(
+ arg1, arg2, arg3):
return [
'hello',
'world',
]
-"""
+""" # noqa: W191,E101
style_contents = u"""\
[style]
-based_on_style = chromium
+based_on_style = yapf
USE_TABS = true
COLUMN_LIMIT=32
INDENT_WIDTH=4
@@ -1243,10 +1327,10 @@ def foo_function(arg1, arg2,
'hello',
'world',
]
-"""
+""" # noqa: W191,E101
style_contents = u"""\
[style]
-based_on_style = chromium
+based_on_style = yapf
USE_TABS = true
COLUMN_LIMIT=32
INDENT_WIDTH=4
@@ -1259,6 +1343,60 @@ CONTINUATION_ALIGN_STYLE = valign-right
expected_formatted_code,
extra_options=['--style={0}'.format(stylepath)])
+ def testUseSpacesContinuationAlignStyleFixed(self):
+ unformatted_code = """\
+def foo_function(arg1, arg2, arg3):
+ return ['hello', 'world',]
+"""
+ expected_formatted_code = """\
+def foo_function(
+ arg1, arg2, arg3):
+ return [
+ 'hello',
+ 'world',
+ ]
+"""
+ style_contents = u"""\
+[style]
+based_on_style = yapf
+COLUMN_LIMIT=32
+INDENT_WIDTH=4
+CONTINUATION_INDENT_WIDTH=8
+CONTINUATION_ALIGN_STYLE = fixed
+"""
+ with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=['--style={0}'.format(stylepath)])
+
+ def testUseSpacesContinuationAlignStyleVAlignRight(self):
+ unformatted_code = """\
+def foo_function(arg1, arg2, arg3):
+ return ['hello', 'world',]
+"""
+ expected_formatted_code = """\
+def foo_function(arg1, arg2,
+ arg3):
+ return [
+ 'hello',
+ 'world',
+ ]
+"""
+ style_contents = u"""\
+[style]
+based_on_style = yapf
+COLUMN_LIMIT=32
+INDENT_WIDTH=4
+CONTINUATION_INDENT_WIDTH=8
+CONTINUATION_ALIGN_STYLE = valign-right
+"""
+ with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=['--style={0}'.format(stylepath)])
+
def testStyleOutputRoundTrip(self):
unformatted_code = textwrap.dedent("""\
def foo_function():
@@ -1343,7 +1481,48 @@ CONTINUATION_ALIGN_STYLE = valign-right
self.assertYapfReformats(
unformatted_code,
expected_formatted_code,
- extra_options=['--style', 'chromium', '--lines', '1-1'])
+ extra_options=['--style', 'yapf', '--lines', '1-1'])
+
+ def testDisableWithLinesOption(self):
+ unformatted_code = textwrap.dedent("""\
+ # yapf_lines_bug.py
+ # yapf: disable
+ def outer_func():
+ def inner_func():
+ return
+ return
+ # yapf: enable
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ # yapf_lines_bug.py
+ # yapf: disable
+ def outer_func():
+ def inner_func():
+ return
+ return
+ # yapf: enable
+ """)
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=['--lines', '1-8'])
+
+ @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
+ def testNoSpacesAroundBinaryOperators(self):
+ unformatted_code = """\
+a = 4-b/c@d**37
+"""
+ expected_formatted_code = """\
+a = 4-b / c@d**37
+"""
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=[
+ '--style',
+ '{based_on_style: pep8, '
+ 'no_spaces_around_selected_binary_operators: "@,**,-"}',
+ ])
@unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
def testCP936Encoding(self):
@@ -1354,13 +1533,41 @@ CONTINUATION_ALIGN_STYLE = valign-right
expected_formatted_code,
env={'PYTHONIOENCODING': 'cp936'})
+ def testDisableWithLineRanges(self):
+ unformatted_code = """\
+# yapf: disable
+a = [
+ 1,
+ 2,
+
+ 3
+]
+"""
+ expected_formatted_code = """\
+# yapf: disable
+a = [
+ 1,
+ 2,
+
+ 3
+]
+"""
+ self.assertYapfReformats(
+ unformatted_code,
+ expected_formatted_code,
+ extra_options=['--style', 'yapf', '--lines', '1-100'])
+
class BadInputTest(unittest.TestCase):
"""Test yapf's behaviour when passed bad input."""
def testBadSyntax(self):
code = ' a = 1\n'
- self.assertRaises(SyntaxError, yapf_api.FormatCode, code)
+ self.assertRaises(errors.YapfError, yapf_api.FormatCode, code)
+
+ def testBadCode(self):
+ code = 'x = """hello\n'
+ self.assertRaises(errors.YapfError, yapf_api.FormatCode, code)
class DiffIndentTest(unittest.TestCase):
@@ -1389,5 +1596,468 @@ class DiffIndentTest(unittest.TestCase):
self._Check(unformatted_code, expected_formatted_code)
+class HorizontallyAlignedTrailingCommentsTest(yapf_test_helper.YAPFTest):
+
+ @staticmethod
+ def _OwnStyle():
+ my_style = style.CreatePEP8Style()
+ my_style['SPACES_BEFORE_COMMENT'] = [
+ 15,
+ 25,
+ 35,
+ ]
+ return my_style
+
+ def _Check(self, unformatted_code, expected_formatted_code):
+ formatted_code, _ = yapf_api.FormatCode(
+ unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle()))
+ self.assertCodeEqual(expected_formatted_code, formatted_code)
+
+ def testSimple(self):
+ unformatted_code = textwrap.dedent("""\
+ foo = '1' # Aligned at first list value
+
+ foo = '2__<15>' # Aligned at second list value
+
+ foo = '3____________<25>' # Aligned at third list value
+
+ foo = '4______________________<35>' # Aligned beyond list values
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ foo = '1' # Aligned at first list value
+
+ foo = '2__<15>' # Aligned at second list value
+
+ foo = '3____________<25>' # Aligned at third list value
+
+ foo = '4______________________<35>' # Aligned beyond list values
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testBlock(self):
+ unformatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testBlockWithLongLine(self):
+ unformatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func___________________(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func___________________(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testBlockFuncSuffix(self):
+ unformatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+
+ def Func():
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+
+
+ def Func():
+ pass
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testBlockCommentSuffix(self):
+ unformatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5 - SpliceComments makes this part of the previous block
+ # Line 6
+
+ # Aligned with prev comment block
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5 - SpliceComments makes this part of the previous block
+ # Line 6
+
+ # Aligned with prev comment block
+ """) # noqa
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testBlockIndentedFuncSuffix(self):
+ unformatted_code = textwrap.dedent("""\
+ if True:
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5 - SpliceComments makes this a new block
+ # Line 6
+
+ # Aligned with Func
+
+ def Func():
+ pass
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ if True:
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+
+ # Line 5 - SpliceComments makes this a new block
+ # Line 6
+
+ # Aligned with Func
+
+
+ def Func():
+ pass
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testBlockIndentedCommentSuffix(self):
+ unformatted_code = textwrap.dedent("""\
+ if True:
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+
+ # Not aligned
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ if True:
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+
+ # Not aligned
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testBlockMultiIndented(self):
+ unformatted_code = textwrap.dedent("""\
+ if True:
+ if True:
+ if True:
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+
+ # Not aligned
+ """) # noqa
+ expected_formatted_code = textwrap.dedent("""\
+ if True:
+ if True:
+ if True:
+ func(1) # Line 1
+ func(2) # Line 2
+ # Line 3
+ func(3) # Line 4
+ # Line 5
+ # Line 6
+
+ # Not aligned
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testArgs(self):
+ unformatted_code = textwrap.dedent("""\
+ def MyFunc(
+ arg1, # Desc 1
+ arg2, # Desc 2
+ a_longer_var_name, # Desc 3
+ arg4,
+ arg5, # Desc 5
+ arg6,
+ ):
+ pass
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ def MyFunc(
+ arg1, # Desc 1
+ arg2, # Desc 2
+ a_longer_var_name, # Desc 3
+ arg4,
+ arg5, # Desc 5
+ arg6,
+ ):
+ pass
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testDisableBlock(self):
+ unformatted_code = textwrap.dedent("""\
+ a() # comment 1
+ b() # comment 2
+
+ # yapf: disable
+ c() # comment 3
+ d() # comment 4
+ # yapf: enable
+
+ e() # comment 5
+ f() # comment 6
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ a() # comment 1
+ b() # comment 2
+
+ # yapf: disable
+ c() # comment 3
+ d() # comment 4
+ # yapf: enable
+
+ e() # comment 5
+ f() # comment 6
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+ def testDisabledLine(self):
+ unformatted_code = textwrap.dedent("""\
+ short # comment 1
+ do_not_touch1 # yapf: disable
+ do_not_touch2 # yapf: disable
+ a_longer_statement # comment 2
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ short # comment 1
+ do_not_touch1 # yapf: disable
+ do_not_touch2 # yapf: disable
+ a_longer_statement # comment 2
+ """)
+ self._Check(unformatted_code, expected_formatted_code)
+
+
+class _SpacesAroundDictListTupleTestImpl(unittest.TestCase):
+
+ @staticmethod
+ def _OwnStyle():
+ my_style = style.CreatePEP8Style()
+ my_style['DISABLE_ENDING_COMMA_HEURISTIC'] = True
+ my_style['SPLIT_ALL_COMMA_SEPARATED_VALUES'] = False
+ my_style['SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED'] = False
+ return my_style
+
+ def _Check(self, unformatted_code, expected_formatted_code):
+ formatted_code, _ = yapf_api.FormatCode(
+ unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle()))
+ self.assertEqual(expected_formatted_code, formatted_code)
+
+ def setUp(self):
+ self.maxDiff = None
+
+
+class SpacesAroundDictTest(_SpacesAroundDictListTupleTestImpl):
+
+ @classmethod
+ def _OwnStyle(cls):
+ style = super(SpacesAroundDictTest, cls)._OwnStyle()
+ style['SPACES_AROUND_DICT_DELIMITERS'] = True
+
+ return style
+
+ def testStandard(self):
+ unformatted_code = textwrap.dedent("""\
+ {1 : 2}
+ {k:v for k, v in other.items()}
+ {k for k in [1, 2, 3]}
+
+ # The following statements should not change
+ {}
+ {1 : 2} # yapf: disable
+
+ # yapf: disable
+ {1 : 2}
+ # yapf: enable
+
+ # Dict settings should not impact lists or tuples
+ [1, 2]
+ (3, 4)
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ { 1: 2 }
+ { k: v for k, v in other.items() }
+ { k for k in [1, 2, 3] }
+
+ # The following statements should not change
+ {}
+ {1 : 2} # yapf: disable
+
+ # yapf: disable
+ {1 : 2}
+ # yapf: enable
+
+ # Dict settings should not impact lists or tuples
+ [1, 2]
+ (3, 4)
+ """)
+
+ self._Check(unformatted_code, expected_formatted_code)
+
+
+class SpacesAroundListTest(_SpacesAroundDictListTupleTestImpl):
+
+ @classmethod
+ def _OwnStyle(cls):
+ style = super(SpacesAroundListTest, cls)._OwnStyle()
+ style['SPACES_AROUND_LIST_DELIMITERS'] = True
+
+ return style
+
+ def testStandard(self):
+ unformatted_code = textwrap.dedent("""\
+ [a,b,c]
+ [4,5,]
+ [6, [7, 8], 9]
+ [v for v in [1,2,3] if v & 1]
+
+ # The following statements should not change
+ index[0]
+ index[a, b]
+ []
+ [v for v in [1,2,3] if v & 1] # yapf: disable
+
+ # yapf: disable
+ [a,b,c]
+ [4,5,]
+ # yapf: enable
+
+ # List settings should not impact dicts or tuples
+ {a: b}
+ (1, 2)
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ [ a, b, c ]
+ [ 4, 5, ]
+ [ 6, [ 7, 8 ], 9 ]
+ [ v for v in [ 1, 2, 3 ] if v & 1 ]
+
+ # The following statements should not change
+ index[0]
+ index[a, b]
+ []
+ [v for v in [1,2,3] if v & 1] # yapf: disable
+
+ # yapf: disable
+ [a,b,c]
+ [4,5,]
+ # yapf: enable
+
+ # List settings should not impact dicts or tuples
+ {a: b}
+ (1, 2)
+ """)
+
+ self._Check(unformatted_code, expected_formatted_code)
+
+
+class SpacesAroundTupleTest(_SpacesAroundDictListTupleTestImpl):
+
+ @classmethod
+ def _OwnStyle(cls):
+ style = super(SpacesAroundTupleTest, cls)._OwnStyle()
+ style['SPACES_AROUND_TUPLE_DELIMITERS'] = True
+
+ return style
+
+ def testStandard(self):
+ unformatted_code = textwrap.dedent("""\
+ (0, 1)
+ (2, 3)
+ (4, 5, 6,)
+ func((7, 8), 9)
+
+ # The following statements should not change
+ func(1, 2)
+ (this_func or that_func)(3, 4)
+ if (True and False): pass
+ ()
+
+ (0, 1) # yapf: disable
+
+ # yapf: disable
+ (0, 1)
+ (2, 3)
+ # yapf: enable
+
+ # Tuple settings should not impact dicts or lists
+ {a: b}
+ [3, 4]
+ """)
+ expected_formatted_code = textwrap.dedent("""\
+ ( 0, 1 )
+ ( 2, 3 )
+ ( 4, 5, 6, )
+ func(( 7, 8 ), 9)
+
+ # The following statements should not change
+ func(1, 2)
+ (this_func or that_func)(3, 4)
+ if (True and False): pass
+ ()
+
+ (0, 1) # yapf: disable
+
+ # yapf: disable
+ (0, 1)
+ (2, 3)
+ # yapf: enable
+
+ # Tuple settings should not impact dicts or lists
+ {a: b}
+ [3, 4]
+ """)
+
+ self._Check(unformatted_code, expected_formatted_code)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/yapftests/yapf_test_helper.py b/yapftests/yapf_test_helper.py
index 1f21b36..3d1da12 100644
--- a/yapftests/yapf_test_helper.py
+++ b/yapftests/yapf_test_helper.py
@@ -21,6 +21,7 @@ from yapf.yapflib import blank_line_calculator
from yapf.yapflib import comment_splicer
from yapf.yapflib import continuation_splicer
from yapf.yapflib import identify_container
+from yapf.yapflib import py3compat
from yapf.yapflib import pytree_unwrapper
from yapf.yapflib import pytree_utils
from yapf.yapflib import pytree_visitor
@@ -31,21 +32,26 @@ from yapf.yapflib import subtype_assigner
class YAPFTest(unittest.TestCase):
+ def __init__(self, *args):
+ super(YAPFTest, self).__init__(*args)
+ if not py3compat.PY3:
+ self.assertRaisesRegex = self.assertRaisesRegexp
+
def assertCodeEqual(self, expected_code, code):
if code != expected_code:
msg = ['Code format mismatch:', 'Expected:']
linelen = style.Get('COLUMN_LIMIT')
- for l in expected_code.splitlines():
- if len(l) > linelen:
- msg.append('!> %s' % l)
+ for line in expected_code.splitlines():
+ if len(line) > linelen:
+ msg.append('!> %s' % line)
else:
- msg.append(' > %s' % l)
+ msg.append(' > %s' % line)
msg.append('Actual:')
- for l in code.splitlines():
- if len(l) > linelen:
- msg.append('!> %s' % l)
+ for line in code.splitlines():
+ if len(line) > linelen:
+ msg.append('!> %s' % line)
else:
- msg.append(' > %s' % l)
+ msg.append(' > %s' % line)
msg.append('Diff:')
msg.extend(
difflib.unified_diff(
@@ -58,7 +64,7 @@ class YAPFTest(unittest.TestCase):
def ParseAndUnwrap(code, dumptree=False):
- """Produces unwrapped lines from the given code.
+ """Produces logical lines from the given code.
Parses the code into a tree, performs comment splicing and runs the
unwrapper.
@@ -69,7 +75,7 @@ def ParseAndUnwrap(code, dumptree=False):
to stderr. Useful for debugging.
Returns:
- List of unwrapped lines.
+ List of logical lines.
"""
tree = pytree_utils.ParseCodeToTree(code)
comment_splicer.SpliceComments(tree)
@@ -82,8 +88,8 @@ def ParseAndUnwrap(code, dumptree=False):
if dumptree:
pytree_visitor.DumpPyTree(tree, target_stream=sys.stderr)
- uwlines = pytree_unwrapper.UnwrapPyTree(tree)
- for uwl in uwlines:
- uwl.CalculateFormattingInformation()
+ llines = pytree_unwrapper.UnwrapPyTree(tree)
+ for lline in llines:
+ lline.CalculateFormattingInformation()
- return uwlines
+ return llines