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)