title: Why does pickle protocol 2 let me serialise an open file object?
body: <p>Consider:</p>
  
  <pre><code>&gt;&gt;&gt; import pickle
  &gt;&gt;&gt; thing = open('foobar.txt','w')
  &gt;&gt;&gt; pickle.dumps(thing)
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
    File "/usr/lib/python2.6/pickle.py", line 1366, in dumps
      Pickler(file, protocol).dump(obj)
    File "/usr/lib/python2.6/pickle.py", line 224, in dump
      self.save(obj)
    File "/usr/lib/python2.6/pickle.py", line 306, in save
      rv = reduce(self.proto)
    File "/usr/lib/python2.6/copy_reg.py", line 70, in _reduce_ex
      raise TypeError, "can't pickle %s objects" % base.__name__
  TypeError: can't pickle file objects
  </code></pre>
  
  <p>Seems entirely reasonable - of course I can't pickle an open file handle. But:</p>
  
  <pre><code>&gt;&gt;&gt; pickle.dumps(thing, 2)
  '\x80\x02c__builtin__\nfile\nq\x00)\x81q\x01.'
  &gt;&gt;&gt; pickle.loads(pickle.dumps(thing, 2))
  &lt;closed file '&lt;uninitialized file&gt;', mode '&lt;uninitialized file&gt;' at 0x7ff3c078&gt;
  </code></pre>
  
  <p>Apparently I can pickle an open file, just not usefully.</p>
  
  <p>Is this deliberate? It was obscuring a bug in my code, where I was wrongly pickling an object that owned a file. Under some conditions, that object also holds a <code>pyodbc</code> cursor, with the same result.</p>
  
  <p>I don't see anything in <a href="http://www.python.org/dev/peps/pep-0307/" rel="noreferrer">PEP 307</a> about it. Was it just an oversight, or is there something important going on that I'm missing, that could let me get the exception I want even when pickling using protocol 2?</p>
  
  <p>I'm using Python 2.6.5. I know, I know, but it's what comes with my distribution. </p>