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, 6 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*/