Verified Commit 5b24daf6 authored by Dmitry Volodin's avatar Dmitry Volodin
Browse files

py3: Fix replace_re_group

parent 9ac28d60
......@@ -708,17 +708,18 @@ class CLI(object):
sl = self.profile.can_strip_hostname_to
for k, v in six.iteritems(match.groupdict()):
if v:
if k == "hostname" and sl and len(v) > sl:
k = smart_bytes(k)
if k == b"hostname" and sl and len(v) > sl:
ss = list(reversed(v[sl:]))
v = re.escape(v[:sl]) + reduce(
lambda x, y: "(?:%s%s)?" % (re.escape(y), x),
lambda x, y: b"(?:%s%s)?" % (re.escape(y), x),
ss[1:],
"(?:%s)?" % re.escape(ss[0]),
b"(?:%s)?" % re.escape(ss[0]),
)
else:
v = re.escape(v)
pattern_prompt = replace_re_group(pattern_prompt, r"(?P<%s>" % k, v)
pattern_prompt = replace_re_group(pattern_prompt, r"(?P=%s" % k, v)
pattern_prompt = replace_re_group(pattern_prompt, b"(?P<%s>" % k, v)
pattern_prompt = replace_re_group(pattern_prompt, b"(?P=%s" % k, v)
else:
self.logger.error("Invalid prompt pattern")
if old_pattern_prompt != pattern_prompt:
......
......@@ -14,6 +14,9 @@ import six
from six.moves import zip_longest
from numpy import array
# NOC modules
from noc.core.comp import bord
rx_header_start = re.compile(r"^\s*[-=]+[\s\+]+[-=]+")
rx_col = re.compile(r"^([\s\+]*)([\-]+|[=]+)")
......@@ -243,11 +246,17 @@ def ranges_to_list(s, splitter=","):
return sorted(r)
#
# Replace regular expression group with pattern
#
def replace_re_group(expr, group, pattern):
if isinstance(expr, six.binary_type):
return _replace_re_group_binary(expr, group, pattern)
return _replace_re_group_text(expr, group, pattern)
def _replace_re_group_text(expr, group, pattern):
# type: (six.text_type, six.text_type, six.text_type) -> six.text_type
"""
Replace regular expression group with pattern
>>> replace_re_group("nothing","(?P<groupname>","groupvalue")
'nothing'
>>> replace_re_group("the (?P<groupname>simple) test","(?P<groupname>","groupvalue")
......@@ -255,13 +264,13 @@ def replace_re_group(expr, group, pattern):
>>> replace_re_group("the (?P<groupname> nested (test)>)","(?P<groupname>","groupvalue")
'the groupvalue'
"""
r = ""
r = []
lg = len(group)
while expr:
idx = expr.find(group)
if idx == -1:
return r + expr # No more groups found
r += expr[:idx]
break
r += [expr[:idx]]
expr = expr[idx + lg :]
level = 1 # Level of parenthesis nesting
while expr:
......@@ -280,9 +289,53 @@ def replace_re_group(expr, group, pattern):
level -= 1
if level == 0:
# Replace with pattern and search for next
r += pattern
r += [pattern]
break
r += [expr]
return "".join(r)
def _replace_re_group_binary(expr, group, pattern):
# type: (six.binary_type, six.binary_type, six.binary_type) -> six.binary_type
"""
Replace regular expression group with pattern
>>> replace_re_group("nothing","(?P<groupname>","groupvalue")
'nothing'
>>> replace_re_group("the (?P<groupname>simple) test","(?P<groupname>","groupvalue")
'the groupvalue test'
>>> replace_re_group("the (?P<groupname> nested (test)>)","(?P<groupname>","groupvalue")
'the groupvalue'
"""
r = []
lg = len(group)
while expr:
idx = expr.find(group)
if idx == -1:
break
r += [expr[:idx]]
expr = expr[idx + lg :]
level = 1 # Level of parenthesis nesting
while expr:
c = bord(expr[0])
expr = expr[1:]
if c == 0x5C: # "\\"
# Skip quoted character
expr = expr[1:]
continue
elif c == 0x28: # "("
# Increase nesting level
level += 1
continue
elif c == 0x29: # ")"
# Decrease nesting level
level -= 1
if level == 0:
# Replace with pattern and search for next
r += [pattern]
break
return r + expr
r += [expr]
return b"".join(r)
def indent(text, n=4):
......
......@@ -336,10 +336,22 @@ def test_ranges_to_list(config, expected):
("the (?P<groupname> nested (test)>)", "the groupvalue"),
],
)
def test_replace_re_group(config, expected):
def test_replace_re_group_text(config, expected):
assert replace_re_group(config, "(?P<groupname>", "groupvalue") == expected
@pytest.mark.parametrize(
"config, expected",
[
(b"nothing", b"nothing"),
(b"the (?P<groupname>simple) test", b"the groupvalue test"),
(b"the (?P<groupname> nested (test)>)", b"the groupvalue"),
],
)
def test_replace_re_group_bytes(config, expected):
assert replace_re_group(config, b"(?P<groupname>", b"groupvalue") == expected
@pytest.mark.parametrize(
"config, expected",
[
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment