diff --git a/python_tests/test_list.py b/python_tests/test_list.py index 45cd1992..68f116ab 100644 --- a/python_tests/test_list.py +++ b/python_tests/test_list.py @@ -491,4 +491,11 @@ def test_db0_list_islice_iteration(db0_fixture): db0_list = db0.list(range(30)) expected_values = [10, 12, 14, 16, 18] for index, value in enumerate(itertools.islice(db0_list, 10, 20, 2)): - assert value == expected_values[index] \ No newline at end of file + assert value == expected_values[index] + +def test_db0_list_compare_with_other_typse(db0_fixture): + db0_list = db0.list([1, 2, 3]) + python_tuple = (1, 2, 3) + python_set = {1, 2, 3} + assert db0_list != python_tuple + assert db0_list != python_set \ No newline at end of file diff --git a/python_tests/test_set.py b/python_tests/test_set.py index f86071f4..7cb8c2da 100644 --- a/python_tests/test_set.py +++ b/python_tests/test_set.py @@ -148,8 +148,8 @@ def test_set_issubset(db0_no_autocommit, make_set): assert set_1.issubset(set_2) assert not set_1.issubset(set_3) assert set_1.issubset(set_1) - assert set_1.issubset([2,3,1,2,4]) - assert not set_1.issubset([2,3,5,6,7]) + assert set_1.issubset({2,3,1,2,4}) + assert not set_1.issubset({2,3,5,6,7}) @pytest.mark.parametrize("make_set", set_test_params) @@ -160,8 +160,8 @@ def test_set_issubset_str(db0_no_autocommit, make_set): assert set_1.issubset(set_2) assert not set_1.issubset(set_3) assert set_1.issubset(set_1) - assert set_1.issubset(["2", "3", "1", "2", "4"]) - assert not set_1.issubset(["2", "3", "5", "6", "7"]) + assert set_1.issubset({"2", "3", "1", "2", "4"}) + assert not set_1.issubset({"2", "3", "5", "6", "7"}) @pytest.mark.parametrize("make_set", set_test_params) def test_set_issubset_le(db0_no_autocommit, make_set): @@ -642,4 +642,11 @@ def test_db0_set_str_with_nested_memo_objects(db0_fixture): # Test that memo object appears in both (exact string comparison for memo object) memo_str = repr(inner_memo) assert memo_str in db0_str - assert memo_str in py_str \ No newline at end of file + assert memo_str in py_str + +def test_db0_set_compare_with_other_types(db0_fixture): + db0_set = db0.set([1, 2, 3]) + python_list = [1, 2, 3] + python_tuple = (1, 2, 3) + assert db0_set != python_list + assert db0_set != python_tuple \ No newline at end of file diff --git a/python_tests/test_tuple.py b/python_tests/test_tuple.py index d5d6347a..4bc97306 100644 --- a/python_tests/test_tuple.py +++ b/python_tests/test_tuple.py @@ -136,4 +136,11 @@ def test_db0_tuple_str_with_nested_memo_objects(db0_fixture): py_inner_memo = inner_memo py_tuple = (py_inner_memo, "test", None) assert str(db0_tuple) == str(py_tuple) - assert repr(db0_tuple) == repr(py_tuple) \ No newline at end of file + assert repr(db0_tuple) == repr(py_tuple) + +def test_db0_tuple_compare_with_other_types(db0_fixture): + db0_tuple = db0.tuple([1, 2, 3]) + python_list = [1, 2, 3] + python_set = {1, 2, 3} + assert db0_tuple != python_list + assert db0_tuple != python_set \ No newline at end of file diff --git a/src/dbzero/bindings/python/collections/PyList.cpp b/src/dbzero/bindings/python/collections/PyList.cpp index 135f10fe..d2e438af 100644 --- a/src/dbzero/bindings/python/collections/PyList.cpp +++ b/src/dbzero/bindings/python/collections/PyList.cpp @@ -84,7 +84,7 @@ namespace db0::python } ListObject *tryMake_ListInternal(PyObject *self, PyObject *const *args, Py_ssize_t nargs) - { + { if (nargs != 1 && nargs != 0) { PyErr_SetString(PyExc_TypeError, "list() takes exactly one or zero argument"); return NULL; @@ -227,7 +227,7 @@ namespace db0::python default: Py_RETURN_NOTIMPLEMENTED; } - } else { + } else if(PyList_Check(other)) { auto iterator = Py_OWN(PyObject_GetIter(other)); if (!iterator) { PyErr_SetString(PyExc_TypeError, "argument must be a sequence"); @@ -252,8 +252,20 @@ namespace db0::python Py_RETURN_NOTIMPLEMENTED; } - Py_RETURN_TRUE; + Py_RETURN_FALSE; + } else { + switch (op) { + case Py_EQ: { + Py_RETURN_FALSE; + } + case Py_NE: { + Py_RETURN_TRUE; + } + default: + Py_RETURN_NOTIMPLEMENTED; + } } + Py_RETURN_NOTIMPLEMENTED; } PyObject *PyAPI_ListObject_rq(ListObject *list_obj, PyObject *other, int op) diff --git a/src/dbzero/bindings/python/collections/PySet.cpp b/src/dbzero/bindings/python/collections/PySet.cpp index ec911574..d0cea71f 100644 --- a/src/dbzero/bindings/python/collections/PySet.cpp +++ b/src/dbzero/bindings/python/collections/PySet.cpp @@ -130,7 +130,7 @@ namespace db0::python } ++it2; } - } else { + } else if (PySet_Check(args[0])) { PyObject *other = args[0]; if (trySetObject_len(self) == 0 || PyObject_Length(other) == 0) { Py_RETURN_TRUE; @@ -147,6 +147,8 @@ namespace db0::python Py_RETURN_FALSE; } } + } else { + Py_RETURN_FALSE; } Py_RETURN_TRUE; } @@ -199,36 +201,48 @@ namespace db0::python PyObject *trySetObject_rq(SetObject *set_obj, PyObject *other, int op) { - PyObject** args = &other; - switch (op) { - case Py_EQ: - if (trySetObject_len(set_obj) != getLenPyObjectOrSet(other)) { - Py_RETURN_FALSE; + PyObject** args = &other; + if(PySet_Check(other) || SetObject_Check(other)) { + + switch (op) { + case Py_EQ: + if (trySetObject_len(set_obj) != getLenPyObjectOrSet(other)) { + Py_RETURN_FALSE; + } + return PyBool_fromBool(has_all_elements_in_collection(set_obj, other)); + case Py_NE: + if (trySetObject_len(set_obj) != getLenPyObjectOrSet(other)) { + Py_RETURN_TRUE; + } + return PyBool_fromBool(!has_all_elements_in_collection(set_obj, other)); + case Py_LE: // Test whether every element in the set is in other. + return trySetObject_issubsetInternal(set_obj, args, 1); + case Py_LT:{ // Test whether the set is a proper subset of other, that is, set <= other and set != other. + if (trySetObject_len(set_obj) == getLenPyObjectOrSet(other)) { + Py_RETURN_FALSE; + } + return trySetObject_issubsetInternal(set_obj, args, 1); } - return PyBool_fromBool(has_all_elements_in_collection(set_obj, other)); - case Py_NE: - if (trySetObject_len(set_obj) != getLenPyObjectOrSet(other)) { - Py_RETURN_TRUE; + case Py_GE: // Test whether every element in the set is in other. + return trySetObject_issupersetInternal(set_obj, args, 1); + case Py_GT:{ // Test whether the set is a proper superset of other, that is, set >= other and set != other. + if (trySetObject_len(set_obj) == getLenPyObjectOrSet(other)) { + Py_RETURN_FALSE; + } + return trySetObject_issupersetInternal(set_obj, args, 1); } - return PyBool_fromBool(!has_all_elements_in_collection(set_obj, other)); - case Py_LE: // Test whether every element in the set is in other. - return trySetObject_issubsetInternal(set_obj, args, 1); - case Py_LT:{ // Test whether the set is a proper subset of other, that is, set <= other and set != other. - if (trySetObject_len(set_obj) == getLenPyObjectOrSet(other)) { - Py_RETURN_FALSE; - } - return trySetObject_issubsetInternal(set_obj, args, 1); + default: + Py_RETURN_NOTIMPLEMENTED; } - case Py_GE: // Test whether every element in the set is in other. - return trySetObject_issupersetInternal(set_obj, args, 1); - case Py_GT:{ // Test whether the set is a proper superset of other, that is, set >= other and set != other. - if (trySetObject_len(set_obj) == getLenPyObjectOrSet(other)) { + } else { + switch (op) { + case Py_EQ: Py_RETURN_FALSE; - } - return trySetObject_issupersetInternal(set_obj, args, 1); + case Py_NE: + Py_RETURN_TRUE; + default: + Py_RETURN_NOTIMPLEMENTED; } - default: - Py_RETURN_NOTIMPLEMENTED; } Py_RETURN_NOTIMPLEMENTED; } diff --git a/src/dbzero/bindings/python/collections/PyTuple.cpp b/src/dbzero/bindings/python/collections/PyTuple.cpp index 8765b94d..1f001945 100644 --- a/src/dbzero/bindings/python/collections/PyTuple.cpp +++ b/src/dbzero/bindings/python/collections/PyTuple.cpp @@ -98,7 +98,7 @@ namespace db0::python default: Py_RETURN_NOTIMPLEMENTED; } - } else { + } else if (PyTuple_Check(other)) { auto iterator = Py_OWN(PyObject_GetIter(other)); if (!iterator) { PyErr_SetString(PyExc_TypeError, "argument must be an iterable"); @@ -122,8 +122,19 @@ namespace db0::python default: Py_RETURN_NOTIMPLEMENTED; } - Py_RETURN_TRUE; + } else { + switch (op) { + case Py_EQ: { + Py_RETURN_FALSE; + } + case Py_NE: { + Py_RETURN_TRUE; + } + default: + Py_RETURN_NOTIMPLEMENTED; + } } + Py_RETURN_NOTIMPLEMENTED; } PyObject *PyAPI_TupleObject_rq(TupleObject *tuple_obj, TupleObject *other, int op)