英文:
How to match a string that contains a Python unordered set object when testing across multiple systems and Python versions?
问题
我有一个运行在Python版本>= 3.7,以及在Ubuntu和macOS系统上运行测试的CI设置。我有一个测试似乎会随机失败,我想知道是否与不同系统上如何存储无序集有关。错误是一个失败,其中正确引发了一个警告,但它与预期的警告消息不匹配,因为它显示了以不同顺序打印的正则表达式模式与集合对象。我想知道在将它们作为对象插入到f-string正则表达式时,是否有更好的比较无序集的方法。
为了明确起见,我有以下要测试的函数:
def check_items(item):
my_set = {True, False, "item1", "item2", "item3"}
if item not in my_set:
raise ValueError(
f"Parameter reorder needs to be one of {my_set}."
)
return item
在一个单独的测试文件中,我有以下测试:
import pytest
my_set = {True, False, "item1", "item2", "item3"}
def test_check_items_error():
with pytest.raises(
ValueError,
match=f"Parameter reorder needs to be one of {my_set}"
):
check_items("new")
测试的失败是:
AssertionError: 正则表达式模式不匹配。
正则表达式: "Parameter reorder needs to be one of {False, True, 'item1', 'item2', 'item3'}"
输入: "Parameter reorder needs to be one of {False, True, 'item2', 'item1', 'item3'}."
在这种情况下,确保相同的无序集在f-strings中正确匹配的最安全方法是什么?
英文:
I have a CI setup that is running tests across Python versions >= 3.7 and on Ubuntu and macOS systems. I have a test that seems to randomly fail and I'm wondering if it has to do with how unordered sets are stored in memory on different systems. The error is a failure where a warning is raised correctly but it does not match the expected warning message because it is showing the regex pattern printed with a different order of the set object. I wonder if there is a better way to compare unordered sets when they are inserted as an object into an f-string regex.
For clarity I have the following function I am testing:
def check_items(item):
my_set = {True, False, "item1", "item2", "item3"}
if item not in my_set:
raise ValueError(
f"Parameter reorder needs to be one of {my_set}."
)
return item
And in a separate test file I have the following test
import pytest
my_set = {True, False, "item1", "item2", "item3"}
def test_check_items_error():
with pytest.raises(
ValueError,
match=f"Parameter reorder needs to be one of {my_set}"
):
check_items("new")
The failure of the test is
AssertionError: Regex pattern did not match.
Regex: "Parameter reorder needs to be one of {False, True, 'item1', 'item2', 'item3'}"
Input: "Parameter reorder needs to be one of {False, True, 'item2', 'item1', 'item3'}."
What is the safest way to make sure that identical unordered sets are matched correctly in this setting where they are inserted into an f-strings?
答案1
得分: 0
我们可以通过对每个集合元素的表示进行排序来"规范化"集合。这样,结果将会按顺序排列:
#!/usr/bin/env python3
import pytest
def check_items(item):
my_set = {True, False, "item1", "item2", "item3"}
if item not in my_set:
normalized = ", ".join(sorted(repr(e) for e in my_set))
raise ValueError(f"参数 reorder 需要是 {normalized} 其中之一。")
return item
def test_check_items_error():
my_set = {"item1", "item2", "item3", False, True}
normalized = ", ".join(sorted(repr(e) for e in my_set))
with pytest.raises(
ValueError, match=f"参数 reorder 需要是 {normalized} 其中之一。"
):
check_items("new")
在这种情况下,无论如何排列集合,消息都将显示为
参数 reorder 需要是 'item1', 'item2', 'item3', False, True 其中之一。
英文:
We can "normalize" the set by sorting the repr of each set element. That way, the result will be in order:
#!/usr/bin/env python3
import pytest
def check_items(item):
my_set = {True, False, "item1", "item2", "item3"}
if item not in my_set:
normalized = ", ".join(sorted(repr(e) for e in my_set))
raise ValueError(f"Parameter reorder needs to be one of {normalized}.")
return item
def test_check_items_error():
my_set = {"item1", "item2", "item3", False, True}
normalized = ", ".join(sorted(repr(e) for e in my_set))
with pytest.raises(
ValueError, match=f"Parameter reorder needs to be one of {normalized}"
):
check_items("new")
In this case, no matter how your order your set, the message will come out to be
Parameter reorder needs to be one of 'item1', 'item2', 'item3', False, True.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论