diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2020-06-17 13:11:01 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2020-06-17 13:11:01 +0200 |
commit | 6933d867cdea2460c922c45702b7e60f3d133c2d (patch) | |
tree | db8da4a057550d7a87ae219aa3fb111121e5a107 | |
parent | 8e3775b8e708c593d3803276288e34e859c31b26 (diff) | |
download | cython-6933d867cdea2460c922c45702b7e60f3d133c2d.tar.gz |
Revert "Python-style binary operation methods."
This reverts commit e6a812402b0368cf930a55ed465a38820f606054.
-rw-r--r-- | Cython/Compiler/ModuleNode.py | 43 | ||||
-rw-r--r-- | Cython/Compiler/Options.py | 1 | ||||
-rw-r--r-- | Cython/Compiler/TypeSlots.py | 44 | ||||
-rw-r--r-- | Cython/Utility/ExtensionTypes.c | 56 |
4 files changed, 17 insertions, 127 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 6437038b5..05485ad5f 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -29,7 +29,7 @@ from . import Pythran from .Errors import error, warning from .PyrexTypes import py_object_type from ..Utils import open_new_file, replace_suffix, decode_filename, build_hex_version -from .Code import UtilityCode, IncludeCode, TempitaUtilityCode +from .Code import UtilityCode, IncludeCode from .StringEncoding import EncodedString from .Pythran import has_np_pythran @@ -1255,9 +1255,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.generate_dict_getter_function(scope, code) if scope.defines_any_special(TypeSlots.richcmp_special_methods): self.generate_richcmp_function(scope, code) - for slot in TypeSlots.PyNumberMethods: - if slot.is_binop and scope.defines_any_special(slot.user_methods): - self.generate_binop_function(scope, slot, code) self.generate_property_accessors(scope, code) self.generate_method_table(scope, code) self.generate_getset_table(scope, code) @@ -1897,44 +1894,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("}") # switch code.putln("}") - def generate_binop_function(self, scope, slot, code): - func_name = scope.mangle_internal(slot.slot_name) - code.putln() - preprocessor_guard = slot.preprocessor_guard_code() - if preprocessor_guard: - code.putln(preprocessor_guard) - if scope.directives['c_api_binop_methods']: - code.putln('#define %s %s' % (func_name, slot.left_slot.slot_code(scope))) - else: - def has_slot_method(method_name): - entry = scope.lookup(method_name) - return bool(entry and entry.is_special and entry.func_cname) - def call_slot_method(method_name, reverse): - entry = scope.lookup(method_name) - if reverse: - operands = "right, left" - else: - operands = "left, right" - if entry and entry.is_special and entry.func_cname: - return "%s(%s)" % (entry.func_cname, operands) - else: - py_ident = code.intern_identifier(EncodedString(method_name)) - return "%s_maybe_call_super(%s, %s)" % (func_name, operands, py_ident) - code.putln( - TempitaUtilityCode.load_cached( - "BinopSlot", "ExtensionTypes.c", - context={ - "func_name": func_name, - "slot_name": slot.slot_name, - "overloads_left": int(has_slot_method(slot.left_slot.method_name)), - "call_left": call_slot_method(slot.left_slot.method_name, reverse=False), - "call_right": call_slot_method(slot.right_slot.method_name, reverse=True), - "type_cname": '((PyTypeObject*) %s)' % scope.namespace_cname, - }).impl.strip()) - code.putln() - if preprocessor_guard: - code.putln("#endif") - def generate_getattro_function(self, scope, code): # First try to get the attribute using __getattribute__, if defined, or # PyObject_GenericGetAttr. diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index db497aa40..a634aaf56 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -178,7 +178,6 @@ _directive_defaults = { 'auto_pickle': None, 'cdivision': False, # was True before 0.12 'cdivision_warnings': False, - 'c_api_binop_methods': True, # Change for 3.0 'overflowcheck': False, 'overflowcheck.fold': True, 'always_allow_keywords': False, diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py index 50e09cd74..137ea4eba 100644 --- a/Cython/Compiler/TypeSlots.py +++ b/Cython/Compiler/TypeSlots.py @@ -180,14 +180,13 @@ class SlotDescriptor(object): # ifdef Full #ifdef string that slot is wrapped in. Using this causes py3, py2 and flags to be ignored.) def __init__(self, slot_name, dynamic=False, inherited=False, - py3=True, py2=True, ifdef=None, is_binop=False): + py3=True, py2=True, ifdef=None): self.slot_name = slot_name self.is_initialised_dynamically = dynamic self.is_inherited = inherited self.ifdef = ifdef self.py3 = py3 self.py2 = py2 - self.is_binop = is_binop def preprocessor_guard_code(self): ifdef = self.ifdef @@ -406,17 +405,6 @@ class SyntheticSlot(InternalMethodSlot): return self.default_value -class BinopSlot(SyntheticSlot): - def __init__(self, signature, slot_name, left_method, **kargs): - assert left_method.startswith('__') - right_method = '__r' + left_method[2:] - SyntheticSlot.__init__( - self, slot_name, [left_method, right_method], "0", is_binop=True, **kargs) - # MethodSlot causes special method registration. - self.left_slot = MethodSlot(signature, "", left_method) - self.right_slot = MethodSlot(signature, "", right_method) - - class RichcmpSlot(MethodSlot): def slot_code(self, scope): entry = scope.lookup_here(self.method_name) @@ -740,23 +728,23 @@ property_accessor_signatures = { PyNumberMethods_Py3_GUARD = "PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000)" PyNumberMethods = ( - BinopSlot(binaryfunc, "nb_add", "__add__"), - BinopSlot(binaryfunc, "nb_subtract", "__sub__"), - BinopSlot(binaryfunc, "nb_multiply", "__mul__"), - BinopSlot(binaryfunc, "nb_divide", "__div__", ifdef = PyNumberMethods_Py3_GUARD), - BinopSlot(binaryfunc, "nb_remainder", "__mod__"), - BinopSlot(binaryfunc, "nb_divmod", "__divmod__"), - BinopSlot(ternaryfunc, "nb_power", "__pow__"), + MethodSlot(binaryfunc, "nb_add", "__add__"), + MethodSlot(binaryfunc, "nb_subtract", "__sub__"), + MethodSlot(binaryfunc, "nb_multiply", "__mul__"), + MethodSlot(binaryfunc, "nb_divide", "__div__", ifdef = PyNumberMethods_Py3_GUARD), + MethodSlot(binaryfunc, "nb_remainder", "__mod__"), + MethodSlot(binaryfunc, "nb_divmod", "__divmod__"), + MethodSlot(ternaryfunc, "nb_power", "__pow__"), MethodSlot(unaryfunc, "nb_negative", "__neg__"), MethodSlot(unaryfunc, "nb_positive", "__pos__"), MethodSlot(unaryfunc, "nb_absolute", "__abs__"), MethodSlot(inquiry, "nb_nonzero", "__nonzero__", py3 = ("nb_bool", "__bool__")), MethodSlot(unaryfunc, "nb_invert", "__invert__"), - BinopSlot(binaryfunc, "nb_lshift", "__lshift__"), - BinopSlot(binaryfunc, "nb_rshift", "__rshift__"), - BinopSlot(binaryfunc, "nb_and", "__and__"), - BinopSlot(binaryfunc, "nb_xor", "__xor__"), - BinopSlot(binaryfunc, "nb_or", "__or__"), + MethodSlot(binaryfunc, "nb_lshift", "__lshift__"), + MethodSlot(binaryfunc, "nb_rshift", "__rshift__"), + MethodSlot(binaryfunc, "nb_and", "__and__"), + MethodSlot(binaryfunc, "nb_xor", "__xor__"), + MethodSlot(binaryfunc, "nb_or", "__or__"), EmptySlot("nb_coerce", ifdef = PyNumberMethods_Py3_GUARD), MethodSlot(unaryfunc, "nb_int", "__int__", fallback="__long__"), MethodSlot(unaryfunc, "nb_long", "__long__", fallback="__int__", py3 = "<RESERVED>"), @@ -779,8 +767,8 @@ PyNumberMethods = ( # Added in release 2.2 # The following require the Py_TPFLAGS_HAVE_CLASS flag - BinopSlot(binaryfunc, "nb_floor_divide", "__floordiv__"), - BinopSlot(binaryfunc, "nb_true_divide", "__truediv__"), + MethodSlot(binaryfunc, "nb_floor_divide", "__floordiv__"), + MethodSlot(binaryfunc, "nb_true_divide", "__truediv__"), MethodSlot(ibinaryfunc, "nb_inplace_floor_divide", "__ifloordiv__"), MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"), @@ -788,7 +776,7 @@ PyNumberMethods = ( MethodSlot(unaryfunc, "nb_index", "__index__"), # Added in release 3.5 - BinopSlot(binaryfunc, "nb_matrix_multiply", "__matmul__", ifdef="PY_VERSION_HEX >= 0x03050000"), + MethodSlot(binaryfunc, "nb_matrix_multiply", "__matmul__", ifdef="PY_VERSION_HEX >= 0x03050000"), MethodSlot(ibinaryfunc, "nb_inplace_matrix_multiply", "__imatmul__", ifdef="PY_VERSION_HEX >= 0x03050000"), ) diff --git a/Cython/Utility/ExtensionTypes.c b/Cython/Utility/ExtensionTypes.c index d34916642..1b39c9e42 100644 --- a/Cython/Utility/ExtensionTypes.c +++ b/Cython/Utility/ExtensionTypes.c @@ -278,59 +278,3 @@ __PYX_GOOD: Py_XDECREF(setstate_cython); return ret; } - -/////////////// BinopSlot /////////////// - -static CYTHON_INLINE PyObject *{{func_name}}_maybe_call_super(PyObject *self, PyObject *other, PyObject* name) { - PyObject *res; - PyObject *method; - if (!Py_TYPE(self)->tp_base) { - return Py_INCREF(Py_NotImplemented), Py_NotImplemented; - } - // TODO: Use _PyType_LookupId or similar. - method = PyObject_GetAttr((PyObject*) Py_TYPE(self)->tp_base, name); - if (!method) { - PyErr_Clear(); - return Py_INCREF(Py_NotImplemented), Py_NotImplemented; - } - res = __Pyx_PyObject_Call2Args(method, self, other); - Py_DECREF(method); - if (!res) { - return Py_INCREF(Py_NotImplemented), Py_NotImplemented; - } - return res; -} - -static PyObject *{{func_name}}(PyObject *left, PyObject *right) { - PyObject *res; - int maybe_self_is_left, maybe_self_is_right = 0; - maybe_self_is_left = Py_TYPE(left) == Py_TYPE(right) - || (Py_TYPE(left)->tp_as_number && Py_TYPE(left)->tp_as_number->{{slot_name}} == &{{func_name}}) - || PyType_IsSubtype(Py_TYPE(left), {{type_cname}}); - // Optimize for the common case where the left operation is defined (and successful). - if (!{{overloads_left}}) { - maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right) - || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}}) - || PyType_IsSubtype(Py_TYPE(right), {{type_cname}}); - } - if (maybe_self_is_left) { - if (maybe_self_is_right && !{{overloads_left}}) { - res = {{call_right}}; - if (res != Py_NotImplemented) return res; - Py_DECREF(res); - maybe_self_is_right = 0; // Don't bother calling it again. - } - res = {{call_left}}; - if (res != Py_NotImplemented) return res; - Py_DECREF(res); - } - if ({{overloads_left}}) { - maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right) - || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}}) - || PyType_IsSubtype(Py_TYPE(right), {{type_cname}}); - } - if (maybe_self_is_right) { - return {{call_right}}; - } - return Py_INCREF(Py_NotImplemented), Py_NotImplemented; -} |