为什么inspect.getfile会给我一个不存在的文件?

时间:2015-08-11 15:24:00

标签: python python-2.7 python-import urllib3 dockerpy

或者,Saltstack + docker-py AttributeError: 'RecentlyUsedContainer' object has no attribute 'lock'

我一直在研究这个问题但无济于事。我试图使用SaltStack来管理我的docker图像/容器但遇到了this problem

最初我使用的是盐状态docker.running,但由于命令不存在而显示。当我将状态更改为docker.running时,我收到了我在GitHub问题上发布的追溯:

      ID: scheduler
Function: docker.pulled
  Result: False
 Comment: An exception occurred in this state: Traceback (most recent call last):
            File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1563, in call
              **cdata['kwargs'])
            File "/usr/lib/python2.7/dist-packages/salt/states/dockerio.py", line 271, in pulled
              returned = pull(name, tag=tag, insecure_registry=insecure_registry)
            File "/usr/lib/python2.7/dist-packages/salt/modules/dockerio.py", line 1599, in pull
              client = _get_client()
            File "/usr/lib/python2.7/dist-packages/salt/modules/dockerio.py", line 277, in _get_client
              client._version = client.version()['ApiVersion']
            File "/usr/local/lib/python2.7/dist-packages/docker/client.py", line 837, in version
              return self._result(self._get(url), json=True)
            File "/usr/local/lib/python2.7/dist-packages/docker/clientbase.py", line 86, in _get
              return self.get(url, **self._set_request_timeout(kwargs))
            File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 310, in get
              #: Stream response content default.
            File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 279, in request
            File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 374, in send
              url=request.url,
            File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 155, in send
              **proxy_kwargs)
            File "/usr/local/lib/python2.7/dist-packages/docker/unixconn/unixconn.py", line 74, in get_connection
              with self.pools.lock:
          AttributeError: 'RecentlyUsedContainer' object has no attribute 'lock'
 Started: 09:33:42.873628
Duration: 22.115 ms

在搜索了更多内容并且没有任何结果之后,我继续开始reading the source

在阅读unixconn.py并意识到RecentlyUsedContainer来自urllib3后,我去找了源代码,发现有一个_lock属性已更改为{{ 1}}前一段时间。这看起来很奇怪。

我仔细查看了导入,发现lock正在尝试使用请求'内置的urllib3和然后回到独立的urllib3。所以我检查了urllib3的请求并发现它确实有unixconn.py更改。但它比我的版本的请求更新。所以我升级了请求并再次尝试。仍然没有骰子 - 同样_lock -> lock

现在情况开始变得怪异了。

为了把信息传回给我的盐主人,我开始在我的盐奴隶上使用docker-py和urllib3代码。起初我使用AttributeError引发了异常,以确保我使用的是正确的文件。但偶尔会返回的文件名是在文件和不存在的文件夹中。通常它显示urllib3.__file__,但是当我删除该文件时,认为可能正在缓存的.pyc导致问题,它仍然会说是/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/_collections.pyc,即使它没有存在。

然后我发现__file__。我得到了同样奇怪的行为 - 我可以删除.pyc文件,但inspect.getfile将返回不存在的文件。

为了让生活更美好,我已经添加了

inspect.getfile(self.pools)

raise Exception('Pining for the Fjords')

/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/_collections.py 结束时。然而,例外不会提高

我刚刚确认 事实上对我说谎,因为尽管改变了RecentlyUsedContainer.__init__

unixconn.py

返回 def get_connection(self, url, proxies=None): import inspect r = RecentlyUsedContainer(10) raise Exception(inspect.getfile(r.__class__) + '\n' + r.__doc__) ,当我编辑.pyc并修改/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/_collections.pyc的文档字符串时我获取原始文档字符串

最后,当我修改RecentlyUsedContainer并更改它的 docstring时,(或相同的路径,而不是/usr/lib/python2.7/dist-packages/urllib3/_collections.pyc)......

我仍然得到相同的文档字符串!

为什么在这里执行错误的代码,我怎样才能找到它的位置以便修复问题?

1 个答案:

答案 0 :(得分:1)

所以我终于找到了问题所在:

确实与salt有关。由于某种原因,盐奴隶进口docker-py库的方式,它做了某种......部分保持进口。我怀疑发生的事情是盐正在重新导入只是 docker-py库,所以当我对这些文件进行更改时,更改会显示出来。

但是,由于Python导入机制将首先搜索预先导入的模块,因此永远不会重新导入urllib3代码。

最终所需的只是重启盐奴才:

salt 'my-minion' cmd.run "nohup /bin/sh -c 'sleep 10 && salt-call --local service.restart salt-minion'"