多年来,我一直在定期针对多个Python版本使用ruamel.yaml
和tox
测试pytest
。在第一个Python 3.7 beta发布后不久,我将其包含在内,并针对3.7的发布版本进行了升级测试。我仍然在日常工作中一直使用Python 3.6(必要时使用2.7)。
因此,对于DeprecationWarning
而言,在Bitbucket上记录问题令我感到非常惊讶,因为ruamel.yaml
仍从collections
的Python 2.X方式导入内容(从3.8开始,这些< strong>已经要从已经居住的collections.abc
导入)。我本来希望我的tox
运行在几个月前就已经流行了,这是我的工具链中必须能够将新版本推送到PyPI的强制性先决条件。
从命令行中可以看到警告,例如当您这样做时:
python3.7 -W always -c "import ruamel.yaml"
经过一番研究,我补充说:
[pytest]
filterwarnings =
error::DeprecationWarning
error::PendingDeprecationWarning
到达我的tox.ini
,后者没有更改目标py37
的测试结果(321次通过/ 2次跳过/ 7次失败)。
然后我添加了:
setenv = PYTHONWARNINGS =错误
设置为默认([testenv]
)目标。由于tox
/ pytest
/ virtualenv
工具链本身中的弃用警告,测试崩溃了,结果使结果产生了一些有趣的变化。
我手动修复了这些问题(打算在干净的tox -r
运行之后将其自动化),看看这样做是否至少会在ruamel.yaml
本身的毒理上产生错误,但是没有没错如果您改为添加:
setenv =
PYTHONWARNINGS=always::DeprecationWarning
到[testenv]
,您会看到工具链具有:
不建议使用警告:不建议使用“ U”模式
DeprecationWarning:不推荐使用imp模块,而推荐使用importlib
DeprecationWarning:不建议使用“集合”而不是“ collections.abc”中的ABC或从中导入ABC,并且在3.8中它将停止工作
最后一个实际上是我正在寻找的东西,但是那些错误是由于tox依赖项pyparsing中的代码...
然后通过一次测试创建新文件test_import.py
:
def test_import():
from ruamel.yaml
并再次确认tox
已执行测试(322个测试通过),但未显示任何消息或警告,即使将-ra
添加到{{1} }。
我一直期望pytest
能够帮助我尽早发现弃用,但实际上似乎根本无法触发它们。我当然可以在我的tox
中添加上面显示的命令行作为附加命令。但是某些弃用操作可能不太容易触发,我不想重复测试工作,只是为了捕捉潜在的弃用操作。
如何使用tox.ini
触发代码中的DeprecationWarning
?
答案 0 :(得分:1)
如果您以最小的tox
test_one.py
简单的def test_one():
from collections import Hashable
:
setup.py
还有一个基本的from setuptools import setup, find_packages
if __name__ == '__main__':
setup(
name="depwarntest",
version="0.0.1",
description="test to get DeprecationWarning in code on 3.7",
long_description = "more details soon",
author_email="a.van.der.neut@ruamel.eu",
author="Anthon van der Neut",
license="MIT",
url="",
packages=find_packages(),
)
:
tox.ini
并运行[tox]
envlist = py37,py36,py27
[testenv]
commands =
/bin/bash -c 'pytest test_*.py'
deps =
pytest
[pytest]
filterwarnings =
error::DeprecationWarning
error::PendingDeprecationWarning
,由于您的tox
,您会得到一个很好的异常:
import
在==================================================================================== FAILURES =====================================================================================
____________________________________________________________________________________ test_one _____________________________________________________________________________________
def test_one():
> from collections import Hashable
test_one.py:6:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
<frozen importlib._bootstrap>:1032: in _handle_fromlist
???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'Hashable'
def __getattr__(name):
# For backwards compatibility, continue to make the collections ABCs
# through Python 3.6 available through the collections module.
# Note, no new collections ABCs were added in Python 3.7
if name in _collections_abc.__all__:
obj = getattr(_collections_abc, name)
import warnings
warnings.warn("Using or importing the ABCs from 'collections' instead "
"of from 'collections.abc' is deprecated, "
"and in 3.8 it will stop working",
> DeprecationWarning, stacklevel=2)
E DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
.tox/py37/lib/python3.7/collections/__init__.py:52: DeprecationWarning
============================================================================ 1 failed in 0.31 seconds =============================================================================
上运行,而py37
和py36
运行良好。
如果将测试文件更改为要读取,则足够有趣
py27
运行from collections import Hashable
def test_one():
from collections import Hashable
也会在tox
上正常运行。 如果将模块级别的导入移动到另一个py37
文件中,甚至是这种情况。
对于test_XYZ.py
,这意味着测试文件中所有ruamel.yaml
的模块级别导入都需要移到方法/函数中。测试中的任何根级别类都取决于,例如在ruamel.yaml
上需要使用生成器;并且模块级别ruamel.yaml.YAML()
也需要以特殊方式处理。
额外的yaml_object()
目标通过进行一致性测试来帮助测试渐进式运动:
tox
此处,将针对已改编的模块还原已更正的源# deprecation warning fail
[testenv:dwf]
basepython = python3.7
commands =
/bin/sed 's/collections.abc/collections/' -i .tox/dwf/lib/python3.7/site-packages/ruamel/yaml/comments.py
/bin/bash -c 'pytest --maxfail=2 _test/test_[a-cz]*.py'
。 comments.py
应该通过第一个(通过321次测试才可以通过),并且在第二个目标上失败。