Commit 753e262f authored by Stefan Behnel's avatar Stefan Behnel

Switch off special methods for closure classes the hard way.

parent bff0e5cb
...@@ -1200,31 +1200,33 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1200,31 +1200,33 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_traverse_function(scope, code, entry) self.generate_traverse_function(scope, code, entry)
if scope.needs_tp_clear(): if scope.needs_tp_clear():
self.generate_clear_function(scope, code, entry) self.generate_clear_function(scope, code, entry)
if scope.defines_any(["__getitem__"]): if not scope.is_closure_class_scope:
self.generate_getitem_int_function(scope, code) # in closure classes, these are user defined variable names
if scope.defines_any(["__setitem__", "__delitem__"]): if scope.defines_any(["__getitem__"]):
self.generate_ass_subscript_function(scope, code) self.generate_getitem_int_function(scope, code)
if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]): if scope.defines_any(["__setitem__", "__delitem__"]):
warning(self.pos, self.generate_ass_subscript_function(scope, code)
"__getslice__, __setslice__, and __delslice__ are not supported by Python 3, " if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]):
"use __getitem__, __setitem__, and __delitem__ instead", 1) warning(self.pos,
code.putln("#if PY_MAJOR_VERSION >= 3") "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, "
code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") "use __getitem__, __setitem__, and __delitem__ instead", 1)
code.putln("#endif") code.putln("#if PY_MAJOR_VERSION >= 3")
if scope.defines_any(["__setslice__", "__delslice__"]): code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
self.generate_ass_slice_function(scope, code) code.putln("#endif")
if scope.defines_any(["__getattr__", "__getattribute__"]): if scope.defines_any(["__setslice__", "__delslice__"]):
self.generate_getattro_function(scope, code) self.generate_ass_slice_function(scope, code)
if scope.defines_any(["__setattr__", "__delattr__"]): if scope.defines_any(["__getattr__", "__getattribute__"]):
self.generate_setattro_function(scope, code) self.generate_getattro_function(scope, code)
if scope.defines_any(["__get__"]): if scope.defines_any(["__setattr__", "__delattr__"]):
self.generate_descr_get_function(scope, code) self.generate_setattro_function(scope, code)
if scope.defines_any(["__set__", "__delete__"]): if scope.defines_any(["__get__"]):
self.generate_descr_set_function(scope, code) self.generate_descr_get_function(scope, code)
if scope.defines_any(["__dict__"]): if scope.defines_any(["__set__", "__delete__"]):
self.generate_dict_getter_function(scope, code) self.generate_descr_set_function(scope, code)
if scope.defines_any(TypeSlots.richcmp_special_methods): if scope.defines_any(["__dict__"]):
self.generate_richcmp_function(scope, code) 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_property_accessors(scope, code)
self.generate_method_table(scope, code) self.generate_method_table(scope, code)
self.generate_getset_table(scope, code) self.generate_getset_table(scope, code)
......
...@@ -304,6 +304,8 @@ class MethodSlot(SlotDescriptor): ...@@ -304,6 +304,8 @@ class MethodSlot(SlotDescriptor):
method_name_to_slot[method_name] = self method_name_to_slot[method_name] = self
def slot_code(self, scope): def slot_code(self, scope):
if scope.is_closure_class_scope:
return "0"
entry = scope.lookup_here(self.method_name) entry = scope.lookup_here(self.method_name)
if entry and entry.func_cname: if entry and entry.func_cname:
return entry.func_cname return entry.func_cname
...@@ -404,6 +406,8 @@ class SyntheticSlot(InternalMethodSlot): ...@@ -404,6 +406,8 @@ class SyntheticSlot(InternalMethodSlot):
class RichcmpSlot(MethodSlot): class RichcmpSlot(MethodSlot):
def slot_code(self, scope): def slot_code(self, scope):
if scope.is_closure_class_scope:
return "0"
entry = scope.lookup_here(self.method_name) entry = scope.lookup_here(self.method_name)
if entry and entry.func_cname: if entry and entry.func_cname:
return entry.func_cname return entry.func_cname
...@@ -456,6 +460,8 @@ class SuiteSlot(SlotDescriptor): ...@@ -456,6 +460,8 @@ class SuiteSlot(SlotDescriptor):
substructures.append(self) substructures.append(self)
def is_empty(self, scope): def is_empty(self, scope):
if scope.is_closure_class_scope:
return True
for slot in self.sub_slots: for slot in self.sub_slots:
if slot.slot_code(scope) != "0": if slot.slot_code(scope) != "0":
return False return False
......
...@@ -24,8 +24,16 @@ def func(): ...@@ -24,8 +24,16 @@ def func():
def __dict__(a): def __dict__(a):
return 'dict' return 'dict'
def __setitem__(x):
return '__setitem__'
def __getslice__(x):
return '__getslice__'
def list_from_gen(g): def list_from_gen(g):
return list(g) return list(g)
# move into closure by using inside of generator expression # 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))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment