Porting to Python 3: An in-depth guide