reformatter_python3_test.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. # Copyright 2016 Google Inc. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """Python 3 tests for yapf.reformatter."""
  15. import sys
  16. import textwrap
  17. import unittest
  18. from yapf.yapflib import reformatter
  19. from yapf.yapflib import style
  20. from yapftests import yapf_test_helper
  21. class TestsForPython3Code(yapf_test_helper.YAPFTest):
  22. """Test a few constructs that are new Python 3 syntax."""
  23. @classmethod
  24. def setUpClass(cls): # pylint: disable=g-missing-super-call
  25. style.SetGlobalStyle(style.CreatePEP8Style())
  26. def testTypedNames(self):
  27. unformatted_code = textwrap.dedent("""\
  28. def x(aaaaaaaaaaaaaaa:int,bbbbbbbbbbbbbbbb:str,ccccccccccccccc:dict,eeeeeeeeeeeeee:set={1, 2, 3})->bool:
  29. pass
  30. """) # noqa
  31. expected_formatted_code = textwrap.dedent("""\
  32. def x(aaaaaaaaaaaaaaa: int,
  33. bbbbbbbbbbbbbbbb: str,
  34. ccccccccccccccc: dict,
  35. eeeeeeeeeeeeee: set = {1, 2, 3}) -> bool:
  36. pass
  37. """) # noqa
  38. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  39. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  40. def testTypedNameWithLongNamedArg(self):
  41. unformatted_code = textwrap.dedent("""\
  42. def func(arg=long_function_call_that_pushes_the_line_over_eighty_characters()) -> ReturnType:
  43. pass
  44. """) # noqa
  45. expected_formatted_code = textwrap.dedent("""\
  46. def func(arg=long_function_call_that_pushes_the_line_over_eighty_characters()
  47. ) -> ReturnType:
  48. pass
  49. """) # noqa
  50. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  51. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  52. def testKeywordOnlyArgSpecifier(self):
  53. unformatted_code = textwrap.dedent("""\
  54. def foo(a, *, kw):
  55. return a+kw
  56. """) # noqa
  57. expected_formatted_code = textwrap.dedent("""\
  58. def foo(a, *, kw):
  59. return a + kw
  60. """) # noqa
  61. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  62. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  63. def testAnnotations(self):
  64. unformatted_code = textwrap.dedent("""\
  65. def foo(a: list, b: "bar") -> dict:
  66. return a+b
  67. """) # noqa
  68. expected_formatted_code = textwrap.dedent("""\
  69. def foo(a: list, b: "bar") -> dict:
  70. return a + b
  71. """) # noqa
  72. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  73. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  74. def testExecAsNonKeyword(self):
  75. unformatted_code = 'methods.exec( sys.modules[name])\n'
  76. expected_formatted_code = 'methods.exec(sys.modules[name])\n'
  77. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  78. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  79. def testAsyncFunctions(self):
  80. code = textwrap.dedent("""\
  81. import asyncio
  82. import time
  83. @print_args
  84. async def slow_operation():
  85. await asyncio.sleep(1)
  86. # print("Slow operation {} complete".format(n))
  87. async def main():
  88. start = time.time()
  89. if (await get_html()):
  90. pass
  91. """) # noqa
  92. llines = yapf_test_helper.ParseAndUnwrap(code)
  93. self.assertCodeEqual(code, reformatter.Reformat(llines, verify=False))
  94. def testNoSpacesAroundPowerOperator(self):
  95. unformatted_code = textwrap.dedent("""\
  96. a**b
  97. """) # noqa
  98. expected_formatted_code = textwrap.dedent("""\
  99. a ** b
  100. """) # noqa
  101. try:
  102. style.SetGlobalStyle(
  103. style.CreateStyleFromConfig(
  104. '{based_on_style: pep8, SPACES_AROUND_POWER_OPERATOR: True}'))
  105. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  106. self.assertCodeEqual(expected_formatted_code,
  107. reformatter.Reformat(llines))
  108. finally:
  109. style.SetGlobalStyle(style.CreatePEP8Style())
  110. def testSpacesAroundDefaultOrNamedAssign(self):
  111. unformatted_code = textwrap.dedent("""\
  112. f(a=5)
  113. """) # noqa
  114. expected_formatted_code = textwrap.dedent("""\
  115. f(a = 5)
  116. """) # noqa
  117. try:
  118. style.SetGlobalStyle(
  119. style.CreateStyleFromConfig(
  120. '{based_on_style: pep8, '
  121. 'SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN: True}'))
  122. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  123. self.assertCodeEqual(expected_formatted_code,
  124. reformatter.Reformat(llines))
  125. finally:
  126. style.SetGlobalStyle(style.CreatePEP8Style())
  127. def testTypeHint(self):
  128. unformatted_code = textwrap.dedent("""\
  129. def foo(x: int=42):
  130. pass
  131. def foo2(x: 'int' =42):
  132. pass
  133. """) # noqa
  134. expected_formatted_code = textwrap.dedent("""\
  135. def foo(x: int = 42):
  136. pass
  137. def foo2(x: 'int' = 42):
  138. pass
  139. """) # noqa
  140. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  141. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  142. def testMatrixMultiplication(self):
  143. unformatted_code = textwrap.dedent("""\
  144. a=b@c
  145. """) # noqa
  146. expected_formatted_code = textwrap.dedent("""\
  147. a = b @ c
  148. """) # noqa
  149. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  150. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  151. def testNoneKeyword(self):
  152. code = textwrap.dedent("""\
  153. None.__ne__()
  154. """) # noqa
  155. llines = yapf_test_helper.ParseAndUnwrap(code)
  156. self.assertCodeEqual(code, reformatter.Reformat(llines))
  157. def testAsyncWithPrecedingComment(self):
  158. unformatted_code = textwrap.dedent("""\
  159. import asyncio
  160. # Comment
  161. async def bar():
  162. pass
  163. async def foo():
  164. pass
  165. """) # noqa
  166. expected_formatted_code = textwrap.dedent("""\
  167. import asyncio
  168. # Comment
  169. async def bar():
  170. pass
  171. async def foo():
  172. pass
  173. """) # noqa
  174. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  175. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  176. def testAsyncFunctionsNested(self):
  177. code = textwrap.dedent("""\
  178. async def outer():
  179. async def inner():
  180. pass
  181. """) # noqa
  182. llines = yapf_test_helper.ParseAndUnwrap(code)
  183. self.assertCodeEqual(code, reformatter.Reformat(llines))
  184. def testKeepTypesIntact(self):
  185. unformatted_code = textwrap.dedent("""\
  186. def _ReduceAbstractContainers(
  187. self, *args: Optional[automation_converter.PyiCollectionAbc]) -> List[
  188. automation_converter.PyiCollectionAbc]:
  189. pass
  190. """) # noqa
  191. expected_formatted_code = textwrap.dedent("""\
  192. def _ReduceAbstractContainers(
  193. self, *args: Optional[automation_converter.PyiCollectionAbc]
  194. ) -> List[automation_converter.PyiCollectionAbc]:
  195. pass
  196. """) # noqa
  197. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  198. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  199. def testContinuationIndentWithAsync(self):
  200. unformatted_code = textwrap.dedent("""\
  201. async def start_websocket():
  202. async with session.ws_connect(
  203. r"ws://a_really_long_long_long_long_long_long_url") as ws:
  204. pass
  205. """) # noqa
  206. expected_formatted_code = textwrap.dedent("""\
  207. async def start_websocket():
  208. async with session.ws_connect(
  209. r"ws://a_really_long_long_long_long_long_long_url") as ws:
  210. pass
  211. """) # noqa
  212. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  213. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  214. def testSplittingArguments(self):
  215. unformatted_code = textwrap.dedent("""\
  216. async def open_file(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None):
  217. pass
  218. async def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None):
  219. pass
  220. def open_file(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None):
  221. pass
  222. def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None):
  223. pass
  224. """) # noqa
  225. expected_formatted_code = textwrap.dedent("""\
  226. async def open_file(
  227. file,
  228. mode='r',
  229. buffering=-1,
  230. encoding=None,
  231. errors=None,
  232. newline=None,
  233. closefd=True,
  234. opener=None
  235. ):
  236. pass
  237. async def run_sync_in_worker_thread(
  238. sync_fn, *args, cancellable=False, limiter=None
  239. ):
  240. pass
  241. def open_file(
  242. file,
  243. mode='r',
  244. buffering=-1,
  245. encoding=None,
  246. errors=None,
  247. newline=None,
  248. closefd=True,
  249. opener=None
  250. ):
  251. pass
  252. def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None):
  253. pass
  254. """) # noqa
  255. try:
  256. style.SetGlobalStyle(
  257. style.CreateStyleFromConfig(
  258. '{based_on_style: pep8, '
  259. 'dedent_closing_brackets: true, '
  260. 'coalesce_brackets: false, '
  261. 'space_between_ending_comma_and_closing_bracket: false, '
  262. 'split_arguments_when_comma_terminated: true, '
  263. 'split_before_first_argument: true}'))
  264. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  265. self.assertCodeEqual(expected_formatted_code,
  266. reformatter.Reformat(llines))
  267. finally:
  268. style.SetGlobalStyle(style.CreatePEP8Style())
  269. def testDictUnpacking(self):
  270. unformatted_code = textwrap.dedent("""\
  271. class Foo:
  272. def foo(self):
  273. foofoofoofoofoofoofoofoo('foofoofoofoofoo', {
  274. 'foo': 'foo',
  275. **foofoofoo
  276. })
  277. """) # noqa
  278. expected_formatted_code = textwrap.dedent("""\
  279. class Foo:
  280. def foo(self):
  281. foofoofoofoofoofoofoofoo('foofoofoofoofoo', {
  282. 'foo': 'foo',
  283. **foofoofoo
  284. })
  285. """) # noqa
  286. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  287. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  288. def testMultilineFormatString(self):
  289. # https://github.com/google/yapf/issues/513
  290. code = textwrap.dedent("""\
  291. # yapf: disable
  292. (f'''
  293. ''')
  294. # yapf: enable
  295. """) # noqa
  296. llines = yapf_test_helper.ParseAndUnwrap(code)
  297. self.assertCodeEqual(code, reformatter.Reformat(llines))
  298. def testEllipses(self):
  299. # https://github.com/google/yapf/issues/533
  300. code = textwrap.dedent("""\
  301. def dirichlet(x12345678901234567890123456789012345678901234567890=...) -> None:
  302. return
  303. """) # noqa
  304. llines = yapf_test_helper.ParseAndUnwrap(code)
  305. self.assertCodeEqual(code, reformatter.Reformat(llines))
  306. def testFunctionTypedReturnNextLine(self):
  307. code = textwrap.dedent("""\
  308. def _GenerateStatsEntries(
  309. process_id: Text,
  310. timestamp: Optional[ffffffff.FFFFFFFFFFF] = None
  311. ) -> Sequence[ssssssssssss.SSSSSSSSSSSSSSS]:
  312. pass
  313. """) # noqa
  314. llines = yapf_test_helper.ParseAndUnwrap(code)
  315. self.assertCodeEqual(code, reformatter.Reformat(llines))
  316. def testFunctionTypedReturnSameLine(self):
  317. code = textwrap.dedent("""\
  318. def rrrrrrrrrrrrrrrrrrrrrr(
  319. ccccccccccccccccccccccc: Tuple[Text, Text]) -> List[Tuple[Text, Text]]:
  320. pass
  321. """) # noqa
  322. llines = yapf_test_helper.ParseAndUnwrap(code)
  323. self.assertCodeEqual(code, reformatter.Reformat(llines))
  324. def testAsyncForElseNotIndentedInsideBody(self):
  325. code = textwrap.dedent("""\
  326. async def fn():
  327. async for message in websocket:
  328. for i in range(10):
  329. pass
  330. else:
  331. pass
  332. else:
  333. pass
  334. """) # noqa
  335. llines = yapf_test_helper.ParseAndUnwrap(code)
  336. self.assertCodeEqual(code, reformatter.Reformat(llines))
  337. def testForElseInAsyncNotMixedWithAsyncFor(self):
  338. code = textwrap.dedent("""\
  339. async def fn():
  340. for i in range(10):
  341. pass
  342. else:
  343. pass
  344. """) # noqa
  345. llines = yapf_test_helper.ParseAndUnwrap(code)
  346. self.assertCodeEqual(code, reformatter.Reformat(llines))
  347. def testParameterListIndentationConflicts(self):
  348. unformatted_code = textwrap.dedent("""\
  349. def raw_message( # pylint: disable=too-many-arguments
  350. self, text, user_id=1000, chat_type='private', forward_date=None, forward_from=None):
  351. pass
  352. """) # noqa
  353. expected_formatted_code = textwrap.dedent("""\
  354. def raw_message( # pylint: disable=too-many-arguments
  355. self,
  356. text,
  357. user_id=1000,
  358. chat_type='private',
  359. forward_date=None,
  360. forward_from=None):
  361. pass
  362. """)
  363. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  364. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  365. def testTypeHintedYieldExpression(self):
  366. # https://github.com/google/yapf/issues/1092
  367. code = textwrap.dedent("""\
  368. def my_coroutine():
  369. x: int = yield
  370. """) # noqa
  371. llines = yapf_test_helper.ParseAndUnwrap(code)
  372. self.assertCodeEqual(code, reformatter.Reformat(llines))
  373. def testSyntaxMatch(self):
  374. # https://github.com/google/yapf/issues/1045
  375. # https://github.com/google/yapf/issues/1085
  376. unformatted_code = textwrap.dedent("""\
  377. a=3
  378. b=0
  379. match a :
  380. case 0 :
  381. b=1
  382. case _ :
  383. b=2
  384. """) # noqa
  385. expected_formatted_code = textwrap.dedent("""\
  386. a = 3
  387. b = 0
  388. match a:
  389. case 0:
  390. b = 1
  391. case _:
  392. b = 2
  393. """) # noqa
  394. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  395. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  396. def testParenthsizedContextManager(self):
  397. # https://github.com/google/yapf/issues/1064
  398. unformatted_code = textwrap.dedent("""\
  399. def test_copy_dimension(self):
  400. with (Dataset() as target_ds,
  401. Dataset() as source_ds):
  402. do_something
  403. """) # noqa
  404. expected_formatted_code = textwrap.dedent("""\
  405. def test_copy_dimension(self):
  406. with (Dataset() as target_ds, Dataset() as source_ds):
  407. do_something
  408. """) # noqa
  409. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  410. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  411. def testUnpackedTuple(self):
  412. # https://github.com/google/yapf/issues/830
  413. # https://github.com/google/yapf/issues/1060
  414. unformatted_code = textwrap.dedent("""\
  415. def a():
  416. t = (2,3)
  417. for i in range(5):
  418. yield i,*t
  419. """) # noqa
  420. expected_formatted_code = textwrap.dedent("""\
  421. def a():
  422. t = (2, 3)
  423. for i in range(5):
  424. yield i, *t
  425. """) # noqa
  426. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  427. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  428. def testTypedTuple(self):
  429. # https://github.com/google/yapf/issues/412
  430. # https://github.com/google/yapf/issues/1058
  431. code = textwrap.dedent("""\
  432. t: tuple = 1, 2
  433. args = tuple(x for x in [2], )
  434. """) # noqa
  435. llines = yapf_test_helper.ParseAndUnwrap(code)
  436. self.assertCodeEqual(code, reformatter.Reformat(llines))
  437. def testWalrusOperator(self):
  438. # https://github.com/google/yapf/issues/894
  439. unformatted_code = textwrap.dedent("""\
  440. import os
  441. a=[1,2,3,4]
  442. if (n:=len(a))>2:
  443. print()
  444. """) # noqa
  445. expected_formatted_code = textwrap.dedent("""\
  446. import os
  447. a = [1, 2, 3, 4]
  448. if (n := len(a)) > 2:
  449. print()
  450. """) # noqa
  451. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  452. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  453. def testCondAssign(self):
  454. # https://github.com/google/yapf/issues/856
  455. unformatted_code = textwrap.dedent("""\
  456. def json(self) -> JSONTask:
  457. result: JSONTask = {
  458. "id": self.id,
  459. "text": self.text,
  460. "status": self.status,
  461. "last_mod": self.last_mod_time
  462. }
  463. for i in "parent_id", "deadline", "reminder":
  464. if x := getattr(self , i):
  465. result[i] = x # type: ignore
  466. return result
  467. """) # noqa
  468. expected_formatted_code = textwrap.dedent("""\
  469. def json(self) -> JSONTask:
  470. result: JSONTask = {
  471. "id": self.id,
  472. "text": self.text,
  473. "status": self.status,
  474. "last_mod": self.last_mod_time
  475. }
  476. for i in "parent_id", "deadline", "reminder":
  477. if x := getattr(self, i):
  478. result[i] = x # type: ignore
  479. return result
  480. """) # noqa
  481. llines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
  482. self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(llines))
  483. def testCopyDictionary(self):
  484. # https://github.com/google/yapf/issues/233
  485. # https://github.com/google/yapf/issues/402
  486. code = textwrap.dedent("""\
  487. a_dict = {'key': 'value'}
  488. a_dict_copy = {**a_dict}
  489. print('a_dict:', a_dict)
  490. print('a_dict_copy:', a_dict_copy)
  491. """) # noqa
  492. llines = yapf_test_helper.ParseAndUnwrap(code)
  493. self.assertCodeEqual(code, reformatter.Reformat(llines))
  494. if __name__ == '__main__':
  495. unittest.main()