<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, May 16, 2013 at 11:19 PM, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This reminds me of the following bug, which can happen when two<br>
processes are both writing the .pyc file and a third is reading it.<br>
First some background.<br>
<br>
When writing a .pyc file, we use the following strategy:<br>
- open the file for writing<br>
- write a dummy header (four null bytes)<br>
- write the .py file's mtime<br>
- write the marshalled code object<br>
- replace the dummy heaer with the correct magic word<br>
<br>
Even py_compile.py (used by compileall.py) uses this strategy.<br>
<br>
When reading a .pyc file, we ignore it when the magic word isn't there<br>
(or when the mtime doesn't match that of the .py file exactly), and<br>
then we will write it back like described above.<br>
<br>
Now consider the following scenario. It involves *three* processes.<br>
<br>
- Two unrelated processes both start and want to import the same module.<br>
- They both see the .pyc file is missing/corrupt and decide to write it.<br>
- The first process finishing writing the file, writing the correct header.<br>
- Now a third process wants to import the module, sees the valid<br>
header, and starts reading the file.<br>
- However, while this is going on, the second process gets ready to<br>
write the file.<br>
- The second process truncates the file, writes the dummy header, and<br>
then stalls.<br>
- At this point the third process (which thought it was reading a<br>
valid file) sees an unexpected EOF because the file has been<br>
truncated.<br>
<br>
Now, this would explain the EOFError, but not necessarily the<br>
ValueError with "unknown type code".</blockquote><div><br></div><div style>The 'unknown type codes' can also be explained if the two processes writing to the .pyc files are *different Python versions*. As you may recall, at Google we used to use modified Python interpreters that used '.pyc-2.2', '.pyc-2.4', etc, for the pyc extension. That was because otherwise different Python versions would keep overwriting the .pyc files of shared Python modules, and "at Google scale" it caused all manner of problems... I guess Ubuntu is approaching Google scale ;-)</div>
<div style><br></div><div style>(The decision to rename to an awkward extension broke a lot of third-party tools; it was made before I -- or you, for that matter -- joined Google... Now we just turn on -B by default :)</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> However, it looks like marshal<br>
doesn't always check for EOF immediately (sometimes it calls getc()<br>
without checking the result, and sometimes it doesn't check the error<br>
state after calling r_string()), so I think all the errors are<br>
actually explainable from this scenario.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org">Python-Dev@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/python-dev" target="_blank">http://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="http://mail.python.org/mailman/options/python-dev/thomas%40python.org" target="_blank">http://mail.python.org/mailman/options/python-dev/thomas%40python.org</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>Thomas Wouters <<a href="mailto:thomas@python.org" target="_blank">thomas@python.org</a>><br><br>Hi! I'm an email virus! Think twice before sending your email to help me spread!
</div></div>