Python 2.7 ImportMismatchError由basedir重命名后的过时pycache引起

2024-09-26 21:51:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我想知道这里发生了什么,这样我就能防止它再次发生。在

我有一个Jenkins的工作在运行一个python程序(pytest实际上)。它正在virtualenv中使用python2.7.6。在某个时刻,Jenkins作业被重命名,这导致Jenkins重命名存储作业工作区的目录。通常这不会引起问题,如果它真的发生了,那么“擦除工作区”就可以解决问题。然而,由于一个特定的原因,这项工作没有完成,工作区仍然保持原样。在

在这个重命名之后,python程序将拒绝运行,为特定的python模块(conftest.py)发出ImportMismatchError。在使用pdb进行了一些调试之后,我发现python模块(conftest.cpython-27-PYTEST.pyc)的缓存版本是从一个名为__pycache__的目录加载的,并且该缓存版本包含一个现在无效的绝对路径。这会导致ImportMismatch错误,因为缓存版本的绝对路径与模块源的绝对路径不匹配,,但它仍然被视为缓存命中!

我知道这个pycache机制取代了python2的“并行”.pyc缓存机制,但是关于我的情况,有一些事情我不明白:

  1. 既然Jenkins使用的是python2.7.6,而且从3.2以后似乎都支持它,那么{}为什么会存在呢?Python2有什么方法可以创建这个目录吗?我注意到它支持从缓存中创建和读取数据,这让我很惊讶-这是2.7.6版本的后端口吗?在
  2. 为什么这个机制在确定缓存版本是否过时时不考虑模块的完整路径?在本例中,python模块的文件名没有更改,但是basedir(path)更改了。但是,这并没有使缓存失效,因此导致ImportMismatch错误。不应该将完整路径用作缓存键的一部分而不仅仅是文件名吗?使用旧的.pyc并排机制,重命名basedir并不重要,因为.py.pyc文件的相对位置和文件名保持不变。在

在我的例子中,修复很简单-我只是删除了__pycache__目录。不过,我花了两个小时才达到这一点,主要是因为我以前从未处理过这种缓存机制,所以我想了解更多关于这方面的内容。在

编辑:以下是我看到的全部错误消息-这里没有提到__pycache__目录或删除它们的说明,很遗憾:

+ pytest -s -v
Traceback (most recent call last):
  File "/srv2/jenkins/shiningpanda/jobs/bcd7891c/virtualenvs/d41d8cd9/local/lib/python2.7/site-packages/_pytest/config.py", line 362, in _importconftest
    mod = conftestpath.pyimport()
  File "/srv2/jenkins/shiningpanda/jobs/bcd7891c/virtualenvs/d41d8cd9/local/lib/python2.7/site-packages/py/_path/local.py", line 680, in pyimport
    raise self.ImportMismatchError(modname, modfile, self)
ImportMismatchError: ('tests.conftest', '/srv2/jenkins/jobs/CI_Job/workspace/tests/conftest.py', local('/srv2/jenkins/jobs/CI_Job_Renamed/workspace/tests/conftest.py'))
ERROR: could not load /srv2/jenkins/jobs/CI_Job_Renamed/workspace/tests/conftest.py

Tags: 模块py版本目录localjobstests机制
1条回答
网友
1楼 · 发布于 2024-09-26 21:51:53

它的存在是因为pytest将其重写的字节码缓存在那里(它需要重写它,以便用一个简单的assert来提供冗长的断言)。在

至于只有basename是键,我猜原因可能与原因test modules need unique basenames相同:

Note that using this scheme your test files must have unique names, because pytest will import them as top-level modules since there are no packages to derive a full package name from. In other words, the test files in the example above will be imported as test_app and test_view top-level modules by adding tests/ to sys.path.

至于这就是解决问题的方法-难道错误消息没有告诉您删除__pycache__目录吗?当然应该有。在

相关问题 更多 >

    热门问题