Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 247281a

Browse files
committed
Implement partition method
1 parent e5dc80a commit 247281a

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/cstring.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static PyObject *_cstring_copy(PyObject *self) {
6363
}
6464

6565
static PyObject *cstring_new_empty(void) {
66+
/* TODO: empty cstring should be a singleton */
6667
return _cstring_new(&cstring_type, "", 0);
6768
}
6869

@@ -538,6 +539,51 @@ PyObject *cstring_lower(PyObject *self, PyObject *args) {
538539
return (PyObject *)new;
539540
}
540541

542+
static PyObject *_tuple_steal_refs(Py_ssize_t count, ...) {
543+
PyObject *result = PyTuple_New(count);
544+
if(!result)
545+
return NULL;
546+
547+
va_list va;
548+
va_start(va, count);
549+
for(int i = 0; i < count; ++i) {
550+
PyObject *o = va_arg(va, PyObject *);
551+
if(!o)
552+
goto fail;
553+
PyTuple_SET_ITEM(result, i, o);
554+
}
555+
va_end(va);
556+
557+
return result;
558+
559+
fail:
560+
Py_DECREF(result);
561+
return NULL;
562+
}
563+
564+
PyDoc_STRVAR(partition__doc__, "");
565+
PyObject *cstring_partition(PyObject *self, PyObject *arg) {
566+
if(!_ensure_cstring(arg))
567+
return NULL;
568+
569+
const char *search = CSTRING_VALUE(arg);
570+
571+
const char *left = CSTRING_VALUE(self);
572+
const char *mid = strstr(left, search);
573+
if(!mid) {
574+
return _tuple_steal_refs(3,
575+
(Py_INCREF(self), self),
576+
cstring_new_empty(),
577+
cstring_new_empty());
578+
}
579+
const char *right = mid + strlen(search);
580+
581+
return _tuple_steal_refs(3,
582+
_cstring_new(Py_TYPE(self), left, mid - left),
583+
_cstring_new(Py_TYPE(self), mid, right - mid),
584+
_cstring_new(Py_TYPE(self), right, &CSTRING_LAST_BYTE(self) - right));
585+
}
586+
541587
PyDoc_STRVAR(rfind__doc__, "");
542588
PyObject *cstring_rfind(PyObject *self, PyObject *args) {
543589
struct _substr_params params;
@@ -726,7 +772,7 @@ static PyMethodDef cstring_methods[] = {
726772
{"lower", cstring_lower, METH_NOARGS, lower__doc__},
727773
{"lstrip", cstring_lstrip, METH_VARARGS, lstrip__doc__},
728774
/* TODO: maketrans */
729-
/* TODO: partition */
775+
{"partition", cstring_partition, METH_O, partition__doc__},
730776
/* TODO: removeprefix */
731777
/* TODO: replace */
732778
{"rfind", cstring_rfind, METH_VARARGS, rfind__doc__},

test/test_methods.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,18 @@ def test_rstrip_arg():
215215
assert target.rstrip('held') == cstring('hello, wor')
216216

217217

218+
def test_partition():
219+
target = cstring('hello, world')
220+
result = (cstring('hello'), cstring(', '), cstring('world'))
221+
assert target.partition(cstring(', ')) == result
222+
223+
224+
def test_partition_sep_not_found():
225+
target = cstring('hello, world')
226+
result = (cstring('hello, world'), cstring(''), cstring(''))
227+
assert target.partition(cstring(': ')) == result
228+
229+
218230
def test_startswith():
219231
target = cstring('hello, world')
220232
assert target.startswith('hello,') is True

0 commit comments

Comments
 (0)