Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
gh-119395: Fix leaky mangling after generic classes#119399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes from1 commit
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
- Loading branch information
Uh oh!
There was an error while loading.Please reload this page.
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -823,6 +823,39 @@ def meth[__U](self, arg: __T, arg2: __U): | ||
| self.assertEqual(Foo.Alias.__value__, (T, V)) | ||
| def test_no_leaky_mangling_in_module(self): | ||
| ns = run_code(""" | ||
| __before = "before" | ||
| class X[T]: pass | ||
| __after = "after" | ||
| """) | ||
| self.assertEqual(ns["__before"], "before") | ||
| self.assertEqual(ns["__after"], "after") | ||
| def test_no_leaky_mangling_in_function(self): | ||
| ns = run_code(""" | ||
| def f(): | ||
| class X[T]: pass | ||
| _X_foo = 2 | ||
| __foo = 1 | ||
| assert locals()['__foo'] == 1 | ||
| return __foo | ||
| """) | ||
| self.assertEqual(ns["f"](), 1) | ||
| def test_no_leaky_mangling_in_class(self): | ||
| ns = run_code(""" | ||
| class Outer: | ||
| __before = "before" | ||
| class Inner[T]: | ||
| __x = "inner" | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Is it a good idea to test MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. You mean in the inner class? That wouldn't really be relevant here since there is nothing else interesting going on in the inner class body. | ||
| __after = "after" | ||
| """) | ||
| Outer = ns["Outer"] | ||
| self.assertEqual(Outer._Outer__before, "before") | ||
| self.assertEqual(Outer.Inner._Inner__x, "inner") | ||
| self.assertEqual(Outer._Outer__after, "after") | ||
| class TypeParamsComplexCallsTest(unittest.TestCase): | ||
| def test_defaults(self): | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2624,6 +2624,7 @@ compiler_class(struct compiler *c, stmt_ty s) | ||
| asdl_type_param_seq *type_params = s->v.ClassDef.type_params; | ||
| int is_generic = asdl_seq_LEN(type_params) > 0; | ||
| PyObject *old_u_private = Py_XNewRef(c->u->u_private); | ||
| if (is_generic) { | ||
| Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name)); | ||
| ||
| PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", | ||
| @@ -2701,6 +2702,7 @@ compiler_class(struct compiler *c, stmt_ty s) | ||
| s->v.ClassDef.bases, | ||
| s->v.ClassDef.keywords)); | ||
| } | ||
| Py_XSETREF(c->u->u_private, old_u_private); | ||
| /* 6. apply decorators */ | ||
| RETURN_IF_ERROR(compiler_apply_decorators(c, decos)); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1508,7 +1508,6 @@ symtable_enter_type_param_block(struct symtable *st, identifier name, | ||
| lineno, col_offset, end_lineno, end_col_offset)) { | ||
| return 0; | ||
| } | ||
| // This is used for setting the generic base | ||
| _Py_DECLARE_STR(generic_base, ".generic_base"); | ||
| if (!symtable_add_def(st, &_Py_STR(generic_base), DEF_LOCAL, | ||
| @@ -1673,13 +1672,15 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) | ||
| VISIT_QUIT(st, 0); | ||
| if (s->v.ClassDef.decorator_list) | ||
| VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list); | ||
| PyObject *old_st_private = st->st_private; | ||
| ||
| if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) { | ||
| if (!symtable_enter_type_param_block(st, s->v.ClassDef.name, | ||
| (void *)s->v.ClassDef.type_params, | ||
| false, false, s->kind, | ||
| LOCATION(s))) { | ||
| VISIT_QUIT(st, 0); | ||
| } | ||
| st->st_private = s->v.ClassDef.name; | ||
| VISIT_SEQ(st, type_param, s->v.ClassDef.type_params); | ||
| } | ||
| VISIT_SEQ(st, expr, s->v.ClassDef.bases); | ||
| @@ -1709,6 +1710,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) | ||
| if (!symtable_exit_block(st)) | ||
| VISIT_QUIT(st, 0); | ||
| } | ||
| st->st_private = old_st_private; | ||
| break; | ||
| } | ||
| case TypeAlias_kind: { | ||