gpt4 book ai didi

python - pytest:使用 re.escape() 断言转义字符失败

转载 作者:太空宇宙 更新时间:2023-11-04 01:47:25 25 4
gpt4 key购买 nike

我有一个使用 re.escape() 方法返回字符的函数。在实证测试中它似乎有效,我想用 pytest 测试它。但是我无法让测试正常工作,所以在尝试了几次之后,我尝试了类似的方法:

    def test_escape():
> assert re.escape('!') == "\\!"
E AssertionError: assert '!' == '\\!'
E - !
E + \!

test/test_e.py:6: AssertionError

我还用解释器测试了它,没有任何问题:

>>> re.escape('!') == '\\!'
True

使用“-s”禁用 pytest 输出的捕获并尝试打印 re.escape('!') 的输出我得到 “!”而不是 "\!",这不会发生在解释器上。

我试图通过强制 "\!" 作为输出来 monkeypatch re.escape,它神奇地起作用了。这显然没有解决我的问题,但通过 re.escape 突出了我不知道的某种问题

@pytest.fixture
def mock_escape(monkeypatch):
monkeypatch.setattr(re, "escape", lambda x: "\\!")

def test_escape(mock_escape):
assert re.escape('!') == "\\!"

...

test/test_e.py .

======================================== 1 passed in 0.07s =========================================
all test passed

出于好奇,我对我的原始函数做了同样的事情(没有 monkeypatching 但编辑了它的返回值),即使在这种情况下它也能工作。所以这不是因为导入而发生的问题。

<罢工># 编辑:#tmt发现是python或者pytest版本的问题。问题出现在 python 3.7.2 和 pytest 5.2.1 上。python 3.6.3 和 pytest 4.5.0 不会出现此问题所以这几乎可以肯定是一个错误(在我看来更容易出现 pytest)正如家伙的回复,这只是 re.escape() 的行为改变

最佳答案

如果您查看 re.py,您会看到 escape() 正在使用定义的特殊字符列表

_special_chars_map = {i: '\\' + chr(i) for i in b'()[]{}?*+-|^$\\.&~# \t\n\r\v\f'}

def escape(pattern):
"""
Escape special characters in a string.
"""
if isinstance(pattern, str):
return pattern.translate(_special_chars_map)
else:
pattern = str(pattern, 'latin1')
return pattern.translate(_special_chars_map).encode('latin1')

! 不包含在那里,所以 re.escape('!') 返回 !,而不是 \!.

assert re.escape('[') == '\\['

例如会起作用。

更新:

此答案适用于 Python 3.7,适用于 Python 3.6。 Pull request #1007 改变了 escape() pull source code

re.escape() now escapes only special characters.

以前的版本:

_alphanum_str = frozenset("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890")
_alphanum_bytes = frozenset(b"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890")

def escape(pattern):
if isinstance(pattern, str):
alphanum = _alphanum_str
s = list(pattern)
for i, c in enumerate(pattern):
if c not in alphanum:
if c == "\000":
s[i] = "\\000"
else:
s[i] = "\\" + c
return "".join(s)
else:
alphanum = _alphanum_bytes
s = []
esc = ord(b"\\")
for c in pattern:
if c in alphanum:
s.append(c)
else:
if c == 0:
s.extend(b"\\000")
else:
s.append(esc)
s.append(c)
return bytes(s)

它于 2017 年 4 月 13 日进行了修改,因此查看 versions history re.escape('!') == '\\!' 应该适用于 Python 3.6 和更旧版本。

关于python - pytest:使用 re.escape() 断言转义字符失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58796508/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com