[Grok-dev] zope.formlib, unicode dictionary keys

Jeffrey D Peterson bgpete at gmail.com
Mon Jul 19 15:05:39 EDT 2010


List,

 

I have a fresh install of Grok 1.1 and I am working on a login page.
Everything works fine until I submit the form at which point I get this:

 

*Snip*

 

 <http://zope3.crary.com:13080/portal/@@login> <<  
        def callObject(self, request, ob):
            return mapply(ob, request.getPositionalArguments(), request)
    
        def afterCall(self, request, ob):
<http://zope3.crary.com:13080/portal/@@login> >>  return mapply(ob,
request.getPositionalArguments(), request)

<crary.security.authentication.Login object at 0x942232c>


Module zope.publisher.publish:109 in mapply
<http://zope3.crary.com:13080/portal/@@login>
http://zope3.crary.com:13080/_debug/media/plus.jpg   
 <http://zope3.crary.com:13080/portal/@@login> <<  
        if __debug__:
            return debug_call(obj, args)
    
        return obj(*args) <http://zope3.crary.com:13080/portal/@@login> >>
return debug_call(obj, args)
Module zope.publisher.publish:115 in debug_call
<http://zope3.crary.com:13080/portal/@@login>
http://zope3.crary.com:13080/_debug/media/plus.jpg   
 <http://zope3.crary.com:13080/portal/@@login> <<  def debug_call(obj,
args):
        # The presence of this function allows us to set a pdb breakpoint
        return obj(*args)
    
    def publish(request, handle_errors=True):
<http://zope3.crary.com:13080/portal/@@login> >>  return obj(*args)
Module grokcore.formlib.components:90 in __call__
<http://zope3.crary.com:13080/portal/@@login>
http://zope3.crary.com:13080/_debug/media/plus.jpg   
 <http://zope3.crary.com:13080/portal/@@login> <<              return
    
            self.update_form()
            return self.render()
     <http://zope3.crary.com:13080/portal/@@login> >>  self.update_form()
Module grokcore.formlib.components:62 in update_form
<http://zope3.crary.com:13080/portal/@@login>
http://zope3.crary.com:13080/_debug/media/plus.jpg   
 <http://zope3.crary.com:13080/portal/@@login> <<          In grok views,
the update() method has a different meaning.
            That's why this method is called update_form() in grok forms.
That's why this method is called update_form() in grok forms."""
            super(GrokForm, self).update()
    
        def render(self): <http://zope3.crary.com:13080/portal/@@login> >>
super(GrokForm, self).update()
Module zope.formlib.form:764 in update
<http://zope3.crary.com:13080/portal/@@login>
http://zope3.crary.com:13080/_debug/media/plus.jpg   
 <http://zope3.crary.com:13080/portal/@@login> <<          elif errors is
not None:
                self.form_reset = True
                result = action.success(data)
            else:
                result = None <http://zope3.crary.com:13080/portal/@@login>
>>  result = action.success(data)
Module grokcore.formlib.formlib:33 in success
<http://zope3.crary.com:13080/portal/@@login>
http://zope3.crary.com:13080/_debug/media/plus.jpg   
 <http://zope3.crary.com:13080/portal/@@login> <<      def success(self,
data):
            if self.success_handler is not None:
                return self.success_handler(self.form, **data)
    
    def Fields(*args, **kw): <http://zope3.crary.com:13080/portal/@@login>
>>  return self.success_handler(self.form, **data)
TypeError: handle_login() keywords must be strings

 

The issue is the data that makes its way to the "success_handler" is a
dictionary with Unicode keywords.  At that point "success_handler" tries to
convert it to a variable length argument list which fails:

 

>>> def test(**d):

...     return d

...

>>> d={u'a':1, 'b':2}

>>> test(**d)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: test() keywords must be strings

>>> 

 

I poked around a bit and found  that the dictionary is created in
zope.formlib.form in "getWidgetsData" and the keywords are produced by
"_widgetKey" from the actual widget name.  In both functions there is no
conversion to unicode so they (the widget names) are Unicode going in.

 

You can work around this easy enough by changing:

 

def _widgetKey(widget, form_prefix):

    name = widget.name

    if name.startswith(form_prefix):

        name = name[len(form_prefix):]

    else:

        raise ValueError("Name does not match prefix", name, form_prefix)

    return name

 

to:

 

def _widgetKey(widget, form_prefix):

    name = widget.name

    if name.startswith(form_prefix):

        name = name[len(form_prefix):]

    else:

        raise ValueError("Name does not match prefix", name, form_prefix)

    return str(name)

 

But I am wondering if this is the place to deal with it, is there anyone out
there that has a better idea?

 

Regards,

 

Jeff Peterson

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.zope.org/pipermail/grok-dev/attachments/20100719/70837969/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 361 bytes
Desc: not available
Url : http://mail.zope.org/pipermail/grok-dev/attachments/20100719/70837969/attachment-0001.jpe 


More information about the Grok-dev mailing list