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