[Python-Dev] confusing exec error message in 3.0

Guido van Rossum guido at python.org
Fri Aug 29 04:25:47 CEST 2008

2008/8/28 Steve Holden <steve at holdenweb.com>:
> Guido van Rossum wrote:
>> On Wed, Aug 27, 2008 at 6:21 PM, Steven D'Aprano <steve at pearwood.info>
>>> 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 "<stdin>", line 1, in <module>
>>>>> 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.
>> While appreciate the use case, there are way more use cases where
>> there's code that must painstakingly strip the trailing 'c' or 'o'
>> from __file__ in order to read the source code. Perhaps we should have
>> a separate API for finding out whether a module was loaded from source
>> or from a .pyc file; but I think it would be better to have such an
>> API somewhere in the imp module. It's also possible to follow what
>> goes on by watching the verbose -v output.
> Painstakingly? Surely the pain level isn't that high, and I agree with
> Michael that the __file__ information would be better as the literal

Some people have custom mods to Python that change the extension, and then
the c/o stripping code breaks. What is the literal truth depends on your use
case. It is the literal truth that the source file is the .py file.

--Guido van Rossum (home page: http://www.python.org/~guido/)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20080828/edeb292e/attachment.htm>

More information about the Python-Dev mailing list