每当启用HTTPretty时,我就无法与PyMongo建立连接。我知道HTTPretty会改变核心套接字模块;有没有办法解决?

代码示例:



    import pymongo
    import httpretty
    import time

    httpretty.enable()
    try:
        client = pymongo.MongoClient()
    except pymongo.errors.AutoReconnect:
        print("AutoReconnect")
        time.sleep(2)


引发异常:


    Traceback (most recent call last):
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 363, in __init__
        self._ensure_connected(True)
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 924, in _ensure_connected
        self.__ensure_member()
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 797, in __ensure_member
        member, nodes = self.__find_node()
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 888, in __find_node
        raise AutoReconnect(', '.join(errors))
    pymongo.errors.AutoReconnect: [WinError 10035] A non-blocking socket operation could not be completed immediately

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "tmp.py", line 7, in
        client = pymongo.MongoClient()
      File "C:\Python33\lib\site-packages\pymongo\mongo_client.py", line 366, in __init__
        raise ConnectionFailure(str(e))
    pymongo.errors.ConnectionFailure: [WinError 10035] A non-blocking socket operation could not be completed immediately


我在Windows 8.1上使用Python 3.3。

谁能解释这种现象以及如何解决?谢谢!

最佳答案

看起来正在引发的异常与HTTPretty的猴子修补程序有关
套接字,只要我们在非HTTP请求中调用settimeout(0),它就会在自己的套接字上调用sendall(请参见
real_sendall )。这
将套接字置于非阻塞模式。套接字上的超时永不重置
real_sendall之后,因此后续对recv的调用失败,并带有WSAEWOULDBLOCK(错误号10035)。这可能是HTTPretty中的错误。

一种解决方法是在之后重置套接字上的超时real_sendall。这可以通过猴子修补fakesocket.socket来完成
在HTTPretty中:

from httpretty.core import fakesock

class MySocket(fakesock.socket):
    def real_sendall(self, data, *args, **kw):
        super(MySocket, self).real_sendall(data, *args, **kw)
        # Restore non-zero timeout
        self.truesock.settimeout(self.timeout)

fakesock.socket = MySocket

关于python - httpretty.enable()之后的MongoClient连接失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24327277/

10-10 02:25