| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 24cb16e commit 51e83ca
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -171,6 +171,17 @@ def test_references___class__(self): | |||
| 171 | 171 | """ | |
| 172 | 172 | self._check_in_scopes(code, raises=NameError) | |
| 173 | 173 | ||
| 174 | + def test_references___class___nested(self): | ||
| 175 | + code = """ | ||
| 176 | + res = [(lambda: __class__)() for _ in [1]] | ||
| 177 | + """ | ||
| 178 | + self._check_in_scopes(code, raises=NameError) | ||
| 179 | + | ||
| 180 | + def test_references___class___nested_used(self): | ||
| 181 | + class _C: | ||
| 182 | + res = [lambda: __class__ for _ in [1]] | ||
| 183 | + self.assertIs(_C.res[0](), _C) | ||
| 184 | + | ||
| 174 | 185 | def test_references___class___defined(self): | |
| 175 | 186 | code = """ | |
| 176 | 187 | __class__ = 2 | |
@@ -180,18 +191,38 @@ def test_references___class___defined(self): | |||
| 180 | 191 | code, outputs={"res": [2]}, scopes=["module", "function"]) | |
| 181 | 192 | self._check_in_scopes(code, raises=NameError, scopes=["class"]) | |
| 182 | 193 | ||
| 194 | + def test_references___class___defined_nested(self): | ||
| 195 | + code = """ | ||
| 196 | + __class__ = 2 | ||
| 197 | + res = [(lambda: __class__)() for x in [1]] | ||
| 198 | + """ | ||
| 199 | + self._check_in_scopes( | ||
| 200 | + code, outputs={"res": [2]}, scopes=["module", "function"]) | ||
| 201 | + self._check_in_scopes(code, raises=NameError, scopes=["class"]) | ||
| 202 | + | ||
| 183 | 203 | def test_references___classdict__(self): | |
| 184 | 204 | code = """ | |
| 185 | 205 | class i: [__classdict__ for x in y] | |
| 186 | 206 | """ | |
| 187 | 207 | self._check_in_scopes(code, raises=NameError) | |
| 188 | 208 | ||
| 209 | + def test_references___classdict___nested(self): | ||
| 210 | + class _C: | ||
| 211 | + res = [(lambda: __classdict__)() for _ in [1]] | ||
| 212 | + self.assertIn("res", _C.res[0]) | ||
| 213 | + | ||
| 189 | 214 | def test_references___conditional_annotations__(self): | |
| 190 | 215 | code = """ | |
| 191 | 216 | class i: [__conditional_annotations__ for x in y] | |
| 192 | 217 | """ | |
| 193 | 218 | self._check_in_scopes(code, raises=NameError) | |
| 194 | 219 | ||
| 220 | + def test_references___conditional_annotations___nested(self): | ||
| 221 | + code = """ | ||
| 222 | + class i: [lambda: __conditional_annotations__ for x in y] | ||
| 223 | + """ | ||
| 224 | + self._check_in_scopes(code, raises=NameError) | ||
| 225 | + | ||
| 195 | 226 | def test_references___class___enclosing(self): | |
| 196 | 227 | code = """ | |
| 197 | 228 | __class__ = 2 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + Fix a :exc:`SystemError` when compiling a class-scope comprehension containing | ||
| 2 | + a ``lambda`` that references ``__class__``, ``__classdict__``, or | ||
| 3 | + ``__conditional_annotations__``. Patch by Bartosz Sławecki. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -831,17 +831,22 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, | |||
| 831 | 831 | return 0; | |
| 832 | 832 | } | |
| 833 | 833 | // __class__, __classdict__ and __conditional_annotations__ are | |
| 834 | - // never allowed to be free through a class scope (see | ||
| 835 | - // drop_class_free) | ||
| 834 | + // not allowed to be free through a class scope (see | ||
| 835 | + // drop_class_free) unless children scopes need it | ||
| 836 | 836 | if (scope == FREE && ste->ste_type == ClassBlock && | |
| 837 | 837 | (_PyUnicode_EqualToASCIIString(k, "__class__") || | |
| 838 | 838 | _PyUnicode_EqualToASCIIString(k, "__classdict__") || | |
| 839 | 839 | _PyUnicode_EqualToASCIIString(k, "__conditional_annotations__"))) { | |
| 840 | 840 | scope = GLOBAL_IMPLICIT; | |
| 841 | - if (PySet_Discard(comp_free, k) < 0) { | ||
| 841 | + int child_needs_free = is_free_in_any_child(comp, k); | ||
| 842 | + if (child_needs_free < 0) { | ||
| 842 | 843 | return 0; | |
| 843 | 844 | } | |
| 844 | - | ||
| 845 | + if (!child_needs_free) { | ||
| 846 | + if (PySet_Discard(comp_free, k) < 0) { | ||
| 847 | + return 0; | ||
| 848 | + } | ||
| 849 | + } | ||
| 845 | 850 | if (_PyUnicode_EqualToASCIIString(k, "__class__")) { | |
| 846 | 851 | remove_dunder_class = 1; | |
| 847 | 852 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments