mirror of
https://github.com/python/cpython.git
synced 2025-07-23 11:15:24 +00:00
Issue #28076: Variable annotations should be mangled for private names.
By Ivan Levkivskyi.
This commit is contained in:
parent
a6d75fdc37
commit
015d874626
3 changed files with 13 additions and 6 deletions
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue