1# -*- coding: utf-8 -*- 2# Copyright 2015 Google Inc. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15"""Tests for yapf.yapf.""" 16 17import io 18import logging 19import os 20import shutil 21import subprocess 22import sys 23import tempfile 24import textwrap 25import unittest 26from io import StringIO 27 28from yapf_third_party._ylib2to3.pgen2 import tokenize 29 30from yapf.yapflib import errors 31from yapf.yapflib import style 32from yapf.yapflib import yapf_api 33 34from yapftests import utils 35from yapftests import yapf_test_helper 36 37YAPF_BINARY = [sys.executable, '-m', 'yapf', '--no-local-style'] 38 39 40class FormatCodeTest(yapf_test_helper.YAPFTest): 41 42 def _Check(self, unformatted_code, expected_formatted_code): 43 formatted_code, _ = yapf_api.FormatCode( 44 unformatted_code, style_config='yapf') 45 self.assertCodeEqual(expected_formatted_code, formatted_code) 46 47 def testSimple(self): 48 unformatted_code = textwrap.dedent("""\ 49 print('foo') 50 """) 51 self._Check(unformatted_code, unformatted_code) 52 53 def testNoEndingNewline(self): 54 unformatted_code = textwrap.dedent("""\ 55 if True: 56 pass""") 57 expected_formatted_code = textwrap.dedent("""\ 58 if True: 59 pass 60 """) 61 self._Check(unformatted_code, expected_formatted_code) 62 63 64class FormatFileTest(yapf_test_helper.YAPFTest): 65 66 def setUp(self): # pylint: disable=g-missing-super-call 67 self.test_tmpdir = tempfile.mkdtemp() 68 69 def tearDown(self): # pylint: disable=g-missing-super-call 70 shutil.rmtree(self.test_tmpdir) 71 72 def testFormatFile(self): 73 unformatted_code = textwrap.dedent("""\ 74 if True: 75 pass 76 """) 77 expected_formatted_code_pep8 = textwrap.dedent("""\ 78 if True: 79 pass 80 """) 81 expected_formatted_code_yapf = textwrap.dedent("""\ 82 if True: 83 pass 84 """) 85 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 86 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 87 self.assertCodeEqual(expected_formatted_code_pep8, formatted_code) 88 89 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') 90 self.assertCodeEqual(expected_formatted_code_yapf, formatted_code) 91 92 def testDisableLinesPattern(self): 93 unformatted_code = textwrap.dedent("""\ 94 if a: b 95 96 # yapf: disable 97 if f: g 98 99 if h: i 100 """) 101 expected_formatted_code = textwrap.dedent("""\ 102 if a: b 103 104 # yapf: disable 105 if f: g 106 107 if h: i 108 """) 109 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 110 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 111 self.assertCodeEqual(expected_formatted_code, formatted_code) 112 113 def testDisableAndReenableLinesPattern(self): 114 unformatted_code = textwrap.dedent("""\ 115 if a: b 116 117 # yapf: disable 118 if f: g 119 # yapf: enable 120 121 if h: i 122 """) 123 expected_formatted_code = textwrap.dedent("""\ 124 if a: b 125 126 # yapf: disable 127 if f: g 128 # yapf: enable 129 130 if h: i 131 """) 132 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 133 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 134 self.assertCodeEqual(expected_formatted_code, formatted_code) 135 136 def testFmtOnOff(self): 137 unformatted_code = textwrap.dedent("""\ 138 if a: b 139 140 # fmt: off 141 if f: g 142 # fmt: on 143 144 if h: i 145 """) 146 expected_formatted_code = textwrap.dedent("""\ 147 if a: b 148 149 # fmt: off 150 if f: g 151 # fmt: on 152 153 if h: i 154 """) 155 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 156 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 157 self.assertCodeEqual(expected_formatted_code, formatted_code) 158 159 def testDisablePartOfMultilineComment(self): 160 unformatted_code = textwrap.dedent("""\ 161 if a: b 162 163 # This is a multiline comment that disables YAPF. 164 # yapf: disable 165 if f: g 166 # yapf: enable 167 # This is a multiline comment that enables YAPF. 168 169 if h: i 170 """) 171 expected_formatted_code = textwrap.dedent("""\ 172 if a: b 173 174 # This is a multiline comment that disables YAPF. 175 # yapf: disable 176 if f: g 177 # yapf: enable 178 # This is a multiline comment that enables YAPF. 179 180 if h: i 181 """) 182 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 183 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 184 self.assertCodeEqual(expected_formatted_code, formatted_code) 185 186 code = textwrap.dedent("""\ 187 def foo_function(): 188 # some comment 189 # yapf: disable 190 191 foo( 192 bar, 193 baz 194 ) 195 196 # yapf: enable 197 """) 198 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 199 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 200 self.assertCodeEqual(code, formatted_code) 201 202 def testEnabledDisabledSameComment(self): 203 code = textwrap.dedent("""\ 204 # yapf: disable 205 a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee) 206 # yapf: enable 207 # yapf: disable 208 a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee) 209 # yapf: enable 210 """) # noqa 211 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 212 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 213 self.assertCodeEqual(code, formatted_code) 214 215 def testFormatFileLinesSelection(self): 216 unformatted_code = textwrap.dedent("""\ 217 if a: b 218 219 if f: g 220 221 if h: i 222 """) 223 expected_formatted_code_lines1and2 = textwrap.dedent("""\ 224 if a: b 225 226 if f: g 227 228 if h: i 229 """) 230 expected_formatted_code_lines3 = textwrap.dedent("""\ 231 if a: b 232 233 if f: g 234 235 if h: i 236 """) 237 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 238 formatted_code, _, _ = yapf_api.FormatFile( 239 filepath, style_config='pep8', lines=[(1, 2)]) 240 self.assertCodeEqual(expected_formatted_code_lines1and2, formatted_code) 241 formatted_code, _, _ = yapf_api.FormatFile( 242 filepath, style_config='pep8', lines=[(3, 3)]) 243 self.assertCodeEqual(expected_formatted_code_lines3, formatted_code) 244 245 def testFormatFileDiff(self): 246 unformatted_code = textwrap.dedent("""\ 247 if True: 248 pass 249 """) 250 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 251 diff, _, _ = yapf_api.FormatFile(filepath, print_diff=True) 252 self.assertIn('+ pass', diff) 253 254 def testFormatFileInPlace(self): 255 unformatted_code = 'True==False\n' 256 formatted_code = 'True == False\n' 257 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 258 result, _, _ = yapf_api.FormatFile(filepath, in_place=True) 259 self.assertEqual(result, None) 260 with open(filepath) as fd: 261 self.assertCodeEqual(formatted_code, fd.read()) 262 263 self.assertRaises( 264 ValueError, 265 yapf_api.FormatFile, 266 filepath, 267 in_place=True, 268 print_diff=True) 269 270 def testNoFile(self): 271 with self.assertRaises(IOError) as context: 272 yapf_api.FormatFile('not_a_file.py') 273 274 self.assertEqual( 275 str(context.exception), 276 "[Errno 2] No such file or directory: 'not_a_file.py'") 277 278 def testCommentsUnformatted(self): 279 code = textwrap.dedent("""\ 280 foo = [# A list of things 281 # bork 282 'one', 283 # quark 284 'two'] # yapf: disable 285 """) 286 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 287 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 288 self.assertCodeEqual(code, formatted_code) 289 290 def testDisabledHorizontalFormattingOnNewLine(self): 291 code = textwrap.dedent("""\ 292 # yapf: disable 293 a = [ 294 1] 295 # yapf: enable 296 """) 297 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 298 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 299 self.assertCodeEqual(code, formatted_code) 300 301 def testSplittingSemicolonStatements(self): 302 unformatted_code = textwrap.dedent("""\ 303 def f(): 304 x = y + 42 ; z = n * 42 305 if True: a += 1 ; b += 1; c += 1 306 """) 307 expected_formatted_code = textwrap.dedent("""\ 308 def f(): 309 x = y + 42 310 z = n * 42 311 if True: 312 a += 1 313 b += 1 314 c += 1 315 """) 316 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 317 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 318 self.assertCodeEqual(expected_formatted_code, formatted_code) 319 320 def testSemicolonStatementsDisabled(self): 321 unformatted_code = textwrap.dedent("""\ 322 def f(): 323 x = y + 42 ; z = n * 42 # yapf: disable 324 if True: a += 1 ; b += 1; c += 1 325 """) 326 expected_formatted_code = textwrap.dedent("""\ 327 def f(): 328 x = y + 42 ; z = n * 42 # yapf: disable 329 if True: 330 a += 1 331 b += 1 332 c += 1 333 """) 334 with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: 335 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 336 self.assertCodeEqual(expected_formatted_code, formatted_code) 337 338 def testDisabledSemiColonSeparatedStatements(self): 339 code = textwrap.dedent("""\ 340 # yapf: disable 341 if True: a ; b 342 """) 343 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 344 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') 345 self.assertCodeEqual(code, formatted_code) 346 347 def testDisabledMultilineStringInDictionary(self): 348 code = textwrap.dedent("""\ 349 # yapf: disable 350 351 A = [ 352 { 353 "aaaaaaaaaaaaaaaaaaa": ''' 354 bbbbbbbbbbb: "ccccccccccc" 355 dddddddddddddd: 1 356 eeeeeeee: 0 357 ffffffffff: "ggggggg" 358 ''', 359 }, 360 ] 361 """) 362 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 363 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') 364 self.assertCodeEqual(code, formatted_code) 365 366 def testDisabledWithPrecedingText(self): 367 code = textwrap.dedent("""\ 368 # TODO(fix formatting): yapf: disable 369 370 A = [ 371 { 372 "aaaaaaaaaaaaaaaaaaa": ''' 373 bbbbbbbbbbb: "ccccccccccc" 374 dddddddddddddd: 1 375 eeeeeeee: 0 376 ffffffffff: "ggggggg" 377 ''', 378 }, 379 ] 380 """) 381 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 382 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') 383 self.assertCodeEqual(code, formatted_code) 384 385 def testCRLFLineEnding(self): 386 code = 'class _():\r\n pass\r\n' 387 with utils.TempFileContents(self.test_tmpdir, code) as filepath: 388 formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') 389 self.assertCodeEqual(code, formatted_code) 390 391 392class CommandLineTest(yapf_test_helper.YAPFTest): 393 """Test how calling yapf from the command line acts.""" 394 395 @classmethod 396 def setUpClass(cls): # pylint: disable=g-missing-super-call 397 cls.test_tmpdir = tempfile.mkdtemp() 398 399 @classmethod 400 def tearDownClass(cls): # pylint: disable=g-missing-super-call 401 shutil.rmtree(cls.test_tmpdir) 402 403 def assertYapfReformats(self, 404 unformatted, 405 expected, 406 extra_options=None, 407 env=None): 408 """Check that yapf reformats the given code as expected. 409 410 Invokes yapf in a subprocess, piping the unformatted code into its stdin. 411 Checks that the formatted output is as expected. 412 413 Arguments: 414 unformatted: unformatted code - input to yapf 415 expected: expected formatted code at the output of yapf 416 extra_options: iterable of extra command-line options to pass to yapf 417 env: dict of environment variables. 418 """ 419 cmdline = YAPF_BINARY + (extra_options or []) 420 p = subprocess.Popen( 421 cmdline, 422 stdout=subprocess.PIPE, 423 stdin=subprocess.PIPE, 424 stderr=subprocess.PIPE, 425 env=env) 426 reformatted_code, stderrdata = p.communicate( 427 unformatted.encode('utf-8-sig')) 428 self.assertEqual(stderrdata, b'') 429 self.assertMultiLineEqual(reformatted_code.decode('utf-8'), expected) 430 431 def testInPlaceReformatting(self): 432 unformatted_code = textwrap.dedent("""\ 433 def foo(): 434 x = 37 435 """) 436 expected_formatted_code = textwrap.dedent("""\ 437 def foo(): 438 x = 37 439 """) 440 with utils.TempFileContents( 441 self.test_tmpdir, unformatted_code, suffix='.py') as filepath: 442 p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) 443 p.wait() 444 with io.open(filepath, mode='r', newline='') as fd: 445 reformatted_code = fd.read() 446 self.assertEqual(reformatted_code, expected_formatted_code) 447 448 def testInPlaceReformattingBlank(self): 449 unformatted_code = '\n\n' 450 expected_formatted_code = '\n' 451 with utils.TempFileContents( 452 self.test_tmpdir, unformatted_code, suffix='.py') as filepath: 453 p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) 454 p.wait() 455 with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd: 456 reformatted_code = fd.read() 457 self.assertEqual(reformatted_code, expected_formatted_code) 458 459 def testInPlaceReformattingWindowsNewLine(self): 460 unformatted_code = '\r\n\r\n' 461 expected_formatted_code = '\r\n' 462 with utils.TempFileContents( 463 self.test_tmpdir, unformatted_code, suffix='.py') as filepath: 464 p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) 465 p.wait() 466 with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd: 467 reformatted_code = fd.read() 468 self.assertEqual(reformatted_code, expected_formatted_code) 469 470 def testInPlaceReformattingNoNewLine(self): 471 unformatted_code = textwrap.dedent('def foo(): x = 37') 472 expected_formatted_code = textwrap.dedent("""\ 473 def foo(): 474 x = 37 475 """) 476 with utils.TempFileContents( 477 self.test_tmpdir, unformatted_code, suffix='.py') as filepath: 478 p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) 479 p.wait() 480 with io.open(filepath, mode='r', newline='') as fd: 481 reformatted_code = fd.read() 482 self.assertEqual(reformatted_code, expected_formatted_code) 483 484 def testInPlaceReformattingEmpty(self): 485 unformatted_code = '' 486 expected_formatted_code = '' 487 with utils.TempFileContents( 488 self.test_tmpdir, unformatted_code, suffix='.py') as filepath: 489 p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) 490 p.wait() 491 with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd: 492 reformatted_code = fd.read() 493 self.assertEqual(reformatted_code, expected_formatted_code) 494 495 def testPrintModified(self): 496 for unformatted_code, has_change in [('1==2', True), ('1 == 2', False)]: 497 with utils.TempFileContents( 498 self.test_tmpdir, unformatted_code, suffix='.py') as filepath: 499 output = subprocess.check_output( 500 YAPF_BINARY + ['--in-place', '--print-modified', filepath], 501 text=True) 502 check = self.assertIn if has_change else self.assertNotIn 503 check(f'Formatted {filepath}', output) 504 505 def testReadFromStdin(self): 506 unformatted_code = textwrap.dedent("""\ 507 def foo(): 508 x = 37 509 """) 510 expected_formatted_code = textwrap.dedent("""\ 511 def foo(): 512 x = 37 513 """) 514 self.assertYapfReformats(unformatted_code, expected_formatted_code) 515 516 def testReadFromStdinWithEscapedStrings(self): 517 unformatted_code = textwrap.dedent("""\ 518 s = "foo\\nbar" 519 """) 520 expected_formatted_code = textwrap.dedent("""\ 521 s = "foo\\nbar" 522 """) 523 self.assertYapfReformats(unformatted_code, expected_formatted_code) 524 525 def testSetYapfStyle(self): 526 unformatted_code = textwrap.dedent("""\ 527 def foo(): # trail 528 x = 37 529 """) 530 expected_formatted_code = textwrap.dedent("""\ 531 def foo(): # trail 532 x = 37 533 """) 534 self.assertYapfReformats( 535 unformatted_code, 536 expected_formatted_code, 537 extra_options=['--style=yapf']) 538 539 def testSetCustomStyleBasedOnYapf(self): 540 unformatted_code = textwrap.dedent("""\ 541 def foo(): # trail 542 x = 37 543 """) 544 expected_formatted_code = textwrap.dedent("""\ 545 def foo(): # trail 546 x = 37 547 """) 548 style_file = textwrap.dedent("""\ 549 [style] 550 based_on_style = yapf 551 spaces_before_comment = 4 552 """) 553 with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath: 554 self.assertYapfReformats( 555 unformatted_code, 556 expected_formatted_code, 557 extra_options=['--style={0}'.format(stylepath)]) 558 559 def testSetCustomStyleSpacesBeforeComment(self): 560 unformatted_code = textwrap.dedent("""\ 561 a_very_long_statement_that_extends_way_beyond # Comment 562 short # This is a shorter statement 563 """) 564 expected_formatted_code = textwrap.dedent("""\ 565 a_very_long_statement_that_extends_way_beyond # Comment 566 short # This is a shorter statement 567 """) # noqa 568 style_file = textwrap.dedent("""\ 569 [style] 570 spaces_before_comment = 15, 20 571 """) 572 with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath: 573 self.assertYapfReformats( 574 unformatted_code, 575 expected_formatted_code, 576 extra_options=['--style={0}'.format(stylepath)]) 577 578 def testReadSingleLineCodeFromStdin(self): 579 unformatted_code = textwrap.dedent("""\ 580 if True: pass 581 """) 582 expected_formatted_code = textwrap.dedent("""\ 583 if True: pass 584 """) 585 self.assertYapfReformats(unformatted_code, expected_formatted_code) 586 587 def testEncodingVerification(self): 588 unformatted_code = textwrap.dedent("""\ 589 '''The module docstring.''' 590 # -*- coding: utf-8 -*- 591 def f(): 592 x = 37 593 """) 594 595 with utils.NamedTempFile( 596 suffix='.py', dirname=self.test_tmpdir) as (out, _): 597 with utils.TempFileContents( 598 self.test_tmpdir, unformatted_code, suffix='.py') as filepath: 599 try: 600 subprocess.check_call(YAPF_BINARY + ['--diff', filepath], stdout=out) 601 except subprocess.CalledProcessError as e: 602 # Indicates the text changed. 603 self.assertEqual(e.returncode, 1) # pylint: disable=g-assert-in-except # noqa 604 605 def testReformattingSpecificLines(self): 606 unformatted_code = textwrap.dedent("""\ 607 def h(): 608 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 609 pass 610 611 612 def g(): 613 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 614 pass 615 """) # noqa 616 expected_formatted_code = textwrap.dedent("""\ 617 def h(): 618 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and 619 xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 620 pass 621 622 623 def g(): 624 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 625 pass 626 """) # noqa 627 # TODO(ambv): the `expected_formatted_code` here is not PEP8 compliant, 628 # raising "E129 visually indented line with same indent as next logical 629 # line" with flake8. 630 self.assertYapfReformats( 631 unformatted_code, 632 expected_formatted_code, 633 extra_options=['--lines', '1-2']) 634 635 def testOmitFormattingLinesBeforeDisabledFunctionComment(self): 636 unformatted_code = textwrap.dedent("""\ 637 import sys 638 639 # Comment 640 def some_func(x): 641 x = ["badly" , "formatted","line" ] 642 """) 643 expected_formatted_code = textwrap.dedent("""\ 644 import sys 645 646 # Comment 647 def some_func(x): 648 x = ["badly", "formatted", "line"] 649 """) 650 self.assertYapfReformats( 651 unformatted_code, 652 expected_formatted_code, 653 extra_options=['--lines', '5-5']) 654 655 def testReformattingSkippingLines(self): 656 unformatted_code = textwrap.dedent("""\ 657 def h(): 658 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 659 pass 660 661 # yapf: disable 662 def g(): 663 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 664 pass 665 # yapf: enable 666 """) # noqa 667 expected_formatted_code = textwrap.dedent("""\ 668 def h(): 669 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and 670 xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 671 pass 672 673 674 # yapf: disable 675 def g(): 676 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 677 pass 678 # yapf: enable 679 """) # noqa 680 self.assertYapfReformats(unformatted_code, expected_formatted_code) 681 682 def testReformattingSkippingToEndOfFile(self): 683 unformatted_code = textwrap.dedent("""\ 684 def h(): 685 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 686 pass 687 688 # yapf: disable 689 def g(): 690 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 691 pass 692 693 def f(): 694 def e(): 695 while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and 696 xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 697 'bbbbbbb'): 698 pass 699 """) # noqa 700 expected_formatted_code = textwrap.dedent("""\ 701 def h(): 702 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and 703 xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 704 pass 705 706 707 # yapf: disable 708 def g(): 709 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 710 pass 711 712 def f(): 713 def e(): 714 while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and 715 xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 716 'bbbbbbb'): 717 pass 718 """) # noqa 719 self.assertYapfReformats(unformatted_code, expected_formatted_code) 720 721 def testReformattingSkippingSingleLine(self): 722 unformatted_code = textwrap.dedent("""\ 723 def h(): 724 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 725 pass 726 727 def g(): 728 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable 729 pass 730 """) # noqa 731 expected_formatted_code = textwrap.dedent("""\ 732 def h(): 733 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and 734 xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 735 pass 736 737 738 def g(): 739 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable 740 pass 741 """) # noqa 742 self.assertYapfReformats(unformatted_code, expected_formatted_code) 743 744 def testDisableWholeDataStructure(self): 745 unformatted_code = textwrap.dedent("""\ 746 A = set([ 747 'hello', 748 'world', 749 ]) # yapf: disable 750 """) 751 expected_formatted_code = textwrap.dedent("""\ 752 A = set([ 753 'hello', 754 'world', 755 ]) # yapf: disable 756 """) 757 self.assertYapfReformats(unformatted_code, expected_formatted_code) 758 759 def testDisableButAdjustIndentations(self): 760 unformatted_code = textwrap.dedent("""\ 761 class SplitPenaltyTest(unittest.TestCase): 762 763 def testUnbreakable(self): 764 self._CheckPenalties(tree, [ 765 ]) # yapf: disable 766 """) 767 expected_formatted_code = textwrap.dedent("""\ 768 class SplitPenaltyTest(unittest.TestCase): 769 770 def testUnbreakable(self): 771 self._CheckPenalties(tree, [ 772 ]) # yapf: disable 773 """) 774 self.assertYapfReformats(unformatted_code, expected_formatted_code) 775 776 def testRetainingHorizontalWhitespace(self): 777 unformatted_code = textwrap.dedent("""\ 778 def h(): 779 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 780 pass 781 782 def g(): 783 if (xxxxxxxxxxxx.yyyyyyyy (zzzzzzzzzzzzz [0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable 784 pass 785 """) # noqa 786 expected_formatted_code = textwrap.dedent("""\ 787 def h(): 788 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and 789 xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 790 pass 791 792 793 def g(): 794 if (xxxxxxxxxxxx.yyyyyyyy (zzzzzzzzzzzzz [0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable 795 pass 796 """) # noqa 797 self.assertYapfReformats(unformatted_code, expected_formatted_code) 798 799 def testRetainingVerticalWhitespace(self): 800 unformatted_code = textwrap.dedent("""\ 801 def h(): 802 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 803 pass 804 805 def g(): 806 807 808 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 809 810 pass 811 """) # noqa 812 expected_formatted_code = textwrap.dedent("""\ 813 def h(): 814 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and 815 xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 816 pass 817 818 def g(): 819 820 821 if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): 822 823 pass 824 """) # noqa 825 self.assertYapfReformats( 826 unformatted_code, 827 expected_formatted_code, 828 extra_options=['--lines', '1-2']) 829 830 unformatted_code = textwrap.dedent("""\ 831 832 833 if a: b 834 835 836 if c: 837 to_much + indent 838 839 same 840 841 842 843 #comment 844 845 # trailing whitespace 846 """) 847 expected_formatted_code = textwrap.dedent("""\ 848 if a: b 849 850 851 if c: 852 to_much + indent 853 854 same 855 856 857 858 #comment 859 860 # trailing whitespace 861 """) 862 self.assertYapfReformats( 863 unformatted_code, 864 expected_formatted_code, 865 extra_options=['--lines', '3-3', '--lines', '13-13']) 866 867 unformatted_code = textwrap.dedent("""\ 868 ''' 869 docstring 870 871 ''' 872 873 import blah 874 """) 875 876 self.assertYapfReformats( 877 unformatted_code, unformatted_code, extra_options=['--lines', '2-2']) 878 879 def testVerticalSpacingWithCommentWithContinuationMarkers(self): 880 unformatted_code = textwrap.dedent("""\ 881 # \\ 882 # \\ 883 # \\ 884 885 x = { 886 } 887 """) 888 expected_formatted_code = textwrap.dedent("""\ 889 # \\ 890 # \\ 891 # \\ 892 893 x = { 894 } 895 """) 896 self.assertYapfReformats( 897 unformatted_code, 898 expected_formatted_code, 899 extra_options=['--lines', '1-1']) 900 901 def testRetainingSemicolonsWhenSpecifyingLines(self): 902 unformatted_code = textwrap.dedent("""\ 903 a = line_to_format 904 def f(): 905 x = y + 42; z = n * 42 906 if True: a += 1 ; b += 1 ; c += 1 907 """) 908 expected_formatted_code = textwrap.dedent("""\ 909 a = line_to_format 910 def f(): 911 x = y + 42; z = n * 42 912 if True: a += 1 ; b += 1 ; c += 1 913 """) 914 self.assertYapfReformats( 915 unformatted_code, 916 expected_formatted_code, 917 extra_options=['--lines', '1-1']) 918 919 def testDisabledMultilineStrings(self): 920 unformatted_code = textwrap.dedent('''\ 921 foo=42 922 def f(): 923 email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br> 924 <b>Czar: </b>"""+despot["Nicholas"]+"""<br> 925 <b>Minion: </b>"""+serf["Dmitri"]+"""<br> 926 <b>Residence: </b>"""+palace["Winter"]+"""<br> 927 </body> 928 </html>""" 929 ''') # noqa 930 expected_formatted_code = textwrap.dedent('''\ 931 foo = 42 932 def f(): 933 email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br> 934 <b>Czar: </b>"""+despot["Nicholas"]+"""<br> 935 <b>Minion: </b>"""+serf["Dmitri"]+"""<br> 936 <b>Residence: </b>"""+palace["Winter"]+"""<br> 937 </body> 938 </html>""" 939 ''') # noqa 940 self.assertYapfReformats( 941 unformatted_code, 942 expected_formatted_code, 943 extra_options=['--lines', '1-1']) 944 945 def testDisableWhenSpecifyingLines(self): 946 unformatted_code = textwrap.dedent("""\ 947 # yapf: disable 948 A = set([ 949 'hello', 950 'world', 951 ]) 952 # yapf: enable 953 B = set([ 954 'hello', 955 'world', 956 ]) # yapf: disable 957 """) 958 expected_formatted_code = textwrap.dedent("""\ 959 # yapf: disable 960 A = set([ 961 'hello', 962 'world', 963 ]) 964 # yapf: enable 965 B = set([ 966 'hello', 967 'world', 968 ]) # yapf: disable 969 """) 970 self.assertYapfReformats( 971 unformatted_code, 972 expected_formatted_code, 973 extra_options=['--lines', '1-10']) 974 975 def testDisableFormattingInDataLiteral(self): 976 unformatted_code = textwrap.dedent("""\ 977 def horrible(): 978 oh_god() 979 why_would_you() 980 [ 981 'do', 982 983 'that', 984 ] 985 986 def still_horrible(): 987 oh_god() 988 why_would_you() 989 [ 990 'do', 991 992 'that' 993 ] 994 """) 995 expected_formatted_code = textwrap.dedent("""\ 996 def horrible(): 997 oh_god() 998 why_would_you() 999 [ 1000 'do', 1001 1002 'that', 1003 ] 1004 1005 def still_horrible(): 1006 oh_god() 1007 why_would_you() 1008 ['do', 'that'] 1009 """) 1010 self.assertYapfReformats( 1011 unformatted_code, 1012 expected_formatted_code, 1013 extra_options=['--lines', '14-15']) 1014 1015 def testRetainVerticalFormattingBetweenDisabledAndEnabledLines(self): 1016 unformatted_code = textwrap.dedent("""\ 1017 class A(object): 1018 def aaaaaaaaaaaaa(self): 1019 c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) 1020 self.assertEqual( 1021 ('ddddddddddddddddddddddddd', 1022 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % 1023 c.ffffffffffff), 1024 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) 1025 iiiii = jjjjjjjjjjjjjj.iiiii 1026 """) 1027 expected_formatted_code = textwrap.dedent("""\ 1028 class A(object): 1029 def aaaaaaaaaaaaa(self): 1030 c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) 1031 self.assertEqual(('ddddddddddddddddddddddddd', 1032 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff), 1033 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) 1034 iiiii = jjjjjjjjjjjjjj.iiiii 1035 """) # noqa 1036 self.assertYapfReformats( 1037 unformatted_code, 1038 expected_formatted_code, 1039 extra_options=['--lines', '4-7']) 1040 1041 def testRetainVerticalFormattingBetweenDisabledLines(self): 1042 unformatted_code = textwrap.dedent("""\ 1043 class A(object): 1044 def aaaaaaaaaaaaa(self): 1045 pass 1046 1047 1048 def bbbbbbbbbbbbb(self): # 5 1049 pass 1050 """) 1051 expected_formatted_code = textwrap.dedent("""\ 1052 class A(object): 1053 def aaaaaaaaaaaaa(self): 1054 pass 1055 1056 1057 def bbbbbbbbbbbbb(self): # 5 1058 pass 1059 """) 1060 self.assertYapfReformats( 1061 unformatted_code, 1062 expected_formatted_code, 1063 extra_options=['--lines', '4-4']) 1064 1065 def testFormatLinesSpecifiedInMiddleOfExpression(self): 1066 unformatted_code = textwrap.dedent("""\ 1067 class A(object): 1068 def aaaaaaaaaaaaa(self): 1069 c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) 1070 self.assertEqual( 1071 ('ddddddddddddddddddddddddd', 1072 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % 1073 c.ffffffffffff), 1074 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) 1075 iiiii = jjjjjjjjjjjjjj.iiiii 1076 """) 1077 expected_formatted_code = textwrap.dedent("""\ 1078 class A(object): 1079 def aaaaaaaaaaaaa(self): 1080 c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) 1081 self.assertEqual(('ddddddddddddddddddddddddd', 1082 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff), 1083 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) 1084 iiiii = jjjjjjjjjjjjjj.iiiii 1085 """) # noqa 1086 self.assertYapfReformats( 1087 unformatted_code, 1088 expected_formatted_code, 1089 extra_options=['--lines', '5-6']) 1090 1091 def testCommentFollowingMultilineString(self): 1092 unformatted_code = textwrap.dedent("""\ 1093 def foo(): 1094 '''First line. 1095 Second line. 1096 ''' # comment 1097 x = '''hello world''' # second comment 1098 return 42 # another comment 1099 """) 1100 expected_formatted_code = textwrap.dedent("""\ 1101 def foo(): 1102 '''First line. 1103 Second line. 1104 ''' # comment 1105 x = '''hello world''' # second comment 1106 return 42 # another comment 1107 """) 1108 self.assertYapfReformats( 1109 unformatted_code, 1110 expected_formatted_code, 1111 extra_options=['--lines', '1-1']) 1112 1113 def testDedentClosingBracket(self): 1114 # no line-break on the first argument, not dedenting closing brackets 1115 unformatted_code = textwrap.dedent("""\ 1116 def overly_long_function_name(first_argument_on_the_same_line, 1117 second_argument_makes_the_line_too_long): 1118 pass 1119 """) 1120 expected_formatted_code = textwrap.dedent("""\ 1121 def overly_long_function_name(first_argument_on_the_same_line, 1122 second_argument_makes_the_line_too_long): 1123 pass 1124 """) # noqa 1125 self.assertYapfReformats( 1126 unformatted_code, 1127 expected_formatted_code, 1128 extra_options=['--style=pep8']) 1129 1130 # TODO(ambv): currently the following produces the closing bracket on a new 1131 # line but indented to the opening bracket which is the worst of both 1132 # worlds. Expected behaviour would be to format as --style=pep8 does in 1133 # this case. 1134 # self.assertYapfReformats(unformatted_code, expected_formatted_code, 1135 # extra_options=['--style=facebook']) 1136 1137 # line-break before the first argument, dedenting closing brackets if set 1138 unformatted_code = textwrap.dedent("""\ 1139 def overly_long_function_name( 1140 first_argument_on_the_same_line, 1141 second_argument_makes_the_line_too_long): 1142 pass 1143 """) 1144 # expected_formatted_pep8_code = textwrap.dedent("""\ 1145 # def overly_long_function_name( 1146 # first_argument_on_the_same_line, 1147 # second_argument_makes_the_line_too_long): 1148 # pass 1149 # """) 1150 expected_formatted_fb_code = textwrap.dedent("""\ 1151 def overly_long_function_name( 1152 first_argument_on_the_same_line, second_argument_makes_the_line_too_long 1153 ): 1154 pass 1155 """) # noqa 1156 self.assertYapfReformats( 1157 unformatted_code, 1158 expected_formatted_fb_code, 1159 extra_options=['--style=facebook']) 1160 # TODO(ambv): currently the following produces code that is not PEP8 1161 # compliant, raising "E125 continuation line with same indent as next 1162 # logical line" with flake8. Expected behaviour for PEP8 would be to use 1163 # double-indentation here. 1164 # self.assertYapfReformats(unformatted_code, expected_formatted_pep8_code, 1165 # extra_options=['--style=pep8']) 1166 1167 def testCoalesceBrackets(self): 1168 unformatted_code = textwrap.dedent("""\ 1169 some_long_function_name_foo( 1170 { 1171 'first_argument_of_the_thing': id, 1172 'second_argument_of_the_thing': "some thing" 1173 } 1174 ) 1175 """) 1176 expected_formatted_code = textwrap.dedent("""\ 1177 some_long_function_name_foo({ 1178 'first_argument_of_the_thing': id, 1179 'second_argument_of_the_thing': "some thing" 1180 }) 1181 """) 1182 with utils.NamedTempFile(dirname=self.test_tmpdir, mode='w') as (f, name): 1183 f.write( 1184 textwrap.dedent("""\ 1185 [style] 1186 column_limit=82 1187 coalesce_brackets = True 1188 """)) 1189 f.flush() 1190 self.assertYapfReformats( 1191 unformatted_code, 1192 expected_formatted_code, 1193 extra_options=['--style={0}'.format(name)]) 1194 1195 def testPseudoParenSpaces(self): 1196 unformatted_code = textwrap.dedent("""\ 1197 def foo(): 1198 def bar(): 1199 return {msg_id: author for author, msg_id in reader} 1200 """) 1201 expected_formatted_code = textwrap.dedent("""\ 1202 def foo(): 1203 def bar(): 1204 return {msg_id: author for author, msg_id in reader} 1205 """) 1206 self.assertYapfReformats( 1207 unformatted_code, 1208 expected_formatted_code, 1209 extra_options=['--lines', '1-1', '--style', 'yapf']) 1210 1211 def testMultilineCommentFormattingDisabled(self): 1212 unformatted_code = textwrap.dedent("""\ 1213 # This is a comment 1214 FOO = { 1215 aaaaaaaa.ZZZ: [ 1216 bbbbbbbbbb.Pop(), 1217 # Multiline comment. 1218 # Line two. 1219 bbbbbbbbbb.Pop(), 1220 ], 1221 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': 1222 ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz), 1223 '#': lambda x: x # do nothing 1224 } 1225 """) 1226 expected_formatted_code = textwrap.dedent("""\ 1227 # This is a comment 1228 FOO = { 1229 aaaaaaaa.ZZZ: [ 1230 bbbbbbbbbb.Pop(), 1231 # Multiline comment. 1232 # Line two. 1233 bbbbbbbbbb.Pop(), 1234 ], 1235 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': 1236 ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz), 1237 '#': lambda x: x # do nothing 1238 } 1239 """) 1240 self.assertYapfReformats( 1241 unformatted_code, 1242 expected_formatted_code, 1243 extra_options=['--lines', '1-1', '--style', 'yapf']) 1244 1245 def testTrailingCommentsWithDisabledFormatting(self): 1246 unformatted_code = textwrap.dedent("""\ 1247 import os 1248 1249 SCOPES = [ 1250 'hello world' # This is a comment. 1251 ] 1252 """) 1253 expected_formatted_code = textwrap.dedent("""\ 1254 import os 1255 1256 SCOPES = [ 1257 'hello world' # This is a comment. 1258 ] 1259 """) 1260 self.assertYapfReformats( 1261 unformatted_code, 1262 expected_formatted_code, 1263 extra_options=['--lines', '1-1', '--style', 'yapf']) 1264 1265 def testUseTabs(self): 1266 unformatted_code = textwrap.dedent("""\ 1267 def foo_function(): 1268 if True: 1269 pass 1270 """) 1271 expected_formatted_code = """\ 1272def foo_function(): 1273 if True: 1274 pass 1275""" # noqa: W191,E101 1276 style_contents = textwrap.dedent("""\ 1277 [style] 1278 based_on_style = yapf 1279 use_tabs = true 1280 indent_width = 1 1281 """) 1282 with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: 1283 self.assertYapfReformats( 1284 unformatted_code, 1285 expected_formatted_code, 1286 extra_options=['--style={0}'.format(stylepath)]) 1287 1288 def testUseTabsWith(self): 1289 unformatted_code = """\ 1290def f(): 1291 return ['hello', 'world',] 1292""" 1293 expected_formatted_code = """\ 1294def f(): 1295 return [ 1296 'hello', 1297 'world', 1298 ] 1299""" # noqa: W191,E101 1300 style_contents = textwrap.dedent("""\ 1301 [style] 1302 based_on_style = yapf 1303 use_tabs = true 1304 indent_width = 1 1305 """) 1306 with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: 1307 self.assertYapfReformats( 1308 unformatted_code, 1309 expected_formatted_code, 1310 extra_options=['--style={0}'.format(stylepath)]) 1311 1312 def testUseTabsContinuationAlignStyleFixed(self): 1313 unformatted_code = """\ 1314def foo_function(arg1, arg2, arg3): 1315 return ['hello', 'world',] 1316""" 1317 expected_formatted_code = """\ 1318def foo_function( 1319 arg1, arg2, arg3): 1320 return [ 1321 'hello', 1322 'world', 1323 ] 1324""" # noqa: W191,E101 1325 style_contents = textwrap.dedent("""\ 1326 [style] 1327 based_on_style = yapf 1328 use_tabs = true 1329 column_limit=32 1330 indent_width=4 1331 continuation_indent_width=8 1332 continuation_align_style = fixed 1333 """) 1334 with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: 1335 self.assertYapfReformats( 1336 unformatted_code, 1337 expected_formatted_code, 1338 extra_options=['--style={0}'.format(stylepath)]) 1339 1340 def testUseTabsContinuationAlignStyleVAlignRight(self): 1341 unformatted_code = """\ 1342def foo_function(arg1, arg2, arg3): 1343 return ['hello', 'world',] 1344""" 1345 expected_formatted_code = """\ 1346def foo_function(arg1, arg2, 1347 arg3): 1348 return [ 1349 'hello', 1350 'world', 1351 ] 1352""" # noqa: W191,E101 1353 style_contents = textwrap.dedent("""\ 1354 [style] 1355 based_on_style = yapf 1356 use_tabs = true 1357 column_limit = 32 1358 indent_width = 4 1359 continuation_indent_width = 8 1360 continuation_align_style = valign-right 1361 """) 1362 with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: 1363 self.assertYapfReformats( 1364 unformatted_code, 1365 expected_formatted_code, 1366 extra_options=['--style={0}'.format(stylepath)]) 1367 1368 def testUseSpacesContinuationAlignStyleFixed(self): 1369 unformatted_code = textwrap.dedent("""\ 1370 def foo_function(arg1, arg2, arg3): 1371 return ['hello', 'world',] 1372 """) 1373 expected_formatted_code = textwrap.dedent("""\ 1374 def foo_function( 1375 arg1, arg2, arg3): 1376 return [ 1377 'hello', 1378 'world', 1379 ] 1380 """) 1381 style_contents = textwrap.dedent("""\ 1382 [style] 1383 based_on_style = yapf 1384 column_limit = 32 1385 indent_width = 4 1386 continuation_indent_width = 8 1387 continuation_align_style = fixed 1388 """) 1389 with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: 1390 self.assertYapfReformats( 1391 unformatted_code, 1392 expected_formatted_code, 1393 extra_options=['--style={0}'.format(stylepath)]) 1394 1395 def testUseSpacesContinuationAlignStyleVAlignRight(self): 1396 unformatted_code = textwrap.dedent("""\ 1397 def foo_function(arg1, arg2, arg3): 1398 return ['hello', 'world',] 1399 """) 1400 expected_formatted_code = textwrap.dedent("""\ 1401 def foo_function(arg1, arg2, 1402 arg3): 1403 return [ 1404 'hello', 1405 'world', 1406 ] 1407 """) 1408 style_contents = textwrap.dedent("""\ 1409 [style] 1410 based_on_style = yapf 1411 column_limit = 32 1412 indent_width = 4 1413 continuation_indent_width = 8 1414 continuation_align_style = valign-right 1415 """) 1416 with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: 1417 self.assertYapfReformats( 1418 unformatted_code, 1419 expected_formatted_code, 1420 extra_options=['--style={0}'.format(stylepath)]) 1421 1422 def testStyleOutputRoundTrip(self): 1423 unformatted_code = textwrap.dedent("""\ 1424 def foo_function(): 1425 pass 1426 """) 1427 expected_formatted_code = textwrap.dedent("""\ 1428 def foo_function(): 1429 pass 1430 """) 1431 1432 with utils.NamedTempFile(dirname=self.test_tmpdir) as (stylefile, 1433 stylepath): 1434 p = subprocess.Popen( 1435 YAPF_BINARY + ['--style-help'], 1436 stdout=stylefile, 1437 stdin=subprocess.PIPE, 1438 stderr=subprocess.PIPE) 1439 _, stderrdata = p.communicate() 1440 self.assertEqual(stderrdata, b'') 1441 self.assertYapfReformats( 1442 unformatted_code, 1443 expected_formatted_code, 1444 extra_options=['--style={0}'.format(stylepath)]) 1445 1446 def testSpacingBeforeComments(self): 1447 unformatted_code = textwrap.dedent("""\ 1448 A = 42 1449 1450 1451 # A comment 1452 def x(): 1453 pass 1454 def _(): 1455 pass 1456 """) 1457 expected_formatted_code = textwrap.dedent("""\ 1458 A = 42 1459 1460 1461 # A comment 1462 def x(): 1463 pass 1464 def _(): 1465 pass 1466 """) 1467 self.assertYapfReformats( 1468 unformatted_code, 1469 expected_formatted_code, 1470 extra_options=['--lines', '1-2']) 1471 1472 def testSpacingBeforeCommentsInDicts(self): 1473 unformatted_code = textwrap.dedent("""\ 1474 A=42 1475 1476 X = { 1477 # 'Valid' statuses. 1478 PASSED: # Passed 1479 'PASSED', 1480 FAILED: # Failed 1481 'FAILED', 1482 TIMED_OUT: # Timed out. 1483 'FAILED', 1484 BORKED: # Broken. 1485 'BROKEN' 1486 } 1487 """) 1488 expected_formatted_code = textwrap.dedent("""\ 1489 A = 42 1490 1491 X = { 1492 # 'Valid' statuses. 1493 PASSED: # Passed 1494 'PASSED', 1495 FAILED: # Failed 1496 'FAILED', 1497 TIMED_OUT: # Timed out. 1498 'FAILED', 1499 BORKED: # Broken. 1500 'BROKEN' 1501 } 1502 """) 1503 self.assertYapfReformats( 1504 unformatted_code, 1505 expected_formatted_code, 1506 extra_options=['--style', 'yapf', '--lines', '1-1']) 1507 1508 def testDisableWithLinesOption(self): 1509 unformatted_code = textwrap.dedent("""\ 1510 # yapf_lines_bug.py 1511 # yapf: disable 1512 def outer_func(): 1513 def inner_func(): 1514 return 1515 return 1516 # yapf: enable 1517 """) 1518 expected_formatted_code = textwrap.dedent("""\ 1519 # yapf_lines_bug.py 1520 # yapf: disable 1521 def outer_func(): 1522 def inner_func(): 1523 return 1524 return 1525 # yapf: enable 1526 """) 1527 self.assertYapfReformats( 1528 unformatted_code, 1529 expected_formatted_code, 1530 extra_options=['--lines', '1-8']) 1531 1532 def testDisableWithLineRanges(self): 1533 unformatted_code = textwrap.dedent("""\ 1534 # yapf: disable 1535 a = [ 1536 1, 1537 2, 1538 1539 3 1540 ] 1541 """) 1542 expected_formatted_code = textwrap.dedent("""\ 1543 # yapf: disable 1544 a = [ 1545 1, 1546 2, 1547 1548 3 1549 ] 1550 """) 1551 self.assertYapfReformats( 1552 unformatted_code, 1553 expected_formatted_code, 1554 extra_options=['--style', 'yapf', '--lines', '1-100']) 1555 1556 1557class BadInputTest(yapf_test_helper.YAPFTest): 1558 """Test yapf's behaviour when passed bad input.""" 1559 1560 def testBadSyntax(self): 1561 code = ' a = 1\n' 1562 self.assertRaises(errors.YapfError, yapf_api.FormatCode, code) 1563 1564 def testBadCode(self): 1565 code = 'x = """hello\n' 1566 self.assertRaises(errors.YapfError, yapf_api.FormatCode, code) 1567 1568 1569class DiffIndentTest(yapf_test_helper.YAPFTest): 1570 1571 @staticmethod 1572 def _OwnStyle(): 1573 my_style = style.CreatePEP8Style() 1574 my_style['INDENT_WIDTH'] = 3 1575 my_style['CONTINUATION_INDENT_WIDTH'] = 3 1576 return my_style 1577 1578 def _Check(self, unformatted_code, expected_formatted_code): 1579 formatted_code, _ = yapf_api.FormatCode( 1580 unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle())) 1581 self.assertEqual(expected_formatted_code, formatted_code) 1582 1583 def testSimple(self): 1584 unformatted_code = textwrap.dedent("""\ 1585 for i in range(5): 1586 print('bar') 1587 """) 1588 expected_formatted_code = textwrap.dedent("""\ 1589 for i in range(5): 1590 print('bar') 1591 """) 1592 self._Check(unformatted_code, expected_formatted_code) 1593 1594 1595class HorizontallyAlignedTrailingCommentsTest(yapf_test_helper.YAPFTest): 1596 1597 @staticmethod 1598 def _OwnStyle(): 1599 my_style = style.CreatePEP8Style() 1600 my_style['SPACES_BEFORE_COMMENT'] = [ 1601 15, 1602 25, 1603 35, 1604 ] 1605 return my_style 1606 1607 def _Check(self, unformatted_code, expected_formatted_code): 1608 formatted_code, _ = yapf_api.FormatCode( 1609 unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle())) 1610 self.assertCodeEqual(expected_formatted_code, formatted_code) 1611 1612 def testSimple(self): 1613 unformatted_code = textwrap.dedent("""\ 1614 foo = '1' # Aligned at first list value 1615 1616 foo = '2__<15>' # Aligned at second list value 1617 1618 foo = '3____________<25>' # Aligned at third list value 1619 1620 foo = '4______________________<35>' # Aligned beyond list values 1621 """) 1622 expected_formatted_code = textwrap.dedent("""\ 1623 foo = '1' # Aligned at first list value 1624 1625 foo = '2__<15>' # Aligned at second list value 1626 1627 foo = '3____________<25>' # Aligned at third list value 1628 1629 foo = '4______________________<35>' # Aligned beyond list values 1630 """) 1631 self._Check(unformatted_code, expected_formatted_code) 1632 1633 def testBlock(self): 1634 unformatted_code = textwrap.dedent("""\ 1635 func(1) # Line 1 1636 func(2) # Line 2 1637 # Line 3 1638 func(3) # Line 4 1639 # Line 5 1640 # Line 6 1641 """) 1642 expected_formatted_code = textwrap.dedent("""\ 1643 func(1) # Line 1 1644 func(2) # Line 2 1645 # Line 3 1646 func(3) # Line 4 1647 # Line 5 1648 # Line 6 1649 """) 1650 self._Check(unformatted_code, expected_formatted_code) 1651 1652 def testBlockWithLongLine(self): 1653 unformatted_code = textwrap.dedent("""\ 1654 func(1) # Line 1 1655 func___________________(2) # Line 2 1656 # Line 3 1657 func(3) # Line 4 1658 # Line 5 1659 # Line 6 1660 """) 1661 expected_formatted_code = textwrap.dedent("""\ 1662 func(1) # Line 1 1663 func___________________(2) # Line 2 1664 # Line 3 1665 func(3) # Line 4 1666 # Line 5 1667 # Line 6 1668 """) 1669 self._Check(unformatted_code, expected_formatted_code) 1670 1671 def testBlockFuncSuffix(self): 1672 unformatted_code = textwrap.dedent("""\ 1673 func(1) # Line 1 1674 func(2) # Line 2 1675 # Line 3 1676 func(3) # Line 4 1677 # Line 5 1678 # Line 6 1679 1680 def Func(): 1681 pass 1682 """) 1683 expected_formatted_code = textwrap.dedent("""\ 1684 func(1) # Line 1 1685 func(2) # Line 2 1686 # Line 3 1687 func(3) # Line 4 1688 # Line 5 1689 # Line 6 1690 1691 1692 def Func(): 1693 pass 1694 """) 1695 self._Check(unformatted_code, expected_formatted_code) 1696 1697 def testBlockCommentSuffix(self): 1698 unformatted_code = textwrap.dedent("""\ 1699 func(1) # Line 1 1700 func(2) # Line 2 1701 # Line 3 1702 func(3) # Line 4 1703 # Line 5 - SpliceComments makes this part of the previous block 1704 # Line 6 1705 1706 # Aligned with prev comment block 1707 """) # noqa 1708 expected_formatted_code = textwrap.dedent("""\ 1709 func(1) # Line 1 1710 func(2) # Line 2 1711 # Line 3 1712 func(3) # Line 4 1713 # Line 5 - SpliceComments makes this part of the previous block 1714 # Line 6 1715 1716 # Aligned with prev comment block 1717 """) # noqa 1718 self._Check(unformatted_code, expected_formatted_code) 1719 1720 def testBlockIndentedFuncSuffix(self): 1721 unformatted_code = textwrap.dedent("""\ 1722 if True: 1723 func(1) # Line 1 1724 func(2) # Line 2 1725 # Line 3 1726 func(3) # Line 4 1727 # Line 5 - SpliceComments makes this a new block 1728 # Line 6 1729 1730 # Aligned with Func 1731 1732 def Func(): 1733 pass 1734 """) # noqa 1735 expected_formatted_code = textwrap.dedent("""\ 1736 if True: 1737 func(1) # Line 1 1738 func(2) # Line 2 1739 # Line 3 1740 func(3) # Line 4 1741 1742 # Line 5 - SpliceComments makes this a new block 1743 # Line 6 1744 1745 # Aligned with Func 1746 1747 1748 def Func(): 1749 pass 1750 """) 1751 self._Check(unformatted_code, expected_formatted_code) 1752 1753 def testBlockIndentedCommentSuffix(self): 1754 unformatted_code = textwrap.dedent("""\ 1755 if True: 1756 func(1) # Line 1 1757 func(2) # Line 2 1758 # Line 3 1759 func(3) # Line 4 1760 # Line 5 1761 # Line 6 1762 1763 # Not aligned 1764 """) 1765 expected_formatted_code = textwrap.dedent("""\ 1766 if True: 1767 func(1) # Line 1 1768 func(2) # Line 2 1769 # Line 3 1770 func(3) # Line 4 1771 # Line 5 1772 # Line 6 1773 1774 # Not aligned 1775 """) 1776 self._Check(unformatted_code, expected_formatted_code) 1777 1778 def testBlockMultiIndented(self): 1779 unformatted_code = textwrap.dedent("""\ 1780 if True: 1781 if True: 1782 if True: 1783 func(1) # Line 1 1784 func(2) # Line 2 1785 # Line 3 1786 func(3) # Line 4 1787 # Line 5 1788 # Line 6 1789 1790 # Not aligned 1791 """) # noqa 1792 expected_formatted_code = textwrap.dedent("""\ 1793 if True: 1794 if True: 1795 if True: 1796 func(1) # Line 1 1797 func(2) # Line 2 1798 # Line 3 1799 func(3) # Line 4 1800 # Line 5 1801 # Line 6 1802 1803 # Not aligned 1804 """) 1805 self._Check(unformatted_code, expected_formatted_code) 1806 1807 def testArgs(self): 1808 unformatted_code = textwrap.dedent("""\ 1809 def MyFunc( 1810 arg1, # Desc 1 1811 arg2, # Desc 2 1812 a_longer_var_name, # Desc 3 1813 arg4, 1814 arg5, # Desc 5 1815 arg6, 1816 ): 1817 pass 1818 """) 1819 expected_formatted_code = textwrap.dedent("""\ 1820 def MyFunc( 1821 arg1, # Desc 1 1822 arg2, # Desc 2 1823 a_longer_var_name, # Desc 3 1824 arg4, 1825 arg5, # Desc 5 1826 arg6, 1827 ): 1828 pass 1829 """) 1830 self._Check(unformatted_code, expected_formatted_code) 1831 1832 def testDisableBlock(self): 1833 unformatted_code = textwrap.dedent("""\ 1834 a() # comment 1 1835 b() # comment 2 1836 1837 # yapf: disable 1838 c() # comment 3 1839 d() # comment 4 1840 # yapf: enable 1841 1842 e() # comment 5 1843 f() # comment 6 1844 """) 1845 expected_formatted_code = textwrap.dedent("""\ 1846 a() # comment 1 1847 b() # comment 2 1848 1849 # yapf: disable 1850 c() # comment 3 1851 d() # comment 4 1852 # yapf: enable 1853 1854 e() # comment 5 1855 f() # comment 6 1856 """) 1857 self._Check(unformatted_code, expected_formatted_code) 1858 1859 def testDisabledLine(self): 1860 unformatted_code = textwrap.dedent("""\ 1861 short # comment 1 1862 do_not_touch1 # yapf: disable 1863 do_not_touch2 # yapf: disable 1864 a_longer_statement # comment 2 1865 """) 1866 expected_formatted_code = textwrap.dedent("""\ 1867 short # comment 1 1868 do_not_touch1 # yapf: disable 1869 do_not_touch2 # yapf: disable 1870 a_longer_statement # comment 2 1871 """) 1872 self._Check(unformatted_code, expected_formatted_code) 1873 1874 1875class _SpacesAroundDictListTupleTestImpl(yapf_test_helper.YAPFTest): 1876 1877 @staticmethod 1878 def _OwnStyle(): 1879 my_style = style.CreatePEP8Style() 1880 my_style['DISABLE_ENDING_COMMA_HEURISTIC'] = True 1881 my_style['SPLIT_ALL_COMMA_SEPARATED_VALUES'] = False 1882 my_style['SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED'] = False 1883 return my_style 1884 1885 def _Check(self, unformatted_code, expected_formatted_code): 1886 formatted_code, _ = yapf_api.FormatCode( 1887 unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle())) 1888 self.assertEqual(expected_formatted_code, formatted_code) 1889 1890 def setUp(self): 1891 self.maxDiff = None 1892 1893 1894class SpacesAroundDictTest(_SpacesAroundDictListTupleTestImpl): 1895 1896 @classmethod 1897 def _OwnStyle(cls): 1898 style = super(SpacesAroundDictTest, cls)._OwnStyle() 1899 style['SPACES_AROUND_DICT_DELIMITERS'] = True 1900 1901 return style 1902 1903 def testStandard(self): 1904 unformatted_code = textwrap.dedent("""\ 1905 {1 : 2} 1906 {k:v for k, v in other.items()} 1907 {k for k in [1, 2, 3]} 1908 1909 # The following statements should not change 1910 {} 1911 {1 : 2} # yapf: disable 1912 1913 # yapf: disable 1914 {1 : 2} 1915 # yapf: enable 1916 1917 # Dict settings should not impact lists or tuples 1918 [1, 2] 1919 (3, 4) 1920 """) 1921 expected_formatted_code = textwrap.dedent("""\ 1922 { 1: 2 } 1923 { k: v for k, v in other.items() } 1924 { k for k in [1, 2, 3] } 1925 1926 # The following statements should not change 1927 {} 1928 {1 : 2} # yapf: disable 1929 1930 # yapf: disable 1931 {1 : 2} 1932 # yapf: enable 1933 1934 # Dict settings should not impact lists or tuples 1935 [1, 2] 1936 (3, 4) 1937 """) 1938 self._Check(unformatted_code, expected_formatted_code) 1939 1940 1941class SpacesAroundListTest(_SpacesAroundDictListTupleTestImpl): 1942 1943 @classmethod 1944 def _OwnStyle(cls): 1945 style = super(SpacesAroundListTest, cls)._OwnStyle() 1946 style['SPACES_AROUND_LIST_DELIMITERS'] = True 1947 1948 return style 1949 1950 def testStandard(self): 1951 unformatted_code = textwrap.dedent("""\ 1952 [a,b,c] 1953 [4,5,] 1954 [6, [7, 8], 9] 1955 [v for v in [1,2,3] if v & 1] 1956 1957 # The following statements should not change 1958 index[0] 1959 index[a, b] 1960 [] 1961 [v for v in [1,2,3] if v & 1] # yapf: disable 1962 1963 # yapf: disable 1964 [a,b,c] 1965 [4,5,] 1966 # yapf: enable 1967 1968 # List settings should not impact dicts or tuples 1969 {a: b} 1970 (1, 2) 1971 """) 1972 expected_formatted_code = textwrap.dedent("""\ 1973 [ a, b, c ] 1974 [ 4, 5, ] 1975 [ 6, [ 7, 8 ], 9 ] 1976 [ v for v in [ 1, 2, 3 ] if v & 1 ] 1977 1978 # The following statements should not change 1979 index[0] 1980 index[a, b] 1981 [] 1982 [v for v in [1,2,3] if v & 1] # yapf: disable 1983 1984 # yapf: disable 1985 [a,b,c] 1986 [4,5,] 1987 # yapf: enable 1988 1989 # List settings should not impact dicts or tuples 1990 {a: b} 1991 (1, 2) 1992 """) 1993 self._Check(unformatted_code, expected_formatted_code) 1994 1995 1996class SpacesAroundTupleTest(_SpacesAroundDictListTupleTestImpl): 1997 1998 @classmethod 1999 def _OwnStyle(cls): 2000 style = super(SpacesAroundTupleTest, cls)._OwnStyle() 2001 style['SPACES_AROUND_TUPLE_DELIMITERS'] = True 2002 2003 return style 2004 2005 def testStandard(self): 2006 unformatted_code = textwrap.dedent("""\ 2007 (0, 1) 2008 (2, 3) 2009 (4, 5, 6,) 2010 func((7, 8), 9) 2011 2012 # The following statements should not change 2013 func(1, 2) 2014 (this_func or that_func)(3, 4) 2015 if (True and False): pass 2016 () 2017 2018 (0, 1) # yapf: disable 2019 2020 # yapf: disable 2021 (0, 1) 2022 (2, 3) 2023 # yapf: enable 2024 2025 # Tuple settings should not impact dicts or lists 2026 {a: b} 2027 [3, 4] 2028 """) 2029 expected_formatted_code = textwrap.dedent("""\ 2030 ( 0, 1 ) 2031 ( 2, 3 ) 2032 ( 4, 5, 6, ) 2033 func(( 7, 8 ), 9) 2034 2035 # The following statements should not change 2036 func(1, 2) 2037 (this_func or that_func)(3, 4) 2038 if (True and False): pass 2039 () 2040 2041 (0, 1) # yapf: disable 2042 2043 # yapf: disable 2044 (0, 1) 2045 (2, 3) 2046 # yapf: enable 2047 2048 # Tuple settings should not impact dicts or lists 2049 {a: b} 2050 [3, 4] 2051 """) 2052 self._Check(unformatted_code, expected_formatted_code) 2053 2054 2055if __name__ == '__main__': 2056 unittest.main() 2057