pyapnsでnotifyしたときのエラー

ドキュメントを見るとpyapnsのnotify関数はdevice_tokenを文字列でも配列でも渡せることになっています
https://github.com/samuraisam/pyapns

ところが文字列で渡すと正常に通知ができて、配列で渡すとエラーになるというのにちょっとはまったのでメモを残しておきます。

テスト用にブラウザからリクエストして内部でnotifyを飛ばせるようにして試していたら、配列で渡した場合のみ、以下のようなエラーになりました。

twistd.logに表示されたエラー

2012-10-13 09:17:40+0900 [HTTPChannel,0,127.0.0.1] APNSService __init__
2012-10-13 09:17:40+0900 [HTTPChannel,0,127.0.0.1] 127.0.0.1 - - [13/Oct/2012:00:17:40 +0000] "POST / HTTP/1.1" 200 114 "-" "xmlrpclib.py/1.0.1 (by www.pythonware.com)"

2012-10-13 09:17:40+0900 [HTTPChannel,1,127.0.0.1] Unhandled Error
	Traceback (most recent call last):
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/http.py", line 1349, in dataReceived
	    finishCallback(data[contentLength:])
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/http.py", line 1569, in _finishRequestBody
	    self.allContentReceived()
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/http.py", line 1624, in allContentReceived
	    req.requestReceived(command, path, version)
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/http.py", line 773, in requestReceived
	    self.process()
	--- <exception caught here> ---
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/server.py", line 156, in process
	    self.render(resrc)
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/server.py", line 191, in render
	    body = resrc.render(self)
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/resource.py", line 216, in render
	    return m(request)
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/xmlrpc.py", line 160, in render_POST
	    function = self.lookupProcedure(functionPath)
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/xmlrpc.py", line 232, in lookupProcedure
	    handler = self.getSubHandler(prefix)
	  File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/twisted/web/xmlrpc.py", line 140, in getSubHandler
	    return self.subHandlers.get(prefix, None)
	exceptions.AttributeError: APNSServer instance has no attribute 'subHandlers'


ブラウザに表示されたエラー

Traceback:
File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/yuhei/Documents/workspace/iridge/iridge-passbook/src/passbookasp/apps/web/views.py" in notify
  11.     push_notify(pass_type_id=pass_type_id, serial_number=serial_number)
File "/Users/yuhei/Documents/workspace/iridge/iridge-passbook/src/passbookasp/apps/api/api.py" in push_notify
  25.     notify(pass_type_id, push_tokens, [{}])
File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/pyapns/client.py" in wrapper
  75.     return func(*a, **kw)
File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/pyapns/client.py" in wrapper
  67.     return func(*a, **kw)
File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/pyapns/client.py" in notify
  97.     return _xmlrpc_thread(*f_args)
File "/Users/yuhei/Documents/workspace/iridge/passbookapp/venv/lib/python2.7/site-packages/pyapns/client.py" in _xmlrpc_thread
  122.     return callback(proxy(*args))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in __call__
  1224.         return self.__send(self.__name, args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in __request
  1564.                         allow_none=self.__allow_none)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in dumps
  1085.     data = m.dumps(params)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in dumps
  632.                 dump(v, write)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in __dump
  654.         f(self, value, write)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in dump_instance
  756.             self.dump_struct(value.__dict__, write)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in dump_struct
  735.             dump(v, write)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in __dump
  654.         f(self, value, write)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in dump_instance
  756.             self.dump_struct(value.__dict__, write)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in dump_struct
  735.             dump(v, write)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py" in __dump
  646.                 raise TypeError, "cannot marshal %s objects" % type(value)

Exception Type: TypeError at /notify/
Exception Value: cannot marshal <type 'set'> objects


setなんて渡してないぞ、と思って最初はよくわからなかったんですが、Pycharmのdebugで追いかけていったところ、エラーになるところで以下のことがわかりました


配列のつもりで渡していたオブジェクトが実はValueListQuerySetだったというオチでした。