<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Let’s Discuss the Matter Further</title>
    <link>http://rhodesmill.org/brandon</link>
    <description>Your Blog's short description</description>
    <pubDate>Thu, 19 Jan 2012 00:48:19 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Grok has book. Book good!</title>
      <link>http://rhodesmill.org/brandon/2010/grok-has-book-book-good/</link>
      <pubDate>Thu, 10 Jun 2010 22:32:52 EDT</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[grok]]></category>
      <category><![CDATA[books]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=350</guid>
      <description>Grok has book. Book good!</description>
      <content:encoded><![CDATA[
<p>
  I little suspected the great chasm that lies
  between the simple act of agreeing to review a book,
  and the actual exercise of sitting down later to write the review.
  It feels quite pleasant, really,
  to jot off a positive reply to the publisher's polite question.
  One feels magnanimous for agreeing to help advance our civilization
  by reviewing a book about Python,
  and for helping out the publisher in what,
  after all, are such hard economic times.
  It is fun when the free copy arrives,
  crisp and smartly bound.
</p>
<p>
  But then, eventually, one has to write the actual review.
</p>
<div class="dropshadow alignright"> 
  <a href="http://www.amazon.com/gp/product/1847197485?ie=UTF8&tag=letsdisthemat-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=1847197485"><img border="0" src="http://rhodesmill.org/brandon/static/2010/grok-book.jpg"></a><img src="http://www.assoc-amazon.com/e/ir?t=letsdisthemat-20&l=as2&o=1&a=1847197485" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
</div>
<p>
  And so,
  a full four months after that friendly email from Packt Publishing,
  it is time that I sit down
  and put together some thoughts
  about Carlos de la Guardia's first book,
  <a href="http://www.amazon.com/gp/product/1847197485?ie=UTF8&tag=letsdisthemat-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=1847197485"
     >Grok 1.0 Web Development</a>.
  Carlos is a long-time veteran of the Zope and Plone communities,
  and <a href="http://grok.zope.org/">Grok</a>,
  of course,
  is the web framework
  that places a simple and agile convention-driven engine
  atop the otherwise notoriously XML-ridden Zope application framework.
  Grok is an important project,
  because it packages the technology of Python's oldest
  and most experienced community of web developers
  in a way that makes it easy to extend and use.
</p>
<!--more-->
<p>
  First, one notices that the book does exhibit the kind of typos
  for which Packt are well known;
  but not so many, in this case, as to distract me from the text.
  The book tackles increasingly complicated topics
  in roughly the same order as every book in the web development genre:
  first installation, then views, models, forms, and so forth.
  But even here one notices an initial difference!
  Because this is the land of Zope,
  the search engine chapter appears quite early in the book —
  in Chapter 6, in fact.
  While some web frameworks can only support search
  through the installation of a special database extension,
  or perhaps through an entirely separate third-party application,
  Grok comes with search already integrated into its object database.
  This lets the concept be introduced early
  as a natural part of the framework,
  rather than being a difficult exercise in product integration
  best left for after the user has learned deployment.
</p>
<p>
  Not that third-party products are bad!
  In fact, I am happy to see that in many cases Carlos teaches his readers to use them.
  Barely twenty pages into the book,
  the new developer is being taught about using
  <a href="http://pypi.python.org/pypi/virtualenv">virtualenv</a>
  to maintain an installation of Python packages;
  and near the end,
  Carlos teaches deployment using the modern and sleek
  <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a> module.
  Some books feel myopically focused on one software community;
  this one, instead, feels expansive,
  a place where best practices from all across the Python ecosystem meet.
</p>
<p>
  It is particularly notable
  that at one point Carlos steps outside of Zope entirely
  and, for an entire chapter, describes how Grok integrates support
  for relational databases through
  <a href="http://www.sqlalchemy.org/">SQLAlchemy</a>,
  Python's most outstanding ORM.
  This both reflects credit upon the flexibility of Grok —
  whose abstractions must be working extremely well
  to build atop an entirely different database model,
  one that is not even native to Zope —
  and it evidences Carlos's determination
  to teach a very wide set of skills in his book.
  In fact, he even goes in the other direction at one point,
  and teaches the interested developer
  how to use the ZODB <i>without</i> Grok
  in case they want to access it from another application!
</p>
<p>
  The book tends to be quite clear in what it explains,
  but it sometimes feels as though a few more side trips
  in its examples would be welcome —
  it was not always clear to me whether a beginner,
  after plowing through an example,
  would understand what alternatives Carlos faced at each step,
  and why Carlos chose to build the solutions in the way he did.
</p>
<p>
  Though the book does cover testing,
  it is not test <i>driven</i> —
  testing is confined to its own chapter near the end of the book,
  rather than motivating the design of each sample application.
  A more interesting omission
  is that the book says nothing about web services,
  despite the fact that XML-RPC and REST are two things that Grok does particularly well!
  A chapter on building web APIs would be a great subject
  for a second edition of this book,
  especially if it then proceeded
  to show how easily Grok can support the Ajax design pattern.
</p>
<p>
  It did strike me as decidedly old-fashioned
  that Carlos repeats the weary canard
  that the Zope template language's awkwardness and verbosity
  are worth it,
  because it allows your templates to remain valid HTML,
  because your designers might, at any moment,
  want to open up and tweak a raw template in their browsers!
  This, of course, only works if your templates are each an entire page —
  if you fail to avail yourself, in other words, of <i>any</i> of the power
  of the macros, slots, and viewlets
  that Carlos goes on to describe later.
  And, in fact, many of his later templates
  are indeed mere un-styled HTML snippets
  that no designer in their right mind would view in isolation.
  All of which leads to the question of why
  <a href="http://genshi.edgewall.org/">Genshi</a>,
  another template language popular with Grok developers,
  does not warrant any mention in the book —
  especially since the book in so many other cases
  is careful to mention more widely deployed Python technologies
  that Grok is able to use.
</p>
<p>
  Finally, I can attest that a concept
  I never managed to learn when I was active with Grok —
  the tangle of concepts that surround
  viewlets, viewlet managers, layers, and skins —
  became quite clear as I sat down
  and read Chapter 8 in close detail.
  On the one topic which I could truly approach as a newcomer, therefore,
  I found Carlos's approach to be very direct and understandable.
</p>
<p>
  Grok has good online documentation,
  but unless you are already an experienced developer
  you will have difficulty putting the pieces together
  into a story that runs smoothly from model to view to deployment.
  If you need help getting the whole picture
  of how Grok apps fit together,
  you will certainly want this book.
  You can purchase it from either
  <a href="http://www.amazon.com/gp/product/1847197485?ie=UTF8&tag=letsdisthemat-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=1847197485"
     >Amazon</a>
  or directly from its publisher,
  <a href="http://www.packtpub.com/grok-1-0-web-development/book?utm_source=rhodesmill.org&utm_medium=bookrev&utm_content=blog&utm_campaign=mdb_002483"
     >Packt Publishing</a>.
</p>]]></content:encoded>
    </item>
    <item>
      <title>GetPaid needs customizable forms</title>
      <link>http://rhodesmill.org/brandon/2009/getpaid-needs-customizable-forms/</link>
      <pubDate>Thu, 10 Sep 2009 00:25:46 EDT</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[plone]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=144</guid>
      <description>GetPaid needs customizable forms</description>
      <content:encoded><![CDATA[
<div class="dropshadow alignright">
  <a href="http://www.plonegetpaid.com/">
    <img src="http://rhodesmill.org/brandon/static/2009/getpaid-logo.png"
         alt="GetPaid for Plone logo"
         width="330" height="83" />
  </a>
</div>
<p>
  I would like some advice from Zope and Plone folks
  about how to create forms
  that are not only easy for other developers to specialize,
  but which allow <i>several</i> specializations to be composed together.
  While I have used <tt>zope.formlib</tt> and <tt>z3c.form</tt> before
  for simple tasks,
  I have not yet been able to tell
  whether they support these more advanced kinds of operations.
</p>
<p>
  Some background:
  I am doing some work
  on <a href="http://www.plonegetpaid.com/">GetPaid for Plone</a>
  with the generous funding of Derek Richardson who,
  if his dreams had not carried him away from grad school
  at the end of the Spring semester,
  would have tackled this same work
  as part of the 2009 Google Summer of Code.
</p>
<p>
  The current mechanisms that GetPaid provides
  for customizing its checkout process are very primitive,
  and my task is to improve them.
  That is why I have been thinking about customizing forms.
</p>
<!--more-->
<h2>Plugging in payment processors</h2>
<p>
  When a Plone user has filled their shopping cart with goods
  and presses the “Checkout” button,
  GetPaid begins stepping them through a checkout process
  of several forms that must all be satisfied
  before, finally, the user's credit card will be charged
  and their purchase recorded.
  GetPaid's current definition of a “Payment Processor”
  requires only that it provide three functions
  <tt>authorize()</tt>, <tt>capture()</tt>, and <tt>refund()</tt>
  that talk on GetPaid's behalf to an online merchant account.
</p>
<p>
  This design works fine
  for traditional payment processors
  that are comfortable letting Plone handle the credit card information,
  but these days site owners usually want to delegate
  the dangerous task of handling card numbers
  to an “off-site” payment site.
  And these off-site payment processors turn out to be
  but one example
  of the many ways in which GetPaid expansion modules
  want to customize (or hijack?) the GetPaid checkout wizard.
  Consider the following scenarios:
</p>
<ul>
  <li>
    <div class="dropshadow alignright">
      <img src="https://checkout.google.com/buttons/checkout.gif?merchant_id=&w=160&h=43&style=trans&variant=text&loc=en_US"
           alt="Google Checkout sample button"
           width="160" height="43" />
    </div>
    Something like Google Checkout
    is comfortable taking the whole checkout process
    out of your hands;
    the “Checkout” button at the bottom of your shopping cart
    is replaced with a branded “Google Checkout” button
    that sends the user right to Google.
    Currently in Getpaid, that button can only be customized
    by providing completely new page templates for the shopping cart
    that duplicate everything already there,
    but which have a Google image on the checkout button.
  </li>
  <li>
    Services like PxPay (at least the way we use them)
    let the GetPaid checkout process
    take care of collecting the customer's address
    and shipping information,
    but then need the user redirected off of the Plone site.
    Again, entire views get replaced
    just to provide an alternate submit button.
  </li>
  <li>
    Many site owners want to allow several payment processors,
    with the user choosing which one gets used
    since the user might already have an account with Google Checkout
    or be previously registered with PayPal.
    This suggests the need for a “meta” payment processor
    which can be given a list of payment processors and,
    when the user reaches the first checkout step
    for which those payment processors differ,
    presents the user with a screen
    from which they select the processor that they like.
  </li>
  <li>
    Some sites have specialized information
    that they need to collect from users:
    they want to ask for extra address information,
    or extra shipping options for certain products,
    or need more contact information from the user
    when they are checking out.
  </li>
</ul>
<p>
  So, currently, in pretty much every one of the above situations,
  the answer to, “How do I tweak the GetPaid checkout process?”
  is, “Override the <i>entire</i> view or module
  that you need to customize,
  by providing your own copy
  that looks exactly the same as the default one,
  except for the one thing you need changed.”
</p>
<p>
  If you are curious, I have created
  <a href="http://rhodesmill.org/brandon/static/2009/getpaid-overrides.png"
   >a diagram showing which payment processors
    have to override which parts of GetPaid</a>.
</p>
<p>
  Not only does this wanton overriding
  mean that modules have to meticulously track
  the changes that GetPaid makes to the forms they are overriding,
  but it means that customizations are inherently not composable:
  you can't put two of them together.
</p>
<p>
  The problem of composability is a big one.
  Imagine that you live in Argentina
  and want to install a module that adjusts GetPaid's mailing address form
  to match the way postal addresses are formatted locally,
  but that you also want to use an off-site payment processor
  that needs to insert its custom “Checkout” button
  on the bottom of the mailing address form.
  Since the two modules will provide competing versions
  of the entire mailing address form,
  only one of them can “win”,
  and the customization that the other module wants to present
  will not be displayed.
</p>
<h2>Four crazy ideas</h2>
<p>
  How might checkout process customizations
  become operations that could be combined and composed,
  instead of each one of them being a fragile, blanket replacement
  of an entire part of GetPaid?
  Here are four ideas that I have thought through
  today as I sat with my trusty pencil and yellow pad:
</p>
<ul>
  <li>
    <b>Plug-in points.</b>
    Currently, GetPaid just has those three functions mentioned above
    (<tt>authorize()</tt>, <tt>capture()</tt>, and <tt>refund()</tt>)
    where payment processors can plug into its checkout logic.
    One way of solving the problems we are encountering
    is simply to provide a <i>lot</i> more plug-in points
    where GetPaid's default behavior can be adjusted or subverted.
    It looks like this would have to include separate views
    for every button, for the body of every major form,
    and for the transitions between forms.
    It is doable within the time I have left for this project,
    and serves as my default, conservative option
    if nothing more spectacular can happen right now.
    But it's very brittle:
    every time in the future that someone thinks of a new way
    of adjusting or tweaking GetPaid,
    they have to ask us to create a new plug-in point.
  </li>
  <li>
    <b>Request-level wrapper.</b>
    It might be possible
    (I mention this technique only for the sake of completeness,
    to spur our imaginations)
    to implement an off-site change processor
    as a wrapper around GetPaid
    that interacted at the bare level of incoming HTTP requests
    and outgoing HTML pages or redirections.
    If you have chosen Google Checkout,
    a special wrapper would be installed
    that would rewrite the shopping cart “Checkout” button with its own.
    If you need another field added to the final checkout page,
    you would create a wrapper that adds the field
    when it sees the HTML for that form going out,
    and that intercepts the additional field on its way back in.
    Such wrappers would at least be composable:
    you could have several active at once,
    that each made their own modification to a single page
    so that the user could see an address form
    that was formatted for Argentina
    <i>and</i> that had the correct checkout button on the bottom.
  </li>
  <li>
    <b>Wrap a form that provided an API.</b>
    What do forms “look like” to the code that calls them?
    If we imagine a form library
    where a <tt>Form</tt> is separate
    from the <tt>FormRenderer</tt>
    that introspects and traverses the properties of each form
    to turn it into HTML,
    then each GetPaid extension
    could be a wrapper around the GetPaid form object(s)
    that passes through most requests intact,
    leaving most parts of most forms alone,
    but that intercepts certain requests
    and returns different answers than GetPaid would return.
    The Argentina module would wrap the default GetPaid shipping form
    and, when traversed for its sub-forms and fields,
    would return a series of fields specific to Argentina.
    The off-site payment processor wrapper
    would just adjust the properties of the checkout button
    before returning them.
    And, these two wrappers would be composable!
    If you wrapped them,
    in any order,
    around the default GetPaid checkout forms,
    then you could enjoy both customizations.
  </li>
  <li>
    <b>Forms as modifiable objects.</b>
    What if forms — or even a small collection of forms,
    like the GetPaid checkout process — were objects
    that you could adjust and edit and modify
    before asking them to be rendered?
    Then, each GetPaid customization could be written
    as a small routine that takes, as its argument,
    a description of the <i>entire</i> checkout process,
    and that modifies that description by tweaking, adding,
    and removing everything that it needs to.
    Before rendering a view for the user,
    GetPaid would construct a copy of the checkout process,
    and then pass it, in turn, to each module.
    The Argentina module would reach in and tweak some address fields.
    The off-site processor would reach in and adjust the checkout
    button sitting below them.
    And the result could then be rendered.
    The one problem, when we compare this approach
    to the previous scenario,
    would be how to intercept new data that would be coming in
    as a result of added form fields.
    I suppose the form descriptions
    would have to include callback functions
    for processing them,
    and that extension modules would just add their own callbacks.
  </li>
</ul>
<p>
  Is there anything here worth trying?
</p>
<p>
  These are just the ideas that have come to me today,
  as I've scribbled and sketched
  and sat down to re-read all of the design patterns
  in <a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&tag=letsdisthemat-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0201633612">the Gang of Four Book</a><img src="http://www.assoc-amazon.com/e/ir?t=letsdisthemat-20&l=as2&o=1&a=0201633612" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
  looking for inspiration.
  (You might recognize the third option above
  as something like the “decorator” design pattern!)
  Does <tt>zope.formlib</tt> or <tt>z3c.form</tt>
  or anything else like that in the Zope universe
  provide the kind of services I would need from a form library
  to implement the ideas outlined above?
</p>
<p>
  If you're a Zope or Plone person with an inkling of an answer,
  then please let me know!
</p>]]></content:encoded>
    </item>
    <item>
      <title>The July 2009 issue of Python Magazine</title>
      <link>http://rhodesmill.org/brandon/2009/pymag-july/</link>
      <pubDate>Sat, 15 Aug 2009 03:50:14 EDT</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[grok]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=209</guid>
      <description>The July 2009 issue of Python Magazine</description>
      <content:encoded><![CDATA[
<div class="dropshadow alignright">
  <a>
    <img src="http://rhodesmill.org/brandon/static/2009/pymag-july.jpg"
         alt="Cover of July 2009 Python Magazine"
         width="200" height="258" />
  </a>
</div>
<p>
  I am home from a relaxing vacation to the Midwest,
  and while I was gone last week my excellent publishing team
  released the July issue <i>Python Magazine</i> to the world.
  I am particularly pleased that two of the feature articles in this issue
  come from important segments of the Python world
  that we have not heard much from in previous issues.
</p>
<p>
  First,
  <a href="http://www.codeplex.com/IronPython"
     >IronPython, the .NET version of Python for Windows</a>,
  is the topic of Jonathan Hartley's article about acceptance testing.
  He illustrates that,
  regardless of the language
  in which you write your .NET application,
  you can deploy simple strategies
  to make your application testable
  through a Python test harness,
  and thereby bring Python's strong flexibility as a testing language
  to bear on a product
  that you might be writing in another .NET language.
</p>
<p>
  Second, Malthe Borch, a veteran of the Zope community,
  shares how he has written
  <a href="http://chameleon.repoze.org/">Chameleon,
  one of the fastest template language
  implementations available for Python</a>.
  By processing each template
  and turning it into Python bytecode
  before it is ever used to render a single page,
  Malthe eliminates a huge amount of redundant processing
  as that same code is used over and over again.
  His library is a key ingredient
  in the new high-efficiency web frameworks
  appearing in the Zope world.
  His work might even (fingers crossed) become one of the components
  that the Plone community uses
  as they streamline their framework
  and move towards a lighter and more agile “Plone 4”.
</p>
<p>
  Other technical topics covered are: the
  <a href="http://hadoop.apache.org/">Hadoop</a> map-reduce framework;
  the concept of hash functions, and how they apply to Python;
  and the new
  <a href="http://docs.python.org/library/string.html#format-string-syntax"
     >string formatting operator</a>
  which Guido hopes will replace all of the percent-signs
  that currently litter our code.
  Wrap it all up with an editorial by Steve Holden
  about <a href="http://www.europython.eu/">EuroPython 2009</a>
  and an editorial by me,
  and you have a complete issue!
  If you do not find Python Magazine
  sitting on your local newsstand,
  then I hope you will avail yourself of a subscription
  and, as always, let me know what topics
  you would like to see covered in future issues.
  Enjoy!
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Plone and IRC</title>
      <link>http://rhodesmill.org/brandon/2009/plone-and-irc/</link>
      <pubDate>Mon, 20 Jul 2009 17:05:53 EDT</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[zope]]></category>
      <guid>http://rhodesmill.org/brandon/?p=182</guid>
      <description>Plone and IRC</description>
      <content:encoded><![CDATA[
<p><i>Hypothesis:</i> the vibrancy of a framework's IRC channel is proportional to the amount of time that the framework takes to start up each time you tweak your code or settings and need it reloaded.</p>
<p><i>Further hypothesis:</i> this relationship is non-linear. My guess is that frameworks which take, say, four seconds to restart probably get no more IRC attention than frameworks which take two seconds to restart, so adding mere seconds of delay to your framework's startup routine is not going to generate thriving community. There is, instead, a threshold — probably around ten or twelve seconds — above which the delay feels so long that the developer can, in good conscience towards their employer, switch over into IRC during a restart without feeling like they hurt their productivity.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Porting a C extension module to Python 3.0</title>
      <link>http://rhodesmill.org/brandon/2008/porting-a-c-extension-module-to-python-30/</link>
      <pubDate>Tue, 09 Dec 2008 04:18:16 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[grok]]></category>
      <category><![CDATA[pyephem]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=25</guid>
      <description>Porting a C extension module to Python 3.0</description>
      <content:encoded><![CDATA[
<p>
With several packages already advertising
<a href="http://pypi.python.org/pypi?:action=browse&c=214&c=534"
 >Python 3.0 compatibility</a>,
it seemed high time to look into releasing my
<a href="http://rhodesmill.org/pyephem/">PyEphem astronomy package</a>
in an edition compatible with the new language.
But I hesitated:
how difficult is it <i>really</i>,
and how many hours of work will it consume,
to port a C-language extension module to Python 3.0?
</p>
<p>
The answer is that,
while the necessary changes were surprisingly easy,
they took lots of time to figure out
because I did not find them documented in any one place.
I offer the following notes to assist
any other adventurers who want to experiment
with porting their extension modules to 3.0.
These notes might also suggest
useful additions to the official documentation.
</p>
<p>
But, first, I need to issue three cautions.
To develop under 3.0, you may have to forego several Python tools
that you probably thought you could no longer do without.
The world of 3.0 is a windswept and icy landscape
from which the glaciers have just receded,
and you will find the stone tools rather primitive
when compared to the comforts of civilization
that you enjoy under Python 2.
To wit:
</p>
<ul>
<li>I cannot find
 <a href="http://pypi.python.org/pypi/virtualenv/1.3.1">virtualenv</a>
 for 3.0,
 which is a disaster.
 This means that you have to create a separate Python 3.0 install,
 built with a different <tt>--prefix</tt> option to <tt>./configure</tt>,
 for each development environment you want to create on your box.
</li>
<li>I cannot find a version of the
 <a href="http://peak.telecommunity.com/DevCenter/setuptools">setuptools</a>
 available for 3.0.
 This means limiting your <tt>setup.py</tt> instructions
 to the primitive vocabulary of the <tt>distutils</tt> package.
 For example,
 I find myself unable to run the PyEphem test suite at this late hour
 because I have been running it for so long with:
 <pre>$ python setup.py test</pre>
 that I am not sure how to get it running otherwise.
</li>
<li>Should you succeed in porting your extension module,
 it is not at <i>all</i> clear how to distribute it.
 I had expected either a new PyPI to spring into being —
 since every package will need an entirely different version under 3.0 —
 or for a sophisticated scheme to appear
 for registering one <tt>pyephem.tar.gz</tt> as the Python 2 version
 and another <tt>pyephem.tar.gz</tt> for 3.0.
 But while the most recent version of your package can
 mark itself as
 <a href="http://pypi.python.org/pypi?:action=browse&c=214&c=527"
  >2-compatible</a> or
 <a href="http://pypi.python.org/pypi?:action=browse&c=214&c=533"
  >3-compatible</a> (or both)
 using classifiers,
 there is no way to have <i>two</i> “most recent” versions
 of a package.
 Are we supposed to start distributing a single <tt>tar.gz</tt>
 that includes the source code for both Python series,
 and that selects the right code by detecting the interpreter version
 at the top of the <tt>setup.py</tt> file?
</li>
</ul>
<p>
So if you make the effort to port your code right now,
you might find that the shiny new version of your module
is all dressed up, but has no place to go.
If you experiment with the following steps, though,
you will at least be ready
when an official distribution channel does appear
for releasing your package into the wilds of 3.0.
</p>
<!--more-->
<h2>Four Steps To 3.0</h2>
<p>
Yes, four steps were all that were necessary
to convert my quite complex extension module to Python 3.0!
</p>
<ol>
<li><b>Use PyModule_Create().</b>
 The old mechanism that I had been using
 to initialize my extension module,
 the rather clunkily-named <tt>Py_InitModule3()</tt>,
 happily does not even exist in the Python 3.0 header files.
 Instead, call the <tt>PyModule_Create()</tt> function
 which you can find described
 in the <a href="http://docs.python.org/3.0/extending/extending.html#the-module-s-method-table-and-initialization-function"
  >Module Initialization</a>
 section of the <a href="http://docs.python.org/3.0/extending/"
  >Extending and Embedding</a> document.
 And be sure to keep its return value:
 unlike in older Pythons,
 you now have to return the module object it creates
 as the return value from your module initialization function.
</li>
<li>
 <p>
 <b>Adjust all Python object headers.</b>
 Each type object in my code started with a macro
 to set up the common fields that all Python objects share.
 This was then followed by the <b>ob_size</b> field,
 which in my code always is always zero,
 and then the type name:
 </p>

<div class="pygments_murphy syntax_highlight"><pre><span class="cm">/* For Python 2 */</span><br/><br/><span class="k">static</span> <span class="n">PyTypeObject</span> <span class="n">BinaryStarType</span> <span class="o">=</span> <span class="p">{</span><br/>     <span class="n">PyObject_HEAD_INIT</span><span class="p">(</span><span class="nb">NULL</span><span class="p">)</span><br/>     <span class="mi">0</span><span class="p">,</span>                   <span class="cm">/* ob_size */</span><br/>     <span class="s">&quot;ephem.BinaryStar&quot;</span><span class="p">,</span>  <span class="cm">/* tp_name */</span><br/>     <span class="p">...</span><br/></pre></div>


 <p>
 Though the Python 3.0 documentation
 <a href="http://docs.python.org/3.0/extending/newtypes.html"
  ><i>still</i> shows this as the way to create types</a>,
 this technique will now completely fail.
 (The <a href="http://bugs.python.org/issue4385">bug indicating
 that the documentation gets this wrong</a> has,
 as its most recent comment,
 the helpful note
 “I'm lowering the priority so it doesn't block the release.”)
 Anyway, the solution is simple:
 the first two lines in the struct shown above
 simply have to be combined into a single macro call:
 </p>

<div class="pygments_murphy syntax_highlight"><pre><span class="cm">/* For Python 3.0 */</span><br/><br/><span class="k">static</span> <span class="n">PyTypeObject</span> <span class="n">BinaryStarType</span> <span class="o">=</span> <span class="p">{</span><br/>     <span class="n">PyVarObject_HEAD_INIT</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><br/>     <span class="s">&quot;ephem.BinaryStar&quot;</span><span class="p">,</span>  <span class="cm">/* tp_name */</span><br/>     <span class="p">...</span><br/></pre></div>


 <p>
 With this change, my objects are now operating fine.
 </p>
</li>
<li><b>Use plain “static.”</b>
 PyEphem inherits code from an era
 when it was popular to use variations on the <tt>static</tt> keyword
 so that Python could work around problems
 with various troublesome C compilers.
 This filled my code with <tt>staticforward</tt> declarations
 like the one you can see at the top of the old Python 2.2
 <a href="http://www.python.org/doc/2.2/ext/dnt-basics.html"
  >Defining New Types</a> page.
 It turns out that for well-behaved compilers
 these were always simply synonyms for the <tt>static</tt> keyword,
 which is what you must replace them with
 when porting your code to 3.0.
</li>
<li><b>Upgrade to Unicode.</b>
 Python 3.0 makes a clean and sharp distinction
 between strings, which are sequences of Unicode characters,
 and byte arrays, which can represent anything.
 To reflect this sea change down at the C level,
 the decision was made
 to eliminate <i>everything</i> from the C API
 whose name started with <tt>PyString</tt>.
 The obvious compiler errors that result from this
 provide a clear signal to programmers
 that they have to decide,
 everywhere that they had been using an old-style Python string,
 whether they should now represent that data
 with the <tt>PyUnicode</tt> or the <tt>PyBytes</tt> type.
 This was a brilliant decision;
 the transition could have been a nightmare
 had it remained possible for old code to compile
 without having been properly converted!
 <p>
 When migrating the PyEphem code base,
 I found that most of the Unicode transition was very easy.
 Everywhere that my code handled or created a string object,
 I simply changed the prefix of the function to <tt>PyUnicode</tt>
 and everything worked:
 </p>
 <pre>
 PyString_Check      ... becomes ... PyUnicode_Check
 PyString_FromString ... becomes ... PyUnicode_FromString
 PyString_FromFormat ... becomes ... PyUnicode_FromFormat
</pre>
 <p>
 Well, okay, the trick does not work <i>everywhere</i>;
 this one was harder to guess:
 </p>
 <pre>
 PyString_Size ... becomes ... PyUnicode_GET_SIZE
</pre>
 <p>
 The situations that require real thought
 are the places where my code needs to convert a Python string
 into the sort of simple ASCII character array
 that the underlying C library can absorb.
 At the moment, my code is leaning heavily
 on a pitiful <tt>PyUnicode_AsString()</tt> routine
 that I wrote just to get things working;
 in the morning I will have to look into doing this more correctly,
 including catching the error if a fancy Unicode character is present
 that cannot properly be converted.
 </p>
</li>
</ol>
<p>
Overall, I am very impressed with how quickly
I was able to get my extension module compiling and running
under Python 3.0.
The procedure was simple —
I just tried, over and over again, to build the module with:
</p>
<pre>
$ python3.0 setup.py build
</pre>
<p>
and then tackled the compiler errors that resulted.
Once every last warning had been addressed,
the module started up and operated without a single further complaint.
This calls for celebration!
I'm going to bed.
</p>
]]></content:encoded>
    </item>
    <item>
      <title>My NOLA Plone Symposium talk, “the Zope 3 Component Architecture”</title>
      <link>http://rhodesmill.org/brandon/2008/nola-plone-symposium-talk/</link>
      <pubDate>Thu, 05 Jun 2008 23:44:02 EDT</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[grok]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=17</guid>
      <description>My NOLA Plone Symposium talk, “the Zope 3 Component Architecture”</description>
      <content:encoded><![CDATA[
<p>
I have delivered my “Zope 3 Component Architecture” talk
to the <a href="http://plone.org/events/regional/nola08">2008 North American
Plone Symposium</a> meeting here in New Orleans.
I want to thank the folks at
<a href="http://enfoldsystems.com/">Enfold Systems</a>
both for hosting the Symposium, inviting me to speak,
and for generously making it possible for me to attend!
Here are my slides:
</p>

<div class="caption">
<a href="/brandon/static/2008/nola-zope3-talk.pdf">
<img src="/brandon/static/2008/nola-zope3-talk.jpg" alt="opening slide" /></a>
<a href="/brandon/static/2008/nola-zope3-talk.pdf"
 >Download slides as PDF</a>
</div>

<p>
They had asked me to attend so that I could present
the <a href="http://rhodesmill.org/brandon/adapters/">Using Grok
to Walk Like a Duck</a> talk that I gave at PyCon 2008
back in March.
They changed the title, I suppose, to better highlight
why it would be of interest to the Plone community;
but the change actually helped me to rethink the presentation.
I wound up using only the first half of my PyCon slides.
For the second half of the talk,
which at PyCon had consisted of a crazy sequence
of hints and tips about using adapters in your own applications,
I instead did a much more successful series of slides
about how adapters are actually used in Zope 3
to suit up objects for presentation on the web.
I think this made the idea more concrete,
and thus much easier to understand
for people seeing adapters for the first time.
</p>
<p>
The talk was well enough received
that I should perhaps think seriously about finding further opportunities
to share Zope 3 technologies with the Plone community.
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Presentations on Buildout and KSS</title>
      <link>http://rhodesmill.org/brandon/2008/presentations-on-buildout-and-kss/</link>
      <pubDate>Sat, 23 Feb 2008 23:29:13 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[grok]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/2008/presentations-on-buildout-and-kss/</guid>
      <description>Presentations on Buildout and KSS</description>
      <content:encoded><![CDATA[
After several frustrating weeks learning how to create, edit, and publish a screencast under Linux (about which I will write a separate post), I have now published screencasts of both presentations that I gave at the PyAtl meetup in January. I opened with a talk about the <tt>import</tt> statement, and where Python packages lived before egg files were invented:

<div class="movietitle"><a href="http://video.google.com/videoplay?docid=5996823626349389448"><b>Python Before Eggs</b></a>

<embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=5996823626349389448&hl=en" flashvars=""> </embed>

</div>

The audience seemed most interested in the last section of the talk, where I discuss three techiques for debugging problems with Python's <tt>import</tt> statement; fast-forward to around 3:00 if you want to catch that part by itself.

Next, Jeremy Jones spoke about eggs, Noah Gift introduced virtualenv, and, finally, I got back up to talk about buildout. This was probably <b>my own favorite</b> among the recent presentations I have given, and it's the one I've worked hardest to adapt to a competent screencast:

<div class="movietitle"><a href="http://video.google.com/videoplay?docid=3428163188647461098&hl=en"><b>Introduction to Buildout</b></a>

<embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=3428163188647461098&hl=en" flashvars=""> </embed>

</div>

I have prepared a supplement to the above screencast that <a href="/brandon/buildout/">gives additional hints and tips about using buildout</a>, as well as a link to the source code of the module that I use as my example.

Finally, if you're ready to see something a little less polished — something that instead of being a screencast is actually a film of me talking in front of a live audience, and gesturing and jumping around — I filled a vacant lightning-talk slot at our February PyAtl meeting with an impromptu introduction to <a href="http://kssproject.org/">Kinetic Style Sheets</a> (KSS), using an example application that was still sitting on my laptop after at a Georgia Tech developer's luncheon earlier that week:

<div class="movietitle"><a href="http://video.google.com/videoplay?docid=3829442611478268688"><b>Introduction to KSS</b></a>

<embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=3829442611478268688&hl=en" flashvars=""> </embed>

</div>

Now I can finally turn my attention to preparing for my upcoming talk at PyCon 2008 in Chicago! I will be talking about the basic “adapter” design pattern, and how a framework like Zope 3 can facilitate its use. Stay tuned for more information!
]]></content:encoded>
    </item>
    <item>
      <title>My November Grok Presentation</title>
      <link>http://rhodesmill.org/brandon/2007/my-november-grok-presentation/</link>
      <pubDate>Fri, 09 Nov 2007 19:06:24 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[grok]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/2007/my-november-grok-presentation/</guid>
      <description>My November Grok Presentation</description>
      <content:encoded><![CDATA[
In this post, I provide the slides and examples from a recent talk that I gave to some fellow software developers at Georgia Tech. Many of them were not familiar with web frameworks, and I wanted to introduce them to two common concepts: the idea of “convention over configuration,” and the practice of passing inert data structures to a page template rather than letting it access live objects directly.

But because I am also really enjoying my work with the new Python web framework <a href="http://grok.zope.org/">Grok</a>, I decided to make it the centerpiece of my presentation<!--more--> and illustrate the more general principles of web development by showing how Grok works. I also gave the talk a week later at an Atlanta Plone gathering, where I knew the interest would be more on what makes Grok unique.

When I was asked for a copy of my slides, I realized that my presentation style — which involves showing several slides, moving to my editor and web browser for some actual programming, then diving back into my slides — leaves the PDF of the presentation perhaps not making as much sense by itself as it might otherwise:

<blockquote><a href="http://rhodesmill.org/brandon/static/2007-11/grok-slides.pdf">Click here to download the PDF of my presentation</a></blockquote>

Hence, this post. Here I take the reader through the aspects of my talk that failed to make it on to the slides, showing both the command-line operations and the coding that illustrated and made sense of the presentation itself.

<h2><a id="creating-a-grok-instance" name="creating-a-grok-instance">Creating a Grok Instance</a></h2>

After some initial slides introducing the idea of “convention over configuration,” my presentation introduces Grok itself — making good use, I think, of the symbolic value of his club — and then announces, “Let's create a Grok instance!” This is the point at which I bring up a command prompt and show the audience how easy <tt>grokproject</tt> makes it to start a new project:


<div class="pygments_murphy syntax_highlight"><pre><span class="nv">$ </span>grokproject MyApp<br/><span class="nv">$ </span>./MyApp/bin/zopectl <span class="nb">fg</span><br/></pre></div>



After <tt>zopectl</tt> has finished starting up, I point my web browser at <tt>http://localhost:8080/</tt>, and then suffer a silent moment of frustration about the fact the web page that appears is <em>not</em> simply the welcome message from the new Grok app. Instead, the “admin interface” comes up, and insists on being fed an application instance name before allowing me to proceed. I choose <tt>lotr</tt> as the name, then show the audience that <tt>http://localhost:8080/lotr</tt> is where the new application lives.

Before continuing with my slides, I visit the directory <tt>MyApp/src/MyApp</tt> and give the audience brief glimpses of both <tt>app.py</tt> and the <tt>app_templates</tt> directory. This introduces three items which will be critical as the slides resume: the <tt>MyApp</tt> object, the <tt>Index</tt> view, and the <tt>index.pt</tt> page template. With these three items pointed out, I am ready to proceed with my slides and discuss how the object, view, and page template together form Grok's “Threefold Way” of making objects available on the web.

<h2><a id="the-actual-example" name="the-actual-example">The Actual Example</a></h2>

Only a few slides later, the time arrives for a more sophisticated example. The presentation exaggerates when it instructs me to “go add some models and further views to your application.” I do not, in fact, make the audience watch me write code, but present them with a finished and working example that I prepare before the presentation. You can create it for yourself by putting this file in place of the one <tt>grokproject</tt> created:

<ul>
<li><a href="http://rhodesmill.org/brandon/static/2007-11/app.py">app.py</a></li>
</ul>

and then putting these four files in <tt>app_templates</tt>:

<ul>
<li><a href="http://rhodesmill.org/brandon/static/2007-11/index.pt">index.pt</a></li>
<li><a href="http://rhodesmill.org/brandon/static/2007-11/contents.pt">contents.pt</a></li>
<li><a href="http://rhodesmill.org/brandon/static/2007-11/battleindex.pt">battleindex.pt</a></li>
<li><a href="http://rhodesmill.org/brandon/static/2007-11/characterindex.pt">characterindex.pt</a></li>
</ul>

The resulting application, though tiny, was probably too complex for my target audience — many eyes, I noticed, glazed over when seeing Zope Page Templates for the first time — but four views is really barely enough to illustrate both that you can have multiple views on the same object (<tt>MyApp</tt> has both an <tt>/index</tt> and a <tt>/contents</tt>), and that several objects can have views with the same name (<tt>Battle</tt> and <tt>Character</tt> have different <tt>/index</tt> views). The example also shows clearly that if you declare four views, you need to write four page templates to go with them.

I emphasize for the audience that most of the 56 lines of <tt>app.py</tt> are concerned with creating the violence-themed object model; only the fifteen lines at the bottom are interesting Grok code, creating four very slender views. This is where I point out “convention over configuration” at work: all of the page templates get discovered without having to be named, and <tt>grok.name()</tt> only has to be employed when we want the view's URL name to differ from the name of the class.

After demonstrating that the application does, in fact, work, we return to the slides and start examining the relationship between page templates and their views.

<h2><a id="moving-to-a-push-model" name="moving-to-a-push-model">Moving to a “push” model</a></h2>

In the presentation I distinguish between “muscular views” and “muscular templates”; perhaps I should have used instead the more conventional idea of templates that “pull” data versus those to which data are “pushed.”

When I reach the slide that reminds me to, “show them your anemic View classes,” I return to my editor and point out that, in the example application, each view has almost no purpose but to associate a particular object class with a particular page template. There is very little information in a declaration like:


<div class="pygments_murphy syntax_highlight"><pre><span class="k">class</span> <span class="nc">CharacterIndex</span><span class="p">(</span><span class="n">grok</span><span class="o">.</span><span class="n">View</span><span class="p">):</span><br/>    <span class="n">grok</span><span class="o">.</span><span class="n">context</span><span class="p">(</span><span class="n">Character</span><span class="p">)</span><br/>    <span class="n">grok</span><span class="o">.</span><span class="n">name</span><span class="p">(</span><span class="s">&#39;index&#39;</span><span class="p">)</span><br/></pre></div>



Whereas there is plenty going on in a template like <tt>characterindex.pt</tt>; every TAL reference it makes is either to the raw <tt>context</tt> object itself, or an object it reaches through the context! Take a look:

<pre>
&lt;h1&gt;The Character:
&lt;span tal:content=&quot;context/name&quot;&gt;Name&lt;/span&gt;&lt;/h1&gt;
This character fought in several battles.
&lt;ul&gt;
  &lt;li tal:repeat=&quot;battle context/battles&quot;&gt;
    &lt;a tal:attributes=&quot;href python: view.url(battle)&quot;
       tal:content=&quot;battle/name&quot;&gt;Name&lt;/a&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</pre>

The slides then continue, pointing out that this makes for very quick coding at the cost of several disadvantages. When the fourth and final intermission arrives (“go make your CharacterIndex View more muscular”), I return to the window where my editor has <tt>app.py</tt> open and rewrite the <tt>CharacterIndex</tt> to look more like this:


<div class="pygments_murphy syntax_highlight"><pre><span class="k">class</span> <span class="nc">CharacterIndex</span><span class="p">(</span><span class="n">grok</span><span class="o">.</span><span class="n">View</span><span class="p">):</span><br/>    <span class="n">grok</span><span class="o">.</span><span class="n">context</span><span class="p">(</span><span class="n">Character</span><span class="p">)</span><br/>    <span class="n">grok</span><span class="o">.</span><span class="n">name</span><span class="p">(</span><span class="s">&#39;index&#39;</span><span class="p">)</span><br/>    <span class="k">def</span> <span class="nf">namespace</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span><br/>        <span class="k">return</span> <span class="p">{</span><br/>            <span class="s">&#39;character_name&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="o">.</span><span class="n">name</span><span class="p">,</span><br/>            <span class="s">&#39;battles&#39;</span><span class="p">:</span> <span class="p">[</span><br/>                <span class="p">{</span> <span class="s">&#39;name&#39;</span><span class="p">:</span> <span class="n">battle</span><span class="o">.</span><span class="n">name</span><span class="p">,</span><br/>                   <span class="s">&#39;url&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">url</span><span class="p">(</span><span class="n">battle</span><span class="p">)</span> <span class="p">}</span><br/>                <span class="k">for</span> <span class="n">battle</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="o">.</span><span class="n">battles</span><br/>                <span class="p">],</span><br/>            <span class="p">}</span><br/></pre></div>



Note what this does: it takes all of the work that the page template was doing in order to fetch the character's name, and the names and URLs of the battles in which the character fought, and performs that access in pure Python and in exactly once place. The values in the dictionary that is being passed — <tt>character_name</tt> and <tt>battle_info</tt> — are, if you will examine them carefully, composed of nothing but primitive Python types! They consist solely of lists and dictionaries containing strings. They contain no objects for the template to browse at its leisure; instead, every bit of pertinent data in our objects is reduced to harmless data structures which cannot be used to affect the original objects in any way. This means that the <tt>characterindex.pt</tt> template can be rewritten both more safely, and also more simply:

<pre>
&lt;html&gt;&lt;body&gt;
  &lt;h1&gt;The Character:
  &lt;span tal:content=&quot;character_name&quot;&gt;Name&lt;/span&gt;&lt;/h1&gt;
  This character fought in several battles.
  &lt;ul&gt;
    &lt;li tal:repeat=&quot;battle battles&quot;&gt;
      &lt;a tal:attributes=&quot;href battle/url&quot;
         tal:content=&quot;battle/name&quot;&gt;Name&lt;/a&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a href=&quot;index&quot;&gt;Return home&lt;/a&gt;
&lt;/body&gt;&lt;/html&gt;
</pre>

And after showing the audience that the rewritten view and the rewritten page template work together, I return to my slides and — finally! — conclude my presentation.

The presentation seemed to weigh in at around forty minutes. Next time, I think I will tackle fewer concepts at once. But I do like making lots of use of the picture of the cave man, and his club.
]]></content:encoded>
    </item>
  </channel>
</rss>

