durusmail: quixote-users: Inconsistency between _c_htmltext.c and_py_htmltext.py
Inconsistency between _c_htmltext.c and _py_htmltext.py
2004-03-08
Inconsistency between _c_htmltext.c and_py_htmltext.py
2004-03-08
Inconsistency between _c_htmltext.c and_py_htmltext.py
2004-03-08
Inconsistency between _c_htmltext.c and_py_htmltext.py
Jason E. Sibre
2004-03-08
Sweet!

Thanks Neil.  I was working on a patch along the lines of my last post, and
it worked, but yours is more elegant, and I really like the performance
boost it got as a side effect. (In my limited test case, it actually cut the
execution time to about 60% of what it used to be) I guess that's because
it's now lazier than it was, only looking up (and wrapping) what is must,
rather than wrapping everything in the dict which, in the usual case of
vars(), could be much more than is really needed.

As a side benefit, I see that I now only have to implement __getitem__ in
order for things to work!

Thanks again,

Jason



> -----Original Message-----
> From: quixote-users-bounces+jsibre=chironsys.com@mems-exchange.org
> [mailto:quixote-users-bounces+jsibre=chironsys.com@mems-exchange.org]On
> Behalf Of Neil Schemenauer
> Sent: Monday, March 08, 2004 10:57 AM
> To: quixote-users@mems-exchange.org
> Subject: Re: [Quixote-users] Inconsistency between _c_htmltext.c
> and_py_htmltext.py
>
>
> On Sun, Mar 07, 2004 at 07:15:28PM -0600, Jason Sibre wrote:
> > The problem is that an instance of htmltext that came from the c version
> > will not accept a mapping object other than a dict, or a
> subclass of one,
> > while the python version of htmltext will allow you to provide any
> > 'mapping-like' object.
>
> This is a known bug that I haven't got around to fixing yet.  I'm
> sorry you had to discover it yourself.  I've just whipped up a patch
> that I think fixes the problem in an elegant way.  See the
> attachment.
>
>   Neil
>
>
> Index: src/_c_htmltext.c
> ===================================================================
> --- src/_c_htmltext.c (revision 23644)
> +++ src/_c_htmltext.c (working copy)
> @@ -23,8 +23,19 @@
>
>  #define QuoteWrapper_Check(v)        ((v)->ob_type == &QuoteWrapper_Type)
>
> +
>  typedef struct {
>       PyObject_HEAD
> +     PyObject *obj;
> +} DictWrapperObject;
> +
> +static PyTypeObject DictWrapper_Type;
> +
> +#define DictWrapper_Check(v) ((v)->ob_type == &DictWrapper_Type)
> +
> +
> +typedef struct {
> +     PyObject_HEAD
>       int html;
>       char *buf;
>       size_t size;
> @@ -179,6 +190,38 @@
>  }
>
>  static PyObject *
> +dict_wrapper_new(PyObject *o)
> +{
> +     DictWrapperObject *self;
> +     self = PyObject_New(DictWrapperObject, &DictWrapper_Type);
> +     if (self == NULL)
> +             return NULL;
> +     Py_INCREF(o);
> +     self->obj = o;
> +     return (PyObject *)self;
> +}
> +
> +static void
> +dict_wrapper_dealloc(DictWrapperObject *self)
> +{
> +     Py_DECREF(self->obj);
> +     PyObject_Del(self);
> +}
> +
> +static PyObject *
> +dict_wrapper_subscript(DictWrapperObject *self, PyObject *key)
> +{
> +     PyObject *v, *w;;
> +     v = PyObject_GetItem(self->obj, key);
> +     if (v == NULL) {
> +             return NULL;
> +     }
> +     w = quote_wrapper_new(v);
> +     Py_DECREF(v);
> +     return w;
> +}
> +
> +static PyObject *
>  htmltext_from_string(PyObject *s)
>  {
>       /* note, this takes a reference */
> @@ -316,21 +359,9 @@
>               }
>       }
>       if (do_dict) {
> -             int pos = 0;
> -             PyObject *key, *value;
> -             wargs = PyDict_New();
> -             while (PyDict_Next(args, &pos, &key, &value)) {
> -                     PyObject *wvalue = wrap_arg(value);
> -                     if (wvalue == NULL) {
> -                             Py_DECREF(wargs);
> -                             return NULL;
> -                     }
> -                     if (PyDict_SetItem(wargs, key, wvalue) < 0) {
> -                             Py_DECREF(wargs);
> -                             return NULL;
> -                     }
> -                     Py_DECREF(wvalue);
> -             }
> +             wargs = dict_wrapper_new(args);
> +             if (wargs == NULL)
> +                     return NULL;
>       }
>       else if (PyTuple_Check(args)) {
>               long i, n = PyTuple_GET_SIZE(args);
> @@ -808,6 +839,30 @@
>       (unaryfunc)quote_wrapper_str,  /*tp_str*/
>  };
>
> +static PyMappingMethods dict_wrapper_as_mapping = {
> +        0, /*mp_length*/
> +        (binaryfunc)dict_wrapper_subscript, /*mp_subscript*/
> +        0, /*mp_ass_subscript*/
> +};
> +
> +static PyTypeObject DictWrapper_Type = {
> +     PyObject_HEAD_INIT(NULL)
> +     0,                      /*ob_size*/
> +     "DictWrapper",          /*tp_name*/
> +     sizeof(DictWrapperObject),      /*tp_basicsize*/
> +     0,                      /*tp_itemsize*/
> +     /* methods */
> +     (destructor)dict_wrapper_dealloc, /*tp_dealloc*/
> +     0,                      /*tp_print*/
> +     0,                      /*tp_getattr*/
> +     0,                      /*tp_setattr*/
> +     0,                      /*tp_compare*/
> +     0,                      /*tp_repr*/
> +     0,                      /*tp_as_number*/
> +     0,                      /*tp_as_sequence*/
> +     &dict_wrapper_as_mapping,/*tp_as_mapping*/
> +};
> +
>  static PyNumberMethods template_io_as_number = {
>       0, /*nb_add*/
>       0, /*nb_subtract*/
> Index: _py_htmltext.py
> ===================================================================
> --- _py_htmltext.py   (revision 23644)
> +++ _py_htmltext.py   (working copy)
> @@ -72,24 +72,18 @@
>      def __mod__(self, args):
>          codes = []
>          usedict = 0
> -        klass = self.__class__
>          for format in _format_re.findall(self.s):
>              if format[-1] != '%':
>                  if format[1] == '(':
>                      usedict = 1
>                  codes.append(format[-1])
>          if usedict:
> -            if not hasattr(args, "items"):
> -                raise TypeError, "mapping required"
> -            wrapped_args = {}
> -            for (k, v) in args.items():
> -                wrapped_args[k] = _wraparg(klass, v)
> -            args = wrapped_args
> +            args = _DictWrapper(args)
>          else:
>              if len(codes) == 1 and not isinstance(args, TupleType):
>                  args = (args,)
> -            args = tuple([_wraparg(klass, arg) for arg in args])
> -        return klass(self.s % args)
> +            args = tuple([_wraparg(arg) for arg in args])
> +        return self.__class__(self.s % args)
>
>      def __add__(self, other):
>          if isinstance(other, StringType):
> @@ -169,8 +163,15 @@
>      def __repr__(self):
>          return self.escape(`self.value`)
>
> -def _wraparg(klass, arg):
> -    if (classof(arg) is klass or
> +class _DictWrapper(object):
> +    def __init__(self, value):
> +        self.value = value
> +
> +    def __getitem__(self, key):
> +        return _wraparg(self.value[key])
> +
> +def _wraparg(arg):
> +    if (classof(arg) is htmltext or
>          isinstance(arg, IntType) or
>          isinstance(arg, LongType) or
>          isinstance(arg, FloatType)):
>
> _______________________________________________
> Quixote-users mailing list
> Quixote-users@mems-exchange.org
> http://mail.mems-exchange.org/mailman/listinfo/quixote-users
>



reply