$ time python -c "import syck; syck.load(file('yaml').read())"
real 0m2.255s
user 0m1.572s
sys 0m0.088s
$ time ruby -ryaml -e "YAML.load(File.open('yaml'))"
real 0m9.455s
user 0m7.984s
sys 0m0.080s
the fruity and personal webpage of armin ronacher
$ time python -c "import syck; syck.load(file('yaml').read())"
real 0m2.255s
user 0m1.572s
sys 0m0.088s
$ time ruby -ryaml -e "YAML.load(File.open('yaml'))"
real 0m9.455s
user 0m7.984s
sys 0m0.080s
With this in mind I was looking for a way to rehash a dict in python. Things that do not work: d = dict(d) and d.update(d) because the first copies the structure of the dict over, the second does nothing because the dict is the merged dict. What works is d.update(d.iteritems())
asirra — Asirra is a human interactive proof that asks users to identify photos of cats and dogs. It’s powered by over two million photos from our unique partnership with Petfinder.com.
“Es hat niemand vor, einen Überwachungsstaat in Deutschland zu errichten” — Wolfgang Bosbach
I now pushed Jinja 1.1 into feature freeze. The trunk is now only used to improve stability, write some more unittests and fix spelling mistakes and stuff like that in the documentation. You can expect a release in about one week.
The changelog so far is huge and the items here are only a very, very short summary with the most important things.
The probably biggest change is the support for {{ super() }}. It works like {{ block.super }} in django, just that it’s a lot more flexible because you can use it like any other function. So you can apply filters on it, put it into a variable, pass it around etc. The whole block system is not a lot more complex in the background, you can render all parents and because of that we also reworked the way Jinja stores debug information. It’s now not a requirement any more to have the sourcecode of the template — the bytecode knows about the debug infos.
We also improved the debugging messages and added support for brace balancing. Now you can set the delimiters of the blocks to ${ and } and still use dict literals in it. You can also have the same delimiters for blocks and variables now, similar to smarty. Other synax improvements: You can now use parentheses for macro definitions: {% macro foo(bar, baz %} instead of {% macro foo bar, baz %} which is a lot easier to read if the editor doesn’t highlight the function name.
Strings without unicode characters are now stored as bytestrings. While this is a bit slower than unicode everywhere it allows to use datetime.strptime and friends which only accept bytestrings. On the other hand an optional C implementation of the context baseclass was added. Variable lookups in the Jinja context are now a lot faster if installed with this module.
A bunch of bugs were also fixed, especially regarding old-style classes and invalid signatures for exceptions. Also the CachedLoader mixing works now for both memory and disk caching which just partially worked in the 1.0 release version.
Last but not least: A new {% call %} tag is available that allows to pass executable template code to a macro. It works exactly like Ruby blocks, just for Jinja templates :-)
If you want to upgrade to the development version to help fixing the latest bugs etc. consider deleting the cache files of your templates first if you have the disk cache enabled.
You can find other changes in the changelog, it’s quite long :-)
Update: here the results from the bigtable benchmark:
Django Templates 415.52 ms Jinja Templates 142.40 ms Kid Templates 1202.83 ms Genshi Templates 635.37 ms Cheetah Templates 56.52 ms Mako Templates 50.09 ms
Caveat. Mutable hash keys in ruby obviously behave different than you would expect:
>> foo = [1, 2, 3]
[1, 2, 3]
>> bar = {foo => 42}
{[1, 2, 3]=>42}
>> foo << 4
[1, 2, 3, 4]
>> bar[foo]
nil
Update: there is Hash#rehash.
I just found again a python library that uses relative imports (the python 2.4 way) and star imports and two days ago mika asked my how to organize Python applications. Interestingly this topic is not often discussed and you can do it terrible wrong because of a fundamental design mistake in Python 2.
Basically the problem occurs as soon as you have more than just one module and make a package around them. This is a good thing. Python packages are an awesome thing, they don’t cause namespace clashes and they work well. But a folder with a __init__.py file in does not automatically make this package importable. Many developers solve that by importing the modules in that package with so-called relative imports (from mymodule import foobar). That works because Python currently looks also in the folder of the module for moduls, no matter how deep in the package structure. The correct way would be from mypackage.mymodule import foobar, but that requires mypackage being in the pythonpath which is not the case per default if the bootstrapping code is also part of the package. Confused? Basically there must be a special file for any python application that starts that application up. In case of a WSGI application this for example is a myapplication.fcgi or whatever. The module that imports all other stuff has a problem. That problem is called __main__. The module that starts up any python powered application is not imported with its normal import name (for example myapplication.main) but as __main__ and can be imported twice because of this. So just create a file called myapplication-bin or something like that, import myapplication.main and start the main function from there.
Now all modules in that package can do from myapplication.somemodule import something because the working directory is the the folder the package “myapplication” is located in and that folder is automatically part of the pythonpath.
Also an example file structure for a GTK application could look like this:
myapplication-bin
lib/
myapplication/
__init__.py
main.py
something_else.py
shipped_dependency/
__init__.py
shared
some_files.glade
In that case the myapplication-bin must add the “lib” to the pythonpath (by appending that folder to sys.path) and notify the application when starting about the location of shared. This also allows moving the shared files to /usr/share, the application code to /usr/lib or /usr/share too and myapplication-bin into /usr/bin.
Over the last few weeks Georg Brandl from the pocoo team worked on an ass kicking building system that generates reStructuredText files out of the original python LaTeX sources. I helped him a bit with the web part and the result is a nifty WSGI application and offline documentation in .html format that does everything what the current docs do, just better :-)
The sources as rst have some real advantages. First of all the whole build system is written in python. Thus it’s a lot easier to have a platform independent build system (what we now have) and write a web documentation interface with patch functionality (editing the sources and sending a patch to the python documentation mailinglist right from the web interface, with preview). The web application also has comments that a user can attach to any page that was generated from rst sources.
Also the web version of the documentation knows about keywords (unique references). So you can jump to os.path.exists without any clicking. Just go to /os.path.exists (or enter the keyword in the quicksearch box) and you will be redirected to the page that documents that function. It also provides a fuzzy search, similar to the php documentation. If you type a function wrong or don’t know the name of the module where it’s in it will present you a list of up to 20 possible results.
We don’t know if it will really replace the current python documentation but the first responses in the thread on python-dev sound positive. You can try out the interactive, online version at pydoc.gbrandl.de:3000.
If you have suggestions, ideas etc. feel free to join the discussion in the thread above or post your comments here.
As you probably know I had a blog some time ago that was written in django. I guess everybody sooner or later writes his own blog and the codebase starts sucking sooner or later. In fact the wordpress codebase sucks too but I don’t have to maintain it :-)
I will use this blog from now on to jot down some ideas, real-life things and other stuff that occurs, just not articles, those will stay where they are currently.
I do have a “blogroll”, just that it’s part of the lucumr links section and not the blog itself.