Source code for openmdao.core.fileref

"""
Support for file variables.
"""

import sys
import copy
import os
import shutil
from six import iteritems

#Public Symbols
__all__ = ['FileRef']

_file_meta = {
    'binary': bool,
}

[docs]class FileRef(object): """ A reference to a file on disk. As well as containing metadata information, it supports :meth:`open` to read and write the file's contents. """ def __init__(self, fname=None): self.fname = fname self.parent_dir = None self.meta = {} def __str__(self): return "FileRef(%s): absolute: %s" % (self.fname, self._abspath()) def _set_meta(self, meta): for name, typ in iteritems(_file_meta): if name in meta: self.meta[name] = typ(meta[name])
[docs] def open(self, mode): """ Open file for reading or writing. """ if self.meta.get('binary') and 'b' not in mode: mode += 'b' return open(self._abspath(), mode)
def _abspath(self): """ Return absolute path to file. """ if os.path.isabs(self.fname): return self.fname else: return os.path.join(self.parent_dir, self.fname)
[docs] def validate(self, src_fref): """ validate() is called on a target `FileRef` to ensure that the source is a `FileRef` and that it has matching metadata. Currently, the only metadata is a binary flag. Other metadata may be added in the future. If the metadata does not match, an exception will be raised. Args ---- src_fref : `FileRef` Source `FileRef` object. """ if not isinstance(src_fref, FileRef): raise TypeError("Source for FileRef '%s' is not a FileRef." % self.fname) for name, typ in iteritems(_file_meta): if name in self.meta or name in src_fref.meta: tgtval = typ(self.meta.get(name)) srcval = typ(src_fref.meta.get(name)) if tgtval != srcval: raise ValueError("Source FileRef has (%s=%s) and dest has (%s=%s)."% (name, srcval, name, tgtval))
def _same_file(self, fref): """Returns True if this FileRef and the given FileRef refer to the same file. """ # TODO: check here if we're on the same host return self._abspath() == fref._abspath() def _assign_to(self, src_fref): """Called by the framework during data passing when a target FileRef is connected to a source FileRef. Validation is performed and the source file will be copied over to the destination path if it differs from the path of the source. """ self.validate(src_fref) # If we refer to the same file as the source, do nothing if self._same_file(src_fref): return with src_fref.open("r") as src, self.open("w") as dst: shutil.copyfileobj(src, dst)