@@ -562,7 +562,8 @@ The Sequence Function Table
562562 - ``int (*objobjproc)(PyObject*, PyObject*) ``
563563 - Returns non-zero if the sequence contains the given object.
564564 Used by `PySequence_Contains() `_.
565- This slot may be left to NULL, in this case PySequence_Contains() simply traverses the sequence until it finds a match.
565+ This slot may be left to NULL, in this case PySequence_Contains() simply traverses the sequence until it
566+ finds a match.
566567 * - `sq_inplace_concat `_
567568 - `binaryfunc `_
568569 - ``PyObject *(*binaryfunc)(PyObject*, PyObject*) ``
@@ -1157,6 +1158,91 @@ Deleting a value with an out of range index:
11571158 assert err.value.args[0 ] == expected
11581159
11591160
1161+ -------------------
1162+ ``sq_ass_contains ``
1163+ -------------------
1164+
1165+ .. list-table :: Sequence Methods: ``sq_ass_contains``
1166+ :widths: 20 80
1167+ :header-rows: 0
1168+
1169+ * - Member
1170+ - `sq_ass_contains `_
1171+ * - Function type
1172+ - `objobjproc `_
1173+ * - Function signature
1174+ - ``int (*objobjproc)(PyObject*, PyObject*) ``
1175+ * - Description
1176+ - Returns non-zero if the sequence contains the given object.
1177+ If an item in o is equal to value, return 1, otherwise return 0. On error, return -1.
1178+ This is equivalent to the Python expression ``value in o ``.
1179+ Used by `PySequence_Contains() `_.
1180+ This slot may be left to NULL, in this case `PySequence_Contains() `_ simply traverses the sequence until it
1181+ finds a match.
1182+
1183+ Implementation
1184+ --------------
1185+
1186+ In ``src/cpy/Object/cSeqObject.c ``:
1187+
1188+ .. code-block :: c
1189+
1190+ /** If an item in self is equal to value, return 1, otherwise return 0.
1191+ * On error, return -1. */
1192+ static int
1193+ SequenceLongObject_sq_contains(PyObject *self, PyObject *value) {
1194+ fprintf(
1195+ stdout, "%s()#%d: self=%p value=%p\n",
1196+ __FUNCTION__, __LINE__, (void *) self, (void *) value
1197+ );
1198+ if (!PyLong_Check(value)) {
1199+ /* Alternates: Could raise TypeError or return -1.
1200+ * Here we act benignly! */
1201+ return 0;
1202+ }
1203+ long c_value = PyLong_AsLong(value);
1204+ /* For convenience. */
1205+ SequenceLongObject *self_as_slo = (SequenceLongObject *) self;
1206+ for (Py_ssize_t i = 0; i < SequenceLongObject_sq_length(self); ++i) {
1207+ if (self_as_slo->array_long[i] == c_value) {
1208+ return 1;
1209+ }
1210+ }
1211+ return 0;
1212+ }
1213+
1214+ .. note ::
1215+
1216+ Whilst ``SequenceLongObject_sq_contains() `` returns 0 or 1 Python code such as ``value in obj `` converts this to
1217+ ``False `` and ``True `` respectively
1218+
1219+ Tests
1220+ --------------
1221+
1222+ Tests are in ``tests/unit/test_c_seqobject.py ``:
1223+
1224+ .. code-block :: python
1225+
1226+ from cPyExtPatt import cSeqObject
1227+
1228+ @pytest.mark.parametrize (
1229+ ' initial_sequence, value, expected' ,
1230+ (
1231+ (
1232+ [7 , ], 0 , False ,
1233+ ),
1234+ (
1235+ [7 , ], 7 , True ,
1236+ ),
1237+ (
1238+ [1 , 4 , 7 , ], 7 , True ,
1239+ ),
1240+ )
1241+ )
1242+ def test_SequenceLongObject_contains (initial_sequence , value , expected ):
1243+ obj = cSeqObject.SequenceLongObject(initial_sequence)
1244+ result = value in obj
1245+ assert result == expected
11601246
11611247
11621248
0 commit comments