Issue #28076: Variable annotations should be mangled for private names.

By Ivan Levkivskyi.
This commit is contained in:
Guido van Rossum 2016-09-11 09:45:24 -07:00
parent a6d75fdc37
commit 015d874626
3 changed files with 13 additions and 6 deletions

View file

@ -334,9 +334,10 @@ only single right hand side value is allowed.
For simple names as assignment targets, if in class or module scope, For simple names as assignment targets, if in class or module scope,
the annotations are evaluated and stored in a special class or module the annotations are evaluated and stored in a special class or module
attribute :attr:`__annotations__` attribute :attr:`__annotations__`
that is a dictionary mapping from variable names to evaluated annotations. that is a dictionary mapping from variable names (mangled if private) to
This attribute is writable and is automatically created at the start evaluated annotations. This attribute is writable and is automatically
of class or module body execution, if annotations are found statically. created at the start of class or module body execution, if annotations
are found statically.
For expressions as assignment targets, the annotations are evaluated if For expressions as assignment targets, the annotations are evaluated if
in class or module scope, but not stored. in class or module scope, but not stored.

View file

@ -328,12 +328,12 @@ class GrammarTests(unittest.TestCase):
# class semantics # class semantics
class C: class C:
x: int __foo: int
s: str = "attr" s: str = "attr"
z = 2 z = 2
def __init__(self, x): def __init__(self, x):
self.x: int = x self.x: int = x
self.assertEqual(C.__annotations__, {'x': int, 's': str}) self.assertEqual(C.__annotations__, {'_C__foo': int, 's': str})
with self.assertRaises(NameError): with self.assertRaises(NameError):
class CBad: class CBad:
no_such_name_defined.attr: int = 0 no_such_name_defined.attr: int = 0

View file

@ -4562,6 +4562,7 @@ static int
compiler_annassign(struct compiler *c, stmt_ty s) compiler_annassign(struct compiler *c, stmt_ty s)
{ {
expr_ty targ = s->v.AnnAssign.target; expr_ty targ = s->v.AnnAssign.target;
PyObject* mangled;
assert(s->kind == AnnAssign_kind); assert(s->kind == AnnAssign_kind);
@ -4576,8 +4577,13 @@ compiler_annassign(struct compiler *c, stmt_ty s)
if (s->v.AnnAssign.simple && if (s->v.AnnAssign.simple &&
(c->u->u_scope_type == COMPILER_SCOPE_MODULE || (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
if (!mangled) {
return 0;
}
VISIT(c, expr, s->v.AnnAssign.annotation); VISIT(c, expr, s->v.AnnAssign.annotation);
ADDOP_O(c, STORE_ANNOTATION, targ->v.Name.id, names) /* ADDOP_N decrefs its argument */
ADDOP_N(c, STORE_ANNOTATION, mangled, names);
} }
break; break;
case Attribute_kind: case Attribute_kind: