
I just got caught out by this: """ def foo(): pass __all__ = [foo] """ Then at the interactive prompt:
from foo import * Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: attribute name must be string
The problem is that __all__ contains a function object rather than a string object. I had to use the debugger to determine why I was getting the failure :( All you 2.1 veterans will immediately pick that it should read '__all__ = ["foo"]' Looking at the __all__ code: if (skip_leading_underscores && PyString_Check(name) && PyString_AS_STRING(name)[0] == '_') { Py_DECREF(name); continue; } value = PyObject_GetAttr(v, name); PyObject_GetAttr explicitly handles string and unicode objects. However, code here won't like Unicode that much :) Would it make sense to a explicitly raise a more meaningful exception here if __all__ doesnt contain strings?