Error message

  • Warning: Illegal string offset 'field' in DatabaseCondition->__clone() (line 1895 of /home/magiksys/sites/blog.magiksys.net/includes/database/query.inc).
  • Warning: Illegal string offset 'field' in DatabaseCondition->__clone() (line 1895 of /home/magiksys/sites/blog.magiksys.net/includes/database/query.inc).
  • Warning: Illegal string offset 'field' in DatabaseCondition->__clone() (line 1895 of /home/magiksys/sites/blog.magiksys.net/includes/database/query.inc).
  • Warning: Illegal string offset 'field' in DatabaseCondition->__clone() (line 1895 of /home/magiksys/sites/blog.magiksys.net/includes/database/query.inc).

Migrating python library to python 3.x

Having a library working under Python 2.X and Python 3.X is not easy.
Having unittest, doctest, scripts, documentation and packaging working under both Python 2.x and 3.x is a lot of work.

This is what I did with pyzmail.

A good way to start, is to use distribute to release your package.

Start by reading Supporting both Python 2 and Python 3 with Distribute.

The idea is to have unittest working for both 2.x and 3.x. Distribute provides a nice way to test your unittest on both python 2.x and 3.x,
it convert your 2.x source into 3.x using 2to3 and run your test suite on it.
Every time you have a failure or a stack trace, correct the 2.x source and re-run the unittest on both.
When it works, use options use_2to3 in your setup.py and distribute will use 2to3 automatically to convert your sources when installing on 3.x platforms.

The main problem when migration to 3.x is when you mix bytes-strings, strings and unicode strings. The solution is often to use the b'' notation and use explicit .encode() and .decode() when required.

  • Drop support for python before 2.6 because 2.5 don't know about bytes-strings
  • Forget support for old python 3.0 and 3.1 and concentrate on 3.2. Some features ares missing in 3.0 and 3.1 that sometime make it impossible to have your code working as it was with 2.x.
  • Don't try to re-use your doctest if your outputs have some u'' in them. 2to3 don't convert doctest output. Use and abuse of #doctest +SKIP attribute.
  • Use unittest instead of doctest, convert existing doctest into unittest, add some if sys.version_info<(3, 0) clause to handle differences in your sources and unittest.
  • improve your test suite to compensate your inexperience with python 3.x

Good luck.

Add new comment