<?xml version="1.0"?><!-- RSS generated by Radio UserLand v8.0.7 on Sat, 11 Jan 2003 19:25:18 GMT --><rss version="2.0">	<channel>		<title>Jeffrey P Shell: Python</title>		<link>http://radio.weblogs.com/0106123/categories/python/</link>		<description>Python related programming topics</description>		<language>en-us</language>		<copyright>Copyright 2003 Jeffrey P Shell</copyright>		<lastBuildDate>Sat, 11 Jan 2003 19:25:18 GMT</lastBuildDate>		<docs>http://backend.userland.com/rss</docs>		<generator>Radio UserLand v8.0.7</generator>		<managingEditor>jeffr@euc.cx</managingEditor>		<webMaster>infor@euc.cx</webMaster>		<category domain="http://www.weblogs.com/rssUpdates/changes.xml">rssUpdates</category> 		<skipHours>			<hour>2</hour>			<hour>3</hour>			<hour>4</hour>			<hour>5</hour>			<hour>20</hour>			<hour>1</hour>			<hour>15</hour>			<hour>17</hour>			</skipHours>		<cloud domain="radio.xmlstoragesystem.com" port="80" path="/RPC2" registerProcedure="xmlStorageSystem.rssPleaseNotify" protocol="xml-rpc"/>		<ttl>60</ttl>		<item>			<title>Moving Toulouse</title>			<link>http://toulouse.amber.org/</link>			<description>Industrie Toulouse has moved to &lt;a href=&quot;http://toulouse.amber.org/&quot;&gt;A new home (toulouse.amber.org)&lt;/a&gt; and a new &lt;a href=&quot;http://www.movabletype.org/&quot;&gt;publishing system&lt;/a&gt;.  Most of the archives will be there soon.  The Radio site will remain up indefintely, but no new content will appear here.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2003/01/11.html#a268</guid>			<pubDate>Sat, 11 Jan 2003 19:24:27 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=268&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2003%2F01%2F11.html%23a268</comments>			</item>		<item>			<title>Big Alpha Releases for Zope and Python</title>			<link></link>			<description>&lt;p&gt;Two big alpha releases were made for the new year: &lt;a href=&quot;http://www.python.org/2.3/&quot;&gt;Python 2.3a1&lt;/a&gt; and &lt;a href=&quot;http://dev.zope.org/Zope3/Downloads&quot;&gt;Zope 3X a1&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Python 2.3 doesn&apos;t make any major changes to the language (unlike previous Python 2 series releases, which brought things like &lt;em&gt;list comprehensions&lt;/em&gt;, &lt;em&gt;generators&lt;/em&gt;, &lt;em&gt;nested scopes&lt;/em&gt;, &lt;em&gt;iterators&lt;/em&gt;, etc).  Andrew Kuchling, as always, &lt;a href=&quot;http://www.python.org/doc/2.3a1/whatsnew/&quot;&gt;covers the changes extensively&lt;/a&gt;.  Of interest are - ability to import from .zip files, &lt;strong&gt;universal newline support!&lt;/strong&gt;, a new logging package, a new Set datatype and default Boolean datatype.&lt;/p&gt;&lt;p&gt;Zope 3X (x for &quot;experimental&quot; - a final Zope 3 release without the &apos;X&apos; is expected to have some Zope 2 migration features) is a completely different beast from its ancestors.  Its primary focus is still the &lt;em&gt;Object Publishing&lt;/em&gt; mission that&apos;s been in place since the days of Bobo, but beneath the covers it is shockingly different from Zope&apos;s 1 and 2 before it.  &lt;/p&gt;&lt;p&gt;Zope 3 is also dubbed the &lt;em&gt;component architecture project&lt;/em&gt;.  Its design focuses on many interacting components with well-defined interfaces.  It&apos;s an aggregation heavy design, as opposed to the inheritance heavy design of Zope 2.  Adapters exist to take the burden off of objects for out-of-scope elements such as text indexing or sorting-by-size.  As the author of a particular object, you can implement those interfaces (ISearchableText, ISized) on the class itself, or as separate classes.  Code that requires searchable text or sizing information asks for an ISearchableText implementation for your class, and since that&apos;s the only interface that it&apos;s expecting to use, it doesn&apos;t matter if it gets an adapter or your class - it only matters that the ISearchableText interface is implemented correctly.  &lt;a href=&quot;http://www.elj.com/eiffel/dbc/&quot;&gt;Design by Contract&lt;/a&gt; finally makes a strong appearance in the Zope world.&lt;/p&gt;&lt;p&gt;Zope 3 should also score big on the &lt;em&gt;packaging and deployment&lt;/em&gt; front.  Zope 3 uses a new configuration language called &lt;strong&gt;ZCML&lt;/strong&gt;.  ZCML is used to register new components at load time, and to load in still further components.  It wrests control away from Python&apos;s import statements and need for special functions in __init__.py such as the common Zope 2 &lt;tt&gt;initialize(context)&lt;/tt&gt;.  As such, it can be not only more expressive, but allows control over the order in which items get initialized.  Under the mantra of &lt;em&gt;explicit is better than implicit&lt;/em&gt;, all new components have to be explicitly added (usually in the &lt;tt&gt;products.zcml&lt;/tt&gt; file).  A side effect of this is that heavily customized Zope distributions can be made.  Some such distributions exist now with &lt;a href=&quot;http://plone.org/&quot;&gt;Plone&lt;/a&gt; installers and &lt;a href=&quot;http://www.bizarsoftware.com.au/&quot;&gt;BizarShop&lt;/a&gt;.  Zope 3&apos;s customization and configuration capabilities should allow similar distributions to be made that don&apos;t look like Zope at all, while still tying in to all of the available features of Zope.&lt;/p&gt;&lt;p&gt;The combination of heavy Interface use combined with rich configuration options should mean that &lt;em&gt;any&lt;/em&gt; part of the system could be kicked out in place of a new one, as long as the expected interfaces are implemented.  This is a fundamental feature of component systems, and Zope 3 looks like it will live up to this feature.&lt;/p&gt;&lt;p&gt;Another big feature of Zope 3 is the proliferation of &lt;em&gt;View Components&lt;/em&gt;.  Views can be individual ZPT pages, attached to a particular content interface via ZCML.  But they can also be full-on components in their own right, usually as Python classes.  And they&apos;re not limited to HTML.  Other views may be written to correspond with the other publishing channels (ftp, xml-rpc, and others in the future).  I wrote a post back in September about my &lt;a href=&quot;http://radio.weblogs.com/0106123/categories/zope/2002/09/02.html&quot;&gt;early experiments augmenting other Zope 3 components&lt;/a&gt;, in which I include some example code making an XML-RPC view onto a Job Board component written by someone else.  My final paragraph in that post reads:&lt;blockquote&gt;And finally, Zope 3 should yield a usable scalable means of adapting the works of other developers into new solutions by providing better control of product/service/view configuration and overrides, such as adding a new XML-RPC API to someone elses bug tracking system without having to alter that bug tracking system, or use secret Python hacks to alter behaviour.&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;A few other positive notes about Zope 3X a1.  The &quot;grand renaming&quot; went into effect during the final weeks of the beta.  This involved cleaning up the Python package hierarchy.  It also involved case-normalization of package and module names.  They are now all lowercase, like most other well-written Python packages/frameworks (distutils, &lt;a href=&quot;http://docutils.sourceforge.net/&quot;&gt;docutils&lt;/a&gt;, etc), which makes it easy to distinguish classes and other module exports from the modules themselves.  Zope 3 also uses Python 2.2 &quot;new-style-classes&quot; and gets rid of ExtensionClasses, since now you can write new extension types for Python in C and subclass them (which was the big point of ExtensionClasses).  Zope 3 also (finally) makes use of other long-standing Python technologies such as distutils.  &lt;/p&gt;&lt;p&gt;Now for the negative aspects.  Since this is an alpha of the Zope 3 &quot;experimental&quot; line, it&apos;s not surprising that there is little or no documentation.  The code structure is &lt;em&gt;significantly&lt;/em&gt; different from that of Zope 2.  It takes some time to find ones way around the code layout.  Most things are pretty clear though (a benefit of having Interfaces) when you do find them, but there&apos;s so much new technology and terminology here that even when you grasp the terminology, it&apos;s not obvious to an outsider how to put it all to work.&lt;/p&gt;&lt;p&gt;Zope 3 is heavily reliant on &lt;em&gt;Services&lt;/em&gt;, which is a good thing.  Services are like &lt;em&gt;Tools&lt;/em&gt; in the CMF - well known objects that provide a service to a global or local region.  Examples of services are Event Channels (yay!  Events!), or something like the &lt;em&gt;Error Log&lt;/em&gt; that showed up in Zope 2.6.  Other examples of Services are &lt;em&gt;Database Adapters&lt;/em&gt;.  In Zope 2, most service objects existed in the same namespace as all other objects.  Zope 3 manages them in special namespaces.  This allows content objects to be managed separately from service objects while still retaining placefulness.  There are numerous upsides to a service based architecture.  What&apos;s the downside?  The downside is there&apos;s significant &quot;what the...?!&quot; effect when first encountering Services and Configuration objects.  I&apos;m sure it will all make more sense as future Zope 3X development releases are made, but right now it&apos;s a proverbial kick in the head.&lt;/p&gt;&lt;p&gt;There are some other aspects of Zope 3 that I&apos;m likewarm to right now, mostly because they&apos;re difficult to fully comprehend how/when/where to use at the moment.  Zope 3 allows for automatic user interface generation to occur.  This was a feature of OS/2 (2.0+), and the defining motive of &lt;a href=&quot;http://www.nakedobjects.org/&quot;&gt;Naked Objects&lt;/a&gt;.  Zope 2 has a subset of this feature in its use of &lt;em&gt;properties&lt;/em&gt;.  What Zope 3 seems to have done is to marry Interfaces (software, not user) and &lt;a href=&quot;http://www.zope.org/Members/faassen/Formulator&quot;&gt;Formulator&lt;/a&gt; together.  In essence, this allows easy edit forms to be generated off of the objects interface description.  From the &apos;src/zope/app/browser/content/configure.zcml&apos; file, here&apos;s an example of how an editform is configured for a ZPT Page:&lt;pre&gt;  &amp;lt;browser:editform      schema=&quot;zope.app.content.zpt.IZPTPage&quot;      name=&quot;edit.html&quot;      menu=&quot;zmi_views&quot;       label=&quot;Edit a ZPT page&quot;      permission=&quot;zope.ManageContent&quot;      /&amp;gt;&lt;/pre&gt;And from the &lt;strong&gt;IZPTPage&lt;/strong&gt; interface:&lt;pre&gt;    source = zope.schema.Text(        title=u&quot;Source&quot;,        description=u&quot;&quot;&quot;The source of the page template.&quot;&quot;&quot;,        required=True)      expand = zope.schema.Bool(        title=u&quot;Expand macros&quot;,        )&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Whew!&lt;/em&gt;  That&apos;s about all I can cover for right now.  If I have time this weekend, I intend to write a new Content Component (probably a reStructuredText Document) to see how different it really is from developing a similar product for Zope 2 or the CMF.  I have no promises right now that it will get done this weekend, but it is something I&apos;ve been wanting to do.  Now that Zope 3X is at alpha1 stage, the fundamental structure should be fairly stable.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2003/01/03.html#a262</guid>			<pubDate>Fri, 03 Jan 2003 22:22:33 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=262&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2003%2F01%2F03.html%23a262</comments>			</item>		<item>			<title>Problems with StructuredText</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/11/13.html#a240</link>			<description>I was going to write up my own list of issues I&apos;ve had with Zope&apos;s StructuredText (Classic and NG) implementation, but &lt;a href=&quot;http://docutils.sourceforge.net/spec/rst/problems.html&quot;&gt;this document&lt;/a&gt; sums it up nicely.My expectation of software is, to quote &lt;a href=&quot;http://www.radiohead.co.uk/&quot;&gt;Radiohead&lt;/a&gt;, &lt;em&gt;&quot;No alarms and no surprises.&quot;&lt;/em&gt;  &quot;Zope&quot; Page Templates live up to that mantra, as does &lt;a href=&quot;http://docutils.sourceforge.net/rst.hml&quot;&gt;reStructuredText&lt;/a&gt;, so far.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/11/13.html#a240</guid>			<pubDate>Wed, 13 Nov 2002 16:50:10 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=240&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F11%2F13.html%23a240</comments>			</item>		<item>			<title>reStructuredText First Impressions</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/10/30.html#a228</link>			<description>Today I started writing up user documentation for the project I&apos;m wrapping up.  It&apos;s the first time I&apos;ve used &lt;a href=&quot;http://docutils.sourceforge.net/rst.html&quot;&gt;reStructuredText&lt;/a&gt;, and I must say that I&apos;m liking it.  As far as structured text markup languages go, it&apos;s pretty comprehensive and not *too* obtrusive.  It&apos;s definitely good enough for most technical documentation needs, and is in fact a &lt;a href=&quot;http://www.python.org/peps/pep-0012.html&quot;&gt;PEP Formatting Standard&lt;/a&gt; (see also &lt;a href=&quot;http://www.python.org/peps/pep-0012.txt&quot;&gt;PEP 12 Source&lt;/a&gt;).  Other items of interest, particularly to Python programmers, are:&lt;ul&gt;  &lt;li&gt;&lt;a href=&quot;http://www.python.org/peps/pep-0256.html&quot;&gt;PEP 256&lt;/a&gt; &quot;Docstring Processing System Framework&quot; &lt;a href=&quot;http://www.python.org/peps/pep-0256.txt&quot;&gt;(src)&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href=&quot;http://www.python.org/peps/pep-0257.html&quot;&gt;PEP 257&lt;/a&gt; &quot;Docstring Conventions&quot; &lt;a href=&quot;http://www.python.org/peps/pep-0257.txt&quot;&gt;(src)&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href=&quot;http://www.python.org/peps/pep-0258.html&quot;&gt;PEP 258&lt;/a&gt; &quot;Docutils Design Specification&quot; &lt;a href=&quot;http://www.python.org/peps/pep-0258.txt&quot;&gt;(src)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;I include the source links to show the relative cleanliness of the markup, which is the point of all &lt;em&gt;Structured Text&lt;/em&gt; formats.  &lt;em&gt;sigh&lt;/em&gt;  I thought I&apos;d have more to say, but I&apos;m really too tired.  So - quick wrap up: I was pretty productive with this stuff right off the bat.  Nice.For &quot;Zope&quot;, there is a &lt;a href=&quot;http://dev.zope.org/Wikis/DevSite/Proposals/ReStructuredTextIntegration&quot;&gt;proposal to integrate reStructuredText into Zope&lt;/a&gt;, hopefully for 2.7.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/10/30.html#a228</guid>			<pubDate>Thu, 31 Oct 2002 05:10:23 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=228&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F10%2F30.html%23a228</comments>			</item>		<item>			<title>Looking ahead to Python 2.3</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/10/08.html#a215</link>			<description>I was trying to ascertain the state of &quot;Python&quot; 2.3 today, and &lt;a href=&quot;http://www.python.org/peps/pep-0283.html&quot;&gt;PEP 283&lt;/a&gt; offered up an interesting list of what is already in for 2.3, and a fairly long list of &quot;planned features&quot;.  What&apos;s in?  Two new types - booleans and &lt;strong&gt;sets!&lt;/strong&gt;.  A fundamental &lt;em&gt;datetime&lt;/em&gt; type or interface may make the release as well.  A planned possible feature is an &lt;a href=&quot;http://mail.python.org/pipermail/python-dev/2002-May/024418.html&quot;&gt;Iterator Tools&lt;/a&gt; module featuring &quot;goodies from SML and Haskell&quot;.I&apos;ve been using Python for over six years now (it&apos;s hard to believe it&apos;s been that long!), and it&apos;s been interesting to watch the language grow since 1.3.  A nice thing about Python&apos;s growth is that it&apos;s been fairly smart - as it picks up new features, it also simplifies itself.  A lot of the old confusions / problems are gone or going away, and helpful features have popped up -- the type/class dichotomy is on its way out (it&apos;s interesting to see the prototype &apos;bool&apos; type written up in Python by subclassing from &apos;int&apos; - see &lt;a href=&quot;http://www.python.org/peps/pep-0285.html&quot;&gt;PEP 285&lt;/a&gt;); booleans are coming in (I&apos;ve always liked the way Python has treated true/false values, but it&apos;s nice to have actual &apos;True&apos; and &apos;False&apos; objects, and the built in &apos;bool&apos; constructor);  much of the old &apos;string&apos; module has become methods on the &apos;string&apos; type, removing the oddities of having a bunch of procedures to operate on a very common object in an object-oriented language;  there are more unifications in expressions (the &apos;in&apos; operator can now be used to search for substrings in a string: &lt;code&gt;if &apos;this&apos; in &apos;there was this thing..&apos;:&lt;/code&gt; in place of &lt;code&gt;if &apos;there was this thing..&apos;.find(&apos;this&apos;) &amp;gt; -1:&lt;/code&gt;; this also applies for dictionary keys: &lt;code&gt;&apos;somekey&apos; in mydict&lt;/code&gt; in place of &lt;code&gt;mydict.has_key(&apos;somekey&apos;)&lt;/code&gt;); iterators are offered throughout the language now, sometimes offering shortcuts for common operations (such as reading individual lines from a file), and keeping resource use down for others; and we finally have nested scopes.  Not to mention the little delights like Generators and List Comprehensions.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/10/08.html#a215</guid>			<pubDate>Tue, 08 Oct 2002 19:26:29 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=215&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F10%2F08.html%23a215</comments>			</item>		<item>			<title>A Zope 3 story - augmenting other components</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/09/02.html#a194</link>			<description>It&apos;s very late, so I&apos;ll try to make this quick and write up more later.  Today, I finally had enough free time in my coffers to download &quot;Python&quot; from CVS (aka - 2.3 pre-alpha) onto my old iMac, and augment that with &quot;Zope 3&quot; - the &lt;em&gt;ComponentArchitecture&lt;/em&gt; project.  Then I installed the simple but usable &lt;a href=&quot;http://cvs.zope.org/ZopeProducts/JobBoardEx/&quot;&gt;Job Board Example&lt;/a&gt;.  I soon noticed that said JobBoardExample was missing out on a couple of things - an editing interface, and an XML-RPC interface. One of the notions of Zope 3 is that it&apos;s supposed to be easier for developers to embrace and extend other components by being able to write new &quot;views&quot; for them.  So, I decided to write a JobEditView.  I made a new Product (esentially, a plain Python package) called JobBoardEditor, and filled it with a couple of files - &lt;tt&gt;EditJobView.py&lt;/tt&gt;, &lt;tt&gt;edit.pt&lt;/tt&gt; (the page template to edit a single job with), and &lt;tt&gt;configure.zcml&lt;/tt&gt;, the configuration file that ties it into the Zope system.  It wasn&apos;t long until I could go to a Job object and traverse to my new edit form, and then have the submit go to my &apos;edit&apos; method.  But, at this point, I&apos;m running into security issues that are beyond my measure to figure out, especially at 1:00 am with a beer headache. &quot;;-&gt;&quot;My other thing to try out was putting a simple XML-RPC interface on to the JobList.  This was particularly interesting to me as I&apos;ve found that while traditional &quot;Zope&quot; method calls should - in theory - work fine with something like XML-RPC, they seldom do.  Sometimes it&apos;s because too much HTML is returned from a call, but most of the time lately (for me at least), it&apos;s that I want the server to do some processing of the results before sending them out to the client, using the relatively simple data types afforded to XML-RPC.  As a result, I&apos;ve been adding in extra Python Scripts particularly for XML-RPC, and letting them work in the proper places either via acquisition or some other clever tricks.  It&apos;s not a bad system, but it&apos;s not exactly formalized or repeatable, since it&apos;s not in a formal Product.In Zope 3, this is different.  I wrote a simple XMLRPCView class.  &apos;View&apos; objects in Zope 3 have two state members - &apos;request&apos; (the incoming request object), and &apos;context&apos; - the object the View is applied against.  So, for me to add in the new functionality whereby I could just get a list of approved Job titles, I wrote the following Python file in my JobBoardEditor product:&lt;pre&gt;from Zope.Publisher.XMLRPC.XMLRPCView import XMLRPCViewfrom ZopeProducts.JobBoardEx.IJob import JobState class JobListXMLRPCView(XMLRPCView):    __implements__ = XMLRPCView.__implements__     def listJobTitles(self):        joblist = self.context        job_ids = joblist.query(state=JobState.Approved)        out = []        for jid in job_ids:            out.append(joblist[jid].summary)        return tuple(out)&lt;/pre&gt;Then, I added the following to &lt;code&gt;JobBoardEditor/configure.zcml&lt;/code&gt; (after adding &lt;code&gt;xmlns:xmlrpc=&apos;&lt;a href=&quot;http://namespaces.zope.org/xmlrpc&quot;&gt;http://namespaces.zope.org/xmlrpc&lt;/a&gt;&apos;&lt;/code&gt; to the head zopeConfigure element):&lt;pre&gt;&amp;lt;xmlrpc:view    name=&quot;joblistmethods&quot;    for=&quot;ZopeProducts.JobBoardEx.IJobList.&quot;    factory=&quot;.JobListXMLRPCView.&quot; /&amp;gt;&lt;/pre&gt;With this configuration statement, I&apos;ve added a new View to be published on the XMLRPC channel (which in Zope 3 runs on a different port than normal HTTP requests, which is probably wise) for objects that implement the IJobList interface.  I was able to do all of this outside of the JobBoardEx product.  I just had to ensure that the Product was added in &lt;em&gt;after&lt;/em&gt; JobBoardEx by using the site&apos;s &lt;em&gt;products.zcml&lt;/em&gt; file to affect the ordering.After restarting Zope 3 (which is a very slow restart on this machine), I was able to do this:&lt;pre&gt;Py$ s = Server(&apos;&lt;a href=&quot;http://localhost:8281/zoo/joblistmethods&quot;&gt;http://localhost:8281/zoo/joblistmethods&lt;/a&gt;&apos;)Py$ s.listJobTitles()[&apos;test test test&apos;]&lt;/pre&gt;I actually had created two jobs through the web interface, but had only approved one.  So I ducked in to the web interface to approve the other job, and then made the call again:&lt;pre&gt;Py$ s.listJobTitles()[&apos;test test test&apos;, &apos;the other job&apos;]&lt;/pre&gt;So, what are some benefits of this?  One that comes to mind is issue trackers.  Earlier in the day, I was writing a Python script to farm through some Tracker data and format it nicely for XML-RPC, with the intent of writing a simple AppleScript Studio application to list pending/accepted Tracker issues.  I did this informally, dropping a Python Script into the folder above a particular tracker.  Ultimately, it didn&apos;t work - and I think a lot of the blame goes on XML-RPC&apos;s utter disregard for semi-proper security.  Since Zope&apos;s always published objects on the web with regards to web security standards (or embarrasments, depending on your view) such as &apos;Basic Auth&apos;, it&apos;s had problems with the &quot;security by passing in arguments&quot; design of many XML-RPC API&apos;s.  But the point I was really going for was packaging.  Even if the Tracker Issue finding Python Script had worked over XML-RPC, now I have to find other places to put it by copying and pasting it, ultimately adding another name onto an ever growing namespace.With Zope 3, however, I could write an XML-RPC view particularly for the application I was designing as a normal Python component, and install and configure it as necessary (and hopefully that configuration work will be better than copying and pasting plain Python Script code).  I can name it specially, essentially adding a new namespace for my application.  I can distribute it to other users fairly easily.Another example would be implementing the Blogger API not as a new weblog product for Zope, but as a view/adapter component that publishes on the XML-RPC channel, and communicates with other Zope components, either built in ones or third party.In summary - my first tangible Zope 3 experience in quite some time has been hopeful and helpful.  There&apos;s still a long way to go, but the kernel is shaping up nicely.  The pattern driven / &quot;extreme programming&quot; sprint driven development has yielded a decent - but still shifting - code base that should be stronger and simpler than Zope 2.  Sometimes, there are enough levels of indirection in Zope 3 to make it look more complex, but so far most code has been easier to follow and trace than Zope 2 (although there are a number of empty folders/packages that probably need some brute force removing from CVS) - at least, it&apos;s usually easier to tell what&apos;s going on (and even this has an at least - at least, once you start learning the new paradigm).  Zope&apos;s ancester, Bobo (the kernel on which Zope is still based), was all about abstracting the means of publishing an object on the web away from the object itself.  Bobo, and then Principia / Zope 1.x, built upon this, but primarily in a single-UI / single protocol type way.  It&apos;s obvious today that there are many ways of looking at things on the web, including never actually using the web itself.  Zope 3 brings us back to the notion of an &lt;em&gt;object publisher&lt;/em&gt; being able to serve up objects on different protocols.  Zope 2 offers this today, but there is great difficulty in making WebDAV, normal HTTP, FTP, and XML-RPC all live harmoniously in the current design.And finally, Zope 3 should yield a usable scalable means of adapting the works of other developers into new solutions by providing better control of product/service/view configuration and overrides, such as adding a new XML-RPC API to someone elses bug tracking system without having to alter that bug tracking system, or use secret Python hacks to alter behaviour.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/09/02.html#a194</guid>			<pubDate>Mon, 02 Sep 2002 08:47:43 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=194&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F09%2F02.html%23a194</comments>			</item>		<item>			<title>Aha! (Python Patch)</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/07/17.html#a158</link>			<description>So, the mysterious core dumps seem to be over, thanks to &lt;a href=&quot;http://sourceforge.net/tracker/?func=detail&amp;aid=554841&amp;group_id=5470&amp;atid=305470&quot;&gt;this patch&lt;/a&gt; on SourceForge.net regarding pthreads and stack sizes on BSD.  I reverted back from the Tracker changes I made last night, and nothing crashed.I did have to make one small patch to Tracker though, introducing a fun filled positive lookahead assertion to a regular expression used to generate HREF&apos;s.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/07/17.html#a158</guid>			<pubDate>Thu, 18 Jul 2002 02:19:05 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=158&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F07%2F17.html%23a158</comments>			</item>		<item>			<title>Issue Trackers Revisited</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/07/16.html#a157</link>			<description>So finally, I have &quot;Tracker&quot; working with &quot;Zope&quot; 2.5.1 and &quot;Python&quot; 2.1.3 on FreeBSD 4.5.  It seems that the restricted Python engine (which I presume is new/revamped in 2.5?) has a problem with expressions that are heavy with parenthesis.  So, after crawling through a lot of DTML code (some of it quite old - some of it predating the &apos;let&apos; tag!) by slowly moving a &apos;dtml-raise&apos; statement around, I was able to find all (or at least most) of my problems.I just couldn&apos;t take &quot;Roundup&quot; any more.  Actually, as a single developer or with another geek, it was alright.  But it&apos;s still young, and doesn&apos;t have a lot of the great user/security/collaboration issues that Tracker has (and which CMF Collector partly has).  And it doesn&apos;t have the workflow.  And it&apos;s still too much tweak-work to configure ones own instance of &quot;Roundup&quot; beyond the two templates they have.  I am going to try to stay active with it though, but it really feels like the goals of &quot;Roundup&quot; and &quot;Tracker&quot; are very different.Tracker is an old unwieldy beast, however, and it seems to take a fair bit of grunt work to get it to work every time Zope has a new revision.  Ugh.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/07/16.html#a157</guid>			<pubDate>Wed, 17 Jul 2002 03:26:02 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=157&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F07%2F16.html%23a157</comments>			</item>		<item>			<title>An optimization dilemma</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/07/08.html#a153</link>			<description>I&apos;m facing a nice little Python/Zope programmers dilemma.  I have a critical &quot;Zope&quot; &quot;Python&quot; Script - Python code objects in Zope that are editable through the web, and are subject to being run in a &quot;restricted mode&quot; interpreter that enforces Zope security policies.  It&apos;s quite long for a single script, weighing in at approximately 170 lines.  But it does its job well, and is written with maintainability in mind (there&apos;s only one variable in there that I find non-obvious, and whose usage I might change).Unfortunately, it seems to do its job slowly.  I think there are a few contributing factors to this:&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Restricted Python.&lt;/strong&gt;  I think the security overhead is slowing the execution down.  In evaluating the script&apos;s code, it doesn&apos;t really need to go through this.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;SQL Calls.&lt;/strong&gt;  There are a lot of calls into SQL Methods, both read and write.  I&apos;m not sure if this can be helped, or indeed is having any real noticeable effect on the speed.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Generating/Sending Emails.&lt;/strong&gt;  I think there might be an issue here.  The &lt;a href=&quot;http://www.dataflake.org/software/maildrophost/&quot;&gt;MailDropHost&lt;/a&gt; Product by Jens Vagelpohl could help as it sends mail asynchronously.&lt;/li&gt;&lt;/ol&gt;With those points in mind, I&apos;ve started tackling the first bullet by moving the code into an &lt;em&gt;External Method&lt;/em&gt;, where it is not victim to the Restricted Python interpreter.  As a bonus, the code can be checked into CVS.  But now I face a new dilemma - &lt;strong&gt;inline or breakout?&lt;/strong&gt;Since the code was originally written as a Zope Python Script, it was one big inline piece of execution.  Now that it&apos;s an External Method, I have the opportunity to &lt;a href=&quot;http://www.refactoring.com/&quot;&gt;refactor&lt;/a&gt;, and turn the code into a class/singleton wherein the code is broken out into methods that are executed in a certain order.  My newer instincts are pulling me in this direction.  But I know that it brings in new overhead to the code whose speed I&apos;m already concerned about.  Now, instead of dealing with restricted Python, I&apos;d have to deal with a number of new function calls and name lookups.  And, possibly, Thread Safety issues.The code in question is very central business logic.  In order of importance, it needs to be solid, maintainable, and relatively fast.  It succeeds on the first two points (very solid, fairly maintainable).  The third one is a matter of some debate, most of which is going on inside my head.  Future writings in this space will look at the avenues explored and if they yielded any results.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/07/08.html#a153</guid>			<pubDate>Mon, 08 Jul 2002 15:28:15 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=153&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F07%2F08.html%23a153</comments>			</item>		<item>			<title>Customizing Roundup, day one</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/07/02.html#a150</link>			<description>I spent some more time working with &quot;Roundup&quot; this morning.  When you create a new instance, one of the files it generates is &lt;code&gt;dbinit.py&lt;/code&gt;.  &lt;code&gt;dbinit.py&lt;/code&gt; contains code to initialize the database schema, and also contains an empty &lt;code&gt;IssueClass&lt;/code&gt; class, subclassed off of the default &lt;code&gt;roundup.roundupdb.IssueClass&lt;/code&gt;.  I was able to take advantage of this to customize the emails sent out by &quot;Roundup&quot; to make them look a bit more like the ones sent out by &lt;a href=&quot;http://www.zope.org/Members/klm/TrackerWiki/FrontPage&quot;&gt;Tracker&lt;/a&gt; (as mentioned in the &quot;Python based Issue Trackers&quot; post, Tracker generates the nicest emails of any issue tracking system I&apos;ve worked with thus far).</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/07/02.html#a150</guid>			<pubDate>Tue, 02 Jul 2002 16:58:21 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=150&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F07%2F02.html%23a150</comments>			</item>		<item>			<title>Python based Issue Trackers</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/07/01.html#a149</link>			<description>I&apos;ve been on one end or another of three Python based issue trackers lately - &lt;a href=&quot;http://www.zope.org/Members/klm/TrackerWiki/FrontPage&quot;&gt;Tracker&lt;/a&gt;, its descendant, &lt;a href=&quot;http://cvs.zope.org/CMF/CMFCollector/&quot;&gt;CMFCollector&lt;/a&gt;, and it&apos;s competition in the Software Carpentry contest, &lt;a href=&quot;http://roundup.sourceforge.net/&quot;&gt;Roundup&lt;/a&gt;.  And there&apos;s always something there to make me unhappy.&lt;strong&gt;Tracker&lt;/strong&gt; is one of the best issue trackers I have used.  It&apos;s got a fairly solid user interface, a fairly solid built in Workflow, and hierarchical correspondence/state changing.  It&apos;s one of the easiest web based issue tracking systems to use to follow the actual history of an item, and it&apos;s easy to see at a glance how actively an issue was discussed/reported on in the Tracker from the issue listing page.  And Tracker sends out &lt;u&gt;best emails&lt;/u&gt; of &lt;em&gt;any&lt;/em&gt; bug tracking system I&apos;ve seen.  Sadly, it&apos;s pretty much dead (and in fact - it&apos;s been core dumping on my when I&apos;ve attempted to use it with Zope 2.5.1 and Python 2.1.2/2.1.3).  You can see it still in full action as the &lt;a href=&quot;http://www.zope.org/Products/PTK/Tracker/&quot;&gt;Tracker&lt;/a&gt; for the whole &lt;a href=&quot;http://cmf.zope.org/&quot;&gt;CMF&lt;/a&gt; project.&lt;strong&gt;CMFCollector&lt;/strong&gt; is its replacement.  I don&apos;t like it as much.  It suffers from a flat transcript (by default in a non-monospaced font) that is harder to follow than the system used in Tracker.  And the UI - by default - just isn&apos;t quite as much there, although this may be due to the pretty basic (or just plain weird) default CMF Skins.  The pretty-much-default CMF Collector setup can be seen in action at &lt;a href=&quot;http://collector.zope.org/Zope/&quot;&gt;The Zope Issue Tracker&lt;/a&gt;.  The &lt;a href=&quot;http://www.plone.org/&quot;&gt;Plone&lt;/a&gt; (a massive skin/layer for the CMF) varation can be seen in action at &lt;a href=&quot;http://plone.org/collector&quot;&gt;The Plone Issue Collector&lt;/a&gt;.&lt;strong&gt;Roundup&lt;/strong&gt; is not Zope based at all.  It&apos;s a pure-python solution with a nice abstraction of layers (frontends/backends).  It seems to be the most actively developed, but still feels young.  Regardless of age, I&apos;ve started installing it at work.  The user interface is very basic (and kindof hard to read), and it suffers from the same flat-transcript issue that &lt;em&gt;CMFCollector&lt;/em&gt; does.  But it&apos;s fast, simple, and fairly solid.  It has a few options for submitting/modifying issues - by email, by command line, and through the web.  It can run as a standalone web server, as a CGI script, or through &quot;Zope&quot; via a frontend called &lt;em&gt;ZRoundup&lt;/em&gt;.  ZRoundup essentially passes and wraps Zope REQUEST data and passes it into Roundup, and returns the resulting HTML -- essentially a CGI-esque gateway for Zope.  But it allows Roundup objects to be placed alongside other Zope content, like ZWiki&apos;s or just plain documents as part of a simple project management solution.I miss Tracker.  And CMFCollector isn&apos;t yet a worthy replacement for it.  Roundup is small, fast, and looks to be broken out enough to be easily programmable.  I may even look into getting involved with its development.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/07/01.html#a149</guid>			<pubDate>Tue, 02 Jul 2002 05:40:11 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=149&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F07%2F01.html%23a149</comments>			</item>		<item>			<title>Universal Newline Support, coming soon to Python</title>			<link>http://www.python.org/peps/pep-0278.html</link>			<description>&lt;a href=&quot;http://www.python.org/peps/pep-0278.html&quot;&gt;PEP 278&lt;/a&gt; is something I (and I&apos;m sure many others) have been wanting for a very long time.  Now, in Python 2.3 (most likely), you&apos;ll be able to have code like &lt;code&gt;f = open(filename, &apos;rU&apos;)&lt;/code&gt;, and have ALL newlines in the file be the single, normal, &lt;code&gt;&apos;n&apos;&lt;/code&gt; character.  Of interest is the new file object attribute, &lt;em&gt;newlines&lt;/em&gt;:&lt;blockquote cite=&quot;http://www.python.org/peps/pep-0278.html&quot;&gt;A file object that has been opened in universal newline mode gets a new attribute &quot;newlines&quot; which reflects the newline convention used in the file.  The value for this attribute is one of None (no newline read yet), &quot;\r&quot;, &quot;\n&quot;, &quot;\r\n&quot; or a tuple containing all the newline types seen.&lt;/blockquote&gt;This is especially welcome on &quot;Mac OS X&quot;, as noted in the PEP, due to OS X&apos;s double standards - Classic and Carbon apps typically use the CR symbol to end a line, while Cocoa and Unix apps typically use LF.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/06/23.html#a145</guid>			<pubDate>Sun, 23 Jun 2002 19:41:52 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=145&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F06%2F23.html%23a145</comments>			</item>		<item>			<title>Reordering Items in a Zope ObjectManager</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/06/15.html#a137</link>			<description>We have &lt;strong&gt;movable Parts!&lt;/strong&gt;.  That&apos;s right.  With a little bit of code, a couple of unit tests, and some surprisingly simple UI work, Parts in an SCS Document can be re-arranged.This is yielding something I&apos;ve been wanting to do (and have) for years - decent through-the-web &lt;em&gt;Document&lt;/em&gt; editing, with drop in objects than can be reorganized easily.  While I&apos;m sure it&apos;s been done many times before, it was great seeing the results yesterday as part of my own framework and application.The work went fairly quickly, once I moved the methods to the right class and added Unit Tests.  The secret is in the &lt;em&gt;_objects&lt;/em&gt; attribute of Zope &lt;strong&gt;ObjectManager&lt;/strong&gt; based instances.  &lt;tt&gt;_objects&lt;/tt&gt; is a &lt;a href=&quot;http://www.python.org/doc/current/lib/typesseq.html&quot;&gt;tuple&lt;/a&gt; of &lt;a href=&quot;http://www.python.org/doc/current/lib/typesmapping.html&quot;&gt;dictionaries&lt;/a&gt; with the keys &lt;tt&gt;&apos;id&apos;&lt;/tt&gt; and &lt;tt&gt;&apos;meta_type&apos;&lt;/tt&gt;.  ObjectManager classes use this information to know what objects in the  ObjectManager are being managed as subobjects, and to define their ordering.  Most people never see or know of this attributes existence as its use is well-handled by the common ObjectManager API&apos;s.  But one can use this list to their advantage, such as reordering.So, in todays code we have what I used to reorder Parts in my PartContainer class.  There are two important elements - finding the index of the object in question, and then swapping its place in the list.  We can&apos;t use &lt;code&gt;parts.index(part_id)&lt;/code&gt; because of the complex data structure of the list - although, if we had the object in question, we could try &lt;code&gt;parts.index({&apos;id&apos;: obj.getId(), &apos;meta_type&apos;: obj.meta_type})&lt;/code&gt;.  But the following works, and could be applied to any ObjectManager based class.  &lt;em&gt;Note - there are already Products available to bring order to Folders in Zope, such as &lt;a href=&quot;http://www.zope.org/Members/srichter/Products/OrderedFolder&quot;&gt;Ordered Folder&lt;/a&gt;.  It&apos;s a feature that was &lt;a href=&quot;http://dev.zope.org/Wikis/DevSite/Projects/Zope2.6/ProposedFeatures&quot;&gt;Proposed for Zope 2.6&lt;/a&gt;, but was deferred.&lt;/em&gt;.&lt;pre&gt;&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&lt;a name=&quot;PartContainer&quot;&gt;&lt;span style=&quot;color: #CC0000&quot;&gt;&lt;b&gt; PartContainer&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;(ObjectManager):    &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&lt;a name=&quot;_findPartIndex&quot;&gt;&lt;span style=&quot;color: #CC0000&quot;&gt;&lt;b&gt; _findPartIndex&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;(self, part_id, objectList=[]):        &lt;span style=&quot;color: #115511&quot;&gt;&quot;&quot;&quot; Returns the index of a part in the object list &quot;&quot;&quot;&lt;/span&gt;        idx = 0        &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; obj &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; objectList:            &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; obj[&lt;span style=&quot;color: #115511&quot;&gt;&apos;id&apos;&lt;/span&gt;] == part_id:                &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;break&lt;/b&gt;&lt;/span&gt;            idx += 1        &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;:            &lt;span style=&quot;color: #1111CC&quot;&gt;## part not found&lt;/span&gt;            &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;raise&lt;/b&gt;&lt;/span&gt; IndexError(part_id)        &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; idx     security.declareProtected(change_scs_documents, &lt;span style=&quot;color: #115511&quot;&gt;&apos;movePartUp&apos;&lt;/span&gt;)    &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&lt;a name=&quot;movePartUp&quot;&gt;&lt;span style=&quot;color: #CC0000&quot;&gt;&lt;b&gt; movePartUp&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;(self, part_id):        &lt;span style=&quot;color: #115511&quot;&gt;&quot;&quot;&quot; Move a part up.  Raises IndexError if part is not found &quot;&quot;&quot;&lt;/span&gt;        &lt;span style=&quot;color: #1111CC&quot;&gt;## make a copy of our _objects list, which is a part of ObjectManager.&lt;/span&gt;        &lt;span style=&quot;color: #1111CC&quot;&gt;## _objects is a tuple of dictionaries with keys &apos;meta_type&apos; and &apos;id&apos;.&lt;/span&gt;        parts = list(self._objects)        idx = self._findPartIndex(part_id, parts)        &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; idx == 0:            &lt;span style=&quot;color: #1111CC&quot;&gt;## Can&apos;t move past top, just exit&lt;/span&gt;            &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; 0        &lt;span style=&quot;color: #1111CC&quot;&gt;## swap fields, moving idx up&lt;/span&gt;        parts[idx], parts[idx-1] = parts[idx-1], parts[idx]        self._objects = tuple(parts)        &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; 1     security.declareProtected(change_scs_documents, &lt;span style=&quot;color: #115511&quot;&gt;&apos;movePartDown&apos;&lt;/span&gt;)    &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&lt;a name=&quot;movePartDown&quot;&gt;&lt;span style=&quot;color: #CC0000&quot;&gt;&lt;b&gt; movePartDown&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;(self, part_id):        &lt;span style=&quot;color: #115511&quot;&gt;&quot;&quot;&quot; Move a part down.  Raises IndexError if part is not found &quot;&quot;&quot;&lt;/span&gt;        &lt;span style=&quot;color: #1111CC&quot;&gt;## make a copy of our _objects list, which is a part of ObjectManager.&lt;/span&gt;        &lt;span style=&quot;color: #1111CC&quot;&gt;## _objects is a tuple of dictionaries with keys &apos;meta_type&apos; and &apos;id&apos;.&lt;/span&gt;        parts = list(self._objects)        idx = self._findPartIndex(part_id, parts)        &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; idx == len(parts)-1:            &lt;span style=&quot;color: #1111CC&quot;&gt;## Can&apos;t move past bottom, so just exit&lt;/span&gt;            &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; 0        &lt;span style=&quot;color: #1111CC&quot;&gt;## swap fields, moving idx up&lt;/span&gt;        parts[idx], parts[idx+1] = parts[idx+1], parts[idx]        self._objects = tuple(parts)        &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; 1&lt;/pre&gt;</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/06/15.html#a137</guid>			<pubDate>Sat, 15 Jun 2002 17:40:39 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=137&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F06%2F15.html%23a137</comments>			</item>		<item>			<title>Zopeishy vs Pythonishy</title>			<link>http://db.cs.helsinki.fi/~jajvirta/cgi-bin/sites.py?opts=zope&amp;opts2=python</link>			<description>According to this program by &lt;a href=&quot;http://pythonowns.blogspot.com/&quot;&gt;Jarno Virtanen&lt;/a&gt;, this site is a tad &lt;a href=&quot;http://db.cs.helsinki.fi/~jajvirta/cgi-bin/sites.py?opts=zope&amp;opts2=python&quot;&gt;more zopishy than pythonishy&lt;/a&gt;.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/06/13.html#a135</guid>			<pubDate>Thu, 13 Jun 2002 14:57:23 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=135&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F06%2F13.html%23a135</comments>			</item>		<item>			<title>Andrew Kuchlings &quot;What&apos;s New in Python 2.3&quot; in development</title>			<link>http://www.python.org/dev/doc/devel/whatsnew/</link>			<description>Andrew Kuchling has published an early development revision of &lt;a href=&quot;http://www.python.org/dev/doc/devel/whatsnew/&quot;&gt;&quot;What&apos;s New in Python 2.3&quot;&lt;/a&gt;, detailing some of the work that&apos;s already been checked in, and what&apos;s no longer bound to the __future__.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/06/11.html#a130</guid>			<pubDate>Tue, 11 Jun 2002 16:31:28 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=130&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F06%2F11.html%23a130</comments>			</item>		<item>			<title>ZWiki and logical structures.</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/06/10.html#a126</link>			<description>&lt;a href=&quot;http://zwiki.org/&quot;&gt;ZWiki&lt;/a&gt; is a sehr-cool beast, as far as Wikis go.  A very attractive feature, seen all over the &lt;a href=&quot;http://www.zope.org/&quot;&gt;Zope.org&lt;/a&gt; web site is &lt;a href=&quot;http://www.zope.org/Members/klm/&quot;&gt;Ken Manheimer&lt;/a&gt;&apos;s work on page/parenting relationships.  This makes it so that Wiki pages, although stored in a flat namespace (all in one folder) can appear to be hierarchical, depending on which page generated which page (parenting can be altered of course).  This in turn leads to cool things, like a structured table of contents (see the Zope 3 wiki&apos;s &lt;a href=&quot;http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FrontPage/map&quot;&gt;TOC Here&lt;/a&gt;).It&apos;s especially cool in that it&apos;s fairly easy to change the hierarchical structure of the Wiki - by looking at a page&apos;s backlinks, one can reparent a page to one or more of its linkers.  Essentially, new logical structures can grow independent of the physical structure.I&apos;ve used a similar feature in a recent simple content system, wherein all documents were stored in a single folder, but the users entering content could classify documents in one or more categories.  The main pages on the site were basically database queries (actually, catalog queries) based on the classifications.  Thus, the site was built out of a simple logical structure rather than a physical one, which allowed documents to appear in more than one place if they needed to be.  It&apos;s no unique concept, &quot;Radio&quot; and some other blogging tools allow this, much to my delight.In the simple compound system I did for that customer, the flat namespace also allowed simple inter-document link management.  The author could say &quot;document A links to document B&quot;, and when document B was deleted, the link to it would also evaporate.  For some reason, doing deep inter-object linking in &quot;Zope&quot; is still tricky business, but there&apos;s hope on the &quot;Zope 3&quot; horizon (some of which looks like it may be backported to Zope 2).</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/06/10.html#a126</guid>			<pubDate>Mon, 10 Jun 2002 19:59:30 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=126&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F06%2F10.html%23a126</comments>			</item>		<item>			<title>Templates, code, and HTML</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/05/28.html#a117</link>			<description>Half of our power is out, but the airport base station and the gateways are still on.  So, todays teaser medicine consists of a &quot;Python&quot; translation of some UserTalk code I wrote (the first major script I wrote in Radio), runnable as an External Method in &quot;Zope&quot;.  Also included is the UserTalk code, as well as some DTML and ZPT output.I show this because, personally, I &lt;em&gt;loathe&lt;/em&gt; coming across HTML in code.  Sorry &lt;a href=&quot;http://radio.weblogs.com/0100887/2002/05/25.html#a266&quot;&gt;Jon&lt;/a&gt;.  Writing for templates increases possibilities for reuse, since the data producing code is independent from the code that displays it.  While you can do this in pure python scripts (by having one script produce data, and have another script as a consumer that outputs HTML from within Python), I take a &quot;why bother?&quot; attitude.  I&apos;ve had to maintain that HTML generating code in the past - the long ago past in web time (1996).  And I hated the maintenance chores that seemed to go along with even the most trivial HTML.  Why do we keep reinventing old problems?  The script-inside-HTML way is often as broken, in my mind, as the HTML-inside-scripts way.  It always surprises me to see ASP/PHP code that looks like::&lt;pre&gt;&amp;lt;table&amp;gt;  &amp;lt;% for row in data {    out.writeln(&apos;&amp;lt;tr&amp;gt;&apos;);    out.writeln(&apos;&amp;lt;td&amp;gt;&apos; + row.name + &apos;&amp;lt;/td&amp;gt;&apos;);    out.writeln(&apos;&amp;lt;/tr&amp;gt;&apos;);  } %&amp;gt;&amp;lt;/table&amp;gt;&lt;/pre&gt;Why bother having the HTML abilities of ?SP/PHP languages at all?  I can understand &lt;em&gt;why&lt;/em&gt; it happens.  I just don&apos;t think it should.  &quot;;-&gt;&quot;.  But, in the words of Dennis Miller, &quot;Of course, that&apos;s just my opinion, I could be wrong&quot;.In any case, I present the Goldberg Variations:&lt;pre&gt;&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;import&lt;/b&gt;&lt;/span&gt; osradioWwwFolder = &lt;span style=&quot;color: #115511&quot;&gt;&apos;/Applications/Radio Userland/www&apos;&lt;/span&gt;&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&lt;a name=&quot;listOutlines&quot;&gt;&lt;span style=&quot;color: #CC0000&quot;&gt;&lt;b&gt; listOutlines&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;():	out  =[]	path = os.path.join(radioWwwFolder, &lt;span style=&quot;color: #115511&quot;&gt;&apos;outlines&apos;&lt;/span&gt;)	&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&lt;a name=&quot;visit&quot;&gt;&lt;span style=&quot;color: #CC0000&quot;&gt;&lt;b&gt; visit&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;(arg, dirname, fnames):		&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; fname &lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; fnames:			&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; fname.endswith(&lt;span style=&quot;color: #115511&quot;&gt;&apos;.opml&apos;&lt;/span&gt;):				fn = os.path.splitext(fname)[0]    &lt;span style=&quot;color: #1111CC&quot;&gt;# Split extension off&lt;/span&gt;				&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; dirname != path:				    &lt;span style=&quot;color: #1111CC&quot;&gt;# Deal with subdirectories&lt;/span&gt;				    fn = os.path.join(dirname[len(path):], fn)				arg.append(fn)	os.path.walk(path, visit, out)	&lt;span style=&quot;color: #3333CC&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; out ZPT = &lt;span style=&quot;color: #115511&quot;&gt;&quot;&quot;&quot;&amp;lt;ol&amp;gt; &amp;lt;li tal:repeat=&quot;item here/listOutlines&quot;&amp;gt;  &amp;lt;a tal:attributes=&quot;href string:${item}.html&quot;     tal:content=&quot;item&quot;&amp;gt;Outline&amp;lt;/a&amp;gt; &amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&quot;&quot;&quot;&lt;/span&gt; DTML = &lt;span style=&quot;color: #115511&quot;&gt;&quot;&quot;&quot;&amp;lt;ol&amp;gt; &amp;lt;dtml-in listOutlines&amp;gt;  &amp;lt;li&amp;gt;&amp;lt;a href=&quot;&amp;amp;dtml-sequence-item;.html&quot;&amp;gt;&amp;lt;dtml-var item&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt; &amp;lt;/dtml-in&amp;gt;&amp;lt;/ol&amp;gt;&quot;&quot;&quot;&lt;/span&gt; USERTALK = &lt;span style=&quot;color: #115511&quot;&gt;&quot;&quot;&quot;on listOutlines() {	local(out = &quot;&amp;lt;ol&amp;gt;\n&quot;);	local(path=user.radio.prefs.wwwFolder + &quot;outlines&quot;);	on visit(f) {		f = file.fileFromPath(f);		if string.hasSuffix(&quot;.opml&quot;, f) {			f = string.popSuffix(f, &apos;.&apos;);			out = out + &quot; &amp;lt;li&amp;gt;&amp;lt;a href=\&quot;&quot; + f + &quot;.html&quot;&amp;gt;&quot; + f + &quot;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;n&quot;};		return true};	file.visitFolder(path, 1, @visit);	out = out + &quot;&amp;lt;/ol&amp;gt;&quot;;	return out}&quot;&quot;&quot;&lt;/span&gt;&lt;/pre&gt;</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/28.html#a117</guid>			<pubDate>Tue, 28 May 2002 18:15:14 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=117&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F28.html%23a117</comments>			</item>		<item>			<title>More Page Templates (a buttal of sorts?)</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/05/23.html#a116</link>			<description>&lt;a href=&quot;http://radio.weblogs.com/0100887/2002/05/23.html#a262&quot;&gt;Jon Udell&lt;/a&gt; and &lt;a href=&quot;http://www.zopenewbies.net/1022194185/&quot;&gt;Zope Newbies&lt;/a&gt; both write stuff along the lines of &lt;em&gt;I decided again not to use them because they would add more complexity to my sites and wouldn&apos;t solve any problems -- I&apos;m not about to start using Dreamweaver or GoLive any time soon. It&apos;s just me and Pepper or Mozilla. I don&apos;t have to work with any designers&lt;/em&gt;, or that &lt;em&gt;the learning curve is too steep&lt;/em&gt;.Personally, I think that the learning curve for Page Templates is much smaller than DTML.  The only problem is in trying to &lt;em&gt;think like DTML&lt;/em&gt; when you really shouldn&apos;t be.  While there are &lt;a href=&quot;http://www.zope.org/Members/peterbe/DTML2ZPT&quot;&gt;helpful conversion guides&lt;/a&gt;, I do think it best to approach ZPT on a fresh project rather than trying to retrofit them into something existing (by either adding on to a site/project, or trying to replace existing DTML).Page Templates have a wonderfully clean syntax in the TAL/TALES combination.  There are very few TAL attributes, and their operations and operational order are &lt;a href=&quot;http://www.zope.org/Wikis/DevSite/Projects/ZPT/TAL&quot;&gt;clearly defined&lt;/a&gt;.  TALES eliminates much of DTML&apos;s guesswork by eliminating the whole &quot;is it an expression? a literal? a name lookup?&quot; game.  The &lt;a href=&quot;http://www.zope.org/Wikis/DevSite/Projects/ZPT/METAL&quot;&gt;METAL&lt;/a&gt; macro expression system is a little more complicated, but ultimately provides a clean way of componentizing HTML/XML, and can be effectively used to eliminate the &lt;tt&gt;standard_html_header/footer&lt;/tt&gt; idiom (I &lt;strong&gt;strongly dislike&lt;/strong&gt; the whole header/footer inclusion idea proffered by so many templating languages, which require you to maintain balance between two separate files/objects to try to give some notion of &quot;standard look&quot; to a site.  METAL is much more along the lines of Dreamweavers and GoLive&apos;s Templates idea, where a page has editable &quot;slots&quot; between commonly shared data, and can thus be edited as a whole page).There are areas that Page Templates break down, especially in comparison with DTML.  First, Page Templates are purely about HTML/XML.  They&apos;re not good for dynamically generating style sheets, Javascript, or SQL, although they &lt;em&gt;can&lt;/em&gt; be used to do so (but as the old maxim goes, just because you can doesn&apos;t mean you should).  Second, DTML has a strong history as a reporting oriented templating language.  TAL and TALES don&apos;t really take on this responsibility, and rather hand it off to other modules like &lt;strong&gt;ZTUtils&lt;/strong&gt; (Zope Template Utilities), a woefully underdocumented piece of the pie.  The Page Templates approach is ultimately better, I believe, because it&apos;s more open to new components being used to handle batching and useful widgets, while with DTML you got what was there.  The &apos;dtml-tree&apos; tag has been woefully stretched in order to allow many variations in how an expanding tree might find its data.  ZTUtils offers handy utility modules, classes, and functions to replace all of this and allow a developer to better handle how it all might work, but it&apos;s currently much harder to do things like &lt;tt&gt;dtml-tree&lt;/tt&gt; in Page Templates.But DTML has suffered from many problems over its lifetime.  Until Python Scripts came to Zope, it was the primary way most people learned how to program Zope.  It grew a lot of programming language style muscle, while retaining all of its reporting language heritage.  Its namespace stack is a powerful but often untamed beast, and its full of grotesque shortcuts and workarounds.  Anyone who&apos;s seen &lt;tt&gt;_[_[&apos;sequence-item&apos;]]&lt;/tt&gt; knows what I mean.  And anyone&apos;s who&apos;s used &lt;tt&gt;_[_[&apos;sequence-item&apos;]]&lt;/tt&gt;  probably had a momentary twinge of &quot;ugh!&quot; before moving on.  DTML has gotten the job done.  There are places where it continues to get the job done - the SQL specific tags are one of my favorite things about doing SQL in Zope.  But DTML is full of accidental surprises - a common mistake is due to the fact that &amp;lt;dtml-var someObj&amp;gt; and &amp;lt;dtml-var &quot;someObj&quot;&amp;gt; can produce wildly different results.I&apos;ve been using DTML since early 1997, and it was a joy when I first used it - there was no Zope, there was no through-the-web editing, there were no DTML expressions, there was just a clean templating language meant to be combined with Bobo published objects.  All real logic happened in Python, and display oriented logic could happen in DTML.  It worked out well.  But, as DTML has grown new appendages in an ad-hoc manner over the years since then, it&apos;s become more and more of a wild card.  Page Templates in Zope, combined with Python Scripts give us back a lot of that early power.  I think there&apos;s less harm in trying them than avoiding them.  They&apos;re truly one of the few &lt;em&gt;really clean&lt;/em&gt; extensions to Zope - well designed, well maintained.  Members of PythonLabs really got involved and did an excellent job ensuring Pythonic standards were met, and early contributors like &lt;a href=&quot;http://www.maplefish.com/todd/&quot;&gt;Todd Coram&lt;/a&gt; (who introduced me to &lt;a href=&quot;http://www.ruby-lang.org/&quot;&gt;Ruby&lt;/a&gt;) did an equally good job of driving the design of TAL/TALES to be a fairly open design specification, of which Page Templates are merely an implementation.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/23.html#a116</guid>			<pubDate>Fri, 24 May 2002 04:49:20 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=116&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F23.html%23a116</comments>			</item>		<item>			<title>Sortof Agile Modeling</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/05/15.html#a104</link>			<description>I started work on a new application today.  We sat around the white board coming up with objects/data, and I did some rapid modeling of the white board data into a rough &lt;b&gt;UML&lt;/b&gt; class diagram using &lt;a href=&quot;http://www.omnigroup.com/applications/omnigraffle/&quot;&gt;OmniGraffle 2.0&lt;/a&gt;.  OmniGraffle is a fine choice for anyone (on Mac OS X) doing some form of &lt;em&gt;Agile Modeling&lt;/em&gt;.I&apos;ve had a love-hate relationship with UML over the years, and especially with modeling tools.  There are many problems (that have been acknowledged, and some tools even do their best to solve them), such as &lt;em&gt;model and source code getting out of sync&lt;/em&gt;, or &lt;em&gt;how do you effectively model a language like &quot;Python&quot;?&lt;/em&gt;.  On top of these issues lie many of the issues that have plagued programming, especially in the age of internet development, for years - the need for speed (just hurry and get it done!  document it later!), scope (a project is [often misconceived as] too small to spend time modeling}, or inability to map web based programming techniques into communicative diagrams (is a JSP page a class?  A UI Component?  Or is its rendered state a UI component?  Huh?).  And often, good development processes seem to be killed by the attempted formalization of a process.This is why it&apos;s been good to see the rise of practices like &quot;Extreme Programming&quot;, &quot;Agile Modeling&quot;, &lt;a href=&quot;http://www.refactoring.com/&quot;&gt;Refactoring&lt;/a&gt;, and so on.  While there is definitely value to a heavy process like the &lt;a href=&quot;http://www.rational.com/products/rup/index.jsp&quot;&gt;Rational Unified Process&lt;/a&gt; or &lt;a href=&quot;http://www.catalysis.org/&quot;&gt;Catalysis&lt;/a&gt;, small shops and teams just can&apos;t take on that kind of overhead most of the time.So, like my story about &quot;Testing Joys&quot; where I was able to get over that often difficult first hump from idea to realization through unit tests, today I &lt;em&gt;re-experienced&lt;/em&gt; the same thing with a quick model.  And I emphasize re-experienced, because these feelings get lost quickly during the course of a project, where deadlines and other pressures often kill off even the best practices a developer tries to have.So, &quot;Agile Modeling&quot;.  Today is actually the first time I&apos;ve read about it at all, besides seeing the book title.  And I don&apos;t claim to follow any of their practices fully.  I just like the general idea.  Modeling is about &lt;em&gt;communication&lt;/em&gt;.  Sometimes that communication is in the form of ideas of how a system could be shaped.  Sometimes that communication is in the form of details about how a system &lt;u&gt;is&lt;/u&gt; shaped.  And often, a tool can be too rigid which gets in the way of the &quot;shaping of ideas&quot;, or it can be too typecast to a particular language or target environment to accurately express the details of what has been/is being produced.The latter bullet has gotten in my way plenty of times.  Few tools support Python concepts.  Fewer still support Zope-ish ones.  At &lt;a href=&quot;http://www.zope.com/&quot;&gt;Zope Corp&lt;/a&gt;, we were never able to come up with a really good system that would let an engineer jump right in easily, even using a Python friendly tool like &lt;a href=&quot;http://www.objectdomain.com/&quot;&gt;Object Domain&lt;/a&gt;.  Furthermore, many UML tools available for the Mac OS are either pure Java, or some other cross-platform compilation, making them awkward to use on a Mac.So where does my take on &quot;Agile Modeling&quot; come in?  Usually, I need diagrams most for sketching out ideas about a schema design or workflow model.  A tool like &lt;strong&gt;OmniGraffle&lt;/strong&gt; makes this easy, since it&apos;s really a very basic diagramming tool.  And that&apos;s its strength.  &lt;a href=&quot;http://www.microsoft.com/office/visio/&quot;&gt;Visio&lt;/a&gt; and &lt;a href=&quot;http://www.conceptdraw.com/&quot;&gt;Concept Draw&lt;/a&gt; are both expansive diagramming tools, with more flexibility than their Pure-UML/CASE tool counterparts, but they&apos;re still too heavyweight.  The learning curve is probably too steep for a developer to pick up quickly enough to do something like capture a schema concepts off of a white board.  And still other tools, like &lt;a href=&quot;http://www.adobe.com/illustrator/&quot;&gt;Illustrator&lt;/a&gt; are too design focused to be used quickly for technical diagrams.  OmniGraffle seems to get it just right.  It has plenty of built in &lt;em&gt;Palettes&lt;/em&gt; of usable objects, which are often simple shapes or compounds of simple shapes.  It includes a UML palette, with various UML objects and connectors.  And, it&apos;s Mac OS X native, meaning most expected shortcuts (option-click-drag to duplicate) work as expected.  Since it&apos;s not a die-hard UML tool, it doesn&apos;t try to do any sort of type-enforcement and it doesn&apos;t present rich dialog boxes or property inspectors to fill in special properties about a class or a method.  The parts of a UML Class object are just boxes with text in them that are freely editable.  This is very good for rapid, er, &quot;Agile&quot; modeling situations, like being in a meeting and trying to capture whiteboard notes that don&apos;t necessarily fit in an outliner, or working on a diagram while meeting a perspective client while he&apos;s talking to someone else.  A fast, flexible tool that gives you just enough features to communicate a design to a boss, coworker, client, customer, or general public...where can it go wrong?It can go wrong when it comes to handling large models.  A pure UML tool, or advanced diagramming tool like Visio, can attach a lot of smart data to a visual representation.  Behind a UML Class object on a diagram can be all sorts of data, such as public/private member settings, where the class resides, OCL constraints, relationships, etcetera.  All of this data can be used in another diagram in the same model, but with different visual representations.  And, in theory, the data could be used to generate code from models.  Documentation can also be auto-generated from all of this extra data in a model.But, since code and models can get out of sync with each other rather quickly, it&apos;s sometimes still best to go couple &quot;Agile Modeling&quot; practices with &quot;Extreme Programming&quot; - keep the code clean and clear enough so that it can communicate the grand design on its own, and use models to express fundamental relationships, schemas, activities, or other aspects of the system before, during, and after the development process.  You rarely &lt;em&gt;need&lt;/em&gt; anything heavier than that.The ultimate point of this rambling post - the diagram I was able to throw together today based on our whiteboard meeting immediately drew expressions of &quot;can I get a printout of that?&quot;.  Since I was able to keep up with the meeting and design as it was happening, instead of wrestling with the tool, the results were on target even though the design was in flux throughout the meeting.  Then, without too much effort, I was able to tweak the diagram after I got back to my desk to better communicate relationships between objects, with very little fuss from the program.  And since it was so quick to start up, work on, and print out, I have no real strong ties to it - I know that changes to the design will be easy to record and reflect, and not take up too much of my time away from producing the software I&apos;m expected to produce.  This ultimately means that I&apos;m more likely to either keep the diagram up to date, or discard it when it&apos;s no longer needed.  This is in contrast to trying to enforce heavier process guidelines on myself, causing me to have to do big &quot;hat switches&quot; to shift from modeling mode, to coding mode, and back again - usually grumbling about &quot;ugh, I have to update the model now..&quot;.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/15.html#a104</guid>			<pubDate>Thu, 16 May 2002 02:17:56 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=104&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F15.html%23a104</comments>			</item>		<item>			<title>Marshalling - the good point of XML-RPC and SOAP.</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/05/07.html#a92</link>			<description>Looking back at &lt;a href=&quot;http://radio.weblogs.com/0101679/&quot;&gt;Sam Ruby&lt;/a&gt;&apos;s article, &lt;a href=&quot;http://www.oreillynet.com/cs/weblog/view/wlg/1351&quot;&gt;Google&apos;s Genius&lt;/a&gt;, he mentions my favorite point in favor of SOAP/RPC:&lt;blockquote cite=&quot;http://www.oreillynet.com/cs/weblog/view/wlg/1351&quot;&gt;Perhaps the most illumining part of Paul&apos;s essay is when he describes his optimized doSpellingSuggestion API.&amp;nbsp; In this case, he declares that XML is overkill for the job.&amp;nbsp; Unquestionably, omitting XML in some cases creates a tighter data stream.&amp;nbsp; It can also require custom marshallers and parsers to be written.&amp;nbsp; More tradeoffs to consider.&lt;/blockquote&gt;The second to last sentence is important.  In my view, XML &quot;scraping&quot; is not much better than HTML &quot;scraping&quot;.  The Google API&apos;s were immediately usable in everything from Ruby to Python to AppleScript to Frontier/Radio, and more, with only a SOAP library needed - nothing specific to Google.  The calls were Google specific, yes, but the client immediately understood the results of the call.Even though it&apos;s a silly application, I would never have even attempted to write something like &lt;strong&gt;HyprSwank&lt;/strong&gt;, as mentioned in &quot;AppleScript Studio, XML-RPC, and Zope&quot;, if I had to parse the results out of my data structure myself.  I&apos;m not sure what XML parsing libraries even exist for AppleScript, but I&apos;m sure if they do (or were to) exist, it couldn&apos;t be any easier to use than:&lt;tt&gt;tell application &quot;http://euc.cx/&quot; to set link_list to call xmlrpc {method name:&quot;hyprSWNK&quot;, parameters:{}}&lt;/tt&gt;Or in Python:&lt;pre&gt;import xmlprclib, pprintlink_list = xmlrpclib.ServerProxy(&apos;&lt;a href=&quot;http://euc.cx/&quot;&gt;http://euc.cx/&lt;/a&gt;&apos;).hyprSWNK()pprint.pprint(link_list)[{&apos;sitename&apos;: &apos;mobileffe&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://www.mobileffe.com/&quot;&gt;http://www.mobileffe.com/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;Prada&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://www.prada.com/&quot;&gt;http://www.prada.com/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;ACFny&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://www.acfny.org/&quot;&gt;http://www.acfny.org/&lt;/a&gt;&apos;}, {&apos;link&apos;: &apos;&lt;a href=&quot;http://www.peopleusedtodream&quot;&gt;http://www.peopleusedtodream&lt;/a&gt;&apos;,  &apos;sitename&apos;: &apos;People Used To Dream About The Future&apos;}, {&apos;sitename&apos;: &apos;David Lynch&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://www.davidlynch.com/&quot;&gt;http://www.davidlynch.com/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;.tiln&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://tiln.net/&quot;&gt;http://tiln.net/&lt;/a&gt;&apos;}, {&apos;link&apos;: &apos;&lt;a href=&quot;http://www.timecube.com/&quot;&gt;http://www.timecube.com/&lt;/a&gt;&apos;,  &apos;sitename&apos;: &apos;educated people are stupid cowards&apos;}, {&apos;link&apos;: &apos;&lt;a href=&quot;http://www.antigirl.com/&quot;&gt;http://www.antigirl.com/&lt;/a&gt;&apos;,  &apos;sitename&apos;: &apos;absolut antigirl !(absolut cybele)&apos;}, {&apos;sitename&apos;: &apos;no ~ type&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://www.notype.com/&quot;&gt;http://www.notype.com/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;meta.am +=&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://meta.am/&quot;&gt;http://meta.am/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;fals.ch&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://fals.ch/&quot;&gt;http://fals.ch/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;infotron&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://infotron.web.fm&quot;&gt;http://infotron.web.fm&lt;/a&gt;&apos;}, {&apos;link&apos;: &apos;&lt;a href=&quot;http://www.m9ndfukc.org/korporat/&quot;&gt;http://www.m9ndfukc.org/korporat/&lt;/a&gt;&apos;,  &apos;sitename&apos;: &apos;aaaaaaa n t i o r   p;uss&apos;}, {&apos;sitename&apos;: &apos;nato0+55+3d&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://www.eusocial.org/&quot;&gt;http://www.eusocial.org/&lt;/a&gt;&apos;}, {&apos;link&apos;: &apos;&lt;a href=&quot;http://www.angelfire.com/electronic/campmsp/&quot;&gt;http://www.angelfire.com/electronic/campmsp/&lt;/a&gt;&apos;,  &apos;sitename&apos;: &apos;themoonstealingproject&apos;}, {&apos;link&apos;: &apos;&lt;a href=&quot;http://artists.mp3s.com/artists/42/musiquemotpol.html&quot;&gt;http://artists.mp3s.com/artists/42/musiquemotpol.html&lt;/a&gt;&apos;,  &apos;sitename&apos;: &apos;musique:motpol @ mp3.com&apos;}, {&apos;link&apos;: &apos;&lt;a href=&quot;http://www.helmutlang.com/&quot;&gt;http://www.helmutlang.com/&lt;/a&gt;&apos;,  &apos;sitename&apos;: &apos;finest cotton armbags since 1997 (HL)&apos;}, {&apos;sitename&apos;: &apos;One Bit Louder&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://mi.cz/obl/&quot;&gt;http://mi.cz/obl/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;purple&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://purple.fr/&quot;&gt;http://purple.fr/&lt;/a&gt;&apos;}, {&apos;sitename&apos;: &apos;OFRPublications&apos;, &apos;link&apos;: &apos;&lt;a href=&quot;http://www.ofrpublications.com/&quot;&gt;http://www.ofrpublications.com/&lt;/a&gt;&apos;}]&lt;/pre&gt;While I could have written my own parser, written my own format, or spent time researching common XML formats and then scouring the web for an already written parser for my language or sitting down with a copy of &quot;XML and Python&quot;, I chose not to.For as much as I rag sometimes on some of XML-RPC&apos;s shortfalls, it&apos;s much better than doing all of that!  It gives one common format for a common internet use, and has spread around to many languages.  If I had to write my parser, or wait for someone to write one, or deal with DOM navigation, in order to deal with GoogleML, I&apos;d be much less curious about &quot;hmm, what can I write today to take advantage of that?&quot;.A nice thing that Bobo got right from day one was to implement and handle marshalling of incoming HTTP requests in such a way that my code never has to go through a &quot;is it a list?  is it a string?  is it a string I can convert to a list?&quot; somersault again.  Or at least, not often.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/07.html#a92</guid>			<pubDate>Tue, 07 May 2002 23:07:28 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=92&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F07.html%23a92</comments>			</item>		<item>			<title>Fun With Generators</title>			<link>http://www.deadlybloodyserious.com/Python/2002/05/02.html</link>			<description>&quot;The great thing about this arrangement is that I can substitute a different block generating function with zero effort, as sizeAndDigest doesn&apos;t need to know how its data is being generated. I could have done that with saved state and a callback to get the next chunk of data, but generators are a lot simpler.&quot; [&lt;a href=&quot;http://www.deadlybloodyserious.com/&quot;&gt;Deadly Bloody Serious&lt;/a&gt;]</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/06.html#a87</guid>			<pubDate>Mon, 06 May 2002 20:50:55 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=87&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F06.html%23a87</comments>			</item>		<item>			<title>Python Generators</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/05/06.html#a84</link>			<description>There&apos;s a post on &lt;a href=&quot;http://lambda.weblogs.com/&quot;&gt;Lambda the Ultimate&lt;/a&gt; &lt;a href=&quot;http://lambda.weblogs.com/2002/05/06&quot;&gt;today&lt;/a&gt; about &lt;em&gt;Generators and Abstraction&lt;/em&gt;, with reference to &quot;Python&quot;.   &lt;a href=&quot;http://www.ruby-lang.org/&quot;&gt;Ruby&lt;/a&gt; has the concept of generators built in from the ground up.  Last summer, I came across Ruby and started playing around with it, and annoyed everyone around me (I was working for &lt;a href=&quot;http://www.zope.com/&quot;&gt;Zope Corporation&lt;/a&gt; who own PythonLabs) by going on and on about Ruby&apos;s object model and generators.While I&apos;m sure my little rants had little or nothing to do with the course of Python 2.2, it is nice to see Python picking up on simple generators, iterators, and the whole &lt;em&gt;new classes&lt;/em&gt; thing.  It has me excited about Python again.An interesting show of the power of generators and iterators comes from &lt;a href=&quot;http://www.python.org/peps/pep-0279.html&quot;&gt;PEP 279&lt;/a&gt;, &lt;em&gt;The enumerate() built-in function&lt;/em&gt;.  It&apos;s a new built in function that gives to all collections (anything iterable) functionality similar to dict.items() (more specifically, &lt;em&gt;dict.iteritems()&lt;/em&gt;) which loops over the keys (index) and values (item) of a dictionary.  This example, from the PEP itself, shows a good use of generators and iterators in action, keeping evaluation of a loop lazy while being able to index it:&lt;pre&gt;def enumerate(collection):    &apos;Generates an indexed series:  (0,coll[0]), (1,coll[1]) ...&apos;         i = 0    it = iter(collection)    while 1:        yield (i, it.next())        i += 1&lt;/pre&gt;</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/06.html#a84</guid>			<pubDate>Mon, 06 May 2002 15:51:39 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=84&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F06.html%23a84</comments>			</item>		<item>			<title>Boolean type for Python 2.3</title>			<link>http://www.python.org/peps/pep-0285.html</link>			<description>I should pay attention to the comp.lang.python mailing list more often, but Usenet newsgroups seem to be a much bigger pain in the ass in these days of Broadband - it&apos;s hard to know whether your provider, or your providers provider, will really offer any usenet service.Anyways, &lt;a href=&quot;http://www.python.org/peps/pep-0285.html&quot;&gt;PEP 285&lt;/a&gt; brings about &lt;tt&gt;True&lt;/tt&gt; and &lt;tt&gt;False&lt;/tt&gt; to the Python language as natural members for the first time.  One of the areas this will help in is the reduction of code like this:&lt;tt&gt;return not not foo           &lt;em&gt;#the twin &apos;not not&apos; keywords cast foo into a boolean statement&lt;/em&gt;&lt;/tt&gt;and replace it with:&lt;tt&gt;return bool(foo)&lt;/tt&gt;Which, while brief, avoids the headslam that boolean logic games like &apos;not not&apos; can be.  One place this will be especially beneficial is with XML-RPC and SOAP, and other means of communicating with languages that have (and expect!) booleans.  It&apos;s been sufficient so far in Python to use any true value or any false value for boolean use, and 1 and 0 for basic usage, but that&apos;s hard to communicate over the wire.  A Python function may return &apos;1&apos; as an integer value.  But it can also be returning &apos;1&apos; to indicate truth (as in predicates like &apos;isinstance()&apos;).So... Interesting.  Never even knew it was up for debate, let alone accepted.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/06.html#a83</guid>			<pubDate>Mon, 06 May 2002 09:19:10 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=83&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F06.html%23a83</comments>			</item>		<item>			<title>Another Python Web Service package.</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/05/05.html#a81</link>			<description>A seemingly forgotten &lt;a href=&quot;http://cvs.zope.org/Packages/WebService/&quot;&gt;Web Service&lt;/a&gt; package for Python.  Even its developer seems to have left it alone for a while.  It was to be part of Web Service support for &quot;Zope&quot;, which has yet to materialize.Anyways, this is an interesting package to look at.  It&apos;s the most complete of the few SOAP + Friends packages I&apos;ve looked at for Python, with deep support for WSDL Reading and Writing among other things.  It&apos;s powerful, flexible, yet still easy to use.  And, it mostly works.  Whether or not it continues to be developed, it&apos;s a good Python package design that&apos;s worth looking at.</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/05.html#a81</guid>			<pubDate>Sun, 05 May 2002 11:07:58 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=81&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F05.html%23a81</comments>			</item>		<item>			<title>Verbosity and Web Services, again.  Does Dave Winer really get it?</title>			<link>http://radio.weblogs.com/0106123/categories/python/2002/05/04.html#a78</link>			<description>&lt;em&gt;Forward: a few hours ago, after getting home from dinner with friends, I was reading more on Web Services, and found this article on &lt;a href=&quot;http://www.onlamp.com/pub/a/python/2002/05/02/pythonnews.html&quot;&gt;Wrapping Web Service APIs&lt;/a&gt; on ORN by Stephan Figgins.  It somehow led me back to an old &lt;a href=&quot;http://www.scripting.com/&quot;&gt;Scripting News&lt;/a&gt; post that somewhat rankled me when I first read it.  I&apos;m finally posting my response.  At 2AM, saturday morning.&lt;/em&gt;Does Dave Winer get Web Services?  &lt;a href=&quot;http://scriptingnews.userland.com/backissues/2002/01/31#lcf476f93cdaa0beda2b0497b10177006&quot;&gt;This posting&lt;/a&gt; talks about the overhead involved in publishing a web service via .NET.  I admit, my experience with Radio and Frontier is still very small.  But, at least with &quot;Radio&quot;, you have to write your Web Services script in a special folder, &lt;em&gt;Web Services&lt;/em&gt;.  How is &lt;em&gt;that&lt;/em&gt; not overhead?  Now, you&apos;re writing a single script adapter to another part of the system in order to publish it on the web services channel.  This may make sense in an environment based on pure scripting, but what about real persistent objects that are already on the web - objects that are both Data and Behavior?  &quot;Zope&quot;, and Bobo before it, have been built on this concept from day one.Many a year ago, Amos Lattier wrote an article called &lt;a href=&quot;http://starship.python.net/crew/amos/bobo_way.html&quot;&gt;The Bobo Way&lt;/a&gt;.  I&apos;m going to quote his article here, because (as I&apos;ve said before), this sounds like familiar ground: &lt;blockquote&gt;For example if your app keeps track of company employees, you will probably want a separate Employee object for each employee. That way you can access these objects with URLs like:&lt;tt&gt;/Employees/amos/set_menu?lunch=spam&lt;/tt&gt;This URL assumes that Employees is a mapping object that contains Employee objects. Employees[&quot;amos&quot;] is an Employee object that represents the amos employee. The above URL calls amos&apos; set_menu method with lunch=spam for arguments:&lt;tt&gt;Employees[&quot;amos&quot;].set_menu(lunch=spam)&lt;/tt&gt;&lt;br&gt;&lt;em&gt;Ed: this could also be &lt;tt&gt;Employees.amos.set_menu(lunch=spam)&lt;/tt&gt;&lt;/em&gt;For contrast lets look at a non-bobo way of doing the same thing:&lt;tt&gt;/set_menu.py?empid=amos&amp;meal=lunch&amp;food=spam&lt;/tt&gt;&lt;/blockquote&gt;It seems to me like an awful lot of XML-RPC interfaces are not much better than this last example.  They&apos;re usually a single function that is handed some sort of key to operate on another object with, rather than going to that object directly.  It defeats polymorphism, it defeats generalization, and ultimately it can lead to a large and unwieldy adapter layer, tucked away in a Web Services directory somewhere.There are merits to this design.  You are basically writing an Adapter pattern of sorts, mapping a Web Service friendly interface into whatever the internal system really has.  And, if that&apos;s the only gateway into your system from the outside, you have some level of security by limiting the amount of access to a collection of XML-RPC dedicated functions instead of opening up access to every potential object.But there are merits to the other design too.  In theory, you can program Zope the same way on the inside as on the outside, so long as you have the credential to do so.  You have instances of classes out there, on the web, already.  .NET seems to be following this route somewhat.  Doing Web Services by this route is scarier.  Why?  Security for one reason.  And, you just don&apos;t want to turn every single method on the object to be callable over the web, or - at the very least - you want to attach conditions.  This is what Microsoft is doing.  Let&apos;s look at how a simple &apos;return hello&apos; class for Zope looks, disregarding any Zope OFS framework stuff (making the class addable through the web interface).  Putting an instance of this class in a Zope tree would yield the same results over XML-RPC as calls to &lt;a href=&quot;http://radio.weblogs.com/0001015/images/2002/01/31/dotnetexample.gif&quot;&gt;this .NET example&lt;/a&gt; would:&lt;pre&gt;from Security import ClassSecurityInfofrom Persistence import Persistentfrom Globals import InitializeClass class Hello(Persistent):    security = ClassSecurityInfo()      #Used to do declarative security     security.declareObjectPublic()      #Make these objects inherently public     security.declarePublic(&apos;sayHello&apos;)  #And make this method public    def sayHello(self, name):       &quot;&quot;&quot; Say hello to &apos;name&apos; &quot;&quot;&quot;       return &quot;Hello %s&quot; % nameInitializeClass(Hello)                  #This processes the security declarations&lt;/pre&gt;Now, it&apos;s about the same overhead as the Microsoft ASP.NET example.  &lt;em&gt;note: There&apos;s more overhead involved with Zope itself in order to fit the Hello class into the Zope framework, but this is purely an example.  This could have been easily written as a Python Script object, where the security settings could be set through a web UI.&lt;/em&gt;.  Why do all this?  Because web services as API&apos;s are ultimately programmatically exposed.  There are two ways this is done:&lt;ol&gt;&lt;li&gt;Declarations, either in code or configuration (ie, xml) files.&lt;/li&gt;&lt;li&gt;Writing separate handlers, and only exposing those to the web&lt;/li&gt;&lt;/ol&gt;The first is the &quot;Zope&quot; way, and apparently the .NET way.  At some point, you&apos;re taking code that exists already and saying &quot;yes, this is a web service&quot;.  The second seems to be the Radio way, where you write a script that calls into other existing code, and say &quot;this script is the web service&quot;.Sometimes, the amount of overhead is equal.  But I think relegating all Web Services to being scripts and functions in a special folder or singleton object weakens their potential.  Likewise, not all existing web-published code is ready to be made into a Web Service.  Both ways are valid.  But, there&apos;s got to be a better unification.  Dave needs to understand the declarative way.  It may look more verbose on a silly little Hello World example, but I have access to thousands of methods exposed via XML-RPC that are done so automatically via Zope&apos;s similar security declarations.  That&apos;s a lot more than I&apos;d have access to if I have to write those methods in a special place.So, here&apos;s another verbosity example.  Let&apos;s say there&apos;s the following bit of code in a Blog Entry class:&lt;pre&gt;class BlogEntry(...):   security.declareProtected(&apos;Edit Entries&apos;, &apos;editPost&apos;)   def editPost(self, content, publish=0):      &quot;&quot;&quot; Set the content of the post, and publishes it if publish is true &quot;&quot;&quot;      self._content = content      if publish:          self._publishedContent = content      return &quot;OK&quot;      #simple return value&lt;/pre&gt;And, for simplicities sake, lets say we had a flat structure for all entries to make URL&apos;s easier, and we have an entry identified as &apos;123&apos;.  So, to edit it via URL.  Hmm, this is almost REST-like:&lt;tt&gt;.../Posts/123/editPost?content=boy+howdy&amp;publish:int=1&lt;/tt&gt;And do to it via BCI (ZPublisher.Client):&lt;pre&gt;myPost = ZPublisher.Object(&apos;.../Posts/123&apos;, username=&apos;bob&apos;, password=&apos;bobby&apos;)myPost.editPost(content=&apos;Boy howdy!&apos;, publish=1)&lt;/pre&gt;And XML-RPC in Python.  Note that in order to do this, due to Zope&apos;s built in security, you either have to have a hacked XML-RPC library locally that generates authentication headers, of have &lt;a href=&quot;http://www.zope.org/Members/natesain/RPCAuth&quot;&gt;RPCAuth&lt;/a&gt; by Nathan Sain (which I haven&apos;t had time to test yet) installed on Zope:&lt;pre&gt;myPost = xmlrpclib.Server(&apos;.../Posts/123&apos;)myPost.editPost(&apos;Boy Howdy!&apos;, 1))&lt;/pre&gt;These are very similar, but ZPublisher.Client was doing this long before XML-RPC.  Why?  Because Zope was already doing distributed objects (of sorts) on the web, translating HTTP requests into object calls.  It only makes sense that there be some simple client lib.Now, to implement this as a proper Blogger API, and do it the way that Radio style web services are done, instead of necessarily having all of those security declarations on the BlogPost class itself, I would instead have to write this:&lt;pre&gt;def editPost(appkey, postid, username, password, content, publish):  &quot;&quot;&quot; Lookup the post by its ID, verify that the user can access it,      and set its content and published flag &quot;&quot;&quot;  thePost = Posts[postid]  ## security assertions based on username/password would go in here, somehow.  thePost.editPost(content=content, publish=publish)  return 1&lt;/pre&gt;Now, this isn&apos;t too bad.  But, it&apos;s a similar amount of overhead to turn an otherwise already existing published web method as a Web Service.  Huh.As people start exposing ever more valuable resources as Web Services, or even REST, it&apos;s no wonder complications arise.  As we move beyond the &apos;getStateName&apos; example and start getting into exchanging business data (Microsoft&apos;s heavily advertised 1 degree of separation), more care must be taken.  I don&apos;t want everything I write automatically turned into a Web Service.  I don&apos;t necessarily want to have to write extra adapters either.To sum up and say it all over again, the way that &quot;Radio&quot; seems to promote for Web Services is easy.  And simple.  But you&apos;re effectively writing scripted adapters and bridges into other code, something that could turn out to be a maintenance nightmare.  The way that &quot;Zope&quot; has promoted for years (even though it&apos;s not a terrific Web Services player, sadly) says that &quot;Objects and their methods are already published on the web.  No gateway scripts needed.&quot;, but with that comes the price of maintaining security declarations similar to C#.NET&apos;s ASPX&apos;s declarative Web Service calls.  Dave calls the latter too much overhead.  I say it&apos;s the other way around.  It should be easy to write Web Services, but you should have to think about what you publish.  Those declarations aren&apos;t much worse anyways than the long signatures verbose languages like Java can make you write (&lt;tt&gt;protected final synchronous int Bob()&lt;/tt&gt;).</description>			<guid>http://radio.weblogs.com/0106123/categories/python/2002/05/04.html#a78</guid>			<pubDate>Sat, 04 May 2002 09:07:25 GMT</pubDate>			<comments>http://radiocomments.userland.com/comments?u=106123&amp;amp;p=78&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0106123%2F2002%2F05%2F04.html%23a78</comments>			</item>		</channel>	</rss>