copied from python, and incompletely updated.