Example #1
0
def test_mct_utf8():
    '''Test that utf8 content can be read and written correctly in
    make_clean_tmpfile.

    '''
    filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            "utf.f90")
    _ = make_clean_tmpfile(filepath)
Example #2
0
def test_mct_invalid_filename_arg():
    '''Test that the expected exception occurs if an invalid input file
    is provided.

    '''
    with pytest.raises(IOError) as excinfo:
        _ = make_clean_tmpfile("nonexistantfile")
    assert "No such file or directory" in str(excinfo.value)
Example #3
0
def test_mct_invalid_encode_arg(tmpdir):
    '''Test that an appropriate exception is raised if the encode argument
    is invalid.

    '''
    input_filepath = create_tmp_file("", tmpdir)
    with pytest.raises(InternalError) as excinfo:
        _ = make_clean_tmpfile(input_filepath, encoding="invalid")
    assert "unknown encoding: invalid'." in str(excinfo.value)
Example #4
0
def test_mct_works(tmpdir):
    '''Test that if there are no errors in the input file then we get an
    exact copy of the input file in the temporary file.'''
    content = ("program valid\n" "end program valid\n")
    input_filepath = create_tmp_file(content, tmpdir)
    output_filepath = make_clean_tmpfile(input_filepath)
    with open(output_filepath, "r") as cfile:
        output = cfile.read()
    assert output == content
Example #5
0
def test_mct_invalid_skip_arg(tmpdir):
    '''Test that the expected exception occurs if an invalid
    skip_bad_input argument is provided.

    '''
    input_filepath = create_tmp_file("", tmpdir)
    with pytest.raises(InternalError) as excinfo:
        _ = make_clean_tmpfile(input_filepath, skip_bad_input="INVALID")
    assert ("skip_bad_input argument should be False or True but "
            "found 'INVALID'.") in str(excinfo.value)
Example #6
0
def test_mct_parse_error(tmpdir):
    '''Test that an appropriate exception is raised if there is an invalid
    character in the input file and skip_bad_argument is set to
    False.

    '''
    invalid_content = u"\xca"
    input_filepath = create_tmp_file(invalid_content, tmpdir)
    with pytest.raises(ParseError) as excinfo:
        _ = make_clean_tmpfile(input_filepath, skip_bad_input=False,
                               encoding="ascii")
    assert ("Bad character in input file. Error returned was 'ascii' "
            "codec can't decode byte ") in str(excinfo.value)
    # Can't check the actual value as some versions of Python3 return
    # a different value to the one above.
    assert "in position 0: ordinal not in range(128)." in str(excinfo.value)
Example #7
0
def test_mct_skip_error(tmpdir, caplog):
    '''Test that invalid characters are skipped in an input file by
    default and that logging messages are created.

    '''
    content = "HELLO"
    invalid_content = u"\xca".join(content)
    input_filepath = create_tmp_file(invalid_content, tmpdir)
    output_filepath = make_clean_tmpfile(input_filepath, encoding="ascii")
    with open(output_filepath, "r") as cfile:
        output = cfile.read()
    assert output == content
    for record in caplog.records:
        assert record.levelname != 'CRITICAL'
    assert ("Skipped bad character in input file. Error returned was 'ascii' "
            "codec can't decode byte ") in caplog.text
    # Can't check the actual value as some versions of Python3 return
    # a different value to the one above.
    assert "in position 1: ordinal not in range(128)." in caplog.text
Example #8
0
def get_source_info(file_candidate):
    '''
    Determines the format of Fortran source held in a file.

    :param file_candidate: a filename or a file object
    :type file_candidate: str or (file (py2) or _io.TextIOWrapper (py3))

    :returns: the Fortran format encoded as a string.
    :rtype: str

    '''
    if hasattr(file_candidate, 'name') and hasattr(file_candidate, 'read'):
        filename = file_candidate.name

        # The behaviour of file.name when associated with a file without a
        # file name has changed between Python 2 and 3.
        #
        # Under Python 3 file.name holds an integer file handle.
        if isinstance(filename, int):
            filename = None

        # Under Python 2 file.name holds a string of the form "<..>".
        elif filename.startswith('<') and filename.endswith('>'):
            filename = None
    elif isinstance(file_candidate, six.string_types):
        # The preferred method for identifying strings changed between Python2
        # and Python3.
        filename = file_candidate
    else:
        message = 'Argument must be a filename or file-like object.'
        raise ValueError(message)

    if filename:
        _, ext = os.path.splitext(filename)
        if ext == '.pyf':
            return FortranFormat(True, True)

    if hasattr(file_candidate, 'read'):
        # If the candidate object has a "read" method we assume it's a file
        # object.
        #
        # If it is a file object then it may be in the process of being read.
        # As such we need to take a note of the current state of the file
        # pointer so we can restore it when we've finished what we're doing.
        #
        pointer = file_candidate.tell()
        file_candidate.seek(0)
        source_info = get_source_info_str(file_candidate.read())
        file_candidate.seek(pointer)
        return source_info
    else:
        # It isn't a file and it passed the type check above so it must be
        # a string.
        #
        # If it's a string we assume it is a filename. In which case we need
        # to open the named file so we can read it.
        #
        # It is closed on completion so as to return it to the state it was
        # found in.
        #
        from fparser.common.utils import make_clean_tmpfile
        tmpfile = make_clean_tmpfile(file_candidate)
        with io.open(tmpfile, 'r', encoding='utf8') as file_object:
            string = get_source_info_str(file_object.read())
        os.remove(tmpfile)
        return string