Skip to content

Commit 7f88115

Browse files
author
Lukasz Langa
committed
Response to Serhiy's review
1 parent bc3ad37 commit 7f88115

File tree

5 files changed

+440
-457
lines changed

5 files changed

+440
-457
lines changed

Include/ast.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@ PyAPI_FUNC(mod_ty) PyAST_FromNodeObject(
1515
PyCompilerFlags *flags,
1616
PyObject *filename,
1717
PyArena *arena);
18-
PyAPI_FUNC(PyObject *) PyAST_UnicodeFromAstExpr(
18+
19+
#ifndef Py_LIMITED_API
20+
21+
/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */
22+
PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(
1923
expr_ty e,
2024
int omit_parens,
2125
int omit_string_brackets);
2226

27+
#endif /* !Py_LIMITED_API */
28+
2329
#ifdef __cplusplus
2430
}
2531
#endif

Lib/test/test_future.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ class AnnotationsFutureTestCase(unittest.TestCase):
110110
from __future__ import annotations
111111
def f() -> {ann}:
112112
...
113+
def g(arg: {ann}) -> None:
114+
...
113115
var: {ann}
114116
var2: {ann} = None
115117
"""
@@ -118,12 +120,14 @@ def f() -> {ann}:
118120
def getActual(self, annotation):
119121
scope = {}
120122
exec(self.template.format(ann=annotation), {}, scope)
121-
func_ann = scope['f'].__annotations__['return']
123+
func_ret_ann = scope['f'].__annotations__['return']
124+
func_arg_ann = scope['g'].__annotations__['arg']
122125
var_ann1 = scope['__annotations__']['var']
123126
var_ann2 = scope['__annotations__']['var2']
124-
self.assertEqual(func_ann, var_ann1)
125-
self.assertEqual(func_ann, var_ann2)
126-
return func_ann
127+
self.assertEqual(func_ret_ann, func_arg_ann)
128+
self.assertEqual(func_ret_ann, var_ann1)
129+
self.assertEqual(func_ret_ann, var_ann2)
130+
return func_ret_ann
127131

128132
def assertAnnotationEqual(
129133
self, annotation, drop_parens=False, is_tuple=False
@@ -162,41 +166,44 @@ def test_annotations(self):
162166
eq('Name1 or (Name2 and Name3)')
163167
eq('(Name1 and Name2) or (Name3 and Name4)')
164168
eq('Name1 or (Name2 and Name3) or Name4')
165-
eq('1 << 2')
166-
eq('1 >> 2')
167-
eq('((1 + 2) - (3 * 4)) ^ (((5 ** 6) / 7) // 8)')
168-
eq('not True')
169-
eq('~True')
170-
eq('+1')
169+
eq('v1 << 2')
170+
eq('1 >> v2')
171+
eq(r'1 % finished')
172+
eq('((1 + v2) - (v3 * 4)) ^ (((5 ** v6) / 7) // 8)')
173+
eq('not great')
174+
eq('~great')
175+
eq('+value')
171176
eq('-1')
172-
eq('(~int) and (not ((True ^ (123 + 2)) | True))')
177+
eq('(~int) and (not ((v1 ^ (123 + v2)) | True))')
173178
eq('lambda arg: None')
174179
eq('lambda a=True: a')
175180
eq('lambda a, b, c=True: a')
176-
eq("lambda a, b, c=True, *, d=(1 << 2), e='str': a")
177-
eq("lambda a, b, c=True, *vararg, d=(1 << 2), e='str', **kwargs: a + b")
181+
eq("lambda a, b, c=True, *, d=(1 << v2), e='str': a")
182+
eq("lambda a, b, c=True, *vararg, d=(v1 << 2), e='str', **kwargs: a + b")
178183
eq('1 if True else 2')
179184
eq('(str or None) if True else (str or bytes or None)')
180185
eq('(str or None) if (1 if True else 2) else (str or bytes or None)')
181186
eq("{'2.7': dead, '3.7': (long_live or die_hard)}")
182187
eq("{'2.7': dead, '3.7': (long_live or die_hard), **{'3.6': verygood}}")
183188
eq("{**a, **b, **c}")
184189
eq("{'2.7', '3.6', '3.7', '3.8', '3.9', ('4.0' if gilectomy else '3.10')}")
185-
eq("({'a': 'b'}, (True or False), (+1), 'string', b'bytes') or None")
190+
eq("({'a': 'b'}, (True or False), (+value), 'string', b'bytes') or None")
186191
eq("()")
187-
eq("(1, )")
192+
eq("(1,)")
193+
eq("(1, 2)")
194+
eq("(1, 2, 3)")
188195
eq("[]")
189196
eq("[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]")
190197
eq("{i for i in (1, 2, 3)}")
191198
eq("{(i ** 2) for i in (1, 2, 3)}")
192-
eq("{(i ** 2) for i, _ in [(1, 'a'), (2, 'b'), (3, 'c')]}")
199+
eq("{(i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}")
193200
eq("{((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3)}")
194201
eq("[i for i in (1, 2, 3)]")
195202
eq("[(i ** 2) for i in (1, 2, 3)]")
196-
eq("[(i ** 2) for i, _ in [(1, 'a'), (2, 'b'), (3, 'c')]]")
203+
eq("[(i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))]")
197204
eq("[((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3)]")
198-
eq("{i: 0 for i in (1, 2, 3)}")
199-
eq("{i: j for i, j in [(1, 'a'), (2, 'b'), (3, 'c')]}")
205+
eq(r"{i: 0 for i in (1, 2, 3)}")
206+
eq("{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}")
200207
eq("Python3 > Python2 > COBOL")
201208
eq("Life is Life")
202209
eq("call()")
@@ -206,11 +213,21 @@ def test_annotations(self):
206213
eq("call(arg, another, kwarg='hey', **kwargs)")
207214
eq("lukasz.langa.pl")
208215
eq("call.me(maybe)")
216+
eq("1 .real")
217+
eq("1.0 .real")
218+
eq("....__class__")
209219
eq("list[str]")
210220
eq("dict[str, int]")
211221
eq("tuple[str, ...]")
212222
eq("tuple[str, int, float, dict[str, int]]")
213-
eq('(str or None) if (sys.version_info[0] > (3, )) else (str or bytes or None)')
223+
eq("slice[0]")
224+
eq("slice[0:1]")
225+
eq("slice[0:1:2]")
226+
eq("slice[:]")
227+
eq("slice[:-1]")
228+
eq("slice[1:]")
229+
eq("slice[::-1]")
230+
eq('(str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None)')
214231

215232
def test_annotations_no_fstring_support_implemented(self):
216233
# FIXME: Add f-string support in ast_unparse.c.
@@ -234,8 +251,8 @@ def test_annotations_inexact(self):
234251
eq('Name1 or Name2 and Name3')
235252
eq('Name1 and Name2 or Name3 and Name4')
236253
eq('Name1 or Name2 and Name3 or Name4')
237-
eq('1 + 2 - 3 * 4 ^ 5 ** 6 / 7 // 8')
238-
eq('~int and not True ^ 123 + 2 | True')
254+
eq('1 + v2 - v3 * 4 ^ v5 ** 6 / 7 // 8')
255+
eq('~int and not v1 ^ 123 + v2 | True')
239256
eq('str or None if True else str or bytes or None')
240257
eq("{'2.7': dead, '3.7': long_live or die_hard}")
241258
eq("{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}")
@@ -252,7 +269,7 @@ def test_annotations_inexact(self):
252269
eq("(Good, Bad, Ugly)")
253270
eq("(i for i in (1, 2, 3))")
254271
eq("((i ** 2) for i in (1, 2, 3))")
255-
eq("((i ** 2) for i, _ in [(1, 'a'), (2, 'b'), (3, 'c')])")
272+
eq("((i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))")
256273
eq("(((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3))")
257274
eq("(*starred)")
258275
eq('(yield from outside_of_generator)')

PCbuild/pythoncore.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,9 @@
827827
<ClCompile Include="..\Python\ast_opt.c">
828828
<Filter>Python</Filter>
829829
</ClCompile>
830+
<ClCompile Include="..\Python\ast_unparse.c">
831+
<Filter>Python</Filter>
832+
</ClCompile>
830833
<ClCompile Include="..\Python\bltinmodule.c">
831834
<Filter>Python</Filter>
832835
</ClCompile>

0 commit comments

Comments
 (0)