Python 最奇怪的恐怖

Python 最奇怪的恐怖,python,virtualenv,pytest,Python,Virtualenv,Pytest,在我的项目上运行PyTest时,我遇到了一个奇怪的问题。项目结构如下所示 myproject ├── env │   └── stuff ├── __init__.py ├── myproject │   ├── __init__.py │   └── myfile.py └── tests ├── __init__.py └── framework └── unit └── test_myfile.py myproject/myproj

在我的项目上运行PyTest时,我遇到了一个奇怪的问题。项目结构如下所示

myproject
├── env
│   └── stuff
├── __init__.py
├── myproject
│   ├── __init__.py
│   └── myfile.py
└── tests
    ├── __init__.py
    └── framework
        └── unit
            └── test_myfile.py
myproject/myproject中的代码运行良好。此外,myproject根目录中包含代码的文件夹将myproject/myproject中的代码作为模块引用

但是当我在virutalenv中使用以下语法运行pytest时

(env) myproject $ python3.6 -m pytest tests/framework
所有测试均失败,并显示以下错误消息:

E           ModuleNotFoundError: No module named 'myproject.tests'


E               _pytest.nodes.Collector.CollectError: ImportError while importing test module '/home/myuser/projects/myproject/tests/__init__.py'.
E               Hint: make sure your test modules/packages have valid Python names.
E               Traceback:
E               ModuleNotFoundError: No module named 'myproject.tests'
产量

(env) myproject $ python3.6 -c "import sys; print('\n'.join(sys.path))" 

/home/myuser/projects/myproject/env/lib/python36.zip
/home/myuser/projects/myproject/env/lib/python3.6
/home/myuser/projects/myproject/env/lib/python3.6/lib-dynload
/usr/lib/python3.6
/home/myuser/projects/myproject/env/lib/python3.6/site-packages
根据其他帖子中的答案,即使我通过.pth文件手动将myproject、myproject/myproject和myproject/tests添加到路径中,也会收到相同的错误消息

修复错误消息的方法是在myproject/myproject中添加一个名为tests的空文件夹。完成后,错误消息消失,测试正常运行。有人能解释是什么导致了这种奇怪的行为吗


编辑:注释中的解决方案。该问题是由于顶级init.py造成的,它本不应该存在。

运行Pytest命令以查找test.*.py文件时,您必须在测试目录中


试着研究一下uuuu name uuuuu==\uuuuuuuuu main uuuuuuuu:但是首先检查Pytest文档中的反模式和抽象。如果您的体系结构遵循Pytest标准,则可能不需要此步骤。

我在一些动态导入中遇到了类似的问题,我发现这可以解决我的问题

如果检查该文件Github代码第46行的ContextImport类

这个类所做的是,它作为一个上下文管理器工作,所以你可以给它一个带有绝对路径的文件,它会将文件导入到这个上下文中

因此,通过修改这个上下文管理器,您可以将项目目录转换为路径,然后在退出上下文时恢复更改

该类的工作原理是将路径放在sys.path列表的第一个条目中,这可能是您的问题,您只是将其附加到路径列表中


尽管如此,我不确定这是否是正确的,或者是蟒蛇式的

你的设置非常奇怪。为什么您有一个顶级的init.py?我相信你把pytest搞糊涂了,因为它使用了_uinit _;,所以它试图在该目录中查找测试。哪一行触发了错误?您的代码是否正在尝试导入myproject.tests,尽管显然没有对其执行任何操作?@jwodder错误消息都来自env/中的文件。代码中的任何地方都没有引用它。@Bakuriu当我得到这个项目时,它是被继承的,并且是这样构造的。删除顶级init解决了这个问题。第一段绝对不是真的。第二段几乎什么也没说。