导入我的函数装饰器时出现 pytest 错误
pytest error when importing my function decorator
我正在为我的软件中的一个函数创建一个 pytest 单元测试。
甚至在开始测试之前,pyunit 似乎无法导入我的 "cache_offline" 装饰器,当我在我的测试中导入我正在测试的函数时,它是间接导入的。
我正在使用 Anaconda 嵌入 Python 3.7 和 pytest 5.2.2
我试图注释掉装饰器应用于我的函数的代码,当我这样做时,pytest 错误消失并且测试正确执行。
我的测试在 ./tests/scripts/test_scripts_helper.py
中,我 运行 pytest 在项目根目录下 .
Pytest 正确找到了我的测试(请参阅错误消息),所以这不是手头的问题。
我的测试从包 vorace.scripts_helper
导入并想测试函数 read_tiff_tag
,它从包 vorace.core.misc
导入函数 safe_mkdir
,它导入包 vorace.core.vorace
,其中3个函数用package vorace.core.misc
中的装饰器cache_offline
装饰
我在项目的根目录下使用 py.test
或 python -m pytest
尝试了两个 运行 测试。
我的项目有以下结构(简化)。
代码根是 ./vorace
测试根是 ./tests
.
├── conftest.py
├── tests
│ ├── __init__.py
│ ├── scripts
│ │ ├── __init__.py
│ │ └── test_scripts_helper.py
│ └── tests_data
│ └── test_ROI.tif
└── vorace
├── __init__.py
├── core
│ ├── __init__.py
│ ├── misc.py
│ └── vorace.py
└── scripts
├── __init__.py
├── batch_analyzis.py
└── scripts_helper.py
我试过了:
- 在
tests
文件夹的每个子文件夹中有和没有空 __init__.py
。 -> 无变化
- 在项目的根目录有和没有空的
conftest.py
。 -> 无变化
- 在我的
test_scripts_helper.py
文件中执行不需要任何导入的测试(我的测试导致问题被注释掉)-> 测试正确执行
我怀疑存在某种循环导入问题,但我一直被告知它不会在 python 中发生。也许装饰器是这个规则的例外?
我的 vorace.core.misc
代码,带有装饰器
from vorace.core import vorace
[...]
def cache_offline(cache_path=os.getcwd()):
[...]
def decorator(func):
[...]
def wrapper(*args, **kwargs):
[...]
return result
return wrapper
return decorator
def safe_mkdir(path):
[...]
vorace.core.vorace
中的修饰函数之一
from vorace.core.misc import *
[...]
@cache_offline(cache_path=".cache")
def classify_clusters_by_connectivity(xyz_data):
[...]
[...]
在项目根
中执行py.test
的输出
==================== test session starts ====================
platform linux -- Python 3.7.3, pytest-5.2.2, py-1.8.0, pluggy-0.12.0
rootdir: /home/flo/PycharmProjects/VorAce
plugins: arraydiff-0.3, openfiles-0.3.2, doctestplus-0.3.0, remotedata-0.3.1
collected 0 items / 1 errors
==================== ERRORS ====================
_________ ERROR collecting tests/scripts/test_scripts_helper.py _________
tests/scripts/test_scripts_helper.py:1: in <module>
import vorace.scripts.scripts_helper as sh
vorace/scripts/scripts_helper.py:6: in <module>
from vorace.core.misc import safe_mkdir
vorace/core/misc.py:8: in <module>
from vorace.core import vorace
vorace/core/vorace.py:91: in <module>
@cache_offline(cache_path=".cache")
E NameError: name 'cache_offline' is not defined
如果我在 tests/scripts/test_scripts_helper.py
文件中执行一个简单的 0 == 0
测试而不从我的项目中导入,则测试 运行 会成功。
当您 运行 ./tests/scripts/test_scripts_helper.py
python 自动将 ./tests/scripts/
设置到 PYTHONPATH 但不设置任何其他目录时,因此您从其他自定义文件的所有导入都应该失败。
将所有工作目录设置到 PYTHONPATH 环境变量中。
Linux shell.
上的类似内容
PYTHONPATH="${PYTHONPATH}:$dir
编辑:我终于得到了循环导入的确认。
与我的想法相反,从模块中导入特定名称
like in from x import y
可以对循环导入敏感,而 import x
不能。
为了解决这个问题,我只是导入了模块并使用了使用模块前缀函数调用的语法。
更多信息:https://www.reddit.com/r/Python/comments/51hdup/from_import_vs_import_on_circular_import/
最终与装饰器或 pytest 无关的问题。
我通过将我的 cache_offline
装饰器放在一个单独的包 vorace.core.caching.py
中解决了这个问题。现在我只从需要修饰的函数所在的 vorace.core.vorace
导入这个包。
这样我的装饰器被人为排除在我的单元测试导入的代码之外,但仍然可供我的其余代码用于正常的应用程序执行。
不过pytest这里还是有问题,导入应该不会失败。我仍在接受任何可以解释为什么 pytest 无法导入我的装饰器的答案,并且我保留 resolve 以获得此类答案。
我正在为我的软件中的一个函数创建一个 pytest 单元测试。
甚至在开始测试之前,pyunit 似乎无法导入我的 "cache_offline" 装饰器,当我在我的测试中导入我正在测试的函数时,它是间接导入的。
我正在使用 Anaconda 嵌入 Python 3.7 和 pytest 5.2.2
我试图注释掉装饰器应用于我的函数的代码,当我这样做时,pytest 错误消失并且测试正确执行。
我的测试在 ./tests/scripts/test_scripts_helper.py
中,我 运行 pytest 在项目根目录下 .
Pytest 正确找到了我的测试(请参阅错误消息),所以这不是手头的问题。
我的测试从包 vorace.scripts_helper
导入并想测试函数 read_tiff_tag
,它从包 vorace.core.misc
导入函数 safe_mkdir
,它导入包 vorace.core.vorace
,其中3个函数用package vorace.core.misc
cache_offline
装饰
我在项目的根目录下使用 py.test
或 python -m pytest
尝试了两个 运行 测试。
我的项目有以下结构(简化)。
代码根是 ./vorace
测试根是 ./tests
.
├── conftest.py
├── tests
│ ├── __init__.py
│ ├── scripts
│ │ ├── __init__.py
│ │ └── test_scripts_helper.py
│ └── tests_data
│ └── test_ROI.tif
└── vorace
├── __init__.py
├── core
│ ├── __init__.py
│ ├── misc.py
│ └── vorace.py
└── scripts
├── __init__.py
├── batch_analyzis.py
└── scripts_helper.py
我试过了:
- 在
tests
文件夹的每个子文件夹中有和没有空__init__.py
。 -> 无变化 - 在项目的根目录有和没有空的
conftest.py
。 -> 无变化 - 在我的
test_scripts_helper.py
文件中执行不需要任何导入的测试(我的测试导致问题被注释掉)-> 测试正确执行
我怀疑存在某种循环导入问题,但我一直被告知它不会在 python 中发生。也许装饰器是这个规则的例外?
我的 vorace.core.misc
代码,带有装饰器
from vorace.core import vorace
[...]
def cache_offline(cache_path=os.getcwd()):
[...]
def decorator(func):
[...]
def wrapper(*args, **kwargs):
[...]
return result
return wrapper
return decorator
def safe_mkdir(path):
[...]
vorace.core.vorace
from vorace.core.misc import *
[...]
@cache_offline(cache_path=".cache")
def classify_clusters_by_connectivity(xyz_data):
[...]
[...]
在项目根
中执行py.test
的输出
==================== test session starts ====================
platform linux -- Python 3.7.3, pytest-5.2.2, py-1.8.0, pluggy-0.12.0
rootdir: /home/flo/PycharmProjects/VorAce
plugins: arraydiff-0.3, openfiles-0.3.2, doctestplus-0.3.0, remotedata-0.3.1
collected 0 items / 1 errors
==================== ERRORS ====================
_________ ERROR collecting tests/scripts/test_scripts_helper.py _________
tests/scripts/test_scripts_helper.py:1: in <module>
import vorace.scripts.scripts_helper as sh
vorace/scripts/scripts_helper.py:6: in <module>
from vorace.core.misc import safe_mkdir
vorace/core/misc.py:8: in <module>
from vorace.core import vorace
vorace/core/vorace.py:91: in <module>
@cache_offline(cache_path=".cache")
E NameError: name 'cache_offline' is not defined
如果我在 tests/scripts/test_scripts_helper.py
文件中执行一个简单的 0 == 0
测试而不从我的项目中导入,则测试 运行 会成功。
当您 运行 ./tests/scripts/test_scripts_helper.py
python 自动将 ./tests/scripts/
设置到 PYTHONPATH 但不设置任何其他目录时,因此您从其他自定义文件的所有导入都应该失败。
将所有工作目录设置到 PYTHONPATH 环境变量中。 Linux shell.
上的类似内容PYTHONPATH="${PYTHONPATH}:$dir
编辑:我终于得到了循环导入的确认。
与我的想法相反,从模块中导入特定名称
like in from x import y
可以对循环导入敏感,而 import x
不能。
为了解决这个问题,我只是导入了模块并使用了使用模块前缀函数调用的语法。 更多信息:https://www.reddit.com/r/Python/comments/51hdup/from_import_vs_import_on_circular_import/
最终与装饰器或 pytest 无关的问题。
我通过将我的 cache_offline
装饰器放在一个单独的包 vorace.core.caching.py
中解决了这个问题。现在我只从需要修饰的函数所在的 vorace.core.vorace
导入这个包。
这样我的装饰器被人为排除在我的单元测试导入的代码之外,但仍然可供我的其余代码用于正常的应用程序执行。
不过pytest这里还是有问题,导入应该不会失败。我仍在接受任何可以解释为什么 pytest 无法导入我的装饰器的答案,并且我保留 resolve 以获得此类答案。