Edgewall Software

Ticket #258: markup-join-iterable.patch

File markup-join-iterable.patch, 2.7 KB (added by anonymous, 15 years ago)
  • genshi/_speedups.c

    diff -r 66f293fadcc5 -r 2256364c3a98 genshi/_speedups.c
    a b  
    229229static PyObject *
    230230Markup_join(PyObject *self, PyObject *args, PyObject *kwds)
    231231{
    232     static char *kwlist[] = {"seq", "escape_quotes", 0};
    233     PyObject *seq = NULL, *seq2, *tmp, *tmp2;
     232    static char *kwlist[] = {"iterable", "escape_quotes", 0};
     233    PyObject *iterable = NULL, *iterator, *iteritem, *seq2, *tmp, *tmp2;
    234234    char quotes = 1;
    235     int n, i;
    236235
    237     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|b", kwlist, &seq, &quotes)) {
     236    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|b", kwlist,
     237            &iterable, &quotes)) {
    238238        return NULL;
    239239    }
    240     if (!PySequence_Check(seq)) {
    241         PyErr_FromString(PyExc_TypeError, "a sequence is required");
     240    iterator = PyObject_GetIter(iterable);
     241    if (iterator == NULL)
    242242        return NULL;
    243     }
    244     n = PySequence_Size(seq);
    245     if (n < 0) {
    246         return NULL;
    247     }
    248     seq2 = PyTuple_New(n);
     243    seq2 = PyList_New(0);
    249244    if (seq2 == NULL) {
    250245        return NULL;
    251246    }
    252     for (i = 0; i < n; i++) {
    253         tmp = PySequence_GetItem(seq, i);
    254         if (tmp == NULL) {
    255             Py_DECREF(seq2);
    256             return NULL;
    257         }
    258         tmp2 = escape(tmp, quotes);
     247    while ((iteritem = PyIter_Next(iterator))) {
     248        tmp2 = escape(iteritem, quotes);
     249        Py_DECREF(iteritem);
    259250        if (tmp2 == NULL) {
    260251            Py_DECREF(seq2);
    261252            return NULL;
    262253        }
    263         PyTuple_SET_ITEM(seq2, i, tmp2);
    264         Py_DECREF(tmp);
     254        if (PyList_Append(seq2, tmp2) < 0) {
     255            Py_DECREF(tmp2);
     256            return NULL;
     257        }
     258        Py_DECREF(tmp2);
    265259    }
     260    if (PyErr_Occurred()) // in PyIter_Next above
     261        return NULL;
    266262    tmp = PyUnicode_Join(self, seq2);
    267263    Py_DECREF(seq2);
    268264    if (tmp == NULL)
  • genshi/tests/core.py

    diff -r 66f293fadcc5 -r 2256364c3a98 genshi/tests/core.py
    a b  
    136136        assert type(markup) is Markup
    137137        self.assertEquals('foo<br />&lt;bar /&gt;<br /><baz />', markup)
    138138
     139    def test_join_iterable(self):
     140        """
     141        Tests calling Markup.join with an argument which is iterable, but not
     142        a sequence.
     143        """
     144        markup = Markup('<br />').join(x for x in
     145                ['foo', '<bar />', Markup('<baz />')])
     146        assert type(markup) is Markup
     147        self.assertEquals('foo<br />&lt;bar /&gt;<br /><baz />', markup)
     148
    139149    def test_join_wrongtype(self):
    140150        """
    141151        Tests calling Markup.join with an argument whose type is nonsensical.