The following code causes an assertion failure in PyErr_WriteUnraisable() (in Python/errors.c): class BadException(Exception): __module__ = None class BadClass: def __del__(self): raise BadException foo = BadClass() del foo this is because PyErr_WriteUnraisable() assumes that __module__ is a string, and passes it to _PyUnicode_EqualToASCIIId(), which asserts it received a string. what is the wanted behavior in such a case? should we ignore the bad __module__ and print '' as the module name in the traceback?
what do you mean by 'Implicit converting to str can raise a warning or exception if __module__ is a bytes object.'? should we treat __module__ differently in case it is a bytes object?
PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) implicitly converts its argument to string. I mean that treating non-string moduleName the same way as string moduleName not equal to string "builtins" and calling PyFile_WriteObject() would cause other problem. Treating non-string moduleName the same way as moduleName==NULL LGTM.