Return blocks of code as list of dicts

    Arguments:
        fname (str): Relative name of caveats file

def parse(fname):
    """Return blocks of code as list of dicts

    Arguments:
        fname (str): Relative name of caveats file

    """

    blocks = list()
    with io.open(fname, "r", encoding="utf-8") as f:
        in_block = False
        current_block = None
        current_header = ""

        for line in f:

            # Doctests are within a quadruple hashtag header.
            if line.startswith("#### "):
                current_header = line.rstrip()

            # The actuat test is within a fenced block.
            if line.startswith("```"):
                in_block = False

            if in_block:
                current_block.append(line)

            if line.startswith("```python"):
                in_block = True
                current_block = list()
                current_block.append(current_header)
                blocks.append(current_block)

    tests = list()
    for block in blocks:
        header = (
            block[0].strip("# ")  # Remove Markdown
                    .rstrip()     # Remove newline
                    .lower()      # PEP08
        )

        # Remove unsupported characters
        header = re.sub(r"\W", "_", header)

        # Adding "untested" anywhere in the first line of
        # the doctest excludes it from the test.
        if "untested" in block[1].lower():
            continue

        data = re.sub(" ", "", block[1])  # Remove spaces
        data = (
            data.strip("#")
                .rstrip()     # Remove newline
                .split(",")
        )

        binding, doctest_version = (data + [None])[:2]

        # Run tests on both Python 2 and 3, unless explicitly stated
        if doctest_version is not None:
            if doctest_version not in ("Python2", "Python3"):
                raise SyntaxError(
                    "Invalid Python version:\n%s\n"
                    "Python version must follow binding, e.g.\n"
                    "# PyQt5, Python3" % doctest_version)

            active_version = "Python%i" % sys.version_info[0]
            if doctest_version != active_version:
                continue

        tests.append({
            "header": header,
            "binding": binding,
            "body": block[2:]
        })

    return tests