def read_until_closing(s: str, open: str, close: str) -> Tuple[(str, str, str)]:
    open_pattern = re.compile(open)
    pattern = re.compile(f'(?:{open_pattern.pattern})|(?:{close})')
    start_pos = end_pos = 0
    depth = 1
    while depth:
        match = pattern.search(s, end_pos)
        if (not match):
            raise ValueError(f'missing closing bracket (expected {depth} closing)')
        (start_pos, end_pos) = (match.start(), match.end())
        if open_pattern.match(match[0]):
            depth += 1
        else:
            depth -= 1
    return (s[:start_pos], s[start_pos:end_pos], s[end_pos:])
def read_until_closing(s: str, open: str, close: str) -> Tuple[(str, str, str)]:
    open_pattern = re.compile(open)
    pattern = re.compile(f'(?:{open_pattern.pattern})|(?:{close})')
    start_pos = end_pos = 0
    depth = 1
    while depth:
        match = pattern.search(s, end_pos)
        if (not match):
            raise ValueError(f'missing closing bracket (expected {depth} closing)')
        (start_pos, end_pos) = (match.start(), match.end())
        if open_pattern.match(match[0]):
            depth += 1
        else:
            depth -= 1
    return (s[:start_pos], s[start_pos:end_pos], s[end_pos:])