<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def parse(cls, filename, root=None):
 """Parses the file at filename and returns a PythonFile. If root is specified, it will open the file with root prepended to the path. The idea is to allow for errors to contain a friendlier file path than the full absolute path. """

    if root is not None:
      if os.path.isabs(filename):
        raise ValueError("filename must be a relative path if root is specified")
      full_filename = os.path.join(root, filename)
    else:
      full_filename = filename

    with io.open(full_filename, 'rb') as fp:
      blob = fp.read()

    tree = cls._parse(blob, filename)
    return cls(blob=blob, tree=tree, root=root, filename=filename)