Premailer on Python 3

08 October 2014   1 comment   Python

Powered by Fusion×

Premailer is probably my most successful open source project in recent years. I base that on the fact that 25 different people have committed to it.

Today I merged a monster PR by Michael Jason Smith of

What it does is basically that it makes premailer work in Python 3, PyPy and Python 2.6. Check out the tox.ini file. Test coverage is still 100%.

If you look at the patch the core of the change is actually surprisingly little. The majority of the "secret sauce" is basically a bunch of import statements which are split by if sys.version_info >= (3, ): and some various minor changes around encoding UTF-8. The rest of the changes are basically test sit-ups.

A really interesting thing that hit us was that the code had assumptions about the order of things. Basically the tests assumed the the order of certain things in the resulting output was predictable even though it was done using a dict. dicts are famously unreliable in terms of the order you get things out and it's meant to be like that and it's a design choice. The reason it worked till now is not only luck but quite amazing.

Anyway, check it out. Now that we have a tox.ini file it should become much easier to run tests which I hope means patches will be better checked as they come in.


Dan Stromberg
First, congratulations on premailer working on 3.x.

Second, if you decide you want a dictionary with an order guarantee, you could try the standard library's OrderedDict or one of these:

Thank you for posting a comment

Your email will never ever be published

Related posts

Do you curl a lot to check headers? 05 September 2014
django-html-validator 20 October 2014
Cope with JSONDecodeError in requests.get().json() in Python 2 and 3 16 November 2016
Premailer 3.0.0 - classes kept by default 07 June 2016 08 July 2015
premailer 2.9.0 and new rules for `base_url` 11 May 2015
premailer now with 100% test coverage 22 August 2014
COPYFILE_DISABLE and python distutils in python 2.6 12 April 2014
Sorting mixed type lists in Python 3 18 January 2014
premailer now excludes pseudo selectors by default 27 May 2013
premailer now honours specificity 21 March 2013
django-mongokit now compatible with Django 1.4 11 August 2012