summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2020-06-17 13:11:01 +0200
committerStefan Behnel <stefan_ml@behnel.de>2020-06-17 13:11:01 +0200
commit6933d867cdea2460c922c45702b7e60f3d133c2d (patch)
treedb8da4a057550d7a87ae219aa3fb111121e5a107
parent8e3775b8e708c593d3803276288e34e859c31b26 (diff)
downloadcython-6933d867cdea2460c922c45702b7e60f3d133c2d.tar.gz
Revert "Python-style binary operation methods."
This reverts commit e6a812402b0368cf930a55ed465a38820f606054.
-rw-r--r--Cython/Compiler/ModuleNode.py43
-rw-r--r--Cython/Compiler/Options.py1
-rw-r--r--Cython/Compiler/TypeSlots.py44
-rw-r--r--Cython/Utility/ExtensionTypes.c56
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;
-}