Python Forum

Full Version: class topen: open with auto temp file
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
this is complete and is working for me. but consider it to be alpha-release grade, for now, due to lack of thorough testing and review. if you prefer to download from its own URL, you can do so at http://ipal.net/python/topen.py
# -*- coding: utf-8 -*-
import os,time,types

def _us():
    """Return a unique string to append to file name."""
    return '_'+str(int(time.time()*3906250))

class topen(dict):
    """Class for opening a file with temporary output name"""\
    """ and automatic rename on close for write."""

    def __init__(self,*args,**kwargs):
        if args:
            args = list(args)
            fname = args.pop(0)
            if args:
                modes = args.pop(0)
            else:
                modes = kwargs.pop('mode',None) 
        else:
            fname = kwargs.pop('file',None)
            modes = kwargs.pop('mode',None)
        if fname is None:
            raise('file is missing')
        if modes is None:
            raise('mode is missing')

        us = kwargs.pop('uniquestring',_us)

        if 'x' in modes and\
           isinstance(fname,(str,bytes)) and\
           os.path.exists(fname):
            raise TypeError(f'{fname!r} already exists')

        fname = os.fspath(fname)
        if isinstance(fname,bytes):
            fname = ''.join(chr(x)for x in fname)
        if isinstance(modes,bytes):
            modes = ''.join(chr(x)for x in modes)
        self['fname'] = fname
        if ('x' in modes or 'w' in modes) and isinstance(fname,str):
            oname = fname+us()
        else:
            oname = None
        self['oname'] = oname
        args = [oname,modes]+list(args)
        ofile = open(*args,**kwargs)
        if ofile is None:
            raise(f'failed to open file {oname!r}')
        self['ofile'] = ofile

    def close(self):
        if self['oname']:
            self['ofile'].close()
            self['closed'] = True
            return os.rename(self['oname'],self['fname'])
        else:
            self['closed'] = True
            return self['ofile'].close()

    def __getattribute__(self,attr):
        if attr == 'close':
            return types.MethodType(type(self).close,self)
        return getattr(self['ofile'],attr)
class topen works similar to open() except that it opens write and exclusive write files to a temporary name then renames the created temporary file to the intended name when closed. this is commonly done on POSIX systems. how that behaves on Microsoft Windows is unknown to me.