8000 Modules and classes · python/cpython@e50cd62 · GitHub
[go: up one dir, main page]

Skip to content

Commit e50cd62

Browse files
committed
Modules and classes
1 parent e65d55a commit e50cd62

File tree

2 files changed

+142
-75
lines changed

2 files changed

+142
-75
lines changed

Python/compile.c

Lines changed: 142 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *);
380380
static int compiler_match(struct compiler *, stmt_ty);
381381
static int compiler_pattern_subpattern(struct compiler *,
382382
pattern_ty, pattern_context *);
383+
static int compiler_make_closure(struct compiler *c, location loc,
384+
PyCodeObject *co, Py_ssize_t flags);
383385

384386
static PyCodeObject *optimize_and_assemble(struct compiler *, int addNone);
385387

@@ -1631,6 +1633,124 @@ compiler_unwind_fblock_stack(struct compiler *c, location *ploc,
16311633
return SUCCESS;
16321634
}
16331635

1636+
static int
1637+
compiler_setup_annotations_scope(struct compiler *c, location loc,
1638+
void *key, jump_target_label label)
1639+
{
1640+
PyObject *annotations_name = PyUnicode_FromFormat(
1641+
"<annotations of %U>", c->u->u_ste->ste_name);
1642+
if (!annotations_name) {
1643+
return ERROR;
1644+
}
1645+
if (compiler_enter_scope(c, annotations_name, COMPILER_SCOPE_ANNOTATIONS,
1646+
key, loc.lineno) == -1) {
1647+
Py_DECREF(annotations_name);
1648+
return ERROR;
1649+
}
1650+
Py_DECREF(annotations_name);
1651+
c->u->u_metadata.u_posonlyargcount = 1;
1652+
_Py_DECLARE_STR(format, ".format");
1653+
ADDOP_I(c, loc, LOAD_FAST, 0);
1654+
ADDOP_LOAD_CONST(c, loc, _PyLong_GetOne());
1655+
ADDOP_I(c, loc, COMPARE_OP, (Py_EQ << 5) | compare_masks[Py_EQ]);
1656+
ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, label);
1657+
return 0;
1658+
}
1659+
1660+
static int
1661+
compiler_leave_annotations_scope(struct compiler *c, location loc,
1662+
int annotations_len, jump_target_label label)
1663+
{
1664+
ADDOP_I(c, loc, BUILD_MAP, annotations_len);
1665+
ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
1666+
USE_LABEL(c, label);
1667+
ADDOP_IN_SCOPE(c, loc, LOAD_ASSERTION_ERROR);
1668+
ADDOP_I(c, loc, RAISE_VARARGS, 1);
1669+
PyCodeObject *co = optimize_and_assemble(c, 1);
1670+
compiler_exit_scope(c);
1671+
if (co == NULL) {
1672+
return ERROR;
1673+
}
1674+
if (compiler_make_closure(c, loc, co, 0) < 0) {
1675+
Py_DECREF(co);
1676+
return ERROR;
1677+
}
1678+
Py_DECREF(co);
1679+
return 0;
1680+
}
1681+
1682+
static int
1683+
compiler_collect_annotations(struct compiler *c, asdl_stmt_seq *stmts,
1684+
int *annotations_len)
1685+
{
1686+
for (int i = 0; i < asdl_seq_LEN(stmts); i++) {
1687+
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, i);
1688+
switch (st->kind) {
1689+
case AnnAssign_kind:
1690+
if (st->v.AnnAssign.target->kind == Name_kind) {
1691+
PyObject *mangled = _Py_Mangle(c->u->u_private, st->v.AnnAssign.target->v.Name.id);
1692+
ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
1693+
VISIT(c, expr, st->v.AnnAssign.annotation);
1694+
*annotations_len += 1;
1695+
}
1696+
break;
1697+
case For_kind:
1698+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.For.body, annotations_len));
1699+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.For.orelse, annotations_len));
1700+
break;
1701+
case AsyncFor_kind:
1702+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.AsyncFor.body, annotations_len));
1703+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.AsyncFor.orelse, annotations_len));
1704+
break;
1705+
case While_kind:
1706+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.While.body, annotations_len));
1707+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.While.orelse, annotations_len));
1708+
break;
1709+
case If_kind:
1710+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.If.body, annotations_len));
1711+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.If.orelse, annotations_len));
1712+
break;
1713+
case With_kind:
1714+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.With.body, annotations_len));
1715+
break;
1716+
case AsyncWith_kind:
1717+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.AsyncWith.body, annotations_len));
1718+
break;
1719+
case Match_kind:
1720+
for (int j = 0; j < asdl_seq_LEN(st->v.Match.cases); j++) {
1721+
match_case_ty match_case = (match_case_ty)asdl_seq_GET(
1722+
st->v.Match.cases, j);
1723+
RETURN_IF_ERROR(compiler_collect_annotations(c, match_case->body, annotations_len));
1724+
}
1725+
break;
1726+
case Try_kind:
1727+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.Try.body, annotations_len));
1728+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.Try.orelse, annotations_len));
1729+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.Try.finalbody, annotations_len));
1730+
for (int j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) {
1731+
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
1732+
st->v.Try.handlers, j);
1733+
RETURN_IF_ERROR(compiler_collect_annotations(c, handler->v.ExceptHandler.body, annotations_len));
1734+
}
1735+
break;
1736+
case TryStar_kind:
1737+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.TryStar.body, annotations_len));
1738+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.TryStar.orelse, annotations_len));
1739+
RETURN_IF_ERROR(compiler_collect_annotations(c, st->v.TryStar.finalbody, annotations_len));
1740+
for (int j = 0; j < asdl_seq_LEN(st->v.TryStar.handlers); j++) {
1741+
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
1742+
st->v.Try.handlers, j);
1743+
RETURN_IF_ERROR(compiler_collect_annotations(c, handler->v.ExceptHandler.body, annotations_len));
1744+
}
1745+
break;
1746+
default:
1747+
break;
1748+
}
1749+
}
1750+
return SUCCESS;
1751+
1752+
}
1753+
16341754
/* Compile a sequence of statements, checking for a docstring
16351755
and for annotations. */
16361756

@@ -1639,17 +1759,11 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
16391759
{
16401760

16411761
/* Set current line number to the line number of first statement.
1642-
This way line number for SETUP_ANNOTATIONS will always
1643-
coincide with the line number of first "real" statement in module.
16441762
If body is empty, then lineno will be set later in optimize_and_assemble. */
16451763
if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) {
16461764
stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
16471765
loc = LOC(st);
16481766
}
1649-
/* Every annotated class and module should have __annotations__. */
1650-
if (find_ann(stmts)) {
1651-
ADDOP(c, loc, SETUP_ANNOTATIONS);
1652-
}
16531767
if (!asdl_seq_LEN(stmts)) {
16541768
return SUCCESS;
16551769
}
@@ -1674,6 +1788,21 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
16741788
for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
16751789
VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
16761790
}
1791+
if (c->u->u_ste->ste_annotation_block != NULL) {
1792+
NEW_JUMP_TARGET_LABEL(c, raise_notimp);
1793+
void *key = (void *)((uintptr_t)c->u->u_ste->ste_id + 1);
1794+
RETURN_IF_ERROR(compiler_setup_annotations_scope(c, loc, key, raise_notimp));
1795+
int annotations_len = 0;
1796+
RETURN_IF_ERROR(
1797+
compiler_collect_annotations(c, stmts, &annotations_len)
1798+
);
1799+
RETURN_IF_ERROR(
1800+
compiler_leave_annotations_scope(c, loc, annotations_len, raise_notimp)
1801+
);
1802+
RETURN_IF_ERROR(
1803+
compiler_nameop(c, loc, &_Py_ID(__annotate__), Store)
1804+
);
1805+
}
16771806
return SUCCESS;
16781807
}
16791808

@@ -2008,22 +2137,9 @@ compiler_visit_annotations(struct compiler *c, location loc,
20082137
NEW_JUMP_TARGET_LABEL(c, raise_notimp);
20092138

20102139
if (!future_annotations && ste->ste_annotations_used) {
2011-
PyObject *annotations_name = PyUnicode_FromFormat("<annotations of %U>", ste->ste_name);
2012-
if (!annotations_name) {
2013-
return ERROR;
2014-
}
2015-
if (compiler_enter_scope(c, annotations_name, COMPILER_SCOPE_ANNOTATIONS,
2016-
(void *)args, loc.lineno) == -1) {
2017-
Py_DECREF(annotations_name);
2018-
return ERROR;
2019-
}
2020-
Py_DECREF(annotations_name);
2021-
c->u->u_metadata.u_posonlyargcount = 1;
2022-
_Py_DECLARE_STR(format, ".format");
2023-
ADDOP_I(c, loc, LOAD_FAST, 0);
2024-
ADDOP_LOAD_CONST(c, loc, _PyLong_GetOne());
2025-
ADDOP_I(c, loc, COMPARE_OP, (Py_EQ << 5) | compare_masks[Py_EQ]);
2026-
ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, raise_notimp);
2140+
RETURN_IF_ERROR(
2141+
compiler_setup_annotations_scope(c, loc, (void *)args, raise_notimp)
2142+
);
20272143
}
20282144

20292145
RETURN_IF_ERROR(
@@ -2057,21 +2173,9 @@ compiler_visit_annotations(struct compiler *c, location loc,
20572173
else {
20582174
assert(ste != NULL);
20592175
if (ste->ste_annotations_used) {
2060-
ADDOP_I(c, loc, BUILD_MAP, annotations_len);
2061-
ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
2062-
USE_LABEL(c, raise_notimp);
2063-
ADDOP_IN_SCOPE(c, loc, LOAD_ASSERTION_ERROR);
2064-
ADDOP_I(c, loc, RAISE_VARARGS, 1);
2065-
PyCodeObject *co = optimize_and_assemble(c, 1);
2066-
compiler_exit_scope(c);
2067-
if (co == NULL) {
2068-
return ERROR;
2069-
}
2070-
if (compiler_make_closure(c, loc, co, 0) < 0) {
2071-
Py_DECREF(co);
2072-
return ERROR;
2073-
}
2074-
Py_DECREF(co);
2176+
RETURN_IF_ERROR(
2177+
compiler_leave_annotations_scope(c, loc, annotations_len, raise_notimp)
2178+
);
20752179
return MAKE_FUNCTION_ANNOTATE;
20762180
}
20772181
}
@@ -6485,23 +6589,6 @@ check_ann_expr(struct compiler *c, expr_ty e)
64856589
return SUCCESS;
64866590
}
64876591

6488-
static int
6489-
check_annotation(struct compiler *c, stmt_ty s)
6490-
{
6491-
/* Annotations of complex targets does not produce anything
6492-
under annotations future */
6493-
if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
6494-
return SUCCESS;
6495-
}
6496-
6497-
/* Annotations are only evaluated in a module or class. */
6498-
if (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
6499-
c->u->u_scope_type == COMPILER_SCOPE_CLASS) {
6500-
return check_ann_expr(c, s->v.AnnAssign.annotation);
6501-
}
6502-
return SUCCESS;
6503-
}
6504-
65056592
static int
65066593
check_ann_subscr(struct compiler *c, expr_ty e)
65076594
{
@@ -6537,7 +6624,6 @@ compiler_annassign(struct compiler *c, stmt_ty s)
65376624
{
65386625
location loc = LOC(s);
65396626
expr_ty targ = s->v.AnnAssign.target;
6540-
PyObject* mangled;
65416627

65426628
assert(s->kind == AnnAssign_kind);
65436629

@@ -6551,21 +6637,6 @@ compiler_annassign(struct compiler *c, stmt_ty s)
65516637
if (forbidden_name(c, loc, targ->v.Name.id, Store)) {
65526638
return ERROR;
65536639
}
6554-
/* If we have a simple name in a module or class, store annotation. */
6555-
// if (s->v.AnnAssign.simple &&
6556-
// (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
6557-
// c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
6558-
// if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
6559-
// VISIT(c, annexpr, s->v.AnnAssign.annotation)
6560-
// }
6561-
// else {
6562-
// VISIT(c, expr, s->v.AnnAssign.annotation);
6563-
// }
6564-
// ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
6565-
// mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
6566-
// ADDOP_LOAD_CONST_NEW(c, loc, mangled);
6567-
// ADDOP(c, loc, STORE_SUBSCR);
6568-
// }
65696640
break;
65706641
case Attribute_kind:
65716642
if (forbidden_name(c, loc, targ->v.Attribute.attr, Store)) {
@@ -6589,10 +6660,7 @@ compiler_annassign(struct compiler *c, stmt_ty s)
65896660
targ->kind);
65906661
return ERROR;
65916662
}
6592-
/* Annotation is evaluated last. */
6593-
// if (!s->v.AnnAssign.simple && check_annotation(c, s) < 0) {
6594-
// return ERROR;
6595-
// }
6663+
/* For non-simple AnnAssign, the annotation is not evaluated. */
65966664
return SUCCESS;
65976665
}
65986666

Python/symtable.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2476,7 +2476,6 @@ symtable_visit_annotation(struct symtable *st, expr_ty annotation,
24762476
VISIT_QUIT(st, 0);
24772477
}
24782478
else {
2479-
printf("enter block %p\n", key);
24802479
if (st->st_cur->ste_annotation_block == NULL) {
24812480
if (!symtable_enter_block(st, &_Py_ID(_annotation), AnnotationBlock,
24822481
key, LOCATION(annotation))) {

0 commit comments

Comments
 (0)
0