Skip to content

Commit 9998e7d

Browse files
committed
Improve compatibility of binary ops
1 parent 935725d commit 9998e7d

File tree

15 files changed

+1428
-167
lines changed

15 files changed

+1428
-167
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,78 @@ char* get_ob_sval(PyObject* op) {
527527
return ((PyBytesObject *)(op))->ob_sval;
528528
}
529529

530+
int64_t get_methods_flags(PyTypeObject *cls) {
531+
if (cls == NULL) {
532+
return 0;
533+
}
534+
535+
int64_t flags = 0;
536+
PyNumberMethods* number = cls->tp_as_number;
537+
if (number != NULL) {
538+
#define COMPUTE_FLAGS(NAME, BIT_IDX) flags |= ((number->NAME != NULL) * BIT_IDX);
539+
COMPUTE_FLAGS(nb_add, NB_ADD)
540+
COMPUTE_FLAGS(nb_subtract, NB_SUBTRACT)
541+
COMPUTE_FLAGS(nb_multiply, NB_MULTIPLY)
542+
COMPUTE_FLAGS(nb_remainder, NB_REMAINDER)
543+
COMPUTE_FLAGS(nb_divmod, NB_DIVMOD)
544+
COMPUTE_FLAGS(nb_power, NB_POWER)
545+
COMPUTE_FLAGS(nb_negative, NB_NEGATIVE)
546+
COMPUTE_FLAGS(nb_positive, NB_POSITIVE)
547+
COMPUTE_FLAGS(nb_absolute, NB_ABSOLUTE)
548+
COMPUTE_FLAGS(nb_bool, NB_BOOL)
549+
COMPUTE_FLAGS(nb_invert, NB_INVERT)
550+
COMPUTE_FLAGS(nb_lshift, NB_LSHIFT)
551+
COMPUTE_FLAGS(nb_rshift, NB_RSHIFT)
552+
COMPUTE_FLAGS(nb_and, NB_AND)
553+
COMPUTE_FLAGS(nb_xor, NB_XOR)
554+
COMPUTE_FLAGS(nb_or, NB_OR)
555+
COMPUTE_FLAGS(nb_int, NB_INT)
556+
COMPUTE_FLAGS(nb_float, NB_FLOAT)
557+
COMPUTE_FLAGS(nb_inplace_add, NB_INPLACE_ADD)
558+
COMPUTE_FLAGS(nb_inplace_subtract, NB_INPLACE_SUBTRACT)
559+
COMPUTE_FLAGS(nb_inplace_multiply, NB_INPLACE_MULTIPLY)
560+
COMPUTE_FLAGS(nb_inplace_remainder, NB_INPLACE_REMAINDER)
561+
COMPUTE_FLAGS(nb_inplace_power, NB_INPLACE_POWER)
562+
COMPUTE_FLAGS(nb_inplace_lshift, NB_INPLACE_LSHIFT)
563+
COMPUTE_FLAGS(nb_inplace_rshift, NB_INPLACE_RSHIFT)
564+
COMPUTE_FLAGS(nb_inplace_and, NB_INPLACE_AND)
565+
COMPUTE_FLAGS(nb_inplace_xor, NB_INPLACE_XOR)
566+
COMPUTE_FLAGS(nb_inplace_or, NB_INPLACE_OR)
567+
COMPUTE_FLAGS(nb_floor_divide, NB_FLOOR_DIVIDE)
568+
COMPUTE_FLAGS(nb_true_divide, NB_TRUE_DIVIDE)
569+
COMPUTE_FLAGS(nb_inplace_floor_divide, NB_INPLACE_FLOOR_DIVIDE)
570+
COMPUTE_FLAGS(nb_inplace_true_divide, NB_INPLACE_TRUE_DIVIDE)
571+
COMPUTE_FLAGS(nb_index, NB_INDEX)
572+
COMPUTE_FLAGS(nb_matrix_multiply, NB_MATRIX_MULTIPLY)
573+
COMPUTE_FLAGS(nb_inplace_matrix_multiply, NB_INPLACE_MATRIX_MULTIPLY)
574+
#undef COMPUTE_FLAGS
575+
}
576+
577+
PySequenceMethods *sequence = cls->tp_as_sequence;
578+
if (sequence != NULL) {
579+
#define COMPUTE_FLAGS(NAME, BIT_IDX) flags |= ((sequence->NAME != NULL) * BIT_IDX);
580+
COMPUTE_FLAGS(sq_length, SQ_LENGTH)
581+
COMPUTE_FLAGS(sq_concat, SQ_CONCAT)
582+
COMPUTE_FLAGS(sq_repeat, SQ_REPEAT)
583+
COMPUTE_FLAGS(sq_item, SQ_ITEM)
584+
COMPUTE_FLAGS(sq_ass_item, SQ_ASS_ITEM)
585+
COMPUTE_FLAGS(sq_contains, SQ_CONTAINS)
586+
COMPUTE_FLAGS(sq_inplace_concat, SQ_INPLACE_CONCAT)
587+
COMPUTE_FLAGS(sq_inplace_repeat, SQ_INPLACE_REPEAT)
588+
#undef COMPUTE_FLAGS
589+
}
590+
591+
PyMappingMethods *mapping = cls->tp_as_mapping;
592+
if (mapping != NULL) {
593+
#define COMPUTE_FLAGS(NAME, BIT_IDX) flags |= ((mapping->NAME != NULL) * BIT_IDX);
594+
COMPUTE_FLAGS(mp_length, MP_LENGTH)
595+
COMPUTE_FLAGS(mp_subscript, MP_SUBSCRIPT)
596+
COMPUTE_FLAGS(mp_ass_subscript, MP_ASS_SUBSCRIPT)
597+
#undef COMPUTE_FLAGS
598+
}
599+
return flags;
600+
}
601+
530602
// not quite as in CPython, this assumes that x is already a double. The rest of
531603
// the implementation is in the Float constructor in Java
532604
PyObject* float_subtype_new(PyTypeObject *type, double x) {

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,53 @@ typedef struct {
791791
#define set_PyTypeObject_tp_vectorcall_offset(OBJ, VALUE) { if (points_to_py_handle_space(OBJ)) GraalPy_set_PyTypeObject_tp_vectorcall_offset((PyTypeObject*) (OBJ), (VALUE)); else ((PyTypeObject*) (OBJ))->tp_vectorcall_offset = (VALUE); }
792792
#define set_PyTypeObject_tp_weaklistoffset(OBJ, VALUE) { if (points_to_py_handle_space(OBJ)) GraalPy_set_PyTypeObject_tp_weaklistoffset((PyTypeObject*) (OBJ), (VALUE)); else ((PyTypeObject*) (OBJ))->tp_weaklistoffset = (VALUE); }
793793
#define set_PyVarObject_ob_size(OBJ, VALUE) { if (points_to_py_handle_space(OBJ)) GraalPy_set_PyVarObject_ob_size((PyVarObject*) (OBJ), (VALUE)); else ((PyVarObject*) (OBJ))->ob_size = (VALUE); }
794+
795+
#define NB_ADD 1
796+
#define NB_SUBTRACT 2
797+
#define NB_MULTIPLY 4
798+
#define NB_REMAINDER 8
799+
#define NB_DIVMOD 16
800+
#define NB_POWER 32
801+
#define NB_NEGATIVE 64
802+
#define NB_POSITIVE 128
803+
#define NB_ABSOLUTE 256
804+
#define NB_BOOL 512
805+
#define NB_INVERT 1024
806+
#define NB_LSHIFT 2048
807+
#define NB_RSHIFT 4096
808+
#define NB_AND 8192
809+
#define NB_XOR 16384
810+
#define NB_OR 32768
811+
#define NB_INT 65536
812+
#define NB_FLOAT 262144
813+
#define NB_INPLACE_ADD 524288
814+
#define NB_INPLACE_SUBTRACT 1048576
815+
#define NB_INPLACE_MULTIPLY 2097152
816+
#define NB_INPLACE_REMAINDER 4194304
817+
#define NB_INPLACE_POWER 8388608
818+
#define NB_INPLACE_LSHIFT 16777216
819+
#define NB_INPLACE_RSHIFT 33554432
820+
#define NB_INPLACE_AND 67108864
821+
#define NB_INPLACE_XOR 134217728
822+
#define NB_INPLACE_OR 268435456
823+
#define NB_FLOOR_DIVIDE 536870912
824+
#define NB_TRUE_DIVIDE 1073741824
825+
#define NB_INPLACE_FLOOR_DIVIDE 2147483648
826+
#define NB_INPLACE_TRUE_DIVIDE 4294967296
827+
#define NB_INDEX 8589934592
828+
#define NB_MATRIX_MULTIPLY 17179869184
829+
#define NB_INPLACE_MATRIX_MULTIPLY 34359738368
830+
#define SQ_LENGTH 1099511627776
831+
#define SQ_CONCAT 2199023255552
832+
#define SQ_REPEAT 4398046511104
833+
#define SQ_ITEM 8796093022208
834+
#define SQ_ASS_ITEM 35184372088832
835+
#define SQ_CONTAINS 140737488355328
836+
#define SQ_INPLACE_CONCAT 281474976710656
837+
#define SQ_INPLACE_REPEAT 562949953421312
838+
#define MP_LENGTH 1125899906842624
839+
#define MP_SUBSCRIPT 2251799813685248
840+
#define MP_ASS_SUBSCRIPT 4503599627370496
794841
// {{end CAPI_BUILTINS}}
795842

796843

graalpython/com.oracle.graal.python.test/src/tests/test_binary_arithmetic.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2022, Oracle and/or its affiliates.
1+
# Copyright (c) 2018, 2023, Oracle and/or its affiliates.
22
# Copyright (c) 2013, Regents of the University of California
33
#
44
# All rights reserved.
@@ -325,3 +325,20 @@ def __pow__(self, power):
325325
# for some reason this hangs CPython on the CI even if it's just parsed
326326
from pow_tests import test_pow
327327
test_pow()
328+
329+
def test_slot1binfull():
330+
class A:
331+
def __add__(self, other):
332+
return 42
333+
334+
def __radd__(self, other):
335+
return 22
336+
337+
class B(A):
338+
pass
339+
340+
341+
assert A() + A() == 42
342+
assert A() + B() == 42
343+
assert B() + A() == 42
344+
assert B() + B() == 42

0 commit comments

Comments
 (0)