Edgewall Software

Ticket #211: mapping-style-__mod__-only-and-no-Markup_new-r826.diff

File mapping-style-__mod__-only-and-no-Markup_new-r826.diff, 5.5 KB (added by cboos, 8 years ago)

3rd attempt, trying out the idea of skipping the Markup __new__ static method altogether.

  • genshi/core.py

     
    419419    """
    420420    __slots__ = []
    421421
    422     def __new__(cls, text='', *args):
    423         if args:
    424             text %= tuple(map(escape, args))
    425         return unicode.__new__(cls, text)
    426 
    427422    def __add__(self, other):
    428423        return Markup(unicode(self) + unicode(escape(other)))
    429424
     
    431426        return Markup(unicode(escape(other)) + unicode(self))
    432427
    433428    def __mod__(self, args):
    434         if not isinstance(args, (list, tuple)):
     429        if isinstance(args, dict):
     430            return Markup(unicode.__mod__(self, dict(zip(args.keys(),
     431                map(escape, args.values())))))
     432        elif not isinstance(args, (list, tuple)):
    435433            args = [args]
    436434        return Markup(unicode.__mod__(self, tuple(map(escape, args))))
    437435
  • genshi/tests/core.py

     
    107107        assert type(markup) is Markup
    108108        self.assertEquals('<b>&amp;</b> boo', markup)
    109109
     110    def test_mod_mapping(self):
     111        markup = Markup('<b>%(foo)s</b>') % {'foo': '&'}
     112        assert type(markup) is Markup
     113        self.assertEquals('<b>&amp;</b>', markup)
     114
    110115    def test_mul(self):
    111116        markup = Markup('<b>foo</b>') * 2
    112117        assert type(markup) is Markup
  • genshi/output.py

     
    244244                if sysid:
    245245                    buf.append(' "%s"')
    246246                buf.append('>\n')
    247                 yield Markup(u''.join(buf), *filter(None, data))
     247                yield Markup(u''.join(buf)) % filter(None, data)
    248248                have_doctype = True
    249249
    250250            elif kind is START_CDATA:
     
    343343                if sysid:
    344344                    buf.append(' "%s"')
    345345                buf.append('>\n')
    346                 yield Markup(u''.join(buf), *filter(None, data))
     346                yield Markup(u''.join(buf)) % filter(None, data)
    347347                have_doctype = True
    348348
    349349            elif kind is START_CDATA:
     
    446446                if sysid:
    447447                    buf.append(' "%s"')
    448448                buf.append('>\n')
    449                 yield Markup(u''.join(buf), *filter(None, data))
     449                yield Markup(u''.join(buf)) % filter(None, data)
    450450                have_doctype = True
    451451
    452452            elif kind is PI:
  • genshi/_speedups.c

     
    144144    return ret;
    145145}
    146146
    147 static PyObject *
    148 Markup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    149 {
    150     PyObject *self, *text, *tmp, *args2;
    151     int nargs, i;
    152 
    153     nargs = PyTuple_GET_SIZE(args);
    154     if (nargs < 2) {
    155         return PyUnicode_Type.tp_new(type, args, NULL);
    156     }
    157 
    158     text = PyTuple_GET_ITEM(args, 0);
    159     args2 = PyTuple_New(nargs - 1);
    160     if (args2 == NULL) {
    161         return NULL;
    162     }
    163     for (i = 1; i < nargs; i++) {
    164         tmp = escape(PyTuple_GET_ITEM(args, i), 1);
    165         if (tmp == NULL) {
    166             Py_DECREF(args2);
    167             return NULL;
    168         }
    169         PyTuple_SET_ITEM(args2, i - 1, tmp);
    170     }
    171     tmp = PyUnicode_Format(text, args2);
    172     Py_DECREF(args2);
    173     if (tmp == NULL) {
    174         return NULL;
    175     }
    176     args = PyTuple_New(1);
    177     if (args == NULL) {
    178         Py_DECREF(tmp);
    179         return NULL;
    180     }
    181     PyTuple_SET_ITEM(args, 0, tmp);
    182     self = PyUnicode_Type.tp_new(type, args, NULL);
    183     Py_DECREF(args);
    184     return self;
    185 }
    186 
    187147PyDoc_STRVAR(escape__doc__,
    188148"Create a Markup instance from a string and escape special characters\n\
    189149it may contain (<, >, & and \").\n\
     
    325285Markup_mod(PyObject *self, PyObject *args)
    326286{
    327287    PyObject *tmp, *tmp2, *ret, *args2;
    328     int i, nargs;
     288    int i, nargs, nkwds = 0;
     289    PyObject *kwds = NULL;
    329290
    330     if (PyTuple_Check(args)) {
     291    if (PyDict_Check(args)) {
     292        kwds = args;
     293    }
     294    if ( kwds ) {
     295        nkwds = PyDict_Size(kwds);
     296    }
     297    if ( nkwds ) {
     298        PyObject *kwcopy, *key, *value;
     299        Py_ssize_t pos = 0;
     300
     301        kwcopy = PyDict_Copy( kwds );
     302        if (kwcopy == NULL) {
     303            return NULL;
     304        }
     305        while (PyDict_Next(kwcopy, &pos, &key, &value)) {
     306            tmp = escape(value, 1);
     307            if (tmp == NULL) {
     308                Py_DECREF(kwcopy);
     309                return NULL;
     310            }
     311            if (PyDict_SetItem(kwcopy, key, tmp) < 0) {
     312                Py_DECREF(tmp);
     313                Py_DECREF(kwcopy);
     314                return NULL;
     315            }
     316        }
     317        tmp = PyUnicode_Format(self, kwcopy);
     318        Py_DECREF(kwcopy);
     319        if (tmp == NULL) {
     320            return NULL;
     321        }
     322    } else if (PyTuple_Check(args)) {
    331323        nargs = PyTuple_GET_SIZE(args);
    332324        args2 = PyTuple_New(nargs);
    333325        if (args2 == NULL) {
     
    589581   
    590582    0,          /*tp_init*/
    591583    0,          /*tp_alloc  will be set to PyType_GenericAlloc in module init*/
    592     Markup_new, /*tp_new*/
     584    0,          /*tp_new*/
    593585    0,          /*tp_free  Low-level free-memory routine */
    594586    0,          /*tp_is_gc For PyObject_IS_GC */
    595587    0,          /*tp_bases*/