diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index b0d44a506412218b0b0ce36b1d5e5c77a78b3966..0b7981deb4fec9448ce85cbfff8d937b67376fb1 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1200,31 +1200,33 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.generate_traverse_function(scope, code, entry) if scope.needs_tp_clear(): self.generate_clear_function(scope, code, entry) - if scope.defines_any(["__getitem__"]): - self.generate_getitem_int_function(scope, code) - if scope.defines_any(["__setitem__", "__delitem__"]): - self.generate_ass_subscript_function(scope, code) - if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]): - warning(self.pos, - "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, " - "use __getitem__, __setitem__, and __delitem__ instead", 1) - code.putln("#if PY_MAJOR_VERSION >= 3") - code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") - code.putln("#endif") - if scope.defines_any(["__setslice__", "__delslice__"]): - self.generate_ass_slice_function(scope, code) - if scope.defines_any(["__getattr__", "__getattribute__"]): - self.generate_getattro_function(scope, code) - if scope.defines_any(["__setattr__", "__delattr__"]): - self.generate_setattro_function(scope, code) - if scope.defines_any(["__get__"]): - self.generate_descr_get_function(scope, code) - if scope.defines_any(["__set__", "__delete__"]): - self.generate_descr_set_function(scope, code) - if scope.defines_any(["__dict__"]): - self.generate_dict_getter_function(scope, code) - if scope.defines_any(TypeSlots.richcmp_special_methods): - self.generate_richcmp_function(scope, code) + if not scope.is_closure_class_scope: + # in closure classes, these are user defined variable names + if scope.defines_any(["__getitem__"]): + self.generate_getitem_int_function(scope, code) + if scope.defines_any(["__setitem__", "__delitem__"]): + self.generate_ass_subscript_function(scope, code) + if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]): + warning(self.pos, + "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, " + "use __getitem__, __setitem__, and __delitem__ instead", 1) + code.putln("#if PY_MAJOR_VERSION >= 3") + code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") + code.putln("#endif") + if scope.defines_any(["__setslice__", "__delslice__"]): + self.generate_ass_slice_function(scope, code) + if scope.defines_any(["__getattr__", "__getattribute__"]): + self.generate_getattro_function(scope, code) + if scope.defines_any(["__setattr__", "__delattr__"]): + self.generate_setattro_function(scope, code) + if scope.defines_any(["__get__"]): + self.generate_descr_get_function(scope, code) + if scope.defines_any(["__set__", "__delete__"]): + self.generate_descr_set_function(scope, code) + if scope.defines_any(["__dict__"]): + self.generate_dict_getter_function(scope, code) + if scope.defines_any(TypeSlots.richcmp_special_methods): + self.generate_richcmp_function(scope, code) self.generate_property_accessors(scope, code) self.generate_method_table(scope, code) self.generate_getset_table(scope, code) diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py index 24ec468ab2ead9ba8b693c4fe4ded67c0cbfcfac..a657d02830320b183f3e3a99d7466e0295429a68 100644 --- a/Cython/Compiler/TypeSlots.py +++ b/Cython/Compiler/TypeSlots.py @@ -304,6 +304,8 @@ class MethodSlot(SlotDescriptor): method_name_to_slot[method_name] = self def slot_code(self, scope): + if scope.is_closure_class_scope: + return "0" entry = scope.lookup_here(self.method_name) if entry and entry.func_cname: return entry.func_cname @@ -404,6 +406,8 @@ class SyntheticSlot(InternalMethodSlot): class RichcmpSlot(MethodSlot): def slot_code(self, scope): + if scope.is_closure_class_scope: + return "0" entry = scope.lookup_here(self.method_name) if entry and entry.func_cname: return entry.func_cname @@ -456,6 +460,8 @@ class SuiteSlot(SlotDescriptor): substructures.append(self) def is_empty(self, scope): + if scope.is_closure_class_scope: + return True for slot in self.sub_slots: if slot.slot_code(scope) != "0": return False diff --git a/tests/run/closure_names.pyx b/tests/run/closure_names.pyx index 584c835c61fff0c751adb49ff8a2067853fd7852..8b96e3646f0333b1fd92b35f9af63075e6ed9c96 100644 --- a/tests/run/closure_names.pyx +++ b/tests/run/closure_names.pyx @@ -24,8 +24,16 @@ def func(): def __dict__(a): return 'dict' + def __setitem__(x): + return '__setitem__' + + def __getslice__(x): + return '__getslice__' + def list_from_gen(g): return list(g) # move into closure by using inside of generator expression - return list_from_gen([__eq__, __str__, __weakref__, __new__, __dict__][i] for i in range(5)) + return list_from_gen( + [__eq__, __str__, __weakref__, __new__, __dict__, __setitem__, __getslice__][i] + for i in range(5))