Skip to content

Commit 6c3d0d9

Browse files
committed
WIP on cSeqObject.c and documentation.
1 parent 19d6e4b commit 6c3d0d9

File tree

4 files changed

+98
-53
lines changed

4 files changed

+98
-53
lines changed

CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ add_executable(PythonExtensionPatterns
126126
src/cpy/Watchers/DictWatcher.c
127127
src/cpy/Watchers/DictWatcher.h
128128
src/cpy/pyextpatt_util.c
129-
src/cpy/pyextpatt_util.h src/cpy/Watchers/cWatchers.c)
129+
src/cpy/pyextpatt_util.h
130+
src/cpy/Watchers/cWatchers.c
131+
src/cpy/Object/cSeqObject.c
132+
)
130133

131134
#link_directories(${PYTHON_LINK_LIBRARY})
132135

doc/sphinx/source/iterators_generators.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ First the implementation of `__len__()`_ in C:
706706
.. code-block:: c
707707
708708
static Py_ssize_t
709-
SequenceOfLong_len(PyObject *self) {
709+
SequenceOfLong_sq_length(PyObject *self) {
710710
return ((SequenceOfLong *)self)->size;
711711
}
712712
@@ -716,17 +716,17 @@ index is out of range:
716716
.. code-block:: c
717717
718718
static PyObject *
719-
SequenceOfLong_getitem(PyObject *self, Py_ssize_t index) {
719+
SequenceOfLong_sq_item(PyObject *self, Py_ssize_t index) {
720720
Py_ssize_t my_index = index;
721721
if (my_index < 0) {
722-
my_index += SequenceOfLong_len(self);
722+
my_index += SequenceOfLong_sq_length(self);
723723
}
724-
if (my_index > SequenceOfLong_len(self)) {
724+
if (my_index > SequenceOfLong_sq_length(self)) {
725725
PyErr_Format(
726726
PyExc_IndexError,
727727
"Index %ld is out of range for length %ld",
728728
index,
729-
SequenceOfLong_len(self)
729+
SequenceOfLong_sq_length(self)
730730
);
731731
return NULL;
732732
}
@@ -738,8 +738,8 @@ Create `PySequenceMethods`_ method table:
738738
.. code-block:: c
739739
740740
PySequenceMethods SequenceOfLong_sequence_methods = {
741-
.sq_length = &SequenceOfLong_len,
742-
.sq_item = &SequenceOfLong_getitem,
741+
.sq_length = &SequenceOfLong_sq_length,
742+
.sq_item = &SequenceOfLong_sq_item,
743743
};
744744
745745
Add this method table into the type specification:

setup.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@
9898
extra_compile_args=extra_compile_args_c,
9999
language='c',
100100
),
101+
Extension(f"{PACKAGE_NAME}.cSeqObject", sources=['src/cpy/Object/cSeqObject.c', ],
102+
include_dirs=['/usr/local/include', ],
103+
library_dirs=[os.getcwd(), ], # path to .a or .so file(s)
104+
extra_compile_args=extra_compile_args_c,
105+
language='c',
106+
),
101107
Extension(f"{PACKAGE_NAME}.cParseArgs", sources=['src/cpy/ParseArgs/cParseArgs.c', ],
102108
include_dirs=['/usr/local/include', ], # os.path.join(os.getcwd(), 'include'),],
103109
library_dirs=[os.getcwd(), ], # path to .a or .so file(s)

src/cpy/Object/cSeqObject.c

Lines changed: 81 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ typedef struct {
1313
PyObject_HEAD
1414
long *array_long;
1515
ssize_t size;
16-
} SequenceOfLong;
16+
} SequenceLongObject;
17+
18+
// Forward references
19+
static PyTypeObject SequenceLongObjectType;
1720

18-
// Forward reference
1921
static int is_sequence_of_long_type(PyObject *op);
2022

2123
static PyObject *
22-
SequenceOfLong_new(PyTypeObject *type, PyObject *Py_UNUSED(args), PyObject *Py_UNUSED(kwds)) {
23-
SequenceOfLong *self;
24-
self = (SequenceOfLong *) type->tp_alloc(type, 0);
24+
SequenceLongObject_new(PyTypeObject *type, PyObject *Py_UNUSED(args), PyObject *Py_UNUSED(kwds)) {
25+
SequenceLongObject *self;
26+
self = (SequenceLongObject *) type->tp_alloc(type, 0);
2527
if (self != NULL) {
2628
assert(!PyErr_Occurred());
2729
self->size = 0;
@@ -31,7 +33,7 @@ SequenceOfLong_new(PyTypeObject *type, PyObject *Py_UNUSED(args), PyObject *Py_U
3133
}
3234

3335
static int
34-
SequenceOfLong_init(SequenceOfLong *self, PyObject *args, PyObject *kwds) {
36+
SequenceLongObject_init(SequenceLongObject *self, PyObject *args, PyObject *kwds) {
3537
static char *kwlist[] = {"sequence", NULL};
3638
PyObject *sequence = NULL;
3739

@@ -46,7 +48,7 @@ SequenceOfLong_init(SequenceOfLong *self, PyObject *args, PyObject *kwds) {
4648
if (!self->array_long) {
4749
return -3;
4850
}
49-
for (Py_ssize_t i = 0; i < PySequence_Length(sequence); ++i) {
51+
for (Py_ssize_t i = 0; i < self->size; ++i) {
5052
// New reference.
5153
PyObject *py_value = PySequence_GetItem(sequence, i);
5254
if (PyLong_Check(py_value)) {
@@ -70,20 +72,15 @@ SequenceOfLong_init(SequenceOfLong *self, PyObject *args, PyObject *kwds) {
7072
}
7173

7274
static void
73-
SequenceOfLong_dealloc(SequenceOfLong *self) {
75+
SequenceLongObject_dealloc(SequenceLongObject *self) {
7476
free(self->array_long);
7577
Py_TYPE(self)->tp_free((PyObject *) self);
7678
}
7779

78-
//static PyObject *
79-
//SequenceOfLong_size(SequenceOfLong *self, PyObject *Py_UNUSED(ignored)) {
80-
// return Py_BuildValue("n", self->size);
81-
//}
82-
83-
static PyMethodDef SequenceOfLong_methods[] = {
80+
static PyMethodDef SequenceLongObject_methods[] = {
8481
// {
8582
// "size",
86-
// (PyCFunction) SequenceOfLong_size,
83+
// (PyCFunction) SequenceLongObject_size,
8784
// METH_NOARGS,
8885
// "Return the size of the sequence."
8986
// },
@@ -92,66 +89,105 @@ static PyMethodDef SequenceOfLong_methods[] = {
9289

9390
/* Sequence methods. */
9491
static Py_ssize_t
95-
SequenceOfLong_len(PyObject *self) {
96-
return ((SequenceOfLong *)self)->size;
92+
SequenceLongObject_sq_length(PyObject *self) {
93+
return ((SequenceLongObject *) self)->size;
9794
}
9895

96+
/**
97+
* Returns a new SequenceLongObject composed of self + other.
98+
* @param self
99+
* @param other
100+
* @return
101+
*/
99102
static PyObject *
100-
SequenceOfLong_getitem(PyObject *self, Py_ssize_t index) {
103+
SequenceLongObject_sq_concat(PyObject *self, PyObject *other) {
104+
if (!is_sequence_of_long_type(other)) {
105+
PyErr_Format(
106+
PyExc_TypeError,
107+
"%s(): argument 1 must have type \"SequenceLongObject\" not %s",
108+
Py_TYPE(other)->tp_name
109+
);
110+
return NULL;
111+
}
112+
PyObject *ret = SequenceLongObject_new(&SequenceLongObjectType, NULL, NULL);
113+
/* For convenience. */
114+
SequenceLongObject *sol = (SequenceLongObject *) ret;
115+
sol->size = ((SequenceLongObject *) self)->size + ((SequenceLongObject *) other)->size;
116+
sol->array_long = malloc(sol->size * sizeof(long));
117+
if (!sol->array_long) {
118+
PyErr_Format(PyExc_MemoryError, "%s(): Can not create new object.", __FUNCTION__);
119+
}
120+
121+
ssize_t i = 0;
122+
ssize_t ub = ((SequenceLongObject *) self)->size;
123+
while (i < ub) {
124+
sol->array_long[i] = ((SequenceLongObject *) self)->array_long[i];
125+
i++;
126+
}
127+
ub += ((SequenceLongObject *) other)->size;
128+
while (i < ub) {
129+
sol->array_long[i] = ((SequenceLongObject *) other)->array_long[i];
130+
i++;
131+
}
132+
return ret;
133+
}
134+
135+
136+
static PyObject *
137+
SequenceLongObject_sq_item(PyObject *self, Py_ssize_t index) {
101138
Py_ssize_t my_index = index;
102139
if (my_index < 0) {
103-
my_index += SequenceOfLong_len(self);
140+
my_index += SequenceLongObject_sq_length(self);
104141
}
105-
if (my_index > SequenceOfLong_len(self)) {
142+
if (my_index > SequenceLongObject_sq_length(self)) {
106143
PyErr_Format(
107144
PyExc_IndexError,
108145
"Index %ld is out of range for length %ld",
109146
index,
110-
SequenceOfLong_len(self)
147+
SequenceLongObject_sq_length(self)
111148
);
112149
return NULL;
113150
}
114-
return PyLong_FromLong(((SequenceOfLong *)self)->array_long[my_index]);
151+
return PyLong_FromLong(((SequenceLongObject *) self)->array_long[my_index]);
115152
}
116153

117-
PySequenceMethods SequenceOfLong_sequence_methods = {
118-
.sq_length = &SequenceOfLong_len,
119-
.sq_concat = NULL,
154+
PySequenceMethods SequenceLongObject_sequence_methods = {
155+
.sq_length = &SequenceLongObject_sq_length,
156+
.sq_concat = &SequenceLongObject_sq_concat,
120157
.sq_repeat = NULL,
121-
.sq_item = &SequenceOfLong_getitem,
158+
.sq_item = &SequenceLongObject_sq_item,
122159
.sq_ass_item = NULL,
123160
.sq_contains = NULL,
124161
.sq_inplace_concat = NULL,
125162
.sq_inplace_repeat = NULL,
126163
};
127164

128165
static PyObject *
129-
SequenceOfLong___str__(SequenceOfLong *self, PyObject *Py_UNUSED(ignored)) {
166+
SequenceLongObject___str__(SequenceLongObject *self, PyObject *Py_UNUSED(ignored)) {
130167
assert(!PyErr_Occurred());
131-
return PyUnicode_FromFormat("<SequenceOfLong sequence size: %ld>", self->size);
168+
return PyUnicode_FromFormat("<SequenceLongObject sequence size: %ld>", self->size);
132169
}
133170

134-
static PyTypeObject SequenceOfLongType = {
171+
static PyTypeObject SequenceLongObjectType = {
135172
PyVarObject_HEAD_INIT(NULL, 0)
136-
.tp_name = "SequenceOfLong",
137-
.tp_basicsize = sizeof(SequenceOfLong),
173+
.tp_name = "SequenceLongObject",
174+
.tp_basicsize = sizeof(SequenceLongObject),
138175
.tp_itemsize = 0,
139-
.tp_dealloc = (destructor) SequenceOfLong_dealloc,
140-
.tp_as_sequence = &SequenceOfLong_sequence_methods,
141-
.tp_str = (reprfunc) SequenceOfLong___str__,
176+
.tp_dealloc = (destructor) SequenceLongObject_dealloc,
177+
.tp_as_sequence = &SequenceLongObject_sequence_methods,
178+
.tp_str = (reprfunc) SequenceLongObject___str__,
142179
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
143180
.tp_doc = "Sequence of long integers.",
144-
.tp_methods = SequenceOfLong_methods,
145-
.tp_init = (initproc) SequenceOfLong_init,
146-
.tp_new = SequenceOfLong_new,
181+
.tp_methods = SequenceLongObject_methods,
182+
.tp_init = (initproc) SequenceLongObject_init,
183+
.tp_new = SequenceLongObject_new,
147184
};
148185

149186
static int
150187
is_sequence_of_long_type(PyObject *op) {
151-
return Py_TYPE(op) == &SequenceOfLongType;
188+
return Py_TYPE(op) == &SequenceLongObjectType;
152189
}
153190

154-
155191
static PyMethodDef cIterator_methods[] = {
156192
// {"iterate_and_print", (PyCFunction) iterate_and_print, METH_VARARGS,
157193
// "Iteratee through the argument printing the values."},
@@ -162,7 +198,7 @@ static PyModuleDef sequence_object_cmodule = {
162198
PyModuleDef_HEAD_INIT,
163199
.m_name = "cSeqObject",
164200
.m_doc = (
165-
"Example module that creates an extension type with sequence methods"
201+
"Example module that creates an extension type with sequence methods"
166202
),
167203
.m_size = -1,
168204
.m_methods = cIterator_methods,
@@ -176,17 +212,17 @@ PyInit_cSeqObject(void) {
176212
return NULL;
177213
}
178214

179-
if (PyType_Ready(&SequenceOfLongType) < 0) {
215+
if (PyType_Ready(&SequenceLongObjectType) < 0) {
180216
Py_DECREF(m);
181217
return NULL;
182218
}
183-
Py_INCREF(&SequenceOfLongType);
219+
Py_INCREF(&SequenceLongObjectType);
184220
if (PyModule_AddObject(
185221
m,
186-
"SequenceOfLong",
187-
(PyObject *) &SequenceOfLongType) < 0
222+
"SequenceLongObject",
223+
(PyObject *) &SequenceLongObjectType) < 0
188224
) {
189-
Py_DECREF(&SequenceOfLongType);
225+
Py_DECREF(&SequenceLongObjectType);
190226
Py_DECREF(m);
191227
return NULL;
192228
}

0 commit comments

Comments
 (0)