Skip to content

Commit

Permalink
add the missing tests, remove IS_PSEUDO_BLOCK macro
Browse files Browse the repository at this point in the history
  • Loading branch information
isidentical committed May 1, 2021
1 parent 5c7d796 commit 7493334
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
18 changes: 15 additions & 3 deletions Lib/test/test_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,13 +377,25 @@ def test_annotations_forbidden(self):
self._exec_future("test: (yield)")

with self.assertRaises(SyntaxError):
self._exec_future("test: (yield from x)")
self._exec_future("test.test: (yield a + b)")

with self.assertRaises(SyntaxError):
self._exec_future("test: (await y)")
self._exec_future("test[something]: (yield from x)")

with self.assertRaises(SyntaxError):
self._exec_future("test: something((a := b))")
self._exec_future("def func(test: (yield from outside_of_generator)): pass")

with self.assertRaises(SyntaxError):
self._exec_future("def test() -> (await y): pass")

with self.assertRaises(SyntaxError):
self._exec_future("async def test() -> something((a := b)): pass")

with self.assertRaises(SyntaxError):
self._exec_future("test: await some.complicated[0].call(with_args=True or 1 is not 1)")

with self.assertRaises(SyntaxError):
self._exec_future("test: f'{(x := 10):=10}'")

with self.assertRaises(SyntaxError):
self._exec_future(dedent("""\
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
Usage of ``await``/``yield``/``yield from`` and named expressions within an
annotation is now forbidden when PEP 563 is activated. Also the annotations
won't interact with symbol table at all, and will be considered no different
than strings.
annotation is now forbidden when PEP 563 is activated.
47 changes: 27 additions & 20 deletions Python/symtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@
#define ANNOTATION_NOT_ALLOWED \
"'%s' can not be used within an annotation"

// Annotation blocks shouldn't have any affect on the symbol table
// since in the compilation stage, they will all be transformed to
// strings.
#define IS_PSUEDO_BLOCK(BLOCK) (BLOCK == AnnotationBlock)

static PySTEntryObject *
ste_new(struct symtable *st, identifier name, _Py_block_ty block,
Expand Down Expand Up @@ -224,7 +220,7 @@ static int symtable_visit_annotations(struct symtable *st, stmt_ty, arguments_ty
static int symtable_visit_withitem(struct symtable *st, withitem_ty item);
static int symtable_visit_match_case(struct symtable *st, match_case_ty m);
static int symtable_visit_pattern(struct symtable *st, pattern_ty s);
static int symtable_check_annotation(struct symtable *st, const char *, expr_ty);
static int symtable_raise_if_annotation_block(struct symtable *st, const char *, expr_ty);


static identifier top = NULL, lambda = NULL, genexpr = NULL,
Expand Down Expand Up @@ -997,9 +993,18 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
/* The entry is owned by the stack. Borrow it for st_cur. */
Py_DECREF(ste);
st->st_cur = ste;

/* Annotation blocks shouldn't have any affect on the symbol table since in
* the compilation stage, they will all be transformed to strings. They are
* only created if future 'annotations' feature is activated. */
if (block == AnnotationBlock) {
return 1;
}

if (block == ModuleBlock)
st->st_global = st->st_cur->ste_symbols;
if (prev && !IS_PSUEDO_BLOCK(block)) {

if (prev) {
if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) {
return 0;
}
Expand Down Expand Up @@ -1577,7 +1582,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
}
switch (e->kind) {
case NamedExpr_kind:
if (!symtable_check_annotation(st, "named expression", e)) {
if (!symtable_raise_if_annotation_block(st, "named expression", e)) {
VISIT_QUIT(st, 0);
}
if(!symtable_handle_namedexpr(st, e))
Expand Down Expand Up @@ -1640,22 +1645,22 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT_QUIT(st, 0);
break;
case Yield_kind:
if (!symtable_check_annotation(st, "yield expression", e)) {
if (!symtable_raise_if_annotation_block(st, "yield expression", e)) {
VISIT_QUIT(st, 0);
}
if (e->v.Yield.value)
VISIT(st, expr, e->v.Yield.value);
st->st_cur->ste_generator = 1;
break;
case YieldFrom_kind:
if (!symtable_check_annotation(st, "yield expression", e)) {
if (!symtable_raise_if_annotation_block(st, "yield expression", e)) {
VISIT_QUIT(st, 0);
}
VISIT(st, expr, e->v.YieldFrom.value);
st->st_cur->ste_generator = 1;
break;
case Await_kind:
if (!symtable_check_annotation(st, "await expression", e)) {
if (!symtable_raise_if_annotation_block(st, "await expression", e)) {
VISIT_QUIT(st, 0);
}
VISIT(st, expr, e->v.Await.value);
Expand Down Expand Up @@ -2088,18 +2093,19 @@ symtable_visit_dictcomp(struct symtable *st, expr_ty e)
}

static int
symtable_check_annotation(struct symtable *st, const char *name, expr_ty e)
symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_ty e)
{
if (st->st_cur->ste_type == AnnotationBlock) {
PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name);
PyErr_RangedSyntaxLocationObject(st->st_filename,
e->lineno,
e->col_offset + 1,
e->end_lineno,
e->end_col_offset + 1);
return 0;
if (st->st_cur->ste_type != AnnotationBlock) {
return 1;
}
return 1;

PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name);
PyErr_RangedSyntaxLocationObject(st->st_filename,
e->lineno,
e->col_offset + 1,
e->end_lineno,
e->end_col_offset + 1);
return 0;
}

struct symtable *
Expand All @@ -2126,6 +2132,7 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
}
future->ff_features |= flags->cf_flags;
st = _PySymtable_Build(mod, filename, future);
PyObject_Free((void *)future);
_PyArena_Free(arena);
return st;
}

0 comments on commit 7493334

Please sign in to comment.