[Python-Dev] confusing exec error message in 3.0 (original) (raw)

Steven D'Aprano steve at pearwood.info
Thu Aug 28 03:21:15 CEST 2008


On Thu, 28 Aug 2008 08:39:01 am Georg Brandl wrote:

Fredrik Lundh schrieb: > (using 3.0a4) > > >>> exec(open("file.py")) > > Traceback (most recent call last): > File "", line 1, in > TypeError: exec() arg 1 must be a string, file, or code object, not > TextIOWrapper > > so what's "file" referring to here? > > (the above works under 2.5, of course)

See http://bugs.python.org/issue1762972 -- it has been decided to drop that possibility.

Hmmm... I have a concern with one of the patches in that issue; I refer to patch that changes the semantics of module's file attribute.

Guido noted that exec(open(M.file).read(), M.dict) almost worked as a replacement for reload(), except that there were issues with file extensions (.py, .pyc, .pyo and even things like .pyc24). So it was decided that M.file should always point to the source file.

But now that reload() is now moved into the imp module, I don't see that the justification for changing the semantics of M.file still exists. imp.reload(M) is much better for interactive use than exec(open(M.file).read(), M.dict).

Is there still a justification for having M.file point to the source even if the module was actually loaded from the .pyc version? If so, what is that?

Some years ago, as a newbie, I was having trouble with reload() repeatedly not picking up changes I was making to a module. The problem turned out to be user-error, but how I discovered that was by looking at M.file and noticing that Python was loading the .pyc file instead of the .py file I was expecting. Had M.file given misleading information, I would have been mislead for much longer. Here's a small contrived example under Python 2.5:

import parrot parrot.file 'parrot.py' # pretend that I made changes to the source ... # in my editor, but forgot to save them ... reload(parrot) <module 'parrot' from 'parrot.pyc'> parrot.file 'parrot.pyc'

I don't think M.file should lie and say it was loaded from a file that it wasn't loaded from. It's useful to be able to look at a module and see what file it was actually loaded from.

-- Steven



More information about the Python-Dev mailing list