예제 #1
0
def open_file_for_write(filepath, mode=None):
    """Writes both to given filepath, and tmpdir location.

    This is to get around the problem with some NFS's where immediately reading
    a file that has just been written is problematic. Instead, any files that we
    write, we also write to /tmp, and reads of these files are redirected there.

    Args:
        filepath (str): File to write.
        mode (int): Same mode arg as you would pass to `os.chmod`.

    Yields:
        File-like object.
    """
    stream = StringIO()
    yield stream
    content = stream.getvalue()

    filepath = os.path.realpath(filepath)
    tmpdir = tmpdir_manager.mkdtemp()
    cache_filepath = os.path.join(tmpdir, os.path.basename(filepath))

    debug_print("Writing to %s (local cache of %s)", cache_filepath, filepath)

    with atomic_write(filepath, overwrite=True) as f:
        f.write(content)

    if mode is not None:
        os.chmod(filepath, mode)

    with open(cache_filepath, 'w') as f:
        f.write(content)

    file_cache[filepath] = cache_filepath
예제 #2
0
def open_file_for_write(filepath, mode=None):
    """Writes both to given filepath, and tmpdir location.

    This is to get around the problem with some NFS's where immediately reading
    a file that has just been written is problematic. Instead, any files that we
    write, we also write to /tmp, and reads of these files are redirected there.

    Args:
        filepath (str): File to write.
        mode (int): Same mode arg as you would pass to `os.chmod`.

    Yields:
        File-like object.
    """
    stream = StringIO()
    yield stream
    content = stream.getvalue()

    filepath = os.path.realpath(filepath)
    tmpdir = tmpdir_manager.mkdtemp()
    cache_filepath = os.path.join(tmpdir, os.path.basename(filepath))

    debug_print("Writing to %s (local cache of %s)", cache_filepath, filepath)

    with atomic_write(filepath, overwrite=True) as f:
        f.write(content)

    if mode is not None:
        os.chmod(filepath, mode)

    with open(cache_filepath, 'w') as f:
        f.write(content)

    file_cache[filepath] = cache_filepath
예제 #3
0
def open_file_for_write(filepath, mode=None):
    """Writes both to given filepath, and tmpdir location.

    This is to get around the problem with some NFS's where immediately reading
    a file that has just been written is problematic. Instead, any files that we
    write, we also write to /tmp, and reads of these files are redirected there.

    Args:
        filepath (str): File to write.
        mode (int): Same mode arg as you would pass to `os.chmod`.

    Yields:
        File-like object.
    """
    stream = StringIO()
    yield stream
    content = stream.getvalue()

    filepath = os.path.realpath(filepath)
    tmpdir = tmpdir_manager.mkdtemp()
    cache_filepath = os.path.join(tmpdir, os.path.basename(filepath))
    encoding = {"encoding": "utf-8"} if PY3 else {}

    debug_print("Writing to %s (local cache of %s)", cache_filepath, filepath)

    # Attempt to make file writable if it isn't already. Just fallthrough
    # if this fails, we'll get the error we expect on write anyway
    #
    try:
        if os.path.exists(filepath):
            orig_mode = os.stat(filepath).st_mode
            os.chmod(filepath, orig_mode | stat.S_IWUSR)
    except:
        pass

    # try atomic write, but that can sometimes fail.
    # https://github.com/nerdvegas/rez/issues/858
    #
    written = False
    try:
        with atomic_write(filepath, overwrite=True, **encoding) as f:
            f.write(content)
        written = True
    except:
        pass

    # fallback to standard write
    if not written:
        with open(filepath, 'w', **encoding) as f:
            f.write(content)

    if mode is not None:
        os.chmod(filepath, mode)

    # write the local fs cache copy
    with open(cache_filepath, 'w', **encoding) as f:
        f.write(content)

    file_cache[filepath] = cache_filepath
예제 #4
0
파일: serialise.py 프로젝트: jlorrain/rez
def open_file_for_write(filepath, mode=None):
    """Writes both to given filepath, and tmpdir location.

    This is to get around the problem with some NFS's where immediately reading
    a file that has just been written is problematic. Instead, any files that we
    write, we also write to /tmp, and reads of these files are redirected there.

    Args:
        filepath (str): File to write.
        mode (int): Same mode arg as you would pass to `os.chmod`.

    Yields:
        File-like object.
    """
    stream = StringIO()
    yield stream
    content = stream.getvalue()

    filepath = os.path.realpath(filepath)
    tmpdir = tmpdir_manager.mkdtemp()
    cache_filepath = os.path.join(tmpdir, os.path.basename(filepath))
    encoding = {"encoding": "utf-8"} if PY3 else {}

    debug_print("Writing to %s (local cache of %s)", cache_filepath, filepath)

    for attempt in range(2):
        try:
            with atomic_write(filepath, overwrite=True, **encoding) as f:
                f.write(content)

        except OSError as e:
            # If we are writing to the network, we can't ensure atomicity
            if e.errno == 22:
                with open(filepath, "w", **encoding) as f:
                    f.write(content)

            elif attempt == 0:
                # `overwrite=True` of atomic_write doesn't restore
                # writability to the file being written to.
                os.chmod(filepath, stat.S_IWRITE | stat.S_IREAD)

            elif sys.platform == "win32":
                # Under Windows, atomic_write doesn't tell you about
                # which file actually failed.
                raise WindowsError("%s: '%s'" % (e, filepath))

    if mode is not None:
        os.chmod(filepath, mode)

    with open(cache_filepath, 'w', **encoding) as f:
        f.write(content)

    file_cache[filepath] = cache_filepath
예제 #5
0
파일: serialise.py 프로젝트: mottosso/rez
def open_file_for_write(filepath, mode=None):
    """Writes both to given filepath, and tmpdir location.

    This is to get around the problem with some NFS's where immediately reading
    a file that has just been written is problematic. Instead, any files that we
    write, we also write to /tmp, and reads of these files are redirected there.

    Args:
        filepath (str): File to write.
        mode (int): Same mode arg as you would pass to `os.chmod`.

    Yields:
        File-like object.
    """
    stream = StringIO()
    yield stream
    content = stream.getvalue()

    filepath = os.path.realpath(filepath)
    tmpdir = tmpdir_manager.mkdtemp()
    cache_filepath = os.path.join(tmpdir, os.path.basename(filepath))

    debug_print("Writing to %s (local cache of %s)", cache_filepath, filepath)

    for attempt in range(2):
        try:
            with atomic_write(filepath, overwrite=True) as f:
                f.write(content)

        except WindowsError as e:
            if attempt == 0:
                # `overwrite=True` of atomic_write doesn't restore
                # writability to the file being written to.
                os.chmod(filepath, stat.S_IWRITE | stat.S_IREAD)

            else:
                # Under Windows, atomic_write doesn't tell you about
                # which file actually failed.
                raise WindowsError("%s: '%s'" % (e, filepath))

    if mode is not None:
        os.chmod(filepath, mode)

    with open(cache_filepath, 'w') as f:
        f.write(content)

    file_cache[filepath] = cache_filepath
예제 #6
0
def open_file_for_write(filepath):
    """Writes both to given filepath, and tmpdir location.

    This is to get around the problem with some NFS's where immediately reading
    a file that has just been written is problematic. Instead, any files that we
    write, we also write to /tmp, and reads of these files are redirected there.
    """
    stream = StringIO()
    yield stream
    content = stream.getvalue()

    filepath = os.path.realpath(filepath)
    tmpdir = tmpdir_manager.mkdtemp()
    cache_filepath = os.path.join(tmpdir, os.path.basename(filepath))

    debug_print("Writing to %s (local cache of %s)", cache_filepath, filepath)

    with atomic_write(filepath, overwrite=True) as f:
        f.write(content)

    with open(cache_filepath, 'w') as f:
        f.write(content)

    file_cache[filepath] = cache_filepath