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
def parse ( fname ) : blocks = list ( ) with io . open ( fname , "r" , encoding = "utf-8" ) as f : in_block = False current_block = None current_header = "" for line in f : if line . startswith ( "#### " ) : current_header = line . rstrip ( ) 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 ( "# " ) . rstrip ( ) . lower ( ) ) header = re . sub ( r"\W" , "_" , header ) if "untested" in block [ 1 ] . lower ( ) : continue data = re . sub ( " " , "" , block [ 1 ] ) data = ( data . strip ( "#" ) . rstrip ( ) . split ( "," ) ) binding , doctest_version = ( data + [ None ] ) [ : 2 ] 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
Return blocks of code as list of dicts

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