test_fstring.py 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360
  1. # -*- coding: utf-8 -*-
  2. # There are tests here with unicode string literals and
  3. # identifiers. There's a code in ast.c that was added because of a
  4. # failure with a non-ascii-only expression. So, I have tests for
  5. # that. There are workarounds that would let me run tests for that
  6. # code without unicode identifiers and strings, but just using them
  7. # directly seems like the easiest and therefore safest thing to do.
  8. # Unicode identifiers in tests is allowed by PEP 3131.
  9. import ast
  10. import os
  11. import re
  12. import types
  13. import decimal
  14. import unittest
  15. from test.support.os_helper import temp_cwd
  16. from test.support.script_helper import assert_python_failure
  17. a_global = 'global variable'
  18. # You could argue that I'm too strict in looking for specific error
  19. # values with assertRaisesRegex, but without it it's way too easy to
  20. # make a syntax error in the test strings. Especially with all of the
  21. # triple quotes, raw strings, backslashes, etc. I think it's a
  22. # worthwhile tradeoff. When I switched to this method, I found many
  23. # examples where I wasn't testing what I thought I was.
  24. class TestCase(unittest.TestCase):
  25. def assertAllRaise(self, exception_type, regex, error_strings):
  26. for str in error_strings:
  27. with self.subTest(str=str):
  28. with self.assertRaisesRegex(exception_type, regex):
  29. eval(str)
  30. def test__format__lookup(self):
  31. # Make sure __format__ is looked up on the type, not the instance.
  32. class X:
  33. def __format__(self, spec):
  34. return 'class'
  35. x = X()
  36. # Add a bound __format__ method to the 'y' instance, but not
  37. # the 'x' instance.
  38. y = X()
  39. y.__format__ = types.MethodType(lambda self, spec: 'instance', y)
  40. self.assertEqual(f'{y}', format(y))
  41. self.assertEqual(f'{y}', 'class')
  42. self.assertEqual(format(x), format(y))
  43. # __format__ is not called this way, but still make sure it
  44. # returns what we expect (so we can make sure we're bypassing
  45. # it).
  46. self.assertEqual(x.__format__(''), 'class')
  47. self.assertEqual(y.__format__(''), 'instance')
  48. # This is how __format__ is actually called.
  49. self.assertEqual(type(x).__format__(x, ''), 'class')
  50. self.assertEqual(type(y).__format__(y, ''), 'class')
  51. def test_ast(self):
  52. # Inspired by http://bugs.python.org/issue24975
  53. class X:
  54. def __init__(self):
  55. self.called = False
  56. def __call__(self):
  57. self.called = True
  58. return 4
  59. x = X()
  60. expr = """
  61. a = 10
  62. f'{a * x()}'"""
  63. t = ast.parse(expr)
  64. c = compile(t, '', 'exec')
  65. # Make sure x was not called.
  66. self.assertFalse(x.called)
  67. # Actually run the code.
  68. exec(c)
  69. # Make sure x was called.
  70. self.assertTrue(x.called)
  71. def test_ast_line_numbers(self):
  72. expr = """
  73. a = 10
  74. f'{a * x()}'"""
  75. t = ast.parse(expr)
  76. self.assertEqual(type(t), ast.Module)
  77. self.assertEqual(len(t.body), 2)
  78. # check `a = 10`
  79. self.assertEqual(type(t.body[0]), ast.Assign)
  80. self.assertEqual(t.body[0].lineno, 2)
  81. # check `f'...'`
  82. self.assertEqual(type(t.body[1]), ast.Expr)
  83. self.assertEqual(type(t.body[1].value), ast.JoinedStr)
  84. self.assertEqual(len(t.body[1].value.values), 1)
  85. self.assertEqual(type(t.body[1].value.values[0]), ast.FormattedValue)
  86. self.assertEqual(t.body[1].lineno, 3)
  87. self.assertEqual(t.body[1].value.lineno, 3)
  88. self.assertEqual(t.body[1].value.values[0].lineno, 3)
  89. # check the binop location
  90. binop = t.body[1].value.values[0].value
  91. self.assertEqual(type(binop), ast.BinOp)
  92. self.assertEqual(type(binop.left), ast.Name)
  93. self.assertEqual(type(binop.op), ast.Mult)
  94. self.assertEqual(type(binop.right), ast.Call)
  95. self.assertEqual(binop.lineno, 3)
  96. self.assertEqual(binop.left.lineno, 3)
  97. self.assertEqual(binop.right.lineno, 3)
  98. self.assertEqual(binop.col_offset, 3)
  99. self.assertEqual(binop.left.col_offset, 3)
  100. self.assertEqual(binop.right.col_offset, 7)
  101. def test_ast_line_numbers_multiple_formattedvalues(self):
  102. expr = """
  103. f'no formatted values'
  104. f'eggs {a * x()} spam {b + y()}'"""
  105. t = ast.parse(expr)
  106. self.assertEqual(type(t), ast.Module)
  107. self.assertEqual(len(t.body), 2)
  108. # check `f'no formatted value'`
  109. self.assertEqual(type(t.body[0]), ast.Expr)
  110. self.assertEqual(type(t.body[0].value), ast.JoinedStr)
  111. self.assertEqual(t.body[0].lineno, 2)
  112. # check `f'...'`
  113. self.assertEqual(type(t.body[1]), ast.Expr)
  114. self.assertEqual(type(t.body[1].value), ast.JoinedStr)
  115. self.assertEqual(len(t.body[1].value.values), 4)
  116. self.assertEqual(type(t.body[1].value.values[0]), ast.Constant)
  117. self.assertEqual(type(t.body[1].value.values[0].value), str)
  118. self.assertEqual(type(t.body[1].value.values[1]), ast.FormattedValue)
  119. self.assertEqual(type(t.body[1].value.values[2]), ast.Constant)
  120. self.assertEqual(type(t.body[1].value.values[2].value), str)
  121. self.assertEqual(type(t.body[1].value.values[3]), ast.FormattedValue)
  122. self.assertEqual(t.body[1].lineno, 3)
  123. self.assertEqual(t.body[1].value.lineno, 3)
  124. self.assertEqual(t.body[1].value.values[0].lineno, 3)
  125. self.assertEqual(t.body[1].value.values[1].lineno, 3)
  126. self.assertEqual(t.body[1].value.values[2].lineno, 3)
  127. self.assertEqual(t.body[1].value.values[3].lineno, 3)
  128. # check the first binop location
  129. binop1 = t.body[1].value.values[1].value
  130. self.assertEqual(type(binop1), ast.BinOp)
  131. self.assertEqual(type(binop1.left), ast.Name)
  132. self.assertEqual(type(binop1.op), ast.Mult)
  133. self.assertEqual(type(binop1.right), ast.Call)
  134. self.assertEqual(binop1.lineno, 3)
  135. self.assertEqual(binop1.left.lineno, 3)
  136. self.assertEqual(binop1.right.lineno, 3)
  137. self.assertEqual(binop1.col_offset, 8)
  138. self.assertEqual(binop1.left.col_offset, 8)
  139. self.assertEqual(binop1.right.col_offset, 12)
  140. # check the second binop location
  141. binop2 = t.body[1].value.values[3].value
  142. self.assertEqual(type(binop2), ast.BinOp)
  143. self.assertEqual(type(binop2.left), ast.Name)
  144. self.assertEqual(type(binop2.op), ast.Add)
  145. self.assertEqual(type(binop2.right), ast.Call)
  146. self.assertEqual(binop2.lineno, 3)
  147. self.assertEqual(binop2.left.lineno, 3)
  148. self.assertEqual(binop2.right.lineno, 3)
  149. self.assertEqual(binop2.col_offset, 23)
  150. self.assertEqual(binop2.left.col_offset, 23)
  151. self.assertEqual(binop2.right.col_offset, 27)
  152. def test_ast_line_numbers_nested(self):
  153. expr = """
  154. a = 10
  155. f'{a * f"-{x()}-"}'"""
  156. t = ast.parse(expr)
  157. self.assertEqual(type(t), ast.Module)
  158. self.assertEqual(len(t.body), 2)
  159. # check `a = 10`
  160. self.assertEqual(type(t.body[0]), ast.Assign)
  161. self.assertEqual(t.body[0].lineno, 2)
  162. # check `f'...'`
  163. self.assertEqual(type(t.body[1]), ast.Expr)
  164. self.assertEqual(type(t.body[1].value), ast.JoinedStr)
  165. self.assertEqual(len(t.body[1].value.values), 1)
  166. self.assertEqual(type(t.body[1].value.values[0]), ast.FormattedValue)
  167. self.assertEqual(t.body[1].lineno, 3)
  168. self.assertEqual(t.body[1].value.lineno, 3)
  169. self.assertEqual(t.body[1].value.values[0].lineno, 3)
  170. # check the binop location
  171. binop = t.body[1].value.values[0].value
  172. self.assertEqual(type(binop), ast.BinOp)
  173. self.assertEqual(type(binop.left), ast.Name)
  174. self.assertEqual(type(binop.op), ast.Mult)
  175. self.assertEqual(type(binop.right), ast.JoinedStr)
  176. self.assertEqual(binop.lineno, 3)
  177. self.assertEqual(binop.left.lineno, 3)
  178. self.assertEqual(binop.right.lineno, 3)
  179. self.assertEqual(binop.col_offset, 3)
  180. self.assertEqual(binop.left.col_offset, 3)
  181. self.assertEqual(binop.right.col_offset, 7)
  182. # check the nested call location
  183. self.assertEqual(len(binop.right.values), 3)
  184. self.assertEqual(type(binop.right.values[0]), ast.Constant)
  185. self.assertEqual(type(binop.right.values[0].value), str)
  186. self.assertEqual(type(binop.right.values[1]), ast.FormattedValue)
  187. self.assertEqual(type(binop.right.values[2]), ast.Constant)
  188. self.assertEqual(type(binop.right.values[2].value), str)
  189. self.assertEqual(binop.right.values[0].lineno, 3)
  190. self.assertEqual(binop.right.values[1].lineno, 3)
  191. self.assertEqual(binop.right.values[2].lineno, 3)
  192. call = binop.right.values[1].value
  193. self.assertEqual(type(call), ast.Call)
  194. self.assertEqual(call.lineno, 3)
  195. self.assertEqual(call.col_offset, 11)
  196. def test_ast_line_numbers_duplicate_expression(self):
  197. expr = """
  198. a = 10
  199. f'{a * x()} {a * x()} {a * x()}'
  200. """
  201. t = ast.parse(expr)
  202. self.assertEqual(type(t), ast.Module)
  203. self.assertEqual(len(t.body), 2)
  204. # check `a = 10`
  205. self.assertEqual(type(t.body[0]), ast.Assign)
  206. self.assertEqual(t.body[0].lineno, 2)
  207. # check `f'...'`
  208. self.assertEqual(type(t.body[1]), ast.Expr)
  209. self.assertEqual(type(t.body[1].value), ast.JoinedStr)
  210. self.assertEqual(len(t.body[1].value.values), 5)
  211. self.assertEqual(type(t.body[1].value.values[0]), ast.FormattedValue)
  212. self.assertEqual(type(t.body[1].value.values[1]), ast.Constant)
  213. self.assertEqual(type(t.body[1].value.values[1].value), str)
  214. self.assertEqual(type(t.body[1].value.values[2]), ast.FormattedValue)
  215. self.assertEqual(type(t.body[1].value.values[3]), ast.Constant)
  216. self.assertEqual(type(t.body[1].value.values[3].value), str)
  217. self.assertEqual(type(t.body[1].value.values[4]), ast.FormattedValue)
  218. self.assertEqual(t.body[1].lineno, 3)
  219. self.assertEqual(t.body[1].value.lineno, 3)
  220. self.assertEqual(t.body[1].value.values[0].lineno, 3)
  221. self.assertEqual(t.body[1].value.values[1].lineno, 3)
  222. self.assertEqual(t.body[1].value.values[2].lineno, 3)
  223. self.assertEqual(t.body[1].value.values[3].lineno, 3)
  224. self.assertEqual(t.body[1].value.values[4].lineno, 3)
  225. # check the first binop location
  226. binop = t.body[1].value.values[0].value
  227. self.assertEqual(type(binop), ast.BinOp)
  228. self.assertEqual(type(binop.left), ast.Name)
  229. self.assertEqual(type(binop.op), ast.Mult)
  230. self.assertEqual(type(binop.right), ast.Call)
  231. self.assertEqual(binop.lineno, 3)
  232. self.assertEqual(binop.left.lineno, 3)
  233. self.assertEqual(binop.right.lineno, 3)
  234. self.assertEqual(binop.col_offset, 3)
  235. self.assertEqual(binop.left.col_offset, 3)
  236. self.assertEqual(binop.right.col_offset, 7)
  237. # check the second binop location
  238. binop = t.body[1].value.values[2].value
  239. self.assertEqual(type(binop), ast.BinOp)
  240. self.assertEqual(type(binop.left), ast.Name)
  241. self.assertEqual(type(binop.op), ast.Mult)
  242. self.assertEqual(type(binop.right), ast.Call)
  243. self.assertEqual(binop.lineno, 3)
  244. self.assertEqual(binop.left.lineno, 3)
  245. self.assertEqual(binop.right.lineno, 3)
  246. self.assertEqual(binop.col_offset, 13)
  247. self.assertEqual(binop.left.col_offset, 13)
  248. self.assertEqual(binop.right.col_offset, 17)
  249. # check the third binop location
  250. binop = t.body[1].value.values[4].value
  251. self.assertEqual(type(binop), ast.BinOp)
  252. self.assertEqual(type(binop.left), ast.Name)
  253. self.assertEqual(type(binop.op), ast.Mult)
  254. self.assertEqual(type(binop.right), ast.Call)
  255. self.assertEqual(binop.lineno, 3)
  256. self.assertEqual(binop.left.lineno, 3)
  257. self.assertEqual(binop.right.lineno, 3)
  258. self.assertEqual(binop.col_offset, 23)
  259. self.assertEqual(binop.left.col_offset, 23)
  260. self.assertEqual(binop.right.col_offset, 27)
  261. def test_ast_numbers_fstring_with_formatting(self):
  262. t = ast.parse('f"Here is that pesky {xxx:.3f} again"')
  263. self.assertEqual(len(t.body), 1)
  264. self.assertEqual(t.body[0].lineno, 1)
  265. self.assertEqual(type(t.body[0]), ast.Expr)
  266. self.assertEqual(type(t.body[0].value), ast.JoinedStr)
  267. self.assertEqual(len(t.body[0].value.values), 3)
  268. self.assertEqual(type(t.body[0].value.values[0]), ast.Constant)
  269. self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue)
  270. self.assertEqual(type(t.body[0].value.values[2]), ast.Constant)
  271. _, expr, _ = t.body[0].value.values
  272. name = expr.value
  273. self.assertEqual(type(name), ast.Name)
  274. self.assertEqual(name.lineno, 1)
  275. self.assertEqual(name.end_lineno, 1)
  276. self.assertEqual(name.col_offset, 22)
  277. self.assertEqual(name.end_col_offset, 25)
  278. def test_ast_line_numbers_multiline_fstring(self):
  279. # See bpo-30465 for details.
  280. expr = """
  281. a = 10
  282. f'''
  283. {a
  284. *
  285. x()}
  286. non-important content
  287. '''
  288. """
  289. t = ast.parse(expr)
  290. self.assertEqual(type(t), ast.Module)
  291. self.assertEqual(len(t.body), 2)
  292. # check `a = 10`
  293. self.assertEqual(type(t.body[0]), ast.Assign)
  294. self.assertEqual(t.body[0].lineno, 2)
  295. # check `f'...'`
  296. self.assertEqual(type(t.body[1]), ast.Expr)
  297. self.assertEqual(type(t.body[1].value), ast.JoinedStr)
  298. self.assertEqual(len(t.body[1].value.values), 3)
  299. self.assertEqual(type(t.body[1].value.values[0]), ast.Constant)
  300. self.assertEqual(type(t.body[1].value.values[0].value), str)
  301. self.assertEqual(type(t.body[1].value.values[1]), ast.FormattedValue)
  302. self.assertEqual(type(t.body[1].value.values[2]), ast.Constant)
  303. self.assertEqual(type(t.body[1].value.values[2].value), str)
  304. self.assertEqual(t.body[1].lineno, 3)
  305. self.assertEqual(t.body[1].value.lineno, 3)
  306. self.assertEqual(t.body[1].value.values[0].lineno, 3)
  307. self.assertEqual(t.body[1].value.values[1].lineno, 3)
  308. self.assertEqual(t.body[1].value.values[2].lineno, 3)
  309. self.assertEqual(t.body[1].col_offset, 0)
  310. self.assertEqual(t.body[1].value.col_offset, 0)
  311. self.assertEqual(t.body[1].value.values[0].col_offset, 0)
  312. self.assertEqual(t.body[1].value.values[1].col_offset, 0)
  313. self.assertEqual(t.body[1].value.values[2].col_offset, 0)
  314. # NOTE: the following lineno information and col_offset is correct for
  315. # expressions within FormattedValues.
  316. binop = t.body[1].value.values[1].value
  317. self.assertEqual(type(binop), ast.BinOp)
  318. self.assertEqual(type(binop.left), ast.Name)
  319. self.assertEqual(type(binop.op), ast.Mult)
  320. self.assertEqual(type(binop.right), ast.Call)
  321. self.assertEqual(binop.lineno, 4)
  322. self.assertEqual(binop.left.lineno, 4)
  323. self.assertEqual(binop.right.lineno, 6)
  324. self.assertEqual(binop.col_offset, 3)
  325. self.assertEqual(binop.left.col_offset, 3)
  326. self.assertEqual(binop.right.col_offset, 7)
  327. expr = """
  328. a = f'''
  329. {blech}
  330. '''
  331. """
  332. t = ast.parse(expr)
  333. self.assertEqual(type(t), ast.Module)
  334. self.assertEqual(len(t.body), 1)
  335. # Check f'...'
  336. self.assertEqual(type(t.body[0]), ast.Assign)
  337. self.assertEqual(type(t.body[0].value), ast.JoinedStr)
  338. self.assertEqual(len(t.body[0].value.values), 3)
  339. self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue)
  340. self.assertEqual(t.body[0].lineno, 2)
  341. self.assertEqual(t.body[0].value.lineno, 2)
  342. self.assertEqual(t.body[0].value.values[0].lineno, 2)
  343. self.assertEqual(t.body[0].value.values[1].lineno, 2)
  344. self.assertEqual(t.body[0].value.values[2].lineno, 2)
  345. self.assertEqual(t.body[0].col_offset, 0)
  346. self.assertEqual(t.body[0].value.col_offset, 4)
  347. self.assertEqual(t.body[0].value.values[0].col_offset, 4)
  348. self.assertEqual(t.body[0].value.values[1].col_offset, 4)
  349. self.assertEqual(t.body[0].value.values[2].col_offset, 4)
  350. # Check {blech}
  351. self.assertEqual(t.body[0].value.values[1].value.lineno, 3)
  352. self.assertEqual(t.body[0].value.values[1].value.end_lineno, 3)
  353. self.assertEqual(t.body[0].value.values[1].value.col_offset, 11)
  354. self.assertEqual(t.body[0].value.values[1].value.end_col_offset, 16)
  355. def test_ast_line_numbers_with_parentheses(self):
  356. expr = """
  357. x = (
  358. f" {test(t)}"
  359. )"""
  360. t = ast.parse(expr)
  361. self.assertEqual(type(t), ast.Module)
  362. self.assertEqual(len(t.body), 1)
  363. # check the test(t) location
  364. call = t.body[0].value.values[1].value
  365. self.assertEqual(type(call), ast.Call)
  366. self.assertEqual(call.lineno, 3)
  367. self.assertEqual(call.end_lineno, 3)
  368. self.assertEqual(call.col_offset, 8)
  369. self.assertEqual(call.end_col_offset, 15)
  370. expr = """
  371. x = (
  372. 'PERL_MM_OPT', (
  373. f'wat'
  374. f'some_string={f(x)} '
  375. f'wat'
  376. ),
  377. )
  378. """
  379. t = ast.parse(expr)
  380. self.assertEqual(type(t), ast.Module)
  381. self.assertEqual(len(t.body), 1)
  382. # check the fstring
  383. fstring = t.body[0].value.elts[1]
  384. self.assertEqual(type(fstring), ast.JoinedStr)
  385. self.assertEqual(len(fstring.values), 3)
  386. wat1, middle, wat2 = fstring.values
  387. # check the first wat
  388. self.assertEqual(type(wat1), ast.Constant)
  389. self.assertEqual(wat1.lineno, 4)
  390. self.assertEqual(wat1.end_lineno, 6)
  391. self.assertEqual(wat1.col_offset, 12)
  392. self.assertEqual(wat1.end_col_offset, 18)
  393. # check the call
  394. call = middle.value
  395. self.assertEqual(type(call), ast.Call)
  396. self.assertEqual(call.lineno, 5)
  397. self.assertEqual(call.end_lineno, 5)
  398. self.assertEqual(call.col_offset, 27)
  399. self.assertEqual(call.end_col_offset, 31)
  400. # check the second wat
  401. self.assertEqual(type(wat2), ast.Constant)
  402. self.assertEqual(wat2.lineno, 4)
  403. self.assertEqual(wat2.end_lineno, 6)
  404. self.assertEqual(wat2.col_offset, 12)
  405. self.assertEqual(wat2.end_col_offset, 18)
  406. def test_docstring(self):
  407. def f():
  408. f'''Not a docstring'''
  409. self.assertIsNone(f.__doc__)
  410. def g():
  411. '''Not a docstring''' \
  412. f''
  413. self.assertIsNone(g.__doc__)
  414. def test_literal_eval(self):
  415. with self.assertRaisesRegex(ValueError, 'malformed node or string'):
  416. ast.literal_eval("f'x'")
  417. def test_ast_compile_time_concat(self):
  418. x = ['']
  419. expr = """x[0] = 'foo' f'{3}'"""
  420. t = ast.parse(expr)
  421. c = compile(t, '', 'exec')
  422. exec(c)
  423. self.assertEqual(x[0], 'foo3')
  424. def test_compile_time_concat_errors(self):
  425. self.assertAllRaise(SyntaxError,
  426. 'cannot mix bytes and nonbytes literals',
  427. [r"""f'' b''""",
  428. r"""b'' f''""",
  429. ])
  430. def test_literal(self):
  431. self.assertEqual(f'', '')
  432. self.assertEqual(f'a', 'a')
  433. self.assertEqual(f' ', ' ')
  434. def test_unterminated_string(self):
  435. self.assertAllRaise(SyntaxError, 'f-string: unterminated string',
  436. [r"""f'{"x'""",
  437. r"""f'{"x}'""",
  438. r"""f'{("x'""",
  439. r"""f'{("x}'""",
  440. ])
  441. def test_mismatched_parens(self):
  442. self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' "
  443. r"does not match opening parenthesis '\('",
  444. ["f'{((}'",
  445. ])
  446. self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\)' "
  447. r"does not match opening parenthesis '\['",
  448. ["f'{a[4)}'",
  449. ])
  450. self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\]' "
  451. r"does not match opening parenthesis '\('",
  452. ["f'{a(4]}'",
  453. ])
  454. self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' "
  455. r"does not match opening parenthesis '\['",
  456. ["f'{a[4}'",
  457. ])
  458. self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' "
  459. r"does not match opening parenthesis '\('",
  460. ["f'{a(4}'",
  461. ])
  462. self.assertRaises(SyntaxError, eval, "f'{" + "("*500 + "}'")
  463. def test_double_braces(self):
  464. self.assertEqual(f'{{', '{')
  465. self.assertEqual(f'a{{', 'a{')
  466. self.assertEqual(f'{{b', '{b')
  467. self.assertEqual(f'a{{b', 'a{b')
  468. self.assertEqual(f'}}', '}')
  469. self.assertEqual(f'a}}', 'a}')
  470. self.assertEqual(f'}}b', '}b')
  471. self.assertEqual(f'a}}b', 'a}b')
  472. self.assertEqual(f'{{}}', '{}')
  473. self.assertEqual(f'a{{}}', 'a{}')
  474. self.assertEqual(f'{{b}}', '{b}')
  475. self.assertEqual(f'{{}}c', '{}c')
  476. self.assertEqual(f'a{{b}}', 'a{b}')
  477. self.assertEqual(f'a{{}}c', 'a{}c')
  478. self.assertEqual(f'{{b}}c', '{b}c')
  479. self.assertEqual(f'a{{b}}c', 'a{b}c')
  480. self.assertEqual(f'{{{10}', '{10')
  481. self.assertEqual(f'}}{10}', '}10')
  482. self.assertEqual(f'}}{{{10}', '}{10')
  483. self.assertEqual(f'}}a{{{10}', '}a{10')
  484. self.assertEqual(f'{10}{{', '10{')
  485. self.assertEqual(f'{10}}}', '10}')
  486. self.assertEqual(f'{10}}}{{', '10}{')
  487. self.assertEqual(f'{10}}}a{{' '}', '10}a{}')
  488. # Inside of strings, don't interpret doubled brackets.
  489. self.assertEqual(f'{"{{}}"}', '{{}}')
  490. self.assertAllRaise(TypeError, 'unhashable type',
  491. ["f'{ {{}} }'", # dict in a set
  492. ])
  493. def test_compile_time_concat(self):
  494. x = 'def'
  495. self.assertEqual('abc' f'## {x}ghi', 'abc## defghi')
  496. self.assertEqual('abc' f'{x}' 'ghi', 'abcdefghi')
  497. self.assertEqual('abc' f'{x}' 'gh' f'i{x:4}', 'abcdefghidef ')
  498. self.assertEqual('{x}' f'{x}', '{x}def')
  499. self.assertEqual('{x' f'{x}', '{xdef')
  500. self.assertEqual('{x}' f'{x}', '{x}def')
  501. self.assertEqual('{{x}}' f'{x}', '{{x}}def')
  502. self.assertEqual('{{x' f'{x}', '{{xdef')
  503. self.assertEqual('x}}' f'{x}', 'x}}def')
  504. self.assertEqual(f'{x}' 'x}}', 'defx}}')
  505. self.assertEqual(f'{x}' '', 'def')
  506. self.assertEqual('' f'{x}' '', 'def')
  507. self.assertEqual('' f'{x}', 'def')
  508. self.assertEqual(f'{x}' '2', 'def2')
  509. self.assertEqual('1' f'{x}' '2', '1def2')
  510. self.assertEqual('1' f'{x}', '1def')
  511. self.assertEqual(f'{x}' f'-{x}', 'def-def')
  512. self.assertEqual('' f'', '')
  513. self.assertEqual('' f'' '', '')
  514. self.assertEqual('' f'' '' f'', '')
  515. self.assertEqual(f'', '')
  516. self.assertEqual(f'' '', '')
  517. self.assertEqual(f'' '' f'', '')
  518. self.assertEqual(f'' '' f'' '', '')
  519. self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
  520. ["f'{3' f'}'", # can't concat to get a valid f-string
  521. ])
  522. def test_comments(self):
  523. # These aren't comments, since they're in strings.
  524. d = {'#': 'hash'}
  525. self.assertEqual(f'{"#"}', '#')
  526. self.assertEqual(f'{d["#"]}', 'hash')
  527. self.assertAllRaise(SyntaxError, "f-string expression part cannot include '#'",
  528. ["f'{1#}'", # error because the expression becomes "(1#)"
  529. "f'{3(#)}'",
  530. "f'{#}'",
  531. ])
  532. self.assertAllRaise(SyntaxError, r"f-string: unmatched '\)'",
  533. ["f'{)#}'", # When wrapped in parens, this becomes
  534. # '()#)'. Make sure that doesn't compile.
  535. ])
  536. def test_many_expressions(self):
  537. # Create a string with many expressions in it. Note that
  538. # because we have a space in here as a literal, we're actually
  539. # going to use twice as many ast nodes: one for each literal
  540. # plus one for each expression.
  541. def build_fstr(n, extra=''):
  542. return "f'" + ('{x} ' * n) + extra + "'"
  543. x = 'X'
  544. width = 1
  545. # Test around 256.
  546. for i in range(250, 260):
  547. self.assertEqual(eval(build_fstr(i)), (x+' ')*i)
  548. # Test concatenating 2 largs fstrings.
  549. self.assertEqual(eval(build_fstr(255)*256), (x+' ')*(255*256))
  550. s = build_fstr(253, '{x:{width}} ')
  551. self.assertEqual(eval(s), (x+' ')*254)
  552. # Test lots of expressions and constants, concatenated.
  553. s = "f'{1}' 'x' 'y'" * 1024
  554. self.assertEqual(eval(s), '1xy' * 1024)
  555. def test_format_specifier_expressions(self):
  556. width = 10
  557. precision = 4
  558. value = decimal.Decimal('12.34567')
  559. self.assertEqual(f'result: {value:{width}.{precision}}', 'result: 12.35')
  560. self.assertEqual(f'result: {value:{width!r}.{precision}}', 'result: 12.35')
  561. self.assertEqual(f'result: {value:{width:0}.{precision:1}}', 'result: 12.35')
  562. self.assertEqual(f'result: {value:{1}{0:0}.{precision:1}}', 'result: 12.35')
  563. self.assertEqual(f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result: 12.35')
  564. self.assertEqual(f'{10:#{1}0x}', ' 0xa')
  565. self.assertEqual(f'{10:{"#"}1{0}{"x"}}', ' 0xa')
  566. self.assertEqual(f'{-10:-{"#"}1{0}x}', ' -0xa')
  567. self.assertEqual(f'{-10:{"-"}#{1}0{"x"}}', ' -0xa')
  568. self.assertEqual(f'{10:#{3 != {4:5} and width}x}', ' 0xa')
  569. self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
  570. ["""f'{"s"!r{":10"}}'""",
  571. # This looks like a nested format spec.
  572. ])
  573. self.assertAllRaise(SyntaxError, "f-string: invalid syntax",
  574. [# Invalid syntax inside a nested spec.
  575. "f'{4:{/5}}'",
  576. ])
  577. self.assertAllRaise(SyntaxError, "f-string: expressions nested too deeply",
  578. [# Can't nest format specifiers.
  579. "f'result: {value:{width:{0}}.{precision:1}}'",
  580. ])
  581. self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character',
  582. [# No expansion inside conversion or for
  583. # the : or ! itself.
  584. """f'{"s"!{"r"}}'""",
  585. ])
  586. def test_side_effect_order(self):
  587. class X:
  588. def __init__(self):
  589. self.i = 0
  590. def __format__(self, spec):
  591. self.i += 1
  592. return str(self.i)
  593. x = X()
  594. self.assertEqual(f'{x} {x}', '1 2')
  595. def test_missing_expression(self):
  596. self.assertAllRaise(SyntaxError, 'f-string: empty expression not allowed',
  597. ["f'{}'",
  598. "f'{ }'"
  599. "f' {} '",
  600. "f'{10:{ }}'",
  601. "f' { } '",
  602. # The Python parser ignores also the following
  603. # whitespace characters in additional to a space.
  604. "f'''{\t\f\r\n}'''",
  605. ])
  606. # Different error messeges are raised when a specfier ('!', ':' or '=') is used after an empty expression
  607. self.assertAllRaise(SyntaxError, "f-string: expression required before '!'",
  608. ["f'{!r}'",
  609. "f'{ !r}'",
  610. "f'{!}'",
  611. "f'''{\t\f\r\n!a}'''",
  612. # Catch empty expression before the
  613. # missing closing brace.
  614. "f'{!'",
  615. "f'{!s:'",
  616. # Catch empty expression before the
  617. # invalid conversion.
  618. "f'{!x}'",
  619. "f'{ !xr}'",
  620. "f'{!x:}'",
  621. "f'{!x:a}'",
  622. "f'{ !xr:}'",
  623. "f'{ !xr:a}'",
  624. ])
  625. self.assertAllRaise(SyntaxError, "f-string: expression required before ':'",
  626. ["f'{:}'",
  627. "f'{ :!}'",
  628. "f'{:2}'",
  629. "f'''{\t\f\r\n:a}'''",
  630. "f'{:'",
  631. ])
  632. self.assertAllRaise(SyntaxError, "f-string: expression required before '='",
  633. ["f'{=}'",
  634. "f'{ =}'",
  635. "f'{ =:}'",
  636. "f'{ =!}'",
  637. "f'''{\t\f\r\n=}'''",
  638. "f'{='",
  639. ])
  640. # Different error message is raised for other whitespace characters.
  641. self.assertAllRaise(SyntaxError, r"invalid non-printable character U\+00A0",
  642. ["f'''{\xa0}'''",
  643. "\xa0",
  644. ])
  645. def test_parens_in_expressions(self):
  646. self.assertEqual(f'{3,}', '(3,)')
  647. # Add these because when an expression is evaluated, parens
  648. # are added around it. But we shouldn't go from an invalid
  649. # expression to a valid one. The added parens are just
  650. # supposed to allow whitespace (including newlines).
  651. self.assertAllRaise(SyntaxError, 'f-string: invalid syntax',
  652. ["f'{,}'",
  653. "f'{,}'", # this is (,), which is an error
  654. ])
  655. self.assertAllRaise(SyntaxError, r"f-string: unmatched '\)'",
  656. ["f'{3)+(4}'",
  657. ])
  658. self.assertAllRaise(SyntaxError, 'unterminated string literal',
  659. ["f'{\n}'",
  660. ])
  661. def test_newlines_before_syntax_error(self):
  662. self.assertAllRaise(SyntaxError, "invalid syntax",
  663. ["f'{.}'", "\nf'{.}'", "\n\nf'{.}'"])
  664. def test_backslashes_in_string_part(self):
  665. self.assertEqual(f'\t', '\t')
  666. self.assertEqual(r'\t', '\\t')
  667. self.assertEqual(rf'\t', '\\t')
  668. self.assertEqual(f'{2}\t', '2\t')
  669. self.assertEqual(f'{2}\t{3}', '2\t3')
  670. self.assertEqual(f'\t{3}', '\t3')
  671. self.assertEqual(f'\u0394', '\u0394')
  672. self.assertEqual(r'\u0394', '\\u0394')
  673. self.assertEqual(rf'\u0394', '\\u0394')
  674. self.assertEqual(f'{2}\u0394', '2\u0394')
  675. self.assertEqual(f'{2}\u0394{3}', '2\u03943')
  676. self.assertEqual(f'\u0394{3}', '\u03943')
  677. self.assertEqual(f'\U00000394', '\u0394')
  678. self.assertEqual(r'\U00000394', '\\U00000394')
  679. self.assertEqual(rf'\U00000394', '\\U00000394')
  680. self.assertEqual(f'{2}\U00000394', '2\u0394')
  681. self.assertEqual(f'{2}\U00000394{3}', '2\u03943')
  682. self.assertEqual(f'\U00000394{3}', '\u03943')
  683. self.assertEqual(f'\N{GREEK CAPITAL LETTER DELTA}', '\u0394')
  684. self.assertEqual(f'{2}\N{GREEK CAPITAL LETTER DELTA}', '2\u0394')
  685. self.assertEqual(f'{2}\N{GREEK CAPITAL LETTER DELTA}{3}', '2\u03943')
  686. self.assertEqual(f'\N{GREEK CAPITAL LETTER DELTA}{3}', '\u03943')
  687. self.assertEqual(f'2\N{GREEK CAPITAL LETTER DELTA}', '2\u0394')
  688. self.assertEqual(f'2\N{GREEK CAPITAL LETTER DELTA}3', '2\u03943')
  689. self.assertEqual(f'\N{GREEK CAPITAL LETTER DELTA}3', '\u03943')
  690. self.assertEqual(f'\x20', ' ')
  691. self.assertEqual(r'\x20', '\\x20')
  692. self.assertEqual(rf'\x20', '\\x20')
  693. self.assertEqual(f'{2}\x20', '2 ')
  694. self.assertEqual(f'{2}\x20{3}', '2 3')
  695. self.assertEqual(f'\x20{3}', ' 3')
  696. self.assertEqual(f'2\x20', '2 ')
  697. self.assertEqual(f'2\x203', '2 3')
  698. self.assertEqual(f'\x203', ' 3')
  699. with self.assertWarns(DeprecationWarning): # invalid escape sequence
  700. value = eval(r"f'\{6*7}'")
  701. self.assertEqual(value, '\\42')
  702. self.assertEqual(f'\\{6*7}', '\\42')
  703. self.assertEqual(fr'\{6*7}', '\\42')
  704. AMPERSAND = 'spam'
  705. # Get the right unicode character (&), or pick up local variable
  706. # depending on the number of backslashes.
  707. self.assertEqual(f'\N{AMPERSAND}', '&')
  708. self.assertEqual(f'\\N{AMPERSAND}', '\\Nspam')
  709. self.assertEqual(fr'\N{AMPERSAND}', '\\Nspam')
  710. self.assertEqual(f'\\\N{AMPERSAND}', '\\&')
  711. def test_misformed_unicode_character_name(self):
  712. # These test are needed because unicode names are parsed
  713. # differently inside f-strings.
  714. self.assertAllRaise(SyntaxError, r"\(unicode error\) 'unicodeescape' codec can't decode bytes in position .*: malformed \\N character escape",
  715. [r"f'\N'",
  716. r"f'\N '",
  717. r"f'\N '", # See bpo-46503.
  718. r"f'\N{'",
  719. r"f'\N{GREEK CAPITAL LETTER DELTA'",
  720. # Here are the non-f-string versions,
  721. # which should give the same errors.
  722. r"'\N'",
  723. r"'\N '",
  724. r"'\N '",
  725. r"'\N{'",
  726. r"'\N{GREEK CAPITAL LETTER DELTA'",
  727. ])
  728. def test_no_backslashes_in_expression_part(self):
  729. self.assertAllRaise(SyntaxError, 'f-string expression part cannot include a backslash',
  730. [r"f'{\'a\'}'",
  731. r"f'{\t3}'",
  732. r"f'{\}'",
  733. r"rf'{\'a\'}'",
  734. r"rf'{\t3}'",
  735. r"rf'{\}'",
  736. r"""rf'{"\N{LEFT CURLY BRACKET}"}'""",
  737. r"f'{\n}'",
  738. ])
  739. def test_no_escapes_for_braces(self):
  740. """
  741. Only literal curly braces begin an expression.
  742. """
  743. # \x7b is '{'.
  744. self.assertEqual(f'\x7b1+1}}', '{1+1}')
  745. self.assertEqual(f'\x7b1+1', '{1+1')
  746. self.assertEqual(f'\u007b1+1', '{1+1')
  747. self.assertEqual(f'\N{LEFT CURLY BRACKET}1+1\N{RIGHT CURLY BRACKET}', '{1+1}')
  748. def test_newlines_in_expressions(self):
  749. self.assertEqual(f'{0}', '0')
  750. self.assertEqual(rf'''{3+
  751. 4}''', '7')
  752. def test_lambda(self):
  753. x = 5
  754. self.assertEqual(f'{(lambda y:x*y)("8")!r}', "'88888'")
  755. self.assertEqual(f'{(lambda y:x*y)("8")!r:10}', "'88888' ")
  756. self.assertEqual(f'{(lambda y:x*y)("8"):10}', "88888 ")
  757. # lambda doesn't work without parens, because the colon
  758. # makes the parser think it's a format_spec
  759. self.assertAllRaise(SyntaxError, 'f-string: invalid syntax',
  760. ["f'{lambda x:x}'",
  761. ])
  762. def test_yield(self):
  763. # Not terribly useful, but make sure the yield turns
  764. # a function into a generator
  765. def fn(y):
  766. f'y:{yield y*2}'
  767. f'{yield}'
  768. g = fn(4)
  769. self.assertEqual(next(g), 8)
  770. self.assertEqual(next(g), None)
  771. def test_yield_send(self):
  772. def fn(x):
  773. yield f'x:{yield (lambda i: x * i)}'
  774. g = fn(10)
  775. the_lambda = next(g)
  776. self.assertEqual(the_lambda(4), 40)
  777. self.assertEqual(g.send('string'), 'x:string')
  778. def test_expressions_with_triple_quoted_strings(self):
  779. self.assertEqual(f"{'''x'''}", 'x')
  780. self.assertEqual(f"{'''eric's'''}", "eric's")
  781. # Test concatenation within an expression
  782. self.assertEqual(f'{"x" """eric"s""" "y"}', 'xeric"sy')
  783. self.assertEqual(f'{"x" """eric"s"""}', 'xeric"s')
  784. self.assertEqual(f'{"""eric"s""" "y"}', 'eric"sy')
  785. self.assertEqual(f'{"""x""" """eric"s""" "y"}', 'xeric"sy')
  786. self.assertEqual(f'{"""x""" """eric"s""" """y"""}', 'xeric"sy')
  787. self.assertEqual(f'{r"""x""" """eric"s""" """y"""}', 'xeric"sy')
  788. def test_multiple_vars(self):
  789. x = 98
  790. y = 'abc'
  791. self.assertEqual(f'{x}{y}', '98abc')
  792. self.assertEqual(f'X{x}{y}', 'X98abc')
  793. self.assertEqual(f'{x}X{y}', '98Xabc')
  794. self.assertEqual(f'{x}{y}X', '98abcX')
  795. self.assertEqual(f'X{x}Y{y}', 'X98Yabc')
  796. self.assertEqual(f'X{x}{y}Y', 'X98abcY')
  797. self.assertEqual(f'{x}X{y}Y', '98XabcY')
  798. self.assertEqual(f'X{x}Y{y}Z', 'X98YabcZ')
  799. def test_closure(self):
  800. def outer(x):
  801. def inner():
  802. return f'x:{x}'
  803. return inner
  804. self.assertEqual(outer('987')(), 'x:987')
  805. self.assertEqual(outer(7)(), 'x:7')
  806. def test_arguments(self):
  807. y = 2
  808. def f(x, width):
  809. return f'x={x*y:{width}}'
  810. self.assertEqual(f('foo', 10), 'x=foofoo ')
  811. x = 'bar'
  812. self.assertEqual(f(10, 10), 'x= 20')
  813. def test_locals(self):
  814. value = 123
  815. self.assertEqual(f'v:{value}', 'v:123')
  816. def test_missing_variable(self):
  817. with self.assertRaises(NameError):
  818. f'v:{value}'
  819. def test_missing_format_spec(self):
  820. class O:
  821. def __format__(self, spec):
  822. if not spec:
  823. return '*'
  824. return spec
  825. self.assertEqual(f'{O():x}', 'x')
  826. self.assertEqual(f'{O()}', '*')
  827. self.assertEqual(f'{O():}', '*')
  828. self.assertEqual(f'{3:}', '3')
  829. self.assertEqual(f'{3!s:}', '3')
  830. def test_global(self):
  831. self.assertEqual(f'g:{a_global}', 'g:global variable')
  832. self.assertEqual(f'g:{a_global!r}', "g:'global variable'")
  833. a_local = 'local variable'
  834. self.assertEqual(f'g:{a_global} l:{a_local}',
  835. 'g:global variable l:local variable')
  836. self.assertEqual(f'g:{a_global!r}',
  837. "g:'global variable'")
  838. self.assertEqual(f'g:{a_global} l:{a_local!r}',
  839. "g:global variable l:'local variable'")
  840. self.assertIn("module 'unittest' from", f'{unittest}')
  841. def test_shadowed_global(self):
  842. a_global = 'really a local'
  843. self.assertEqual(f'g:{a_global}', 'g:really a local')
  844. self.assertEqual(f'g:{a_global!r}', "g:'really a local'")
  845. a_local = 'local variable'
  846. self.assertEqual(f'g:{a_global} l:{a_local}',
  847. 'g:really a local l:local variable')
  848. self.assertEqual(f'g:{a_global!r}',
  849. "g:'really a local'")
  850. self.assertEqual(f'g:{a_global} l:{a_local!r}',
  851. "g:really a local l:'local variable'")
  852. def test_call(self):
  853. def foo(x):
  854. return 'x=' + str(x)
  855. self.assertEqual(f'{foo(10)}', 'x=10')
  856. def test_nested_fstrings(self):
  857. y = 5
  858. self.assertEqual(f'{f"{0}"*3}', '000')
  859. self.assertEqual(f'{f"{y}"*3}', '555')
  860. def test_invalid_string_prefixes(self):
  861. single_quote_cases = ["fu''",
  862. "uf''",
  863. "Fu''",
  864. "fU''",
  865. "Uf''",
  866. "uF''",
  867. "ufr''",
  868. "urf''",
  869. "fur''",
  870. "fru''",
  871. "rfu''",
  872. "ruf''",
  873. "FUR''",
  874. "Fur''",
  875. "fb''",
  876. "fB''",
  877. "Fb''",
  878. "FB''",
  879. "bf''",
  880. "bF''",
  881. "Bf''",
  882. "BF''",]
  883. double_quote_cases = [case.replace("'", '"') for case in single_quote_cases]
  884. self.assertAllRaise(SyntaxError, 'invalid syntax',
  885. single_quote_cases + double_quote_cases)
  886. def test_leading_trailing_spaces(self):
  887. self.assertEqual(f'{ 3}', '3')
  888. self.assertEqual(f'{ 3}', '3')
  889. self.assertEqual(f'{3 }', '3')
  890. self.assertEqual(f'{3 }', '3')
  891. self.assertEqual(f'expr={ {x: y for x, y in [(1, 2), ]}}',
  892. 'expr={1: 2}')
  893. self.assertEqual(f'expr={ {x: y for x, y in [(1, 2), ]} }',
  894. 'expr={1: 2}')
  895. def test_not_equal(self):
  896. # There's a special test for this because there's a special
  897. # case in the f-string parser to look for != as not ending an
  898. # expression. Normally it would, while looking for !s or !r.
  899. self.assertEqual(f'{3!=4}', 'True')
  900. self.assertEqual(f'{3!=4:}', 'True')
  901. self.assertEqual(f'{3!=4!s}', 'True')
  902. self.assertEqual(f'{3!=4!s:.3}', 'Tru')
  903. def test_equal_equal(self):
  904. # Because an expression ending in = has special meaning,
  905. # there's a special test for ==. Make sure it works.
  906. self.assertEqual(f'{0==1}', 'False')
  907. def test_conversions(self):
  908. self.assertEqual(f'{3.14:10.10}', ' 3.14')
  909. self.assertEqual(f'{3.14!s:10.10}', '3.14 ')
  910. self.assertEqual(f'{3.14!r:10.10}', '3.14 ')
  911. self.assertEqual(f'{3.14!a:10.10}', '3.14 ')
  912. self.assertEqual(f'{"a"}', 'a')
  913. self.assertEqual(f'{"a"!r}', "'a'")
  914. self.assertEqual(f'{"a"!a}', "'a'")
  915. # Not a conversion.
  916. self.assertEqual(f'{"a!r"}', "a!r")
  917. # Not a conversion, but show that ! is allowed in a format spec.
  918. self.assertEqual(f'{3.14:!<10.10}', '3.14!!!!!!')
  919. self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character',
  920. ["f'{3!g}'",
  921. "f'{3!A}'",
  922. "f'{3!3}'",
  923. "f'{3!G}'",
  924. "f'{3!!}'",
  925. "f'{3!:}'",
  926. "f'{3! s}'", # no space before conversion char
  927. ])
  928. self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
  929. ["f'{x!s{y}}'",
  930. "f'{3!ss}'",
  931. "f'{3!ss:}'",
  932. "f'{3!ss:s}'",
  933. ])
  934. def test_assignment(self):
  935. self.assertAllRaise(SyntaxError, r'invalid syntax',
  936. ["f'' = 3",
  937. "f'{0}' = x",
  938. "f'{x}' = x",
  939. ])
  940. def test_del(self):
  941. self.assertAllRaise(SyntaxError, 'invalid syntax',
  942. ["del f''",
  943. "del '' f''",
  944. ])
  945. def test_mismatched_braces(self):
  946. self.assertAllRaise(SyntaxError, "f-string: single '}' is not allowed",
  947. ["f'{{}'",
  948. "f'{{}}}'",
  949. "f'}'",
  950. "f'x}'",
  951. "f'x}x'",
  952. r"f'\u007b}'",
  953. # Can't have { or } in a format spec.
  954. "f'{3:}>10}'",
  955. "f'{3:}}>10}'",
  956. ])
  957. self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
  958. ["f'{3:{{>10}'",
  959. "f'{3'",
  960. "f'{3!'",
  961. "f'{3:'",
  962. "f'{3!s'",
  963. "f'{3!s:'",
  964. "f'{3!s:3'",
  965. "f'x{'",
  966. "f'x{x'",
  967. "f'{x'",
  968. "f'{3:s'",
  969. "f'{{{'",
  970. "f'{{}}{'",
  971. "f'{'",
  972. "f'x{<'", # See bpo-46762.
  973. "f'x{>'",
  974. "f'{i='", # See gh-93418.
  975. ])
  976. # But these are just normal strings.
  977. self.assertEqual(f'{"{"}', '{')
  978. self.assertEqual(f'{"}"}', '}')
  979. self.assertEqual(f'{3:{"}"}>10}', '}}}}}}}}}3')
  980. self.assertEqual(f'{2:{"{"}>10}', '{{{{{{{{{2')
  981. def test_if_conditional(self):
  982. # There's special logic in compile.c to test if the
  983. # conditional for an if (and while) are constants. Exercise
  984. # that code.
  985. def test_fstring(x, expected):
  986. flag = 0
  987. if f'{x}':
  988. flag = 1
  989. else:
  990. flag = 2
  991. self.assertEqual(flag, expected)
  992. def test_concat_empty(x, expected):
  993. flag = 0
  994. if '' f'{x}':
  995. flag = 1
  996. else:
  997. flag = 2
  998. self.assertEqual(flag, expected)
  999. def test_concat_non_empty(x, expected):
  1000. flag = 0
  1001. if ' ' f'{x}':
  1002. flag = 1
  1003. else:
  1004. flag = 2
  1005. self.assertEqual(flag, expected)
  1006. test_fstring('', 2)
  1007. test_fstring(' ', 1)
  1008. test_concat_empty('', 2)
  1009. test_concat_empty(' ', 1)
  1010. test_concat_non_empty('', 1)
  1011. test_concat_non_empty(' ', 1)
  1012. def test_empty_format_specifier(self):
  1013. x = 'test'
  1014. self.assertEqual(f'{x}', 'test')
  1015. self.assertEqual(f'{x:}', 'test')
  1016. self.assertEqual(f'{x!s:}', 'test')
  1017. self.assertEqual(f'{x!r:}', "'test'")
  1018. def test_str_format_differences(self):
  1019. d = {'a': 'string',
  1020. 0: 'integer',
  1021. }
  1022. a = 0
  1023. self.assertEqual(f'{d[0]}', 'integer')
  1024. self.assertEqual(f'{d["a"]}', 'string')
  1025. self.assertEqual(f'{d[a]}', 'integer')
  1026. self.assertEqual('{d[a]}'.format(d=d), 'string')
  1027. self.assertEqual('{d[0]}'.format(d=d), 'integer')
  1028. def test_errors(self):
  1029. # see issue 26287
  1030. self.assertAllRaise(TypeError, 'unsupported',
  1031. [r"f'{(lambda: 0):x}'",
  1032. r"f'{(0,):x}'",
  1033. ])
  1034. self.assertAllRaise(ValueError, 'Unknown format code',
  1035. [r"f'{1000:j}'",
  1036. r"f'{1000:j}'",
  1037. ])
  1038. def test_filename_in_syntaxerror(self):
  1039. # see issue 38964
  1040. with temp_cwd() as cwd:
  1041. file_path = os.path.join(cwd, 't.py')
  1042. with open(file_path, 'w', encoding="utf-8") as f:
  1043. f.write('f"{a b}"') # This generates a SyntaxError
  1044. _, _, stderr = assert_python_failure(file_path,
  1045. PYTHONIOENCODING='ascii')
  1046. self.assertIn(file_path.encode('ascii', 'backslashreplace'), stderr)
  1047. def test_loop(self):
  1048. for i in range(1000):
  1049. self.assertEqual(f'i:{i}', 'i:' + str(i))
  1050. def test_dict(self):
  1051. d = {'"': 'dquote',
  1052. "'": 'squote',
  1053. 'foo': 'bar',
  1054. }
  1055. self.assertEqual(f'''{d["'"]}''', 'squote')
  1056. self.assertEqual(f"""{d['"']}""", 'dquote')
  1057. self.assertEqual(f'{d["foo"]}', 'bar')
  1058. self.assertEqual(f"{d['foo']}", 'bar')
  1059. def test_backslash_char(self):
  1060. # Check eval of a backslash followed by a control char.
  1061. # See bpo-30682: this used to raise an assert in pydebug mode.
  1062. self.assertEqual(eval('f"\\\n"'), '')
  1063. self.assertEqual(eval('f"\\\r"'), '')
  1064. def test_debug_conversion(self):
  1065. x = 'A string'
  1066. self.assertEqual(f'{x=}', 'x=' + repr(x))
  1067. self.assertEqual(f'{x =}', 'x =' + repr(x))
  1068. self.assertEqual(f'{x=!s}', 'x=' + str(x))
  1069. self.assertEqual(f'{x=!r}', 'x=' + repr(x))
  1070. self.assertEqual(f'{x=!a}', 'x=' + ascii(x))
  1071. x = 2.71828
  1072. self.assertEqual(f'{x=:.2f}', 'x=' + format(x, '.2f'))
  1073. self.assertEqual(f'{x=:}', 'x=' + format(x, ''))
  1074. self.assertEqual(f'{x=!r:^20}', 'x=' + format(repr(x), '^20'))
  1075. self.assertEqual(f'{x=!s:^20}', 'x=' + format(str(x), '^20'))
  1076. self.assertEqual(f'{x=!a:^20}', 'x=' + format(ascii(x), '^20'))
  1077. x = 9
  1078. self.assertEqual(f'{3*x+15=}', '3*x+15=42')
  1079. # There is code in ast.c that deals with non-ascii expression values. So,
  1080. # use a unicode identifier to trigger that.
  1081. tenπ = 31.4
  1082. self.assertEqual(f'{tenπ=:.2f}', 'tenπ=31.40')
  1083. # Also test with Unicode in non-identifiers.
  1084. self.assertEqual(f'{"Σ"=}', '"Σ"=\'Σ\'')
  1085. # Make sure nested fstrings still work.
  1086. self.assertEqual(f'{f"{3.1415=:.1f}":*^20}', '*****3.1415=3.1*****')
  1087. # Make sure text before and after an expression with = works
  1088. # correctly.
  1089. pi = 'π'
  1090. self.assertEqual(f'alpha α {pi=} ω omega', "alpha α pi='π' ω omega")
  1091. # Check multi-line expressions.
  1092. self.assertEqual(f'''{
  1093. 3
  1094. =}''', '\n3\n=3')
  1095. # Since = is handled specially, make sure all existing uses of
  1096. # it still work.
  1097. self.assertEqual(f'{0==1}', 'False')
  1098. self.assertEqual(f'{0!=1}', 'True')
  1099. self.assertEqual(f'{0<=1}', 'True')
  1100. self.assertEqual(f'{0>=1}', 'False')
  1101. self.assertEqual(f'{(x:="5")}', '5')
  1102. self.assertEqual(x, '5')
  1103. self.assertEqual(f'{(x:=5)}', '5')
  1104. self.assertEqual(x, 5)
  1105. self.assertEqual(f'{"="}', '=')
  1106. x = 20
  1107. # This isn't an assignment expression, it's 'x', with a format
  1108. # spec of '=10'. See test_walrus: you need to use parens.
  1109. self.assertEqual(f'{x:=10}', ' 20')
  1110. # Test named function parameters, to make sure '=' parsing works
  1111. # there.
  1112. def f(a):
  1113. nonlocal x
  1114. oldx = x
  1115. x = a
  1116. return oldx
  1117. x = 0
  1118. self.assertEqual(f'{f(a="3=")}', '0')
  1119. self.assertEqual(x, '3=')
  1120. self.assertEqual(f'{f(a=4)}', '3=')
  1121. self.assertEqual(x, 4)
  1122. # Make sure __format__ is being called.
  1123. class C:
  1124. def __format__(self, s):
  1125. return f'FORMAT-{s}'
  1126. def __repr__(self):
  1127. return 'REPR'
  1128. self.assertEqual(f'{C()=}', 'C()=REPR')
  1129. self.assertEqual(f'{C()=!r}', 'C()=REPR')
  1130. self.assertEqual(f'{C()=:}', 'C()=FORMAT-')
  1131. self.assertEqual(f'{C()=: }', 'C()=FORMAT- ')
  1132. self.assertEqual(f'{C()=:x}', 'C()=FORMAT-x')
  1133. self.assertEqual(f'{C()=!r:*^20}', 'C()=********REPR********')
  1134. self.assertRaises(SyntaxError, eval, "f'{C=]'")
  1135. # Make sure leading and following text works.
  1136. x = 'foo'
  1137. self.assertEqual(f'X{x=}Y', 'Xx='+repr(x)+'Y')
  1138. # Make sure whitespace around the = works.
  1139. self.assertEqual(f'X{x =}Y', 'Xx ='+repr(x)+'Y')
  1140. self.assertEqual(f'X{x= }Y', 'Xx= '+repr(x)+'Y')
  1141. self.assertEqual(f'X{x = }Y', 'Xx = '+repr(x)+'Y')
  1142. # These next lines contains tabs. Backslash escapes don't
  1143. # work in f-strings.
  1144. # patchcheck doesn't like these tabs. So the only way to test
  1145. # this will be to dynamically created and exec the f-strings. But
  1146. # that's such a hassle I'll save it for another day. For now, convert
  1147. # the tabs to spaces just to shut up patchcheck.
  1148. #self.assertEqual(f'X{x =}Y', 'Xx\t='+repr(x)+'Y')
  1149. #self.assertEqual(f'X{x = }Y', 'Xx\t=\t'+repr(x)+'Y')
  1150. def test_walrus(self):
  1151. x = 20
  1152. # This isn't an assignment expression, it's 'x', with a format
  1153. # spec of '=10'.
  1154. self.assertEqual(f'{x:=10}', ' 20')
  1155. # This is an assignment expression, which requires parens.
  1156. self.assertEqual(f'{(x:=10)}', '10')
  1157. self.assertEqual(x, 10)
  1158. def test_invalid_syntax_error_message(self):
  1159. with self.assertRaisesRegex(SyntaxError, "f-string: invalid syntax"):
  1160. compile("f'{a $ b}'", "?", "exec")
  1161. def test_with_two_commas_in_format_specifier(self):
  1162. error_msg = re.escape("Cannot specify ',' with ','.")
  1163. with self.assertRaisesRegex(ValueError, error_msg):
  1164. f'{1:,,}'
  1165. def test_with_two_underscore_in_format_specifier(self):
  1166. error_msg = re.escape("Cannot specify '_' with '_'.")
  1167. with self.assertRaisesRegex(ValueError, error_msg):
  1168. f'{1:__}'
  1169. def test_with_a_commas_and_an_underscore_in_format_specifier(self):
  1170. error_msg = re.escape("Cannot specify both ',' and '_'.")
  1171. with self.assertRaisesRegex(ValueError, error_msg):
  1172. f'{1:,_}'
  1173. def test_with_an_underscore_and_a_comma_in_format_specifier(self):
  1174. error_msg = re.escape("Cannot specify both ',' and '_'.")
  1175. with self.assertRaisesRegex(ValueError, error_msg):
  1176. f'{1:_,}'
  1177. def test_syntax_error_for_starred_expressions(self):
  1178. error_msg = re.escape("cannot use starred expression here")
  1179. with self.assertRaisesRegex(SyntaxError, error_msg):
  1180. compile("f'{*a}'", "?", "exec")
  1181. error_msg = re.escape("cannot use double starred expression here")
  1182. with self.assertRaisesRegex(SyntaxError, error_msg):
  1183. compile("f'{**a}'", "?", "exec")
  1184. if __name__ == '__main__':
  1185. unittest.main()