urllib.urlopenでTypeError: endheaders() takes exactly 1 argument (2 given)

google app engine1.6.0でurllib.urlopenを使用したところ、以下のようなエラーが発生。

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 84, in urlopen
    return opener.open(url)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 205, in open
    return getattr(self, name)(url)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 342, in open_http
    h.endheaders(data)
TypeError: endheaders() takes exactly 1 argument (2 given)

endheadersはhttplibに定義されてますが、app engineのライブラリとpython自体のライブラリの両方にファイルが存在していて、appengineのほうが先に読み込まれるため、上記のエラーになるようです。


/Applications/GoogleAppEngineLauncher1.6.0.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/dist/httplib.py

  def endheaders(self):
    pass

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py

    def endheaders(self, message_body=None):
        """Indicate that the last header line has been sent to the server.

        This method sends the request to the server.  The optional
        message_body argument can be used to pass message body
        associated with the request.  The message body will be sent in
        the same packet as the message headers if possible.  The
        message_body should be a string.
        """
        if self.__state == _CS_REQ_STARTED:
            self.__state = _CS_REQ_SENT
        else:
            raise CannotSendHeader()
        self._send_output(message_body)

調べたところ、これは既知の不具合で、1.6.1で修正されてました。

1.6.1のリリースノート
https://docs.google.com/document/pub?id=1AZjOs_it3FwPF5ZjUYsbpntGTbbnPqtl0kGChaPZxok&pli=1

SDK での httplib における Python2.5 と Python2.7 間の互換性問題を修正しました。
http://code.google.com/p/googleappengine/issues/detail?id=6271

1.6.1のライブラリに含まれるhttplib.pyではendheadersは引数を2つとるように修正されてます。

  def endheaders(self, message_body=None):

    if message_body is not None:
      self.send(message_body)