Lars Wirzenius - log2
This is my web log. See also my old log.
While writing some code for EoC 2 to parse the command line, I needed
a generic way to find which command line options were set by the user.
That is, after I've parsed a command line, and have the return value
optparse.OptionParser.parse_args method, how do I find which
options were set?
The return value is an instance of
optparse.Values, which does not have
a convenient method for that. So what I do is this:
classattrs = dir(optparse.Values)
for name in [_ for _ in dir(options) if _ not in classattrs]:
print name, getattr(options, name)
Slightly tricky, and it may stop working in a future version if they change things in the in (undocumented, therefore private) interface, but it's nice to be able to work around library design warts like this when the language itself is nicely powerful.
The Finnish computer magazine Tietokone reports that the Finnish computer museum has received some funding to cover its rent. This means they will survive at least for the time being. This is a good thing.
The Debian Policy Manual specifies how Debian version numbers are
The specification is reasonably straightforward on the surface, but
there are a lot of details that need to be exactly right. The canonical
implementation of this comparision is
dpkg --compare-versions, but
it has been implemented in other places as well, for various reasons.
It strikes me that it would be cool to have a set of test cases that could be used to verify that all implementations of version number comparisons work the same way. I envision a file like this:
1 eq 1
1 lt 2
10 gt 2
1.1 lt 2
1 gt 0
1 eq 0:1
2 lt 1:0
1 lt 1-0
(For simplicity, let's assume the only relations are eq, lt, and gt.) An implementation of the version number comparison algorithm could use such a data set in its test suite.
A quick and dirty implementation for dpkg might look like this:
grep -vE '^:space:*(#.*)?$' "$@" |
while read v1 relation v2
if ! dpkg --compare-versions "$v1" "$relation" "$v2"
echo "Error: $v1 $relation $v2" 1>&2
I don't have time to think through all cases and construct a comprehensive set of test cases, but I think someone should do that.
At the last Free Thursday someone told me that Python list comprehensions leak variables. I didn't believe it, but after testing it quickly, it turns out to be true:
foo = [1, 2, 3]
bar = [x+1 for x in foo]
The above prints out "3". I would have expected it to give a NameError exception.
This turns out to be a known, and deprecated feature in Python 2.5 (see the reference manual), and it will probably be fixed in Python 3000, some time in the future.
Adeodato Simó, Stefano Zacchiroli, and myself discussed an idea for "Debian Enhancement Proposals" (DEPs) at the Debian QA meeting in Extremadura, Spain, in December. It took us a few weeks to finish the first public draft, but today it was posted to debian-project. Feedback would be welcome.
coverage.py (python-coverage package in Python) is a wonderful little tool for measuring which parts of your program are executed while you run it. It only measures at the statement level, but even that makes it quite useful when developing unit tests. Any code not covered by a unit test is obviously not being tested.
I've been using coverage.py since early this year. It's been pretty systematically the case that any code not being tested by my unit tests has at least an order of magnitude more bugs in it when it gets to production.
One thing I figured out was that it's even better if you structure you code and unit tests into pairs: the code in foo.py should be fully tested by the tests in foo_tests.py. To make this easier, I wrote a "test runner" which enforces this. It tests such pairs of modules and fails the test unless all statements in the code module are visited during the test.
I give you: CoverageTestRunner.
I've just uploaded it to Debian, so it should be through the NEW queue after some time.
The Debian listmasters have just created the debian-photo mailing list, based on a suggestion from Wouter Verhelst and myself. Subscriptions are open and seem to work, so now it's time to start discussion. (I'll wait a few days first, though, before posting the first time, to let other people subscribe, too.)
Enemies of Carlotta, my little mailing list manager, now has a wiki, courtesy of Michael Durgener. It also has its own domain, courtesy of Andreas Barth. See: http://www.e-o-c.org/.
There is also now a mailing list for commits to the EoC 2 development
branch. To subscribe, e-mail
I've started a new blog at http://blog.liw.fi so please update your feed readers and bookmarks, if you want to continue following this.
I'm not going to be moving old content to the new place. The old content will stay online at the old place.
Unperish is my little script for automating the process of releasing software. I just pushed out version 2.2, which fixes the --pbuilder-basetgz option. I have not mentioned 2.1 anywhere, since my web log wasn't working at the time, so I'll mention it here, too: it adds Subversion support, plus hides internal options from the --help output.
Some day soon I hope to add Git support, too, but first I'll have to learn Git.