In the beginning Guido created Python. Now Python was formless and empty, duplicate code was over the surface of programs. And Guido said, “Let there be modules” and there were modules. Guido saw that the modules were good, and he separated them from the programs. Guido called them the “standard library”. And there was the library, and there was the program – the first abstraction.
Now, not all of us are lucky enough to be able to toss things into the Python stdlib. The practice has arisen in Twisted to take functionality that is generally useful – not specific to Twisted – and place it in the twisted.python
package. There’s an option parser and file path manipulation functions and so forth. This works okay for Twisted development, but the code can’t really be re-used without creating a Twisted dependency (which is okay by me, mind you, but I hear it’s inconvenient for some other people). Later, at Divmod, a similar derivative practice became common. Common functionality that wasn’t really specific to our projects was aggregated in a module named atop.tpython
– the “tpython” being short for, of course, twisted.python
. So now we’re two levels abstracted from where we really want to be.
Well, a new day is upon us. Divmod has now released Epsilon, a package for some generally useful code that others might find handy. This first release, 0.1.0, has two major offerings and a few more minor ones.
First, there’s epsilon.extime
, a module which offers conversion to and from a variety of time formats: RFC 2822 formatted dates, POSIX timestamps, datetime objects, struct_time objects, ISO8601 formatted timestamps, and a particular context-aware format known as the “human readable format”. Additionally, it offers a Time class which can be constructed from or converted to any of these formats, as well as have certain date math performed on it. Here’s a brief sample:
>>> from epsilon.extime import Time >>> Time().asDatetime() datetime.datetime( 2005, 10, 12, 4, 52, 8, 237248, tzinfo=<epsilon.extime.FixedOffset object at 0x-4860a234 offset datetime.timedelta(0)>) >>> Time().asISO8601TimeAndDate() '2005-10-12T04:52:29.485647+00:00' >>> Time.fromISO8601TimeAndDate('2005-10-12T04:52:29.485647+00:00').asHumanly() '04:52 am' >>> import datetime >>> (Time() + datetime.timedelta(days=2)).asHumanly() '14 Oct, 04:53 am' >>>
Next up is epsilon.cooperator
. This provides a scheduler for tasks implemented as iterators. It offers full Deferred support and hooks for scheduling behavior. In particular, it can be used when it’s possible for so many tasks to be running concurrently that to allow them all to set their own pace would damage interactive performance: here it slows things down and makes sure new events can be processed. With a little creativity, it can also be used to group or prioritize tasks.
The remaining features include a setup hook for Twisted applications which install plugins to cause the distutils process to regenerate the plugin cache, a class for simplifying providing multiple listeners with the result of a Deferred, and a structured Version class with special SVN integration (for example,
$ python -c 'from epsilon import version; print version' [epsilon, version 0.1.0 (SVN r529)]
showing that I have something at least as new as Epsilon 0.1.0 installed, and it is being imported from an SVN checkout at revision 529).
Divmod’s Wiki has an Epsilon project page at http://divmod.org/trac/wiki/EpsilonProject.