Python Programming, news on the Voidspace Python Projects and all things techie.

Introduction to OOP

emoticon:paper I've put a new tutorial online. This is Introduction to OOP with Python.

It's a tutorial for beginners - and covers objects, classes, etc. It's totally Python-centric, so it's not a theoretical tutorial, but an introduction to the OOP features of Python.

There are still a few rough edges to sort (a couple of the sidebars need finishing and I really ought to flesh out a couple of the advanced subjects) - but it's already usable.

Anyway, I hope someone finds it useful, and I welcome feedback.

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-11-11 09:40:59 | |

Categories: , ,

Python Search Engine

emoticon:globesearch I've been hacking around with the Yahoo Search API. It returns results a lot faster than the google one.

I've put together (by fair means and foul) a list of nearly nine hundred domains relevant to Python programming.

I've also cobbled together a CGI search engine that only returns results from a specific set of domains.

Try the Python Search Engine.

It's only a bit of fun - but it does mean that with a list of relevant domains you can roll your own search engine. Smile

At some point I'll package the source code for you all to play with....

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-11-09 12:44:04 | |

Categories: , ,

Twisted Network and Other Mega Frameworks

Very Happy My new copy of Twisted Network Programming Essentials has just arrived. It's time to get Twisted...

Whilst we're on the subject, I'll jump on the "discussing web frameworks" bandwagon. Razz

It's nice to watch (from afar) the progress on Python web frameworks. It's also good to see the Python community efforts accrete round a few good products. I think Zope, Django, and Turbogears all serve different portions of the market - so they're not necessarily direct competitors.

Subway seems very similar to Turbogears - but despite being older, never got the same publicity. Then there are smaller projects like Karrigell that can still thrive if they present a simpler learning curve for people building small projects. [1]

What the larger of these frameworks all have in common [2], is that they're multi-threaded solutions. It amazes me that no-one has built a framework on top of Twisted.

It looks there might now be a partial solution in the form of Mantissa from the Divmod folks. This describes itself as an "application server", which is good start. Smile

I don't know how re-usable this is going to be, as it's targeted for the particular needs of Divmod.

It doesn't include the bells and whistles of other projects. Things like AJAX can be done through Nevow's livepage. This may not work with Mantissa - and by all accounts is not as good as the Turbogears offering (which uses the allegedly excellent Mochikit).

I'm also uncertain of how Twisted would work with SQLObject which I believe is synchronous: I don't know what the best [3] database system for use with Twisted is.

[1]I'm sure there are a host of other ones as well. I'm simply rattling through the ones I'm aware of.
[2]Karrigell being an exception - offering an asynchronous and a threaded version of its built in server.
[3]Read most scalable and Pythonic.

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-11-07 09:37:20 | |


ConfigObj in Bazaar

emoticon:envelope A couple (or so) of pieces of ConfigObj related news.

I've just discovered that ConfigObj is in bazaar 0.6 (the Python distributed VCS). It's used to read bazaar.conf and branches.conf.

This is a high profile project - so it's nice to see ConfigObj being used.

ConfigObj continues to be pretty popular - ConfigObj and pythonutils (which contains ConfigObj) get at least ten downloads a day via voidspace [1]. Based on my own habits I use about one in thirty of the interesting code/projects that I download. That means a new user every three days.

I've also just received and squashed a bug report. There was a bug in the walk section method - if you use walk to change member names. It's now fixed. Smile

It's highlighted a nice use-case for walk, which I wasn't sure if anyone would use at all. You can create a template config file with placeholders in names and values. When you need to create a new config file (E.g. to add a new user to an application) you can use walk to replace the placeholders with appropriate values in member names, section names, and values.

# We use 'XXXX' as a placeholder
# config is our template config file
config = '''
XXXXkey1 = XXXXvalue1
XXXXkey2 = XXXXvalue2
XXXXkey3 = XXXXvalue3
XXXXkey1 = XXXXvalue1
XXXXkey2 = XXXXvalue2
XXXXkey3 = XXXXvalue3
XXXXkey1 = XXXXvalue1
XXXXkey2 = XXXXvalue2
XXXXkey3 = XXXXvalue3
    XXXXkey1 = XXXXvalue1
    XXXXkey2 = XXXXvalue2
    XXXXkey3 = XXXXvalue3
# create a config object
# normally we'd read from a file to do this
cfg = ConfigObj(config)
# this is our function that does replacement
# in the config file
def transform(section, key):
    val = section[key]
    # change the member name
    newkey = key.replace('XXXX', 'CLIENT1')
    section.rename(key, newkey)
    if isinstance(val, (tuple, list, dict)):
        # change the value - only if it isn't
        # a section (dict) or a list value
        val = val.replace('XXXX', 'CLIENT1')
        section[newkey] = val
cfg.walk(transform, call_on_sections=True)
print cfg
{'CLIENT1key1': 'CLIENT1value1', 'CLIENT1key2': 'CLIENT1value2',
'CLIENT1key3': 'CLIENT1value3',
'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1',
    'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'},
'CLIENT1section2': {'CLIENT1key1': 'CLIENT1value1',
    'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3',
    'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1',
        'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'}}}
# all the occurences of 'XXXX' have been changed
# let's save our new config file
cfg.filename = new_config_filename

(Thanks to M. Gehling for the bug report).

I've added an istrue section method. This will fetch string values as booleans. The following are interpreted as True (not case sensitive) :

true, yes, on, 1

The following are False :

false, no, off, 0

Anything else raises a ValueError.

We have also finally [2] resolved the issue with list_values=False. This is when ConfigObj doesn't parse values as list values. Previously when unquoting it could do the wrong thing. The quoting and unquoting was also causing a user some problems.

I've settled on a behaviour which solves both problems in one go. There is now a note in the docs which explains it :

The list_values attribute [and option] is True or False. If set to False then values are not parsed for list values. In addition single line values are not unquoted.

This allows you to do your own parsing of values. It exists primarily to support the reading of the configspec - but has other use cases.

For example you could use the LineParser from listquote to read values for nested lists.

Single line values aren't quoted when writing - but multiline values are handled as normal.


Because values aren't quoted when writing, leading or trailing whitespace can be lost.

This behaviour was changed in version 4.0.1.

Prior to this, single line values might have been quoted; even with list_values=False. This means that files written by ConfigObj could now be incompatible - and need the quotes removing by hand.

These changes are in the ConfigObj 4.0.1 release.

[1]Plus more from PyPi, sourceforge, gentoo-portage, etc. Very Happy
[2]Well I hope finally, so long as no-one objects to the change. Neutral

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-11-05 23:36:14 | |

Categories: ,

logintools Critical Bugfix

emoticon:bugs I recently updated logintools and jalopy to be compatible with the new pythonutils code. This was the 0.6.0 releases.

Embarrassingly, I didn't update the email calls to use the new function signature in cgiutils. Embarassed

New user sign-ups have been thoroughly broken since. sigh

The application I use logintools for doesn't allow new user signups. It only has administrator created accounts, so I didn't notice the broken code.

This is now fixed and anyone who wants jalopy or logintools to work should download the new release. Razz


Since the update, a fellow hacker has created the Hacker's Diet Tracker, which uses logintools. cool Very Happy

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-11-05 17:18:48 | |

Categories: , ,

rest2web Progress

emoticon:html The new standard functions and lots of docs changes are now in rest2web SVN.

I still haven't been able to cleanup the plugin API to my satisfaction. However, the doc refactor is nearly complete.

The version of rest2web in subversion has so many improvements over the 0.3.0 release that I'm going to do an interim 0.4.0 alpha release. This will allow me to get the new documentation online - and should hit the streets any day now.

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-11-05 16:36:03 | |

Categories: , ,

Python API Documentation

emoticon:beaker For a long time now, autobuilding API documentation from docstrings has been a well under served area in the Python repertoire.

There is one school of thought that says that auto-generated API documentation is not very useful. On the other hand, it can certainly be more useful than no documentation at all - in the open source world this is the all too common alternative.

In my (limited) experience, if you write docstrings deliberately as documentation then they can be useful. As usual clarity and quality of writing matter.

For those who have insisted on generating API docs. from docstrings - preferably using reST format - there has long been only one serious option. Epydoc is the de-facto system for generating HTML API docs from docstrings.

The output isn't bad and it does support reST. Unfortunately it seems to be unmaintained - and has begun the slow, graceless slide into bitrot. Bug reports go unreplied-to and patches remain resolutely unapplied.

Even worse, the GUI is built on top of wxPython. This is a great system [1], but previous API instability [2] means that many of the standard ways of doing things from wx 2.4 and 2.5 have been deprecated. Most programs created for these builds now issue a stream of warnings at runtime - and I guess will eventually just be broken. Sad


The Twisted crew apparently use a modified version of Epydoc - so perhaps all is not lost for it. I haven't seen anything emerge back from Twisted though.

Thankfully there is a new contender on the scene - the interesting sounding Pudge from the no less intriguing folks at

It's a serious tool and is integrated with the Kid Templating system. As it's at an early stage of development you can only fetch it using svn. It also uses setuptools [3] to install all the dependencies.

Like Epydoc, it works by importing modules and introspecting objects. This approach has pros and cons. For example it means documentation is likely to be arbitrarily ordered and it's hard to document constants in your code.

Over the weekend I had a play with pudge (under windows). My initial reaction ? I like it, a great deal Smile

This will be extremely useful for me - and save me creating my own system... Laughing

It doesn't seem to be 'production ready', but it may already be usable. My experimentation was a little inconclusive; I didn't touch the templating system which obviously vastly affects the quality of the results.

As you can see from the example on the homepage - the basic usage is very simple.

First I created my own bsd.rst license file in the module directory, and then followed the three steps to generate the documentation.

My generated index.html had no links on it and was marked up with old fashioned HTML 4.... It did include :

<DIV CLASS="rst-doc">


This probably means you need to provide a template to get any sensible result.

The generated file for my license was bsd.html. Every page says "This documentation is licensed under the BSD License". This links to : doc-license.html (not bsd.html), which didn't exist.

I also got the following error under windows :

Running 'F:\Python Projects\modules in progress\pudge\' ...
  File "<source>", line 8, in ?
  File "...pudge\", line 81, in generate
  File "...pudge\", line 217, in generate_source
    os.utime(dest_file, (-1, src_mtime))
OSError: [Errno 22] Invalid argument: '.\\'

Commenting out that line in generate_source results in a clean exit.

Definitely something I'll be using more.

[1]Even better if you use it via Wax.
[2]This is a faith statement that such instability is firmly in the past. Razz
[3]It's getting perilously close to the point where I'll have to explore setuptools for distributing my code. sigh

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-11-05 13:43:03 | |

Categories: ,

Hosted by Webfaction