py.test 试图在 Travis 上导入错误的模块,但不是在本地

py.test trying to import wrong module on Travis but not locally

我有a Travis CI build that is failingpy.test 似乎在尝试导入错误的模块,但我无法在本地重现。我希望它导入 tools.lint.tests.test_lint,而不是 lint.tests.test_lint,正如您在回溯中看到的那样,假设构建具有 --full-trace!当它尝试从工具包进行相对导入时,这会导致下面的错误。

简短的引用是:

___________________ ERROR collecting lint/tests/test_lint.py ___________________
.tox/py27/lib/python2.7/site-packages/py/_path/local.py:650: in pyimport
    __import__(modname)
lint/__init__.py:1: in <module>
    from . import lint
lint/lint.py:15: in <module>
    from .. import localpaths
E   ValueError: Attempted relative import beyond toplevel package

考虑到顶级包的名称只是存储库所在的目录,看到不同我不会感到惊讶 — 但我仍然希望在那里看到它!

查看 Travis 在 /home/travis/build/w3c/wpt-tools/lint/tests/test_lint.py 处拥有该文件的路径。您计算机上名为 tools 的目录在 Travis 上名为 wpt-tools,跟在 GitHub.

上的存储库名称之后

重要的是,wpt-tools 不是有效的 Python 包名称,因为 Python 包名称中不能包含连字符。 (它们必须是 identifier)。这导致 py.test 断定它不是一个包,尽管 __init__.py 包含在其中,因此它没有将它包含在导入路径中,导致代码尝试从中进行相对导入时出错什么是顶级包。

这里有几个解决方案:

  • 最简单的方法是重命名存储库,使其不包含任何连字符,但很明显,如果您是已建立的存储库,这可能是不可取的。

  • 获取 Travis CI 到 运行 某个目录中的代码,通过 copying/moving 存储库到名称不包含连字符的目录,在before_install 的开头,使用类似:

    before_install:
      - mv `pwd` /tmp/tools
      - cd /tmp/tools
    

    这将 运行 从 /tmp/tools 开始的所有安装和后续步骤,这将允许一切按预期 运行。

    (请注意,您不能在此处使用符号 link,因为 Python 中的 os.getcwd() 将从路径中消除 link,返回真实路径,引导看似解决方法根本不起作用。)