Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Colander: Is preparer supported in schema binding?

Received: by 10.100.20.19 with SMTP id 19mr1131600ant.0.1320876592443;
        Wed, 09 Nov 2011 14:09:52 -0800 (PST)
X-BeenThere: pylons-discuss@googlegroups.com
Received: by 10.150.41.17 with SMTP id o17ls1706537ybo.2.gmail; Wed, 09 Nov
 2011 14:09:44 -0800 (PST)
Received: by 10.236.185.197 with SMTP id u45mr6579757yhm.6.1320876584218;
        Wed, 09 Nov 2011 14:09:44 -0800 (PST)
Received: by 10.236.185.197 with SMTP id u45mr6579753yhm.6.1320876584206;
        Wed, 09 Nov 2011 14:09:44 -0800 (PST)
Return-Path: <mariano.m...@gmail.com>
Received: from mail-gx0-f178.google.com (mail-gx0-f178.google.com [209.85.161.178])
        by gmr-mx.google.com with ESMTPS id y7si2107891yha.4.2011.11.09.14.09.44
        (version=TLSv1/SSLv3 cipher=OTHER);
        Wed, 09 Nov 2011 14:09:44 -0800 (PST)
Received-SPF: pass (google.com: domain of mariano.m...@gmail.com designates 209.85.161.178 as permitted sender) client-ip=209.85.161.178;
Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of mariano.m...@gmail.com designates 209.85.161.178 as permitted sender) smtp.mail=mariano.m...@gmail.com; dkim=pass (test mode) header...@gmail.com
Received: by mail-gx0-f178.google.com with SMTP id h1so2473309ggn.37
        for <pylons-discuss@googlegroups.com>; Wed, 09 Nov 2011 14:09:44 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=date:from:to:subject:message-id:mail-followup-to:references
         :mime-version:content-type:content-disposition
         :content-transfer-encoding:in-reply-to:user-agent;
        bh=HW/DdTltZuDGec8l/gxBst+mWToLB8Z1F+ruqs8TVVk=;
        b=Gy9wvlb1J3xjRyUuZldfTWwlEAxmI3xEG28zejWbkJiEGplpkkzqQFtOVyFbXAOQn2
         L0Tdju2p3GQN625E5hqyENBx8oTp6YESp4h/Ct3cz9IVQVskYBmL38Fmk3uh3o7QYNmF
         F7utkAdQSumB1EFSpZAZHgHkD0jiCvgSl5e6w=
Received: by 10.101.8.31 with SMTP id l31mr1957564ani.94.1320876584090;
        Wed, 09 Nov 2011 14:09:44 -0800 (PST)
Return-Path: <mariano.m...@gmail.com>
Received: from localhost ([186.182.146.74])
        by mx.google.com with ESMTPS id 40sm17525066anu.17.2011.11.09.14.09.41
        (version=TLSv1/SSLv3 cipher=OTHER);
        Wed, 09 Nov 2011 14:09:42 -0800 (PST)
Date: Wed, 9 Nov 2011 19:09:38 -0300
From: Mariano Mara <mariano.m...@gmail.com>
To: pylons-discuss@googlegroups.com
Subject: Re: Colander: Is preparer supported in schema binding?
Message-ID: <20111109220938.GB20393@suspiria>
Mail-Followup-To: pylons-discuss@googlegroups.com
References: <20111108044357.GA6013@suspiria>
 <CAMysB04930kz1anT_k0WX_2KPiQWRxtg8nUcqjJjA6hdhYJ...@mail.gmail.com>
 <20111108125221.GB2806@suspiria>
 <CAMysB07hZWhRaP+ERZvrCxSiM34EkxXD3kc=NQCsdgyXDm8...@mail.gmail.com>
 <CAMysB07CvZ5+df3Ka78VgSXVRaWQ72R44_Zxt2g_Zdo_gyr...@mail.gmail.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <CAMysB07CvZ5+df3Ka78VgSXVRaWQ72R44_Zxt2g_Zdo_gyr...@mail.gmail.com>
User-Agent: Mutt/1.5.21 (2010-09-15)

On 09.11.11 13:56, Eric Rasmussen wrote:
> Hi Mariano,
> 
> I was hoping one of the colander experts might jump in, but I'll go
> out on a limb and say there's probably not a really clean way to do
> exactly what you want. However, you might consider passing in a
> deferred missing function to the SchemaNode. It does bypass
> validation, but otherwise appears to do what you want. Here's an
> example (needs some cleanup):
> 
> import colander, datetime
> from xlrd import xldate_as_tuple
> 
> # missing values not validated!
> @colander.deferred
> def xldate_missing(node, kw):
>    book = kw.get('book')
>    datemode = getattr(book, 'datemode')
>    datefloat = kw.get('datefloat')
>    tupledate = xldate_as_tuple(datefloat, datemode)
>    return datetime.datetime(*tupledate)
> 
> class CUser(colander.MappingSchema):
>    id = colander.SchemaNode(colander.String())
>    xldate = colander.SchemaNode(colander.Date(), missing=xldate_missing)
> 
> if __name__ == '__main__':
>    """ assign floating date to bound keyword datefloat
>    deferred missing method will fill in value"""
>    cstruct = {'id':u'TEST'}
>    schema = CUser().bind(
>       book=type('Book', (object,), {'datemode':0}),
>       datefloat=40808.0)
>    schema.deserialize(cstruct)
>    print 'final xldate value: %s' % schema.children[1].deserialize()
> 
> Or if you have a default datemode that's used most of the time, you
> could use a preparer function that converts with the default, and then
> modify the value if needed with an after_bind callback.
> 
> Best,
> Eric
> 

Eric, thanks a lot for your time and detailed suggestion. I will try to apply
it right away and see how it works and let you know.

Regards,
Mariano

> 
> On Tue, Nov 8, 2011 at 9:16 AM, Eric Rasmussen <ericrasmus...@gmail.com> wrote:
> > Hi Mariano,
> >
> > I understand the issue now and see what you're trying to do. My initial
> > thought is this isn't possible with preparer because it takes a value as its
> > only argument and returns the value as-is or modified.
> >
> > However, I'll take a look at this again tonight if no one else knows a
> > solution off-hand.
> >
> > Best,
> > Eric
> >
> >
> >
> > On Tue, Nov 8, 2011 at 4:52 AM, Mariano Mara <mariano.m...@gmail.com> wrote:
> >>
> >> On 07.11.11 21:17, Eric Rasmussen wrote:
> >> > � �Hi Mariano,
> >> > � �I haven't had any trouble with this but it would help to see your
> >> > code
> >> > � �to make sure I understand you correctly. The kw parameter should be
> >> > the
> >> > � �second argument to your deferred widget, and it will let you access
> >> > � �keyword arguments passed to the bind function like this:
> >> > � �# deferred select widget
> >> > � �@colander.deferred
> >> > � �def deferred_widget(node, kw):
> >> > � � � �options = kw.get('mykeyword', [])
> >> > � � � �return widget.SelectWidget(values=options)
> >> > � �# binding
> >> > � �SomeSchema().bind(mykeyword=data)
> >> > � �There's a more complete example at
> >> >
> >> > �[1]http://docs.pylonsproject.org/projects/colander/dev/binding.html?hig
> >> > � �hlight=deferred, but let me know if I misunderstood.
> >> > � �Thanks,
> >> > � �Eric
> >> >
> >>
> >> Hi Eric, thanks a lot for your quick answer.
> >>
> >> In order to give a little of extra context regarding my problem: I'm using
> >> colander to
> >> deserialize an excel file. One of the values is a date and excel stores it
> >> as
> >> a float. The xlrd package provides a suitable method to turn that float
> >> into a
> >> proper date value, however it requires a 'datemode' parameter that can
> >> only be
> >> obtained once you opened and parsed the excel file. That's why I'm
> >> deferring
> >> this preparer.
> >>
> >> I managed to create the following auto contained example (this can be
> >> reproduced installing the xlrd package). After some rounds of debugging my
> >> understanding is that a deferred preparer method is unable to receive the
> >> kw
> >> parameter.
> >>
> >> import colander, datetime
> >> from xlrd import xldate_as_tuple
> >>
> >> @colander.deferred
> >> def deferred_xls_date(value, kw):
> >> � �"""Preparer method to turn an excel float into the corresponding date
> >> � �value. We will know the datemode parameter once the excel book has been
> >> � �opened and parsed"""
> >> � �if value is None or value=='': return None
> >> � �datemode = getattr(kw.get('book'), 'datemode')
> >> � �return xldate_as_tuple(value, datemode)
> >>
> >> class CUser(colander.MappingSchema):
> >> � �id = colander.SchemaNode(colander.String())
> >>
> >> cstruct = {'id':u'TEST', 'sdate':40808.0}
> >> schema = CUser().bind(book=type('Book', (object,), {'datemode':0}))
> >> schema.add(colander.SchemaNode(colander.Date(),
> >> � � � � � � � �preparer=deferred_xls_date,
> >> � � � � � � � �validator=colander.Range(max=datetime.datetime.now())
> >> � � � � � � � �))
> >> schema.deserialize(cstruct)
> >>
> >> This happens when you execute it:
> >>
> >> $ python colander_example.py
> >> Traceback (most recent call last):
> >> �File "colander_example.py", line 22, in <module>
> >> � �schema.deserialize(cstruct)
> >> �File
> >> "/home/mariano/Code/SmD/env/lib/python2.7/site-packages/colander/__init__.py",
> >> line 1576, in deserialize
> >> � �appstruct = self.typ.deserialize(self, cstruct)
> >> �File
> >> "/home/mariano/Code/SmD/env/lib/python2.7/site-packages/colander/__init__.py",
> >> line 477, in deserialize
> >> � �return self._impl(node, cstruct, callback)
> >> �File
> >> "/home/mariano/Code/SmD/env/lib/python2.7/site-packages/colander/__init__.py",
> >> line 439, in _impl
> >> � �result[name] = callback(subnode, subval)
> >> �File
> >> "/home/mariano/Code/SmD/env/lib/python2.7/site-packages/colander/__init__.py",
> >> line 475, in callback
> >> � �return subnode.deserialize(subcstruct)
> >> �File
> >> "/home/mariano/Code/SmD/env/lib/python2.7/site-packages/colander/__init__.py",
> >> line 1579, in deserialize
> >> � �appstruct = self.preparer(appstruct)
> >> TypeError: __call__() takes exactly 3 arguments (2 given)
> >>
> >>
> >>
> >> > � �On Mon, Nov 7, 2011 at 8:43 PM, Mariano Mara
> >> > � �<[2]mariano.m...@gmail.com> wrote:
> >> >
> >> > � � �Hi there, I have a deferred preparer I want to apply in schema
> >> > � � �binding,
> >> > � � �however it seems it's ignoring the kw parameter. Is this the
> >> > � � �expected behaviour
> >> > � � �or I'm missing some detail?
> >> > � � �TIA,
> >> > � � �Mariano
> >>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "pylons-discuss" group.
> >> To post to this group, send email to pylons-discuss@googlegroups.com.
> >> To unsubscribe from this group, send email to
> >> pylons-discuss+unsubscribe@googlegroups.com.
> >> For more options, visit this group at
> >> http://groups.google.com/group/pylons-discuss?hl=en.
> >>
> >
> >
> 
> -- 
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To post to this group, send email to pylons-discuss@googlegroups.com.
> To unsubscribe from this group, send email to pylons-discuss+unsubscribe@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.
>