only Py3 version included; substantial refactoring without changing functionality