2008/8/28 Steve Holden <<a href="mailto:steve@holdenweb.com">steve@holdenweb.com</a>>:<br>> Guido van Rossum wrote:<br>>> On Wed, Aug 27, 2008 at 6:21 PM, Steven D'Aprano <<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>> wrote:<br>
>>> On Thu, 28 Aug 2008 08:39:01 am Georg Brandl wrote:<br>>>>> Fredrik Lundh schrieb:<br>>>>>> (using 3.0a4)<br>>>>>><br>>>>>> >>> exec(open("file.py"))<br>
>>>>><br>>>>>> Traceback (most recent call last):<br>>>>>> File "<stdin>", line 1, in <module><br>>>>>> TypeError: exec() arg 1 must be a string, file, or code object, not<br>
>>>>> TextIOWrapper<br>>>>>><br>>>>>> so what's "file" referring to here?<br>>>>>><br>>>>>> (the above works under 2.5, of course)<br>
>>>> See <a href="http://bugs.python.org/issue1762972">http://bugs.python.org/issue1762972</a> -- it has been decided to<br>>>>> drop that possibility.<br>>>> Hmmm... I have a concern with one of the patches in that issue; I refer<br>
>>> to patch that changes the semantics of module's __file__ attribute.<br>>>><br>>>> Guido noted that exec(open(M.__file__).read(), M.__dict__) almost worked<br>>>> as a replacement for reload(), except that there were issues with file<br>
>>> extensions (.py, .pyc, .pyo and even things like .pyc24). So it was<br>>>> decided that M.__file__ should always point to the source file.<br>>>><br>>>> But now that reload() is now moved into the imp module, I don't see that<br>
>>> the justification for changing the semantics of M.__file__ still<br>>>> exists. imp.reload(M) is much better for interactive use than<br>>>> exec(open(M.__file__).read(), M.__dict__).<br>>>><br>
>>> Is there still a justification for having M.__file__ point to the source<br>>>> even if the module was actually loaded from the .pyc version? If so,<br>>>> what is that?<br>>>><br>>>> Some years ago, as a newbie, I was having trouble with reload()<br>
>>> repeatedly not picking up changes I was making to a module. The problem<br>>>> turned out to be user-error, but how I discovered that was by looking<br>>>> at M.__file__ and noticing that Python was loading the .pyc file<br>
>>> instead of the .py file I was expecting. Had M.__file__ given<br>>>> misleading information, I would have been mislead for much longer.<br>>>> Here's a small contrived example under Python 2.5:<br>
>>><br>>>>>>> import parrot<br>>>>>>> parrot.__file__<br>>>> 'parrot.py'<br>>>>>>> # pretend that I made changes to the source<br>>>> ... # in my editor, but forgot to save them<br>
>>> ... reload(parrot)<br>>>> <module 'parrot' from 'parrot.pyc'><br>>>>>>> parrot.__file__<br>>>> 'parrot.pyc'<br>>>><br>>>><br>
>>> I don't think M.__file__ should lie and say it was loaded from a file<br>>>> that it wasn't loaded from. It's useful to be able to look at a module<br>>>> and see what file it was actually loaded from.<br>
>><br>>> While appreciate the use case, there are way more use cases where<br>>> there's code that must painstakingly strip the trailing 'c' or 'o'<br>>> from __file__ in order to read the source code. Perhaps we should have<br>
>> a separate API for finding out whether a module was loaded from source<br>>> or from a .pyc file; but I think it would be better to have such an<br>>> API somewhere in the imp module. It's also possible to follow what<br>
>> goes on by watching the verbose -v output.<br>>><br>> Painstakingly? Surely the pain level isn't that high, and I agree with<br>> Michael that the __file__ information would be better as the literal truth.<br>
<br>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.<br>
<br>-- <br>--Guido van Rossum (home page: <a href="http://www.python.org/~guido/">http://www.python.org/~guido/</a>)<br><br>