summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_fstring.py109
-rw-r--r--Lib/test/test_future.py9
2 files changed, 118 insertions, 0 deletions
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py
index 9d60be3..a0fae50 100644
--- a/Lib/test/test_fstring.py
+++ b/Lib/test/test_fstring.py
@@ -1,3 +1,12 @@
+# -*- coding: utf-8 -*-
+# There are tests here with unicode string literals and
+# identifiers. There's a code in ast.c that was added because of a
+# failure with a non-ascii-only expression. So, I have tests for
+# that. There are workarounds that would let me run tests for that
+# code without unicode identifiers and strings, but just using them
+# directly seems like the easiest and therefore safest thing to do.
+# Unicode identifiers in tests is allowed by PEP 3131.
+
import ast
import types
import decimal
@@ -878,6 +887,12 @@ non-important content
self.assertEqual(f'{3!=4!s}', 'True')
self.assertEqual(f'{3!=4!s:.3}', 'Tru')
+ def test_equal_equal(self):
+ # Because an expression ending in = has special meaning,
+ # there's a special test for ==. Make sure it works.
+
+ self.assertEqual(f'{0==1}', 'False')
+
def test_conversions(self):
self.assertEqual(f'{3.14:10.10}', ' 3.14')
self.assertEqual(f'{3.14!s:10.10}', '3.14 ')
@@ -1049,6 +1064,100 @@ non-important content
self.assertEqual(eval('f"\\\n"'), '')
self.assertEqual(eval('f"\\\r"'), '')
+ def test_debug_conversion(self):
+ x = 'A string'
+ self.assertEqual(f'{x=}', 'x=' + repr(x))
+ self.assertEqual(f'{x =}', 'x =' + repr(x))
+ self.assertEqual(f'{x=!s}', 'x=' + str(x))
+ self.assertEqual(f'{x=!r}', 'x=' + repr(x))
+ self.assertEqual(f'{x=!a}', 'x=' + ascii(x))
+
+ x = 2.71828
+ self.assertEqual(f'{x=:.2f}', 'x=' + format(x, '.2f'))
+ self.assertEqual(f'{x=:}', 'x=' + format(x, ''))
+ self.assertEqual(f'{x=!r:^20}', 'x=' + format(repr(x), '^20'))
+ self.assertEqual(f'{x=!s:^20}', 'x=' + format(str(x), '^20'))
+ self.assertEqual(f'{x=!a:^20}', 'x=' + format(ascii(x), '^20'))
+
+ x = 9
+ self.assertEqual(f'{3*x+15=}', '3*x+15=42')
+
+ # There is code in ast.c that deals with non-ascii expression values. So,
+ # use a unicode identifier to trigger that.
+ tenπ = 31.4
+ self.assertEqual(f'{tenπ=:.2f}', 'tenπ=31.40')
+
+ # Also test with Unicode in non-identifiers.
+ self.assertEqual(f'{"Σ"=}', '"Σ"=\'Σ\'')
+
+ # Make sure nested fstrings still work.
+ self.assertEqual(f'{f"{3.1415=:.1f}":*^20}', '*****3.1415=3.1*****')
+
+ # Make sure text before and after an expression with = works
+ # correctly.
+ pi = 'π'
+ self.assertEqual(f'alpha α {pi=} ω omega', "alpha α pi='π' ω omega")
+
+ # Check multi-line expressions.
+ self.assertEqual(f'''{
+3
+=}''', '\n3\n=3')
+
+ # Since = is handled specially, make sure all existing uses of
+ # it still work.
+
+ self.assertEqual(f'{0==1}', 'False')
+ self.assertEqual(f'{0!=1}', 'True')
+ self.assertEqual(f'{0<=1}', 'True')
+ self.assertEqual(f'{0>=1}', 'False')
+ self.assertEqual(f'{(x:="5")}', '5')
+ self.assertEqual(x, '5')
+ self.assertEqual(f'{(x:=5)}', '5')
+ self.assertEqual(x, 5)
+ self.assertEqual(f'{"="}', '=')
+
+ x = 20
+ # This isn't an assignment expression, it's 'x', with a format
+ # spec of '=10'. See test_walrus: you need to use parens.
+ self.assertEqual(f'{x:=10}', ' 20')
+
+ # Test named function parameters, to make sure '=' parsing works
+ # there.
+ def f(a):
+ nonlocal x
+ oldx = x
+ x = a
+ return oldx
+ x = 0
+ self.assertEqual(f'{f(a="3=")}', '0')
+ self.assertEqual(x, '3=')
+ self.assertEqual(f'{f(a=4)}', '3=')
+ self.assertEqual(x, 4)
+
+ # Make sure __format__ is being called.
+ class C:
+ def __format__(self, s):
+ return f'FORMAT-{s}'
+ def __repr__(self):
+ return 'REPR'
+
+ self.assertEqual(f'{C()=}', 'C()=REPR')
+ self.assertEqual(f'{C()=!r}', 'C()=REPR')
+ self.assertEqual(f'{C()=:}', 'C()=FORMAT-')
+ self.assertEqual(f'{C()=: }', 'C()=FORMAT- ')
+ self.assertEqual(f'{C()=:x}', 'C()=FORMAT-x')
+ self.assertEqual(f'{C()=!r:*^20}', 'C()=********REPR********')
+
+ def test_walrus(self):
+ x = 20
+ # This isn't an assignment expression, it's 'x', with a format
+ # spec of '=10'.
+ self.assertEqual(f'{x:=10}', ' 20')
+
+ # This is an assignment expression, which requires parens.
+ self.assertEqual(f'{(x:=10)}', '10')
+ self.assertEqual(x, 10)
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py
index c60a016..38de3df 100644
--- a/Lib/test/test_future.py
+++ b/Lib/test/test_future.py
@@ -255,6 +255,15 @@ class AnnotationsFutureTestCase(unittest.TestCase):
eq("f'space between opening braces: { {a for a in (1, 2, 3)}}'")
eq("f'{(lambda x: x)}'")
eq("f'{(None if a else lambda x: x)}'")
+ eq("f'{x}'")
+ eq("f'{x!r}'")
+ eq("f'{x!a}'")
+ eq("f'{x=!r}'")
+ eq("f'{x=:}'")
+ eq("f'{x=:.2f}'")
+ eq("f'{x=!r}'")
+ eq("f'{x=!a}'")
+ eq("f'{x=!s:*^20}'")
eq('(yield from outside_of_generator)')
eq('(yield)')
eq('(yield a + b)')