Skip to content
This repository was archived by the owner on Jul 5, 2023. It is now read-only.

Commit 7735bfa

Browse files
ilevkivskyiddfisher
authored andcommitted
Implement PEP 526 Variable Annotations Syntax (#16)
An implementation of the PEP 526 syntax with minimal changes in typed_ast API. The only externally visible change is: ``` Assign(expr* targets, expr? value, string? type_comment, expr? annotation) ```
1 parent f4495f4 commit 7735bfa

File tree

10 files changed

+1164
-1045
lines changed

10 files changed

+1164
-1045
lines changed

ast35/Grammar/Grammar

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ stmt: simple_stmt | compound_stmt
4444
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
4545
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
4646
import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
47-
expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
47+
expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
4848
('=' (yield_expr|testlist_star_expr))* [TYPE_COMMENT])
49+
annassign: ':' test ['=' test]
4950
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
5051
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
5152
'<<=' | '>>=' | '**=' | '//=')

ast35/Include/Python-ast.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ struct _stmt {
119119
asdl_seq *targets;
120120
expr_ty value;
121121
string type_comment;
122+
expr_ty annotation;
122123
} Assign;
123124

124125
struct {
@@ -468,9 +469,10 @@ stmt_ty _Ta35_Return(expr_ty value, int lineno, int col_offset, PyArena *arena);
468469
#define Delete(a0, a1, a2, a3) _Ta35_Delete(a0, a1, a2, a3)
469470
stmt_ty _Ta35_Delete(asdl_seq * targets, int lineno, int col_offset, PyArena
470471
*arena);
471-
#define Assign(a0, a1, a2, a3, a4, a5) _Ta35_Assign(a0, a1, a2, a3, a4, a5)
472+
#define Assign(a0, a1, a2, a3, a4, a5, a6) _Ta35_Assign(a0, a1, a2, a3, a4, a5, a6)
472473
stmt_ty _Ta35_Assign(asdl_seq * targets, expr_ty value, string type_comment,
473-
int lineno, int col_offset, PyArena *arena);
474+
expr_ty annotation, int lineno, int col_offset, PyArena
475+
*arena);
474476
#define AugAssign(a0, a1, a2, a3, a4, a5) _Ta35_AugAssign(a0, a1, a2, a3, a4, a5)
475477
stmt_ty _Ta35_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
476478
lineno, int col_offset, PyArena *arena);

ast35/Include/compile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
#define Py_single_input 256
77
#define Py_file_input 257
88
#define Py_eval_input 258
9-
#define Py_func_type_input 341
9+
#define Py_func_type_input 342
1010

1111
#endif /* !Ta35_COMPILE_H */

ast35/Include/graminit.h

Lines changed: 72 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -17,74 +17,75 @@
1717
#define simple_stmt 270
1818
#define small_stmt 271
1919
#define expr_stmt 272
20-
#define testlist_star_expr 273
21-
#define augassign 274
22-
#define del_stmt 275
23-
#define pass_stmt 276
24-
#define flow_stmt 277
25-
#define break_stmt 278
26-
#define continue_stmt 279
27-
#define return_stmt 280
28-
#define yield_stmt 281
29-
#define raise_stmt 282
30-
#define import_stmt 283
31-
#define import_name 284
32-
#define import_from 285
33-
#define import_as_name 286
34-
#define dotted_as_name 287
35-
#define import_as_names 288
36-
#define dotted_as_names 289
37-
#define dotted_name 290
38-
#define global_stmt 291
39-
#define nonlocal_stmt 292
40-
#define assert_stmt 293
41-
#define compound_stmt 294
42-
#define async_stmt 295
43-
#define if_stmt 296
44-
#define while_stmt 297
45-
#define for_stmt 298
46-
#define try_stmt 299
47-
#define with_stmt 300
48-
#define with_item 301
49-
#define except_clause 302
50-
#define suite 303
51-
#define test 304
52-
#define test_nocond 305
53-
#define lambdef 306
54-
#define lambdef_nocond 307
55-
#define or_test 308
56-
#define and_test 309
57-
#define not_test 310
58-
#define comparison 311
59-
#define comp_op 312
60-
#define star_expr 313
61-
#define expr 314
62-
#define xor_expr 315
63-
#define and_expr 316
64-
#define shift_expr 317
65-
#define arith_expr 318
66-
#define term 319
67-
#define factor 320
68-
#define power 321
69-
#define atom_expr 322
70-
#define atom 323
71-
#define testlist_comp 324
72-
#define trailer 325
73-
#define subscriptlist 326
74-
#define subscript 327
75-
#define sliceop 328
76-
#define exprlist 329
77-
#define testlist 330
78-
#define dictorsetmaker 331
79-
#define classdef 332
80-
#define arglist 333
81-
#define argument 334
82-
#define comp_iter 335
83-
#define comp_for 336
84-
#define comp_if 337
85-
#define encoding_decl 338
86-
#define yield_expr 339
87-
#define yield_arg 340
88-
#define func_type_input 341
89-
#define func_type 342
90-
#define typelist 343
20+
#define annassign 273
21+
#define testlist_star_expr 274
22+
#define augassign 275
23+
#define del_stmt 276
24+
#define pass_stmt 277
25+
#define flow_stmt 278
26+
#define break_stmt 279
27+
#define continue_stmt 280
28+
#define return_stmt 281
29+
#define yield_stmt 282
30+
#define raise_stmt 283
31+
#define import_stmt 284
32+
#define import_name 285
33+
#define import_from 286
34+
#define import_as_name 287
35+
#define dotted_as_name 288
36+
#define import_as_names 289
37+
#define dotted_as_names 290
38+
#define dotted_name 291
39+
#define global_stmt 292
40+
#define nonlocal_stmt 293
41+
#define assert_stmt 294
42+
#define compound_stmt 295
43+
#define async_stmt 296
44+
#define if_stmt 297
45+
#define while_stmt 298
46+
#define for_stmt 299
47+
#define try_stmt 300
48+
#define with_stmt 301
49+
#define with_item 302
50+
#define except_clause 303
51+
#define suite 304
52+
#define test 305
53+
#define test_nocond 306
54+
#define lambdef 307
55+
#define lambdef_nocond 308
56+
#define or_test 309
57+
#define and_test 310
58+
#define not_test 311
59+
#define comparison 312
60+
#define comp_op 313
61+
#define star_expr 314
62+
#define expr 315
63+
#define xor_expr 316
64+
#define and_expr 317
65+
#define shift_expr 318
66+
#define arith_expr 319
67+
#define term 320
68+
#define factor 321
69+
#define power 322
70+
#define atom_expr 323
71+
#define atom 324
72+
#define testlist_comp 325
73+
#define trailer 326
74+
#define subscriptlist 327
75+
#define subscript 328
76+
#define sliceop 329
77+
#define exprlist 330
78+
#define testlist 331
79+
#define dictorsetmaker 332
80+
#define classdef 333
81+
#define arglist 334
82+
#define argument 335
83+
#define comp_iter 336
84+
#define comp_for 337
85+
#define comp_if 338
86+
#define encoding_decl 339
87+
#define yield_expr 340
88+
#define yield_arg 341
89+
#define func_type_input 342
90+
#define func_type 343
91+
#define typelist 344

ast35/Parser/Python.asdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module Python
2323
| Return(expr? value)
2424

2525
| Delete(expr* targets)
26-
| Assign(expr* targets, expr value, string? type_comment)
26+
| Assign(expr* targets, expr? value, string? type_comment, expr? annotation)
2727
| AugAssign(expr target, operator op, expr value)
2828

2929
-- use 'orelse' because else is a keyword in target languages

ast35/Python/Python-ast.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ static char *Delete_fields[]={
8585
"targets",
8686
};
8787
static PyTypeObject *Assign_type;
88+
_Py_IDENTIFIER(annotation);
8889
static char *Assign_fields[]={
8990
"targets",
9091
"value",
9192
"type_comment",
93+
"annotation",
9294
};
9395
static PyTypeObject *AugAssign_type;
9496
_Py_IDENTIFIER(target);
@@ -464,7 +466,6 @@ static char *arg_attributes[] = {
464466
"col_offset",
465467
};
466468
_Py_IDENTIFIER(arg);
467-
_Py_IDENTIFIER(annotation);
468469
static char *arg_fields[]={
469470
"arg",
470471
"annotation",
@@ -862,7 +863,7 @@ static int init_types(void)
862863
if (!Return_type) return 0;
863864
Delete_type = make_type("Delete", stmt_type, Delete_fields, 1);
864865
if (!Delete_type) return 0;
865-
Assign_type = make_type("Assign", stmt_type, Assign_fields, 3);
866+
Assign_type = make_type("Assign", stmt_type, Assign_fields, 4);
866867
if (!Assign_type) return 0;
867868
AugAssign_type = make_type("AugAssign", stmt_type, AugAssign_fields, 3);
868869
if (!AugAssign_type) return 0;
@@ -1369,22 +1370,18 @@ Delete(asdl_seq * targets, int lineno, int col_offset, PyArena *arena)
13691370
}
13701371

13711372
stmt_ty
1372-
Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int
1373-
col_offset, PyArena *arena)
1373+
Assign(asdl_seq * targets, expr_ty value, string type_comment, expr_ty
1374+
annotation, int lineno, int col_offset, PyArena *arena)
13741375
{
13751376
stmt_ty p;
1376-
if (!value) {
1377-
PyErr_SetString(PyExc_ValueError,
1378-
"field value is required for Assign");
1379-
return NULL;
1380-
}
13811377
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
13821378
if (!p)
13831379
return NULL;
13841380
p->kind = Assign_kind;
13851381
p->v.Assign.targets = targets;
13861382
p->v.Assign.value = value;
13871383
p->v.Assign.type_comment = type_comment;
1384+
p->v.Assign.annotation = annotation;
13881385
p->lineno = lineno;
13891386
p->col_offset = col_offset;
13901387
return p;
@@ -2729,6 +2726,11 @@ ast2obj_stmt(void* _o)
27292726
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
27302727
goto failed;
27312728
Py_DECREF(value);
2729+
value = ast2obj_expr(o->v.Assign.annotation);
2730+
if (!value) goto failed;
2731+
if (_PyObject_SetAttrId(result, &PyId_annotation, value) == -1)
2732+
goto failed;
2733+
Py_DECREF(value);
27322734
break;
27332735
case AugAssign_kind:
27342736
result = PyType_GenericNew(AugAssign_type, NULL, NULL);
@@ -4554,6 +4556,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
45544556
asdl_seq* targets;
45554557
expr_ty value;
45564558
string type_comment;
4559+
expr_ty annotation;
45574560

45584561
if (_PyObject_HasAttrId(obj, &PyId_targets)) {
45594562
int res;
@@ -4579,16 +4582,15 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
45794582
PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Assign");
45804583
return 1;
45814584
}
4582-
if (_PyObject_HasAttrId(obj, &PyId_value)) {
4585+
if (exists_not_none(obj, &PyId_value)) {
45834586
int res;
45844587
tmp = _PyObject_GetAttrId(obj, &PyId_value);
45854588
if (tmp == NULL) goto failed;
45864589
res = obj2ast_expr(tmp, &value, arena);
45874590
if (res != 0) goto failed;
45884591
Py_CLEAR(tmp);
45894592
} else {
4590-
PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Assign");
4591-
return 1;
4593+
value = NULL;
45924594
}
45934595
if (exists_not_none(obj, &PyId_type_comment)) {
45944596
int res;
@@ -4600,7 +4602,18 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
46004602
} else {
46014603
type_comment = NULL;
46024604
}
4603-
*out = Assign(targets, value, type_comment, lineno, col_offset, arena);
4605+
if (exists_not_none(obj, &PyId_annotation)) {
4606+
int res;
4607+
tmp = _PyObject_GetAttrId(obj, &PyId_annotation);
4608+
if (tmp == NULL) goto failed;
4609+
res = obj2ast_expr(tmp, &annotation, arena);
4610+
if (res != 0) goto failed;
4611+
Py_CLEAR(tmp);
4612+
} else {
4613+
annotation = NULL;
4614+
}
4615+
*out = Assign(targets, value, type_comment, annotation, lineno,
4616+
col_offset, arena);
46044617
if (*out == NULL) goto failed;
46054618
return 0;
46064619
}

0 commit comments

Comments
 (0)