@path_required<EOL><INDENT>def copy_file(self, relativePath, newRelativePath,<EOL>force=False, raiseError=True, ntrials=<NUM_LIT:3>):<DEDENT>

assert isinstance(raiseError, bool), "<STR_LIT>"<EOL>assert isinstance(force, bool), "<STR_LIT>"<EOL>assert isinstance(ntrials, int), "<STR_LIT>"<EOL>assert ntrials><NUM_LIT:0>, "<STR_LIT>"<EOL>relativePath = self.to_repo_relative_path(path=relativePath, split=False)<EOL>realPath     = os.path.join(self.__path,relativePath)<EOL>fPath, fName = os.path.split(realPath)<EOL>newRelativePath = self.to_repo_relative_path(path=newRelativePath, split=False)<EOL>newRealPath     = os.path.join(self.__path,newRelativePath)<EOL>nfPath, nfName  = os.path.split(newRealPath)<EOL>LO =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(fPath,self.__fileLock%fName))<EOL>acquired, code = LO.acquire_lock()<EOL>if not acquired:<EOL><INDENT>error = "<STR_LIT>"%(code,relativePath)<EOL>assert not raiseError, error<EOL>return False, error<EOL><DEDENT>try:<EOL><INDENT>success, reason = self.add_directory(nfPath, raiseError=False, ntrials=ntrials)<EOL><DEDENT>except Exception as err:<EOL><INDENT>reason  = "<STR_LIT>"%(str(err))<EOL>success = False<EOL><DEDENT>if not success:<EOL><INDENT>LO.release_lock()<EOL>assert not raiseError, reason<EOL>return False, reason<EOL><DEDENT>LN =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(nfPath,self.__fileLock%nfName))<EOL>acquired, code = LN.acquire_lock()<EOL>if not acquired:<EOL><INDENT>LO.release_lock()<EOL>error = "<STR_LIT>"%(code,newRelativePath)<EOL>assert not raiseError, error<EOL>return False, error<EOL><DEDENT>for _trial in range(ntrials):<EOL><INDENT>copied = False<EOL>error  = None<EOL>try:<EOL><INDENT>isRepoFile,fileOnDisk, infoOnDisk, classOnDisk = self.is_repository_file(relativePath)<EOL>assert isRepoFile,  "<STR_LIT>"%(relativePath,)<EOL>assert fileOnDisk,  "<STR_LIT>"%(relativePath,)<EOL>assert infoOnDisk,  "<STR_LIT>"%self.__fileInfo%fName<EOL>assert classOnDisk, "<STR_LIT>"%self.__fileClass%fName<EOL>nisRepoFile,nfileOnDisk,ninfoOnDisk,nclassOnDisk = self.is_repository_file(newRelativePath)<EOL>assert not nisRepoFile or force, "<STR_LIT>"<EOL>nDirList = self.__get_repository_directory(nfPath)<EOL>if os.path.isfile(newRealPath):<EOL><INDENT>os.remove(newRealPath)<EOL><DEDENT>if os.path.isfile(os.path.join(nfPath,self.__fileInfo%nfName)):<EOL><INDENT>os.remove(os.path.join(nfPath,self.__fileInfo%nfName))<EOL><DEDENT>if os.path.isfile(os.path.join(nfPath,self.__fileClass%nfName)):<EOL><INDENT>os.remove(os.path.join(nfPath,self.__fileClass%nfName))<EOL><DEDENT>shutil.copy(realPath, newRealPath)<EOL>shutil.copy(os.path.join(fPath,self.__fileInfo%fName),  os.path.join(nfPath,self.__fileInfo%nfName))<EOL>shutil.copy(os.path.join(fPath,self.__fileClass%fName), os.path.join(nfPath,self.__fileClass%nfName))<EOL>if nfName not in nDirList:<EOL><INDENT>nDirList.append(nfName)<EOL><DEDENT><DEDENT>except Exception as err:<EOL><INDENT>copied = False<EOL>error = str(err)<EOL>if self.DEBUG_PRINT_FAILED_TRIALS: print("<STR_LIT>"%(_trial, inspect.stack()[<NUM_LIT:1>][<NUM_LIT:3>], str(error)))<EOL><DEDENT>else:<EOL><INDENT>error = None<EOL>copied = True<EOL>break<EOL><DEDENT><DEDENT>LO.release_lock()<EOL>LN.release_lock()<EOL>assert copied or not raiseError, "<STR_LIT>"%(relativePath, newRelativePath, ntrials, error,)<EOL>return copied, '<STR_LIT:\n>'.join(message)<EOL>

Copy a file in the repository.

:Parameters:
    #. relativePath (string): The relative to the repository path of
       the file that needst to be renamed.
    #. newRelativePath (string): The new relative to the repository path
       of where to move and rename the file.
    #. force (boolean): Whether to force renaming even when another
       repository file exists. In this case old repository file
       will be removed from the repository and the system as well.
    #. raiseError (boolean): Whether to raise encountered error instead
       of returning failure.
    #. ntrials (int): After aquiring all locks, ntrials is the maximum
       number of trials allowed before failing.
       In rare cases, when multiple processes
       are accessing the same repository components, different processes
       can alter repository components between successive lock releases
       of some other process. Bigger number of trials lowers the
       likelyhood of failure due to multiple processes same time
       alteration.

:Returns:
    #. success (boolean): Whether renaming the file was successful.
    #. message (None, string): Some explanatory message or error reason
       why directory was not updated.


@path_required<EOL><INDENT>def update_file(self, value, relativePath, description=False,<EOL>dump=False, pull=False, raiseError=True, ntrials=<NUM_LIT:3>):<DEDENT>

<EOL>assert isinstance(raiseError, bool), "<STR_LIT>"<EOL>assert description is False or description is None or isinstance(description, basestring), "<STR_LIT>"<EOL>assert dump is False or dump is None or isinstance(dump, basestring), "<STR_LIT>"<EOL>assert pull is False or pull is None or isinstance(pull, basestring), "<STR_LIT>"<EOL>assert isinstance(ntrials, int), "<STR_LIT>"<EOL>assert ntrials><NUM_LIT:0>, "<STR_LIT>"<EOL>relativePath = self.to_repo_relative_path(path=relativePath, split=False)<EOL>savePath     = os.path.join(self.__path,relativePath)<EOL>fPath, fName = os.path.split(savePath)<EOL>LF =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(fPath,self.__fileLock%fName))<EOL>acquired, code = LF.acquire_lock()<EOL>if not acquired:<EOL><INDENT>error = "<STR_LIT>"%(code,relativePath)<EOL>assert not raiseError, error<EOL>return False, error<EOL><DEDENT>for _trial in range(ntrials):<EOL><INDENT>message = []<EOL>updated = False<EOL>try:<EOL><INDENT>isRepoFile, fileOnDisk, infoOnDisk, classOnDisk = self.is_repository_file(relativePath)<EOL>assert isRepoFile, "<STR_LIT>"%(relativePath,)<EOL>if not fileOnDisk:<EOL><INDENT>assert description is not False,  "<STR_LIT>"%(relativePath,)<EOL>assert dump is not False,  "<STR_LIT>"%(relativePath,)<EOL>assert pull is not False,  "<STR_LIT>"%(relativePath,)<EOL>info = {}<EOL>info['<STR_LIT>'] = self.__repo['<STR_LIT>']<EOL>info['<STR_LIT>'] = info['<STR_LIT>'] = time.time()<EOL><DEDENT>else:<EOL><INDENT>with open(os.path.join(fPath,self.__fileInfo%fName), '<STR_LIT:rb>') as fd:<EOL><INDENT>info = pickle.load(fd)<EOL>info['<STR_LIT>'] = time.time()<EOL><DEDENT><DEDENT>if not fileOnDisk:<EOL><INDENT>message.append("<STR_LIT>"%relativePath)<EOL><DEDENT>if not infoOnDisk:<EOL><INDENT>message.append("<STR_LIT>"%self.__fileInfo%fName)<EOL><DEDENT>if not classOnDisk:<EOL><INDENT>message.append("<STR_LIT>"%self.__fileClass%fName)<EOL><DEDENT>if (description is False) or (dump is False) or (pull is False):<EOL><INDENT>if description is False:<EOL><INDENT>description = info['<STR_LIT:description>']<EOL><DEDENT>elif description is None:<EOL><INDENT>description = '<STR_LIT>'<EOL><DEDENT>if dump is False:<EOL><INDENT>dump = info['<STR_LIT>']<EOL><DEDENT>elif dump is None:<EOL><INDENT>dump = get_dump_method(dump, protocol=self._DEFAULT_PICKLE_PROTOCOL)<EOL><DEDENT>if pull is False:<EOL><INDENT>pull = info['<STR_LIT>']<EOL><DEDENT>elif pull is None:<EOL><INDENT>pull = get_pull_method(pull)<EOL><DEDENT><DEDENT>info['<STR_LIT>'] = dump<EOL>info['<STR_LIT>'] = pull<EOL>info['<STR_LIT:description>'] = description<EOL>my_exec( dump.replace("<STR_LIT>", str(savePath)), locals=locals(), globals=globals(), description='<STR_LIT>'  )<EOL>_path = os.path.join(fPath,self.__fileInfo%fName)<EOL>with open(_path, '<STR_LIT:wb>') as fd:<EOL><INDENT>pickle.dump( info,fd, protocol=self._DEFAULT_PICKLE_PROTOCOL )<EOL>fd.flush()<EOL>os.fsync(fd.fileno())<EOL><DEDENT>fileClassPath = os.path.join(self.__path,os.path.dirname(relativePath),self.__fileClass%fName)<EOL>with open(fileClassPath, '<STR_LIT:wb>') as fd:<EOL><INDENT>if value is None:<EOL><INDENT>klass = None<EOL><DEDENT>else:<EOL><INDENT>klass = value.__class__<EOL><DEDENT>pickle.dump(klass , fd, protocol=self._DEFAULT_PICKLE_PROTOCOL )<EOL>fd.flush()<EOL>os.fsync(fd.fileno())<EOL><DEDENT><DEDENT>except Exception as err:<EOL><INDENT>message.append(str(err))<EOL>updated = False<EOL>try:<EOL><INDENT>if '<STR_LIT>' in dump:<EOL><INDENT>mi = get_pickling_errors(value)<EOL>if mi is not None:<EOL><INDENT>message.append('<STR_LIT>'%str(mi))<EOL><DEDENT><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT>if self.DEBUG_PRINT_FAILED_TRIALS: print("<STR_LIT>"%(_trial, inspect.stack()[<NUM_LIT:1>][<NUM_LIT:3>], '<STR_LIT:\n>'.join(message)))<EOL><DEDENT>else:<EOL><INDENT>updated = True<EOL>break<EOL><DEDENT><DEDENT>LF.release_lock()<EOL>assert updated or not raiseError, "<STR_LIT>"%(relativePath, '<STR_LIT:\n>'.join(message),)<EOL>return updated, '<STR_LIT:\n>'.join(message)<EOL>

Update the value of a file that is already in the Repository.\n
 If file is not registered in repository, and error will be thrown.\n
 If file is missing in the system, it will be regenerated as dump method
 is called.
 Unlike dump_file, update_file won't block the whole repository but only
 the file being updated.

 :Parameters:
     #. value (object): The value of a file to update.
     #. relativePath (str): The relative to the repository path of the
        file to be updated.
     #. description (False, string): Any random description about the file.
        If False is given, the description info won't be updated,
        otherwise it will be update to what description argument value is.
     #. dump (False, string): The new dump method. If False is given,
        the old one will be used.
     #. pull (False, string): The new pull method. If False is given,
        the old one will be used.
     #. raiseError (boolean): Whether to raise encountered error instead
        of returning failure.
     #. ntrials (int): After aquiring all locks, ntrials is the maximum
        number of trials allowed before failing.
        In rare cases, when multiple processes
        are accessing the same repository components, different processes
        can alter repository components between successive lock releases
        of some other process. Bigger number of trials lowers the
        likelyhood of failure due to multiple processes same time
        alteration.

:Returns:
    #. success (boolean): Whether renaming the directory was successful.
    #. message (None, string): Some explanatory message or error reason
       why directory was not updated.


return self.update_file(*args, **kwargs)<EOL>


@path_required<EOL><INDENT>def pull_file(self, relativePath, pull=None, update=True, ntrials=<NUM_LIT:3>):<DEDENT>

assert isinstance(ntrials, int), "<STR_LIT>"<EOL>assert ntrials><NUM_LIT:0>, "<STR_LIT>"<EOL>relativePath = self.to_repo_relative_path(path=relativePath, split=False)<EOL>realPath     = os.path.join(self.__path,relativePath)<EOL>fPath, fName = os.path.split(realPath)<EOL>isRepoFile,fileOnDisk, infoOnDisk, classOnDisk = self.is_repository_file(relativePath)<EOL>if not isRepoFile:<EOL><INDENT>fileOnDisk  = ["<STR_LIT>","<STR_LIT>"][fileOnDisk]<EOL>infoOnDisk  = ["<STR_LIT>","<STR_LIT>"%self.__fileInfo%fName][infoOnDisk]<EOL>classOnDisk = ["<STR_LIT>","<STR_LIT>"%self.__fileClass%fName][classOnDisk]<EOL>assert False, "<STR_LIT>"%(relativePath,fileOnDisk,infoOnDisk,classOnDisk)<EOL><DEDENT>assert fileOnDisk, "<STR_LIT>"%(relativePath,)<EOL>if not infoOnDisk:<EOL><INDENT>if pull is not None:<EOL><INDENT>warnings.warn("<STR_LIT>"%(self.__fileInfo%fName))<EOL><DEDENT>else:<EOL><INDENT>raise Exception("<STR_LIT>"%(relativePath,(self.__fileInfo%fName)))<EOL><DEDENT><DEDENT>LF =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(fPath,self.__fileLock%fName))<EOL>acquired, code = LF.acquire_lock()<EOL>if not acquired:<EOL><INDENT>error = "<STR_LIT>"%(code,relativePath)<EOL>return False, error<EOL><DEDENT>for _trial in range(ntrials):<EOL><INDENT>error = None<EOL>try:<EOL><INDENT>if pull is not None:<EOL><INDENT>pull = get_pull_method(pull)<EOL><DEDENT>else:<EOL><INDENT>with open(os.path.join(fPath,self.__fileInfo%fName), '<STR_LIT:rb>') as fd:<EOL><INDENT>info = pickle.load(fd)<EOL><DEDENT>pull = info['<STR_LIT>']<EOL><DEDENT>my_exec( pull.replace("<STR_LIT>", str(realPath) ), locals=locals(), globals=globals(), description='<STR_LIT>' )<EOL><DEDENT>except Exception as err:<EOL><INDENT>LF.release_lock()<EOL>m = str(pull).replace("<STR_LIT>", str(realPath) )<EOL>error = "<STR_LIT>"%(m,err)<EOL>if self.DEBUG_PRINT_FAILED_TRIALS: print("<STR_LIT>"%(_trial, inspect.stack()[<NUM_LIT:1>][<NUM_LIT:3>], str(error)))<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>LF.release_lock()<EOL>assert error is None, "<STR_LIT>"%(ntrials, error)<EOL>return locals()['<STR_LIT>']<EOL>

Pull a file's data from the Repository.

:Parameters:
    #. relativePath (string): The relative to the repository path from
       where to pull the file.
    #. pull (None, string): The pulling method.
       If None, the pull method saved in the file info will be used.
       If a string is given, the string should include all the necessary
       imports, a '$FILE_PATH' that replaces the absolute file path when
       the dumping will be performed and finally a PULLED_DATA variable.
       e.g "import numpy as np; PULLED_DATA=np.loadtxt(fname='$FILE_PATH')"
    #. update (boolean): If pull is not None, Whether to update the pull
       method stored in the file info by the given pull method.
    #. ntrials (int): After aquiring all locks, ntrials is the maximum
       number of trials allowed before failing.
       In rare cases, when multiple processes
       are accessing the same repository components, different processes
       can alter repository components between successive lock releases
       of some other process. Bigger number of trials lowers the
       likelyhood of failure due to multiple processes same time
       alteration.

:Returns:
    #. data (object): The pulled data from the file.


return self.pull_file(*args, **kwargs)<EOL>


@path_required<EOL><INDENT>def rename_file(self, relativePath, newRelativePath,<EOL>force=False, raiseError=True, ntrials=<NUM_LIT:3>):<DEDENT>

assert isinstance(raiseError, bool), "<STR_LIT>"<EOL>assert isinstance(force, bool), "<STR_LIT>"<EOL>assert isinstance(ntrials, int), "<STR_LIT>"<EOL>assert ntrials><NUM_LIT:0>, "<STR_LIT>"<EOL>relativePath = self.to_repo_relative_path(path=relativePath, split=False)<EOL>realPath     = os.path.join(self.__path,relativePath)<EOL>fPath, fName = os.path.split(realPath)<EOL>newRelativePath = self.to_repo_relative_path(path=newRelativePath, split=False)<EOL>newRealPath     = os.path.join(self.__path,newRelativePath)<EOL>nfPath, nfName  = os.path.split(newRealPath)<EOL>LO =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(fPath,self.__fileLock%fName))<EOL>acquired, code = LO.acquire_lock()<EOL>if not acquired:<EOL><INDENT>error = "<STR_LIT>"%(code,relativePath)<EOL>assert not raiseError, error<EOL>return False, error<EOL><DEDENT>try:<EOL><INDENT>success, reason = self.add_directory(nfPath, raiseError=False, ntrials=ntrials)<EOL><DEDENT>except Exception as err:<EOL><INDENT>reason  = "<STR_LIT>"%(str(err))<EOL>success = False<EOL><DEDENT>if not success:<EOL><INDENT>LO.release_lock()<EOL>assert not raiseError, reason<EOL>return False, reason<EOL><DEDENT>LN =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(nfPath,self.__fileLock%nfName))<EOL>acquired, code = LN.acquire_lock()<EOL>if not acquired:<EOL><INDENT>LO.release_lock()<EOL>error = "<STR_LIT>"%(code,newRelativePath)<EOL>assert not raiseError, error<EOL>return False, error<EOL><DEDENT>for _trial in range(ntrials):<EOL><INDENT>renamed = False<EOL>error   = None<EOL>try:<EOL><INDENT>isRepoFile,fileOnDisk, infoOnDisk, classOnDisk = self.is_repository_file(relativePath)<EOL>assert isRepoFile,  "<STR_LIT>"%(relativePath,)<EOL>assert fileOnDisk,  "<STR_LIT>"%(relativePath,)<EOL>assert infoOnDisk,  "<STR_LIT>"%self.__fileInfo%fName<EOL>assert classOnDisk, "<STR_LIT>"%self.__fileClass%fName<EOL>nisRepoFile,nfileOnDisk,ninfoOnDisk,nclassOnDisk = self.is_repository_file(newRelativePath)<EOL>assert not nisRepoFile or force, "<STR_LIT>"<EOL>oDirList = self.__get_repository_directory(fPath)<EOL>nDirList = self.__get_repository_directory(nfPath)<EOL>if os.path.isfile(newRealPath):<EOL><INDENT>os.remove(newRealPath)<EOL><DEDENT>if os.path.isfile(os.path.join(nfPath,self.__fileInfo%nfName)):<EOL><INDENT>os.remove(os.path.join(nfPath,self.__fileInfo%nfName))<EOL><DEDENT>if os.path.isfile(os.path.join(nfPath,self.__fileClass%nfName)):<EOL><INDENT>os.remove(os.path.join(nfPath,self.__fileClass%nfName))<EOL><DEDENT>os.rename(realPath, newRealPath)<EOL>os.rename(os.path.join(fPath,self.__fileInfo%fName), os.path.join(nfPath,self.__fileInfo%nfName))<EOL>os.rename(os.path.join(fPath,self.__fileClass%fName), os.path.join(nfPath,self.__fileClass%nfName))<EOL>findex = oDirList.index(fName)<EOL>oDirList.pop(findex)<EOL>if nfName not in nDirList:<EOL><INDENT>nDirList.append(nfName)<EOL><DEDENT><DEDENT>except Exception as err:<EOL><INDENT>renamed = False<EOL>error = str(err)<EOL>if self.DEBUG_PRINT_FAILED_TRIALS: print("<STR_LIT>"%(_trial, inspect.stack()[<NUM_LIT:1>][<NUM_LIT:3>], str(error)))<EOL><DEDENT>else:<EOL><INDENT>renamed = True<EOL>break<EOL><DEDENT><DEDENT>LO.release_lock()<EOL>LN.release_lock()<EOL>try:<EOL><INDENT>if os.path.isfile(os.path.join(fPath,self.__fileLock%fName)):<EOL><INDENT>os.remove(os.path.join(fPath,self.__fileLock%fName))<EOL><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT>assert renamed or not raiseError, "<STR_LIT>"%(relativePath, newRelativePath, ntrials, error,)<EOL>return renamed, error<EOL>

Rename a file in the repository. It insures renaming the file in the system.

:Parameters:
    #. relativePath (string): The relative to the repository path of
       the file that needst to be renamed.
    #. newRelativePath (string): The new relative to the repository path
       of where to move and rename the file.
    #. force (boolean): Whether to force renaming even when another
       repository file exists. In this case old repository file
       will be removed from the repository and the system as well.
    #. raiseError (boolean): Whether to raise encountered error instead
       of returning failure.
    #. ntrials (int): After aquiring all locks, ntrials is the maximum
       number of trials allowed before failing.
       In rare cases, when multiple processes
       are accessing the same repository components, different processes
       can alter repository components between successive lock releases
       of some other process. Bigger number of trials lowers the
       likelyhood of failure due to multiple processes same time
       alteration.

:Returns:
    #. success (boolean): Whether renaming the file was successful.
    #. message (None, string): Some explanatory message or error reason
       why directory was not updated.


@path_required<EOL><INDENT>def remove_file(self, relativePath, removeFromSystem=False,<EOL>raiseError=True, ntrials=<NUM_LIT:3>):<DEDENT>

assert isinstance(raiseError, bool), "<STR_LIT>"<EOL>assert isinstance(removeFromSystem, bool), "<STR_LIT>"<EOL>assert isinstance(ntrials, int), "<STR_LIT>"<EOL>assert ntrials><NUM_LIT:0>, "<STR_LIT>"<EOL>relativePath = self.to_repo_relative_path(path=relativePath, split=False)<EOL>realPath     = os.path.join(self.__path,relativePath)<EOL>fPath, fName = os.path.split(realPath)<EOL>LF =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(fPath,self.__fileLock%fName))<EOL>acquired, code = LF.acquire_lock()<EOL>if not acquired:<EOL><INDENT>error = "<STR_LIT>"%(code,relativePath)<EOL>assert not raiseError, error<EOL>return False, error<EOL><DEDENT>for _trial in range(ntrials):<EOL><INDENT>removed = False<EOL>message = []<EOL>try:<EOL><INDENT>isRepoFile,fileOnDisk, infoOnDisk, classOnDisk = self.is_repository_file(relativePath)<EOL>if not isRepoFile:<EOL><INDENT>message("<STR_LIT>"%(relativePath,))<EOL>if fileOnDisk:<EOL><INDENT>message.append("<STR_LIT>")<EOL><DEDENT>if infoOnDisk:<EOL><INDENT>message.append("<STR_LIT>"%self.__fileInfo%fName)<EOL><DEDENT>if classOnDisk:<EOL><INDENT>message.append("<STR_LIT>"%self.__fileClass%fName)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>dirList = self.__get_repository_directory(fPath)<EOL>findex  = dirList.index(fName)<EOL>dirList.pop(findex)<EOL>if os.path.isfile(realPath):<EOL><INDENT>os.remove(realPath)<EOL><DEDENT>if os.path.isfile(os.path.join(fPath,self.__fileInfo%fName)):<EOL><INDENT>os.remove(os.path.join(fPath,self.__fileInfo%fName))<EOL><DEDENT>if os.path.isfile(os.path.join(fPath,self.__fileClass%fName)):<EOL><INDENT>os.remove(os.path.join(fPath,self.__fileClass%fName))<EOL><DEDENT><DEDENT><DEDENT>except Exception as err:<EOL><INDENT>removed = False<EOL>message.append(str(err))<EOL>if self.DEBUG_PRINT_FAILED_TRIALS: print("<STR_LIT>"%(_trial, inspect.stack()[<NUM_LIT:1>][<NUM_LIT:3>], '<STR_LIT:\n>'.join(message)))<EOL><DEDENT>else:<EOL><INDENT>removed = True<EOL>break<EOL><DEDENT><DEDENT>LF.release_lock()<EOL>try:<EOL><INDENT>if os.path.isfile(os.path.join(fPath,self.__fileLock%fName)):<EOL><INDENT>os.remove(os.path.join(fPath,self.__fileLock%fName))<EOL><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT>assert removed or not raiseError, "<STR_LIT>"%(relativePath, ntrials, '<STR_LIT:\n>'.join(message),)<EOL>return removed, '<STR_LIT:\n>'.join(message)<EOL>

Remove file from repository.

:Parameters:
    #. relativePath (string): The relative to the repository path of the
       file to remove.
    #. removeFromSystem (boolean): Whether to remove file from disk as
       well.
    #. raiseError (boolean): Whether to raise encountered error instead
       of returning failure.
    #. ntrials (int): After aquiring all locks, ntrials is the maximum
       number of trials allowed before failing.
       In rare cases, when multiple processes
       are accessing the same repository components, different processes
       can alter repository components between successive lock releases
       of some other process. Bigger number of trials lowers the
       likelyhood of failure due to multiple processes same time
       alteration.


@wraps(func)<EOL>def wrapper(self, *args, **kwargs):<EOL><INDENT>if self.path is None:<EOL><INDENT>warnings.warn('<STR_LIT>')<EOL>return<EOL><DEDENT>return func(self, *args, **kwargs)<EOL><DEDENT>return wrapper<EOL>

Decorate methods when repository path is required.


@wraps(func)<EOL>def wrapper(self, *args, **kwargs):<EOL><INDENT>with self.locker as r:<EOL><INDENT>acquired, code, _  = r<EOL>if acquired:<EOL><INDENT>try:<EOL><INDENT>r = func(self, *args, **kwargs)<EOL><DEDENT>except Exception as err:<EOL><INDENT>e = str(err)<EOL><DEDENT>else:<EOL><INDENT>e = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>warnings.warn("<STR_LIT>"%(code,func.__name__) )<EOL>e = None<EOL>r = None<EOL><DEDENT><DEDENT>if e is not None:<EOL><INDENT>traceback.print_stack()<EOL>raise Exception(e)<EOL><DEDENT>return r<EOL><DEDENT>return wrapper<EOL>

Decorate methods when locking repository is required.


@wraps(func)<EOL>def wrapper(self, *args, **kwargs):<EOL><INDENT>if not self._keepSynchronized:<EOL><INDENT>r = func(self, *args, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>state = self._load_state()<EOL>if state is None:<EOL><INDENT>r = func(self, *args, **kwargs)<EOL><DEDENT>elif state == self.state:<EOL><INDENT>r = func(self, *args, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>warnings.warn("<STR_LIT>"%self.path)<EOL>r = None<EOL><DEDENT><DEDENT>return r<EOL><DEDENT>return wrapper<EOL>

Decorate methods when synchronizing repository is required.


if seen == None:<EOL><INDENT>seen = []<EOL><DEDENT>if hasattr(obj, "<STR_LIT>"):<EOL><INDENT>state = obj.__getstate__()<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>if state == None:<EOL><INDENT>return '<STR_LIT>'<EOL><DEDENT>if isinstance(state,tuple):<EOL><INDENT>if not isinstance(state[<NUM_LIT:0>], dict):<EOL><INDENT>state=state[<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>state=state[<NUM_LIT:0>].update(state[<NUM_LIT:1>])<EOL><DEDENT><DEDENT>result = {}<EOL>for i in state:<EOL><INDENT>try:<EOL><INDENT>pickle.dumps(state[i], protocol=<NUM_LIT:2>)<EOL><DEDENT>except pickle.PicklingError as e:<EOL><INDENT>if not state[i] in seen:<EOL><INDENT>seen.append(state[i])<EOL>result[i]=get_pickling_errors(state[i],seen)<EOL><DEDENT><DEDENT><DEDENT>return result<EOL>


return self.__state<EOL>


return self.__locker<EOL>


return self.__path<EOL>

The repository instance path which points to the folder and
        directory where .pyrepinfo is.


return copy.deepcopy( self.__info )<EOL>

The unique user defined information of this repository instance.


return dict.__getitem__(self,"<STR_LIT>")<EOL>


The universally unique id of this repository.


assert isinstance(ACID, bool), "<STR_LIT>"<EOL>self.__ACID = ACID<EOL>

Set the gobal ACID poperty of the repository.

:parameters:
    #. ACID (boolean): Whether to ensure the ACID (Atomicity, Consistency, Isolation, Durability)
       properties of the repository upon dumping a file. This is ensured by dumping the file in
       a temporary path first and then moving it to the desired path.


if self.__path is None:<EOL><INDENT>return []<EOL><DEDENT>repr = [ self.__path+"<STR_LIT>"+'<STR_LIT:U+002C>'.join(list(dict.__getitem__(self, '<STR_LIT>')))+'<STR_LIT:]>' ]<EOL>for directory in sorted(list(self.walk_directories_relative_path())):<EOL><INDENT>directoryRepr = os.path.normpath(directory)<EOL>dirInfoDict, errorMessage = self.get_directory_info(directory)<EOL>assert dirInfoDict is not None, errorMessage<EOL>directoryRepr += "<STR_LIT>"+'<STR_LIT:U+002C>'.join( list(dict.__getitem__(dirInfoDict, '<STR_LIT>')))+'<STR_LIT:]>'<EOL>repr.append(directoryRepr)<EOL><DEDENT>return repr<EOL>

Gets a representation of the Repository content in a list of directories(files) format.

:Returns:
    #. repr (list): The list representation of the Repository content.


def walk_files(directory, relativePath):<EOL><INDENT>directories = dict.__getitem__(directory, '<STR_LIT>')<EOL>files       = dict.__getitem__(directory, '<STR_LIT>')<EOL>for f in sorted(files):<EOL><INDENT>yield os.path.join(relativePath, f)<EOL><DEDENT>for k in sorted(dict.keys(directories)):<EOL><INDENT>path = os.path.join(relativePath, k)<EOL>dir  = directories.__getitem__(k)<EOL>for e in walk_files(dir, path):<EOL><INDENT>yield e<EOL><DEDENT><DEDENT><DEDENT>dir, errorMessage = self.get_directory_info(relativePath)<EOL>assert dir is not None, errorMessage<EOL>return walk_files(dir, relativePath='<STR_LIT>')<EOL>

Walk the repository and yield all found files relative path joined with file name.

:parameters:
    #. relativePath (str): The relative path from which start the walk.


def walk_files(directory, relativePath):<EOL><INDENT>directories = dict.__getitem__(directory, '<STR_LIT>')<EOL>files       = dict.__getitem__(directory, '<STR_LIT>')<EOL>for fname in sorted(files):<EOL><INDENT>info = dict.__getitem__(files,fname)<EOL>yield os.path.join(relativePath, fname), info<EOL><DEDENT>for k in sorted(dict.keys(directories)):<EOL><INDENT>path = os.path.join(relativePath, k)<EOL>dir  = dict.__getitem__(directories, k)<EOL>for e in walk_files(dir, path):<EOL><INDENT>yield e<EOL><DEDENT><DEDENT><DEDENT>dir, errorMessage = self.get_directory_info(relativePath)<EOL>assert dir is not None, errorMessage<EOL>return walk_files(dir, relativePath='<STR_LIT>')<EOL>

Walk the repository and yield tuples as the following:\n
(relative path to relativePath joined with file name, file info dict).

:parameters:
    #. relativePath (str): The relative path from which start the walk.


def walk_directories(directory, relativePath):<EOL><INDENT>directories = dict.__getitem__(directory, '<STR_LIT>')<EOL>dirNames = dict.keys(directories)<EOL>for d in sorted(dirNames):<EOL><INDENT>yield os.path.join(relativePath, d)<EOL><DEDENT>for k in sorted(dict.keys(directories)):<EOL><INDENT>path = os.path.join(relativePath, k)<EOL>dir  = dict.__getitem__(directories, k)<EOL>for e in walk_directories(dir, path):<EOL><INDENT>yield e<EOL><DEDENT><DEDENT><DEDENT>dir, errorMessage = self.get_directory_info(relativePath)<EOL>assert dir is not None, errorMessage<EOL>return walk_directories(dir, relativePath='<STR_LIT>')<EOL>

Walk repository and yield all found directories relative path

:parameters:
    #. relativePath (str): The relative path from which start the walk.


def walk_directories(directory, relativePath):<EOL><INDENT>directories = dict.__getitem__(directory, '<STR_LIT>')<EOL>for fname in sorted(directories):<EOL><INDENT>info = dict.__getitem__(directories,fname)<EOL>yield os.path.join(relativePath, fname), info<EOL><DEDENT>for k in sorted(dict.keys(directories)):<EOL><INDENT>path = os.path.join(relativePath, k)<EOL>dir  = dict.__getitem__(directories, k)<EOL>for e in walk_directories(dir, path):<EOL><INDENT>yield e<EOL><DEDENT><DEDENT><DEDENT>dir, errorMessage = self.get_directory_info(relativePath)<EOL>assert dir is not None, errorMessage<EOL>return walk_directories(dir, relativePath='<STR_LIT>')<EOL>

Walk repository and yield all found directories relative path.

:parameters:
    #. relativePath (str): The relative path from which start the walk.


<EOL>relativePath = os.path.normpath(relativePath)<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>for fname in dict.__getitem__(dirInfoDict, "<STR_LIT>"):<EOL><INDENT>yield os.path.join(relativePath, fname)<EOL><DEDENT>

Walk a certain directory in repository and yield all found
files relative path joined with file name.

:parameters:
    #. relativePath (str): The relative path of the directory.


<EOL>relativePath = os.path.normpath(relativePath)<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>for fname in dict.__getitem__(dirInfoDict, "<STR_LIT>"):<EOL><INDENT>yield os.path.join(relativePath, fname),  dict.__getitem__(dirInfoDict, "<STR_LIT>")[fname]<EOL><DEDENT>

Walk a certain directory in repository and yield tuples as the following:\n
(relative path joined with file name, file info dict).

:parameters:
    #. relativePath (str): The relative path of the directory.


<EOL>errorMessage = "<STR_LIT>"<EOL>relativePath = os.path.normpath(relativePath)<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>for dname in dict.__getitem__(dirInfoDict, "<STR_LIT>"):<EOL><INDENT>yield os.path.join(relativePath, dname)<EOL><DEDENT>

Walk a certain directory in repository and yield all found directories relative path.

:parameters:
    #. relativePath (str): The relative path of the directory.


<EOL>relativePath = os.path.normpath(relativePath)<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>for fname in dict.__getitem__(dirInfoDict, "<STR_LIT>"):<EOL><INDENT>yield os.path.join(relativePath, fname), dict.__getitem__(dirInfoDict, "<STR_LIT>")[fname]<EOL><DEDENT>

Walk a certain directory in repository and yield tuples as the following:\n
(relative path joined with directory name, file info dict).

:parameters:
    #. relativePath (str): The relative path of the directory.


if self.__path is None:<EOL><INDENT>return<EOL><DEDENT>for dirPath in sorted(list(self.walk_directories_relative_path())):<EOL><INDENT>realPath = os.path.join(self.__path, dirPath)<EOL>if os.path.isdir(realPath):<EOL><INDENT>continue<EOL><DEDENT>if verbose: warnings.warn("<STR_LIT>"%realPath)<EOL>keys = dirPath.split(os.sep)<EOL>dirInfoDict = self<EOL>for idx in range(len(keys)-<NUM_LIT:1>):<EOL><INDENT>dirs = dict.get(dirInfoDict, '<STR_LIT>', None)<EOL>if dirs is None: break<EOL>dirInfoDict = dict.get(dirs, keys[idx], None)<EOL>if dirInfoDict is None: break<EOL><DEDENT>if dirInfoDict is not None:<EOL><INDENT>dirs = dict.get(dirInfoDict, '<STR_LIT>', None)<EOL>if dirs is not None:<EOL><INDENT>dict.pop( dirs, keys[-<NUM_LIT:1>], None )<EOL><DEDENT><DEDENT><DEDENT>for filePath in sorted(list(self.walk_files_relative_path())):<EOL><INDENT>realPath = os.path.join(self.__path, filePath)<EOL>if os.path.isfile( realPath ):<EOL><INDENT>continue<EOL><DEDENT>if verbose: warnings.warn("<STR_LIT>"%realPath)<EOL>keys = filePath.split(os.sep)<EOL>dirInfoDict = self<EOL>for idx in range(len(keys)-<NUM_LIT:1>):<EOL><INDENT>dirs = dict.get(dirInfoDict, '<STR_LIT>', None)<EOL>if dirs is None: break<EOL>dirInfoDict = dict.get(dirs, keys[idx], None)<EOL>if dirInfoDict is None: break<EOL><DEDENT>if dirInfoDict is not None:<EOL><INDENT>files = dict.get(dirInfoDict, '<STR_LIT>', None)<EOL>if files is not None:<EOL><INDENT>dict.pop( files, keys[-<NUM_LIT:1>], None )<EOL><DEDENT><DEDENT><DEDENT>

Synchronizes the Repository information with the directory.
All registered but missing files and directories in the directory,
will be automatically removed from the Repository.

:parameters:
    #. verbose (boolean): Whether to be warn and inform about any abnormalities.


<EOL>if path.strip() in ('<STR_LIT>','<STR_LIT:.>'):<EOL><INDENT>path = os.getcwd()<EOL><DEDENT>repoPath = os.path.realpath( os.path.expanduser(path) )<EOL>if not self.is_repository(repoPath):<EOL><INDENT>raise Exception("<STR_LIT>"%str(repoPath))<EOL><DEDENT>repoInfoPath = os.path.join(repoPath, "<STR_LIT>")<EOL>try:<EOL><INDENT>fd = open(repoInfoPath, '<STR_LIT:rb>')<EOL><DEDENT>except Exception as e:<EOL><INDENT>raise Exception("<STR_LIT>"%e)<EOL><DEDENT>L =  Locker(filePath=None, lockPass=str(uuid.uuid1()), lockPath=os.path.join(repoPath, "<STR_LIT>"))<EOL>acquired, code = L.acquire_lock()<EOL>if not acquired:<EOL><INDENT>warnings.warn("<STR_LIT>"%(code,) )<EOL>return<EOL><DEDENT>try:<EOL><INDENT>try:<EOL><INDENT>repo = pickle.load( fd )<EOL><DEDENT>except Exception as e:<EOL><INDENT>fd.close()<EOL>raise Exception("<STR_LIT>"%e)<EOL><DEDENT>finally:<EOL><INDENT>fd.close()<EOL><DEDENT>if not isinstance(repo, Repository):<EOL><INDENT>raise Exception("<STR_LIT>"%s)<EOL><DEDENT>else:<EOL><INDENT>self.__reset_repository()<EOL>self.__update_repository(repo)<EOL>self.__path = repoPath<EOL><DEDENT>self.__state = self._get_or_create_state()<EOL><DEDENT>except Exception as e:<EOL><INDENT>L.release_lock()<EOL>raise Exception(e)<EOL><DEDENT>finally:<EOL><INDENT>L.release_lock()<EOL><DEDENT>self.__locker = L<EOL>return self<EOL>

Load repository from a directory path and update the current instance.

:Parameters:
    #. path (string): The path of the directory from where to load the repository.
       If '.' or an empty string is passed, the current working directory will be used.

:Returns:
     #. repository (pyrep.Repository): returns self repository with loaded data.


return self.load_repository(path)<EOL>


def create_repository(self, path, info=None, verbose=True):

try:<EOL><INDENT>info = copy.deepcopy( info )<EOL><DEDENT>except:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>if path.strip() in ('<STR_LIT>','<STR_LIT:.>'):<EOL><INDENT>path = os.getcwd()<EOL><DEDENT>realPath = os.path.realpath( os.path.expanduser(path) )<EOL>if not os.path.isdir(realPath):<EOL><INDENT>os.makedirs(realPath)<EOL><DEDENT>self.__path = realPath<EOL>self.__info = info<EOL>if self.is_repository(realPath):<EOL><INDENT>if verbose:<EOL><INDENT>warnings.warn("<STR_LIT>"%path)<EOL><DEDENT><DEDENT>self.__reset_repository()<EOL>lp = '<STR_LIT>'<EOL>if self.__path is not None:<EOL><INDENT>lp = os.path.join(self.__path,lp)<EOL><DEDENT>self.__locker.set_lock_path(lp)<EOL>self.__locker.set_lock_pass(str(uuid.uuid1()))<EOL>self.save()<EOL>

create a repository in a directory.
This method insures the creation of the directory in the system if it is missing.\n

**N.B. This method erases existing pyrep repository in the path but not the repository files.**

:Parameters:
    #. path (string): The real absolute path where to create the Repository.
       If '.' or an empty string is passed, the current working directory will be used.
    #. info (None, object): Any information that can identify the repository.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


def get_repository(self, path, info=None, verbose=True):

<EOL>if path.strip() in ('<STR_LIT>','<STR_LIT:.>'):<EOL><INDENT>path = os.getcwd()<EOL><DEDENT>realPath = os.path.realpath( os.path.expanduser(path) )<EOL>if not os.path.isdir(realPath):<EOL><INDENT>os.makedirs(realPath)<EOL><DEDENT>if not self.is_repository(realPath):<EOL><INDENT>self.create_repository(realPath, info=info, verbose=verbose)<EOL><DEDENT>else:<EOL><INDENT>self.load_repository(realPath)<EOL><DEDENT>

Create a repository at given real path or load any existing one.
This method insures the creation of the directory in the system if it is missing.\n
Unlike create_repository, this method doesn't erase any existing repository
in the path but loads it instead.

**N.B. On some systems and some paths, creating a directory may requires root permissions.**

:Parameters:
    #. path (string): The real absolute path where to create the Repository.
       If '.' or an empty string is passed, the current working directory will be used.
    #. info (None, object): Any information that can identify the repository.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


def remove_repository(self, path=None, relatedFiles=False, relatedFolders=False, verbose=True):

if path is not None:<EOL><INDENT>realPath = os.path.realpath( os.path.expanduser(path) )<EOL><DEDENT>else:<EOL><INDENT>realPath = self.__path<EOL><DEDENT>if realPath is None:<EOL><INDENT>if verbose: warnings.warn('<STR_LIT>')<EOL>return<EOL><DEDENT>if not self.is_repository(realPath):<EOL><INDENT>if verbose: warnings.warn("<STR_LIT>"%realPath)<EOL>return<EOL><DEDENT>if realPath == os.path.realpath('<STR_LIT>') :<EOL><INDENT>if verbose: warnings.warn('<STR_LIT>')<EOL>return<EOL><DEDENT>if path is not None:<EOL><INDENT>repo = Repository()<EOL>repo.load_repository(realPath)<EOL><DEDENT>else:<EOL><INDENT>repo = self<EOL><DEDENT>if relatedFiles:<EOL><INDENT>for relativePath in repo.walk_files_relative_path():<EOL><INDENT>realPath = os.path.join(repo.path, relativePath)<EOL>if not os.path.isfile(realPath):<EOL><INDENT>continue<EOL><DEDENT>if not os.path.exists(realPath):<EOL><INDENT>continue<EOL><DEDENT>os.remove( realPath )<EOL><DEDENT><DEDENT>if relatedFolders:<EOL><INDENT>for relativePath in reversed(list(repo.walk_directories_relative_path())):<EOL><INDENT>realPath = os.path.join(repo.path, relativePath)<EOL>if not os.path.isdir(realPath):<EOL><INDENT>continue<EOL><DEDENT>if not os.path.exists(realPath):<EOL><INDENT>continue<EOL><DEDENT>if not len(os.listdir(realPath)):<EOL><INDENT>os.rmdir( realPath )<EOL><DEDENT><DEDENT><DEDENT>os.remove( os.path.join(repo.path, "<STR_LIT>" ) )<EOL>for fname in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>p = os.path.join(repo.path, fname )<EOL>if os.path.exists( p ):<EOL><INDENT>os.remove( p )<EOL><DEDENT><DEDENT>if os.path.isdir(repo.path):<EOL><INDENT>if not len(os.listdir(repo.path)):<EOL><INDENT>os.rmdir( repo.path )<EOL><DEDENT><DEDENT>repo.__reset_repository()<EOL>

Remove .pyrepinfo file from path if exists and related files and directories
when respective flags are set to True.

:Parameters:
    #. path (None, string): The path of the directory where to remove an existing repository.
       If None, current repository is removed if initialized.
    #. relatedFiles (boolean): Whether to also remove all related files from system as well.
    #. relatedFolders (boolean): Whether to also remove all related directories from system as well.
       Directories will be removed only if they are left empty after removing the files.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


<EOL>repoInfoPath = os.path.join(self.__path, "<STR_LIT>")<EOL>try:<EOL><INDENT>fdinfo = open(repoInfoPath, '<STR_LIT:wb>')<EOL><DEDENT>except Exception as e:<EOL><INDENT>raise Exception("<STR_LIT>"%e)<EOL><DEDENT>try:<EOL><INDENT>pickle.dump( self, fdinfo, protocol=<NUM_LIT:2> )<EOL><DEDENT>except Exception as e:<EOL><INDENT>fdinfo.flush()<EOL>os.fsync(fdinfo.fileno())<EOL>fdinfo.close()<EOL>raise Exception( "<STR_LIT>"%e )<EOL><DEDENT>finally:<EOL><INDENT>fdinfo.flush()<EOL>os.fsync(fdinfo.fileno())<EOL>fdinfo.close()<EOL><DEDENT>repoTimePath = os.path.join(self.__path, "<STR_LIT>")<EOL>try:<EOL><INDENT>self.__state = ("<STR_LIT>"%time.time()).encode()<EOL>with open(repoTimePath, '<STR_LIT:wb>') as fdtime:<EOL><INDENT>fdtime.write( self.__state )<EOL>fdtime.flush()<EOL>os.fsync(fdtime.fileno())<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>raise Exception("<STR_LIT>"%e)<EOL><DEDENT>


@path_required<EOL><INDENT>def create_package(self, path=None, name=None, mode=None):<DEDENT>

<EOL>assert mode in (None, '<STR_LIT:w>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'), '<STR_LIT>'%str(mode)<EOL>if mode is None:<EOL><INDENT>mode = '<STR_LIT>'<EOL>mode = '<STR_LIT>'<EOL><DEDENT>if path is None:<EOL><INDENT>root = os.path.split(self.__path)[<NUM_LIT:0>]<EOL><DEDENT>elif path.strip() in ('<STR_LIT>','<STR_LIT:.>'):<EOL><INDENT>root = os.getcwd()<EOL><DEDENT>else:<EOL><INDENT>root = os.path.realpath( os.path.expanduser(path) )<EOL><DEDENT>assert os.path.isdir(root), '<STR_LIT>'%path<EOL>if name is None:<EOL><INDENT>ext = mode.split("<STR_LIT::>")<EOL>if len(ext) == <NUM_LIT:2>:<EOL><INDENT>if len(ext[<NUM_LIT:1>]):<EOL><INDENT>ext = "<STR_LIT:.>"+ext[<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>ext = '<STR_LIT>'<EOL><DEDENT><DEDENT>else:<EOL><INDENT>ext = '<STR_LIT>'<EOL><DEDENT>name = os.path.split(self.__path)[<NUM_LIT:1>]+ext<EOL><DEDENT>self.save()<EOL>tarfilePath = os.path.join(root, name)<EOL>try:<EOL><INDENT>tarHandler = tarfile.TarFile.open(tarfilePath, mode=mode)<EOL><DEDENT>except Exception as e:<EOL><INDENT>raise Exception("<STR_LIT>"%e)<EOL><DEDENT>for directory in sorted(list(self.walk_directories_relative_path())):<EOL><INDENT>t = tarfile.TarInfo( directory )<EOL>t.type = tarfile.DIRTYPE<EOL>tarHandler.addfile(t)<EOL><DEDENT>for file in self.walk_files_relative_path():<EOL><INDENT>tarHandler.add(os.path.join(self.__path,file), arcname=file)<EOL><DEDENT>tarHandler.add(os.path.join(self.__path,"<STR_LIT>"), arcname="<STR_LIT>")<EOL>tarHandler.close()<EOL>

Create a tar file package of all the repository files and directories.
Only files and directories that are stored in the repository info
are stored in the package tar file.

**N.B. On some systems packaging requires root permissions.**

:Parameters:
    #. path (None, string): The real absolute path where to create the package.
       If None, it will be created in the same directory as the repository
       If '.' or an empty string is passed, the current working directory will be used.
    #. name (None, string): The name to give to the package file
       If None, the package directory name will be used with the appropriate extension added.
    #. mode (None, string): The writing mode of the tarfile.
       If None, automatically the best compression mode will be chose.
       Available modes are ('w', 'w:', 'w:gz', 'w:bz2')


realPath = os.path.realpath( os.path.expanduser(path) )<EOL>if not os.path.isdir(realPath):<EOL><INDENT>return False<EOL><DEDENT>if "<STR_LIT>" not in os.listdir(realPath):<EOL><INDENT>return False<EOL><DEDENT>return True<EOL>

Check if there is a Repository in path.

:Parameters:
    #. path (string): The real path of the directory where to check if there is a repository.

:Returns:
    #. result (boolean): Whether its a repository or not.


relativePath = os.path.normpath(relativePath)<EOL>if relativePath in ('<STR_LIT>','<STR_LIT:.>'):<EOL><INDENT>return self, "<STR_LIT>"<EOL><DEDENT>currentDir  = self.__path<EOL>dirInfoDict = self<EOL>for dir in relativePath.split(os.sep):<EOL><INDENT>dirInfoDict = dict.__getitem__(dirInfoDict, "<STR_LIT>")<EOL>currentDir = os.path.join(currentDir, dir)<EOL>if not os.path.exists(currentDir):<EOL><INDENT>return None,  "<STR_LIT>"%currentDir<EOL><DEDENT>val = dirInfoDict.get(dir, None)<EOL>if val is None:<EOL><INDENT>return None,  "<STR_LIT>"%currentDir<EOL><DEDENT>dirInfoDict = val<EOL><DEDENT>return dirInfoDict, "<STR_LIT>"<EOL>

get directory info from the Repository.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory.

:Returns:
    #. info (None, dictionary): The directory information dictionary.
       If None, it means an error has occurred.
    #. error (string): The error message if any error occurred.


relativePath = os.path.normpath(relativePath)<EOL>if relativePath in ('<STR_LIT>','<STR_LIT:.>'):<EOL><INDENT>return self, "<STR_LIT>"<EOL><DEDENT>parentDirPath, _ = os.path.split(relativePath)<EOL>return self.get_directory_info(parentDirPath)<EOL>

get parent directory info of a file or directory from the Repository.

:Parameters:
    #. relativePath (string): The relative to the repository path of the file or directory of which the parent directory info is requested.

:Returns:
    #. info (None, dictionary): The directory information dictionary.
       If None, it means an error has occurred.
    #. error (string): The error message if any error occurred.


def get_file_info(self, relativePath, name=None):

<EOL>relativePath = os.path.normpath(relativePath)<EOL>if relativePath == '<STR_LIT:.>':<EOL><INDENT>relativePath = '<STR_LIT>'<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL><DEDENT>if name is None:<EOL><INDENT>assert len(relativePath), "<STR_LIT>"<EOL>relativePath,name = os.path.split(relativePath)<EOL><DEDENT>errorMessage = "<STR_LIT>"<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>if dirInfoDict is None:<EOL><INDENT>return None, errorMessage<EOL><DEDENT>fileInfo = dict.__getitem__(dirInfoDict, "<STR_LIT>").get(name, None)<EOL>if fileInfo is None:<EOL><INDENT>errorMessage = "<STR_LIT>"%(name, relativePath)<EOL><DEDENT>return fileInfo, errorMessage<EOL>

get file information dict from the repository given its relative path and name.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory where the file is.
    #. name (string): The file name.
       If None is given, name will be split from relativePath.

:Returns:
    #. info (None, dictionary): The file information dictionary.
       If None, it means an error has occurred.
    #. errorMessage (string): The error message if any error occurred.


for path, info in self.walk_files_info():<EOL><INDENT>if info['<STR_LIT:id>']==id:<EOL><INDENT>return path, info<EOL><DEDENT><DEDENT>return None, None<EOL>

Given an id, get the corresponding file info as the following:\n
(relative path joined with file name, file info dict)

Parameters:
    #. id (string): The file unique id string.

:Returns:
    #. relativePath (string): The file relative path joined with file name.
       If None, it means file was not found.
    #. info (None, dictionary): The file information dictionary.
       If None, it means file was not found.


for path, info in self.walk_files_info():<EOL><INDENT>if info['<STR_LIT:id>']==id:<EOL><INDENT>return path<EOL><DEDENT><DEDENT>return None<EOL>

Given an id, get the corresponding file info relative path joined with file name.

Parameters:
    #. id (string): The file unique id string.

:Returns:
    #. relativePath (string): The file relative path joined with file name.
       If None, it means file was not found.


def get_file_relative_path_by_name(self, name, skip=<NUM_LIT:0>):

if skip is None:<EOL><INDENT>paths = []<EOL><DEDENT>else:<EOL><INDENT>paths = None<EOL><DEDENT>for path, info in self.walk_files_info():<EOL><INDENT>_, n = os.path.split(path)<EOL>if n==name:<EOL><INDENT>if skip is None:<EOL><INDENT>paths.append(path)<EOL><DEDENT>elif skip><NUM_LIT:0>:<EOL><INDENT>skip -= <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>paths = path<EOL>break<EOL><DEDENT><DEDENT><DEDENT>return paths<EOL>

Get file relative path given the file name. If file name is redundant in different
directories in the repository, this method ensures to return all or some of the
files according to skip value.

Parameters:
    #. name (string): The file name.
    #. skip (None, integer): As file names can be identical, skip determines
       the number of satisfying files name to skip before returning.\n
       If None is given, a list of all files relative path will be returned.

:Returns:
    #. relativePath (string, list): The file relative path.
       If None, it means file was not found.\n
       If skip is None a list of all found files relative paths will be returned.


def get_file_info_by_name(self, name, skip=<NUM_LIT:0>):

if skip is None:<EOL><INDENT>paths = []<EOL>infos = []<EOL><DEDENT>else:<EOL><INDENT>paths = None<EOL>infos = None<EOL><DEDENT>for path, info in self.walk_files_info():<EOL><INDENT>_, n = os.path.split(path)<EOL>if n==name:<EOL><INDENT>if skip is None:<EOL><INDENT>paths.append(path)<EOL>infos.append(info)<EOL><DEDENT>elif skip><NUM_LIT:0>:<EOL><INDENT>skip -= <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>paths = path<EOL>infos = info<EOL>break<EOL><DEDENT><DEDENT><DEDENT>return paths, infos<EOL>

Get file information tuple given the file name. If file name is redundant in different
directories in the repository, this method ensures to return all or some of the
files infos according to skip value.

Parameters:
    #. name (string): The file name.
    #. skip (None, integer): As file names can be identical, skip determines
       the number of satisfying files name to skip before returning.\n
       If None is given, a list of all files relative path will be returned.

:Returns:
    #. relativePath (string, list): The file relative path joined with file name.
       If None, it means file was not found.\n
       If skip is None a list of all found files relative paths will be returned.
    #. info (None, dictionary, list): The file information dictionary.
       If None, it means file was not found.\n
       If skip is None a list of all found files info dicts will be returned.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def add_directory(self, relativePath, info=None):<DEDENT>

path = os.path.normpath(relativePath)<EOL>currentDir  = self.path<EOL>currentDict = self<EOL>if path in ("<STR_LIT>","<STR_LIT:.>"):<EOL><INDENT>return currentDict<EOL><DEDENT>save = False<EOL>for dir in path.split(os.sep):<EOL><INDENT>dirPath = os.path.join(currentDir, dir)<EOL>if not os.path.exists(dirPath):<EOL><INDENT>os.mkdir(dirPath)<EOL><DEDENT>currentDict = dict.__getitem__(currentDict, "<STR_LIT>")<EOL>if currentDict.get(dir, None) is None:<EOL><INDENT>save = True<EOL>currentDict[dir] = {"<STR_LIT>":{}, "<STR_LIT>":{},<EOL>"<STR_LIT>":datetime.utcnow(),<EOL>"<STR_LIT:id>":str(uuid.uuid1()),<EOL>"<STR_LIT:info>": info} <EOL><DEDENT>currentDict = currentDict[dir]<EOL>currentDir  = dirPath<EOL><DEDENT>if save:<EOL><INDENT>self.save()<EOL><DEDENT>return currentDict<EOL>

Adds a directory in the repository and creates its
attribute in the Repository with utc timestamp.
It insures adding all the missing directories in the path.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory to add in the repository.
    #. info (None, string, pickable object): Any random info about the folder.

:Returns:
    #. info (dict): The directory info dict.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def remove_directory(self, relativePath, removeFromSystem=False):<DEDENT>

<EOL>relativePath = os.path.normpath(relativePath)<EOL>parentDirInfoDict, errorMessage = self.get_parent_directory_info(relativePath)<EOL>assert parentDirInfoDict is not None, errorMessage<EOL>path, name = os.path.split(relativePath)<EOL>if dict.__getitem__(parentDirInfoDict, '<STR_LIT>').get(name, None) is None:<EOL><INDENT>raise Exception("<STR_LIT>"%(name, path))<EOL><DEDENT>if removeFromSystem:<EOL><INDENT>for rp in self.walk_files_relative_path(relativePath=relativePath):<EOL><INDENT>ap = os.path.join(self.__path, relativePath, rp)<EOL>if not os.path.isfile(ap):<EOL><INDENT>continue<EOL><DEDENT>if not os.path.exists(ap):<EOL><INDENT>continue<EOL><DEDENT>if os.path.isfile(ap):<EOL><INDENT>os.remove( ap )<EOL><DEDENT><DEDENT>for rp in self.walk_directories_relative_path(relativePath=relativePath):<EOL><INDENT>ap = os.path.join(self.__path, relativePath, rp)<EOL>if not os.path.isdir(ap):<EOL><INDENT>continue<EOL><DEDENT>if not os.path.exists(ap):<EOL><INDENT>continue<EOL><DEDENT>if not len(os.listdir(ap)):<EOL><INDENT>os.rmdir(ap)<EOL><DEDENT><DEDENT><DEDENT>dict.__getitem__(parentDirInfoDict, '<STR_LIT>').pop(name, None)<EOL>ap = os.path.join(self.__path, relativePath)<EOL>if not os.path.isdir(ap):<EOL><INDENT>if not len(os.listdir(ap)):<EOL><INDENT>os.rmdir(ap)<EOL><DEDENT><DEDENT>self.save()<EOL>

Remove directory from repository.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory to remove from the repository.
    #. removeFromSystem (boolean): Whether to also remove directory and all files from the system.\n
       Only files saved in the repository will be removed and empty left directories.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def move_directory(self, relativePath, relativeDestination, replace=False, verbose=True):<DEDENT>

<EOL>relativePath    = os.path.normpath(relativePath)<EOL>relativeDestination = os.path.normpath(relativeDestination)<EOL>filesInfo = list( self.walk_files_info(relativePath=relativePath) )<EOL>dirsPath  = list( self.walk_directories_relative_path(relativePath=relativePath) )<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>self.remove_directory(relativePath=relativePath, removeFromSystem=False)<EOL>self.add_directory(relativeDestination)<EOL>for RP, info in filesInfo:<EOL><INDENT>source      = os.path.join(self.__path, relativePath, RP)<EOL>destination = os.path.join(self.__path, relativeDestination, RP)<EOL>newDirRP, fileName = os.path.split(os.path.join(relativeDestination, RP))<EOL>dirInfoDict = self.add_directory( newDirRP )<EOL>if os.path.isfile(destination):<EOL><INDENT>if replace:<EOL><INDENT>os.remove(destination)<EOL>if verbose:<EOL><INDENT>warnings.warn("<STR_LIT>"%(fileName, newDirRP))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if verbose:<EOL><INDENT>warnings.warn("<STR_LIT>"%(fileName,destination))<EOL><DEDENT>continue<EOL><DEDENT><DEDENT>os.rename(source, destination)<EOL>dict.__getitem__(dirInfoDict, "<STR_LIT>")[fileName] = info<EOL><DEDENT>self.save()<EOL>

Move a directory in the repository from one place to another. It insures moving all the
files and subdirectories in the system.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory to be moved.
    #. relativeDestination (string): The new relative to the repository path of the directory.
    #. replace (boolean): Whether to replace existing files with the same name in the new created directory.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def rename_directory(self, relativePath, newName, replace=False, verbose=True):<DEDENT>

<EOL>relativePath    = os.path.normpath(relativePath)<EOL>parentDirInfoDict, errorMessage = self.get_parent_directory_info(relativePath)<EOL>assert parentDirInfoDict is not None, errorMessage<EOL>parentDirPath, dirName = os.path.split(relativePath)<EOL>realPath  = os.path.join(self.__path, relativePath)<EOL>assert os.path.isdir( realPath ), "<STR_LIT>"%realPath<EOL>assert dirName in dict.__getitem__(parentDirInfoDict, "<STR_LIT>"), "<STR_LIT>"%(dirName, parentDirPath)<EOL>assert newName not in dict.__getitem__(parentDirInfoDict, "<STR_LIT>"), "<STR_LIT>"%(newName, parentDirPath)<EOL>newRealPath = os.path.join(self.__path, parentDirPath, newName)<EOL>if os.path.isdir( newRealPath ):<EOL><INDENT>if replace:<EOL><INDENT>shutil.rmtree(newRealPath)<EOL>if verbose:<EOL><INDENT>warnings.warn( "<STR_LIT>"%newRealPath )<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise Exception( "<STR_LIT>"%newRealPath )<EOL><DEDENT><DEDENT>os.rename(realPath, newRealPath)<EOL>dict.__setitem__( dict.__getitem__(parentDirInfoDict, "<STR_LIT>"),<EOL>newName,<EOL>dict.__getitem__(parentDirInfoDict, "<STR_LIT>").pop(dirName) )<EOL>self.save()<EOL>

Rename a directory in the repository. It insures renaming the directory in the system.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory to be renamed.
    #. newName (string): The new directory name.
    #. replace (boolean): Whether to force renaming when new name exists in the system.
       It fails when new folder name is registered in repository.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def rename_file(self, relativePath, name, newName, replace=False, verbose=True):<DEDENT>

<EOL>relativePath = os.path.normpath(relativePath)<EOL>if relativePath == '<STR_LIT:.>':<EOL><INDENT>relativePath = '<STR_LIT>'<EOL><DEDENT>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>assert name in dict.__getitem__(dirInfoDict, "<STR_LIT>"), "<STR_LIT>"%(name, relativePath)<EOL>realPath = os.path.join(self.__path, relativePath, name)<EOL>assert os.path.isfile(realPath), "<STR_LIT>"%realPath<EOL>assert newName not in dict.__getitem__(dirInfoDict, "<STR_LIT>"), "<STR_LIT>"%(newName, relativePath)<EOL>newRealPath = os.path.join(self.__path, relativePath, newName)<EOL>if os.path.isfile( newRealPath ):<EOL><INDENT>if replace:<EOL><INDENT>os.remove(newRealPath)<EOL>if verbose:<EOL><INDENT>warnings.warn( "<STR_LIT>"%(newRealPath,realPath) )<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise Exception( "<STR_LIT>"%newRealPath )<EOL><DEDENT><DEDENT>os.rename(realPath, newRealPath)<EOL>dict.__setitem__( dict.__getitem__(dirInfoDict, "<STR_LIT>"),<EOL>newName,<EOL>dict.__getitem__(dirInfoDict, "<STR_LIT>").pop(name) )<EOL>self.save()<EOL>

Rename a directory in the repository. It insures renaming the file in the system.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory where the file is located.
    #. name (string): The file name.
    #. newName (string): The file new name.
    #. replace (boolean): Whether to force renaming when new folder name exists in the system.
       It fails when new folder name is registered in repository.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def remove_file(self, relativePath, name=None, removeFromSystem=False):<DEDENT>

<EOL>relativePath = os.path.normpath(relativePath)<EOL>if relativePath == '<STR_LIT:.>':<EOL><INDENT>relativePath = '<STR_LIT>'<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL><DEDENT>if name is None:<EOL><INDENT>assert len(relativePath), "<STR_LIT>"<EOL>relativePath, name = os.path.split(relativePath)<EOL><DEDENT>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>assert name in dict.__getitem__(dirInfoDict, "<STR_LIT>"), "<STR_LIT>"%(name, relativePath)<EOL>dict.__getitem__(dirInfoDict, "<STR_LIT>").pop(name)<EOL>if removeFromSystem:<EOL><INDENT>ap = os.path.join(self.__path, relativePath, name )<EOL>if os.path.isfile(ap):<EOL><INDENT>os.remove( ap )<EOL><DEDENT><DEDENT>self.save()<EOL>

Remove file from repository.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory where the file should be dumped.
       If relativePath does not exist, it will be created automatically.
    #. name (string): The file name.
       If None is given, name will be split from relativePath.
    #. removeFromSystem (boolean): Whether to also remove directory and all files from the system.\n
       Only files saved in the repository will be removed and empty left directories.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def dump_copy(self, path, relativePath, name=None,<EOL>description=None,<EOL>replace=False, verbose=False):<DEDENT>

relativePath = os.path.normpath(relativePath)<EOL>if relativePath == '<STR_LIT:.>':<EOL><INDENT>relativePath = '<STR_LIT>'<EOL><DEDENT>if name is None:<EOL><INDENT>_,name = os.path.split(path)<EOL><DEDENT>self.add_directory(relativePath)<EOL>realPath = os.path.join(self.__path, relativePath)<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>if name in dict.__getitem__(dirInfoDict, "<STR_LIT>"):<EOL><INDENT>if not replace:<EOL><INDENT>if verbose:<EOL><INDENT>warnings.warn("<STR_LIT>"%(name))<EOL><DEDENT>return<EOL><DEDENT><DEDENT>dump = "<STR_LIT>"<EOL>pull = "<STR_LIT>"<EOL>try:<EOL><INDENT>shutil.copyfile(path, os.path.join(realPath,name))<EOL><DEDENT>except Exception as e:<EOL><INDENT>if verbose:<EOL><INDENT>warnings.warn(e)<EOL><DEDENT>return<EOL><DEDENT>klass = None<EOL>dict.__getitem__(dirInfoDict, "<STR_LIT>")[name] = {"<STR_LIT>":dump,<EOL>"<STR_LIT>":pull,<EOL>"<STR_LIT>":datetime.utcnow(),<EOL>"<STR_LIT:id>":str(uuid.uuid1()),<EOL>"<STR_LIT:class>": klass,<EOL>"<STR_LIT:description>":description}<EOL>self.save()<EOL>

Copy an exisitng system file to the repository.
attribute in the Repository with utc timestamp.

:Parameters:
    #. path (str): The full path of the file to copy into the repository.
    #. relativePath (str): The relative to the repository path of the directory where the file should be dumped.
       If relativePath does not exist, it will be created automatically.
    #. name (string): The file name.
       If None is given, name will be split from path.
    #. description (None, string, pickable object): Any random description about the file.
    #. replace (boolean): Whether to replace any existing file with the same name if existing.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


@acquire_lock<EOL><INDENT>@sync_required<EOL>def dump_file(self, value, relativePath, name=None,<EOL>description=None, klass=None,<EOL>dump=None, pull=None,<EOL>replace=False, ACID=None, verbose=False):<DEDENT>

<EOL>if ACID is None:<EOL><INDENT>ACID = self.__ACID<EOL><DEDENT>assert isinstance(ACID, bool), "<STR_LIT>"<EOL>relativePath = os.path.normpath(relativePath)<EOL>if relativePath == '<STR_LIT:.>':<EOL><INDENT>relativePath = '<STR_LIT>'<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL><DEDENT>if name is None:<EOL><INDENT>assert len(relativePath), "<STR_LIT>"<EOL>relativePath,name = os.path.split(relativePath)<EOL><DEDENT>self.add_directory(relativePath)<EOL>realPath = os.path.join(self.__path, relativePath)<EOL>dirInfoDict, errorMessage = self.get_directory_info(relativePath)<EOL>assert dirInfoDict is not None, errorMessage<EOL>if name in dict.__getitem__(dirInfoDict, "<STR_LIT>"):<EOL><INDENT>if not replace:<EOL><INDENT>if verbose:<EOL><INDENT>warnings.warn("<STR_LIT>"%(name))<EOL><DEDENT>return<EOL><DEDENT><DEDENT>if dump is None:<EOL><INDENT>dump=DEFAULT_DUMP<EOL><DEDENT>if pull is None:<EOL><INDENT>pull=DEFAULT_PULL<EOL><DEDENT>if ACID:<EOL><INDENT>savePath = os.path.join(tempfile.gettempdir(), str(uuid.uuid1()))<EOL><DEDENT>else:<EOL><INDENT>savePath = os.path.join(realPath,name)<EOL><DEDENT>try:<EOL><INDENT>exec( dump.replace("<STR_LIT>", str(savePath)) )<EOL><DEDENT>except Exception as e:<EOL><INDENT>message = "<STR_LIT>"%e<EOL>if '<STR_LIT>' in dump:<EOL><INDENT>message += '<STR_LIT>'%str(get_pickling_errors(value))<EOL><DEDENT>raise Exception( message )<EOL><DEDENT>if ACID:<EOL><INDENT>try:<EOL><INDENT>shutil.copyfile(savePath, os.path.join(realPath,name))<EOL><DEDENT>except Exception as e:<EOL><INDENT>os.remove(savePath)<EOL>if verbose:<EOL><INDENT>warnings.warn(e)<EOL><DEDENT>return<EOL><DEDENT>os.remove(savePath)<EOL><DEDENT>if klass is None and value is not None:<EOL><INDENT>klass = value.__class__<EOL><DEDENT>if klass is not None:<EOL><INDENT>assert inspect.isclass(klass), "<STR_LIT>"<EOL><DEDENT>dict.__getitem__(dirInfoDict, "<STR_LIT>")[name] = {"<STR_LIT>":dump,<EOL>"<STR_LIT>":pull,<EOL>"<STR_LIT>":datetime.utcnow(),<EOL>"<STR_LIT:id>":str(uuid.uuid1()),<EOL>"<STR_LIT:class>": klass,<EOL>"<STR_LIT:description>":description}<EOL>self.save()<EOL>

Dump a file using its value to the system and creates its
attribute in the Repository with utc timestamp.

:Parameters:
    #. value (object): The value of a file to dump and add to the repository. It is any python object or file.
    #. relativePath (str): The relative to the repository path of the directory where the file should be dumped.
       If relativePath does not exist, it will be created automatically.
    #. name (string): The file name.
       If None is given, name will be split from relativePath.
    #. description (None, string, pickable object): Any random description about the file.
    #. klass (None, class): The dumped object class. If None is given
       klass will be automatically set to the following value.__class__
    #. dump (None, string): The dumping method.
       If None it will be set automatically to pickle and therefore the object must be pickleable.
       If a string is given, the string should include all the necessary imports
       and a '$FILE_PATH' that replaces the absolute file path when the dumping will be performed.\n
       e.g. "import numpy as np; np.savetxt(fname='$FILE_PATH', X=value, fmt='%.6e')"
    #. pull (None, string): The pulling method.
       If None it will be set automatically to pickle and therefore the object must be pickleable.
       If a string is given, the string should include all the necessary imports,
       a '$FILE_PATH' that replaces the absolute file path when the dumping will be performed
       and finally a PULLED_DATA variable.\n
       e.g "import numpy as np; PULLED_DATA=np.loadtxt(fname='$FILE_PATH')"
    #. replace (boolean): Whether to replace any existing file with the same name if existing.
    #. ACID (None, boolean): Whether to ensure the ACID (Atomicity, Consistency, Isolation, Durability)
       properties of the repository upon dumping a file. This is ensured by dumping the file in
       a temporary path first and then moving it to the desired path.
       If None is given, repository ACID property will be used.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


self.dump_file(*args, **kwargs)<EOL>


@acquire_lock<EOL><INDENT>@sync_required<EOL>def update_file(self, value, relativePath, name=None,<EOL>description=False, klass=False,<EOL>dump=False, pull=False,<EOL>ACID=None, verbose=False):<DEDENT>

<EOL>if ACID is None:<EOL><INDENT>ACID = self.__ACID<EOL><DEDENT>assert isinstance(ACID, bool), "<STR_LIT>"<EOL>relativePath = os.path.normpath(relativePath)<EOL>if relativePath == '<STR_LIT:.>':<EOL><INDENT>relativePath = '<STR_LIT>'<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL><DEDENT>if name is None:<EOL><INDENT>assert len(relativePath), "<STR_LIT>"<EOL>relativePath,name = os.path.split(relativePath)<EOL><DEDENT>fileInfoDict, errorMessage = self.get_file_info(relativePath, name)<EOL>assert fileInfoDict is not None, errorMessage<EOL>realPath = os.path.join(self.__path, relativePath)<EOL>if verbose:<EOL><INDENT>if not os.path.isfile( os.path.join(realPath, name) ):<EOL><INDENT>warnings.warn("<STR_LIT>"%os.path.join(realPath, name))<EOL><DEDENT><DEDENT>if not dump:<EOL><INDENT>dump = fileInfoDict["<STR_LIT>"]<EOL><DEDENT>if not pull:<EOL><INDENT>pull = fileInfoDict["<STR_LIT>"]<EOL><DEDENT>if ACID:<EOL><INDENT>savePath = os.path.join(tempfile.gettempdir(), name)<EOL><DEDENT>else:<EOL><INDENT>savePath = os.path.join(realPath,name)<EOL><DEDENT>try:<EOL><INDENT>exec( dump.replace("<STR_LIT>", str(savePath)) )<EOL><DEDENT>except Exception as e:<EOL><INDENT>message = "<STR_LIT>"%e<EOL>if '<STR_LIT>' in dump:<EOL><INDENT>message += '<STR_LIT>'%str(get_pickling_errors(value))<EOL><DEDENT>raise Exception( message )<EOL><DEDENT>if ACID:<EOL><INDENT>try:<EOL><INDENT>shutil.copyfile(savePath, os.path.join(realPath,name))<EOL><DEDENT>except Exception as e:<EOL><INDENT>os.remove(savePath)<EOL>if verbose:<EOL><INDENT>warnings.warn(e)<EOL><DEDENT>return<EOL><DEDENT>os.remove(savePath)<EOL><DEDENT>fileInfoDict["<STR_LIT>"] = datetime.utcnow()<EOL>if description is not False:<EOL><INDENT>fileInfoDict["<STR_LIT:description>"] = description<EOL><DEDENT>if klass is not False:<EOL><INDENT>assert inspect.isclass(klass), "<STR_LIT>"<EOL>fileInfoDict["<STR_LIT:class>"] = klass<EOL><DEDENT>self.save()<EOL>

Update the value and the utc timestamp of a file that is already in the Repository.\n
If file is not registered in repository, and error will be thrown.\n
If file is missing in the system, it will be regenerated as dump method is called.

:Parameters:
    #. value (object): The value of the file to update. It is any python object or a file.
    #. relativePath (str): The relative to the repository path of the directory where the file should be dumped.
    #. name (None, string): The file name.
       If None is given, name will be split from relativePath.
    #. description (False, string, pickable object): Any random description about the file.
       If False is given, the description info won't be updated,
       otherwise it will be update to what description argument value is.
    #. klass (False, class): The dumped object class. If False is given,
       the class info won't be updated, otherwise it will be update to what klass argument value is.
    #. dump (False, string): The new dump method. If False is given, the old one will be used.
    #. pull (False, string): The new pull method. If False is given, the old one will be used.
    #. ACID (boolean): Whether to ensure the ACID (Atomicity, Consistency, Isolation, Durability)
       properties of the repository upon dumping a file. This is ensured by dumping the file in
       a temporary path first and then moving it to the desired path.
       If None is given, repository ACID property will be used.
    #. verbose (boolean): Whether to be warn and informed about any abnormalities.


self.update_file(*args, **kwargs)<EOL>


def pull_file(self, relativePath, name=None, pull=None, update=True):

<EOL>relativePath = os.path.normpath(relativePath)<EOL>if relativePath == '<STR_LIT:.>':<EOL><INDENT>relativePath = '<STR_LIT>'<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL>assert name != '<STR_LIT>', "<STR_LIT>"<EOL><DEDENT>if name is None:<EOL><INDENT>assert len(relativePath), "<STR_LIT>"<EOL>relativePath,name = os.path.split(relativePath)<EOL><DEDENT>fileInfo, errorMessage = self.get_file_info(relativePath, name)<EOL>assert fileInfo is not None, errorMessage<EOL>realPath = os.path.join(self.__path, relativePath)<EOL>assert os.path.exists(realPath), "<STR_LIT>"%(relativePath, self.__path)<EOL>fileAbsPath = os.path.join(realPath, name)<EOL>assert os.path.isfile(fileAbsPath), "<STR_LIT>"%(name,realPath)<EOL>if pull is None:<EOL><INDENT>pull = fileInfo["<STR_LIT>"]<EOL><DEDENT>try:<EOL><INDENT>namespace = {}<EOL>namespace.update( globals() )<EOL>exec( pull.replace("<STR_LIT>", str(os.path.join(realPath,name)) ), namespace )<EOL><DEDENT>except Exception as e:<EOL><INDENT>m = pull.replace("<STR_LIT>", str(os.path.join(realPath,name)) )<EOL>raise Exception( "<STR_LIT>"%(m,e) )<EOL><DEDENT>if update:<EOL><INDENT>fileInfo["<STR_LIT>"] = pull<EOL><DEDENT>return namespace['<STR_LIT>']<EOL>

Pull a file's data from the Repository.

:Parameters:
    #. relativePath (string): The relative to the repository path of the directory where the file should be pulled.
    #. name (string): The file name.
       If None is given, name will be split from relativePath.
    #. pull (None, string): The pulling method.
       If None, the pull method saved in the file info will be used.
       If a string is given, the string should include all the necessary imports,
       a '$FILE_PATH' that replaces the absolute file path when the dumping will be performed
       and finally a PULLED_DATA variable.
       e.g "import numpy as np; PULLED_DATA=np.loadtxt(fname='$FILE_PATH')"
    #. update (boolean): If pull is not None, Whether to update the pull method stored in the file info by the given pull method.

:Returns:
    #. data (object): The pulled data from the file.


return self.pull_file(*args, **kwargs)<EOL>


return __version__<EOL>


return __author__<EOL>


return __email__<EOL>


return __onlinedoc__<EOL>

Get pyrep's official online documentation link.


return __repository__<EOL>

Get pyrep's official online repository link.


return __pypi__<EOL>


if not api_key:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>self.API_KEY = api_key<EOL>self.DEFAULT_TIMEOUT = default_timeout<EOL>self._json_encoder = json_encoder<EOL>self._raise_errors = raise_errors<EOL>if '<STR_LIT>' in kwargs:<EOL><INDENT>self.API_HOST = kwargs['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>self.API_PROTO = kwargs['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>self.API_PORT = kwargs['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>self.API_VERSION = kwargs['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>self.DEBUG = kwargs['<STR_LIT>']<EOL><DEDENT>if self.DEBUG:<EOL><INDENT>logging.basicConfig(format=LOGGER_FORMAT, level=logging.DEBUG)<EOL>logger.debug('<STR_LIT>')<EOL>logger.propagate = True<EOL><DEDENT>


if not self._raise_errors:<EOL><INDENT>return response<EOL><DEDENT>is_4xx_error = str(response.status_code)[<NUM_LIT:0>] == '<STR_LIT:4>'<EOL>is_5xx_error = str(response.status_code)[<NUM_LIT:0>] == '<STR_LIT:5>'<EOL>content = response.content<EOL>if response.status_code == <NUM_LIT>:<EOL><INDENT>raise AuthenticationError(content)<EOL><DEDENT>elif is_4xx_error:<EOL><INDENT>raise APIError(content)<EOL><DEDENT>elif is_5xx_error:<EOL><INDENT>raise ServerError(content)<EOL><DEDENT>return response<EOL>

Parses the API response and raises appropriate errors if
        raise_errors was set to True


def _api_request(self, endpoint, http_method, *args, **kwargs):

logger.debug('<STR_LIT>' % endpoint)<EOL>auth = self._build_http_auth()<EOL>headers = self._build_request_headers(kwargs.get('<STR_LIT>'))<EOL>logger.debug('<STR_LIT>' % headers)<EOL>path = self._build_request_path(endpoint)<EOL>logger.debug('<STR_LIT>' % path)<EOL>data = self._build_payload(kwargs.get('<STR_LIT>'))<EOL>if not data:<EOL><INDENT>data = kwargs.get('<STR_LIT:data>')<EOL><DEDENT>logger.debug('<STR_LIT>' % data)<EOL>req_kw = dict(<EOL>auth=auth,<EOL>headers=headers,<EOL>timeout=kwargs.get('<STR_LIT>', self.DEFAULT_TIMEOUT)<EOL>)<EOL>if (http_method == self.HTTP_POST):<EOL><INDENT>if (data):<EOL><INDENT>r = requests.post(path, data=data, **req_kw)<EOL><DEDENT>else:<EOL><INDENT>r = requests.post(path, **req_kw)<EOL><DEDENT><DEDENT>elif http_method == self.HTTP_PUT:<EOL><INDENT>if (data):<EOL><INDENT>r = requests.put(path, data=data, **req_kw)<EOL><DEDENT>else:<EOL><INDENT>r = requests.put(path, **req_kw)<EOL><DEDENT><DEDENT>elif http_method == self.HTTP_DELETE:<EOL><INDENT>r = requests.delete(path, **req_kw)<EOL><DEDENT>else:<EOL><INDENT>r = requests.get(path, **req_kw)<EOL><DEDENT>logger.debug('<STR_LIT>' % r.status_code)<EOL>try:<EOL><INDENT>logger.debug('<STR_LIT>' % r.json())<EOL><DEDENT>except:<EOL><INDENT>logger.debug('<STR_LIT>' % r.content)<EOL><DEDENT>return self._parse_response(r)<EOL>


def get_log(self, log_id, timeout=None):

return self._api_request(<EOL>self.GET_LOG_ENDPOINT % log_id,<EOL>self.HTTP_GET,<EOL>timeout=timeout<EOL>)<EOL>


def get_log_events(self, log_id, timeout=None):

return self._api_request(<EOL>self.GET_LOG_EVENTS_ENDPOINT % log_id,<EOL>self.HTTP_GET,<EOL>timeout=timeout<EOL>)<EOL>


return self.templates()<EOL>

[DEPRECATED] API call to get a list of emails


return self._api_request(<EOL>self.TEMPLATES_ENDPOINT,<EOL>self.HTTP_GET,<EOL>timeout=timeout<EOL>)<EOL>


def get_template(self, template_id, version=None, timeout=None):

if (version):<EOL><INDENT>return self._api_request(<EOL>self.TEMPLATES_VERSION_ENDPOINT % (template_id, version),<EOL>self.HTTP_GET,<EOL>timeout=timeout<EOL>)<EOL><DEDENT>else:<EOL><INDENT>return self._api_request(<EOL>self.TEMPLATES_SPECIFIC_ENDPOINT % template_id,<EOL>self.HTTP_GET,<EOL>timeout=timeout<EOL>)<EOL><DEDENT>


def create_email(self, name, subject, html, text='<STR_LIT>'):

return self.create_template(name, subject, html, text)<EOL>

[DECPRECATED] API call to create an email


payload = {<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT>': subject,<EOL>'<STR_LIT:html>': html,<EOL>'<STR_LIT:text>': text<EOL>}<EOL>return self._api_request(<EOL>self.TEMPLATES_ENDPOINT,<EOL>self.HTTP_POST,<EOL>payload=payload,<EOL>timeout=timeout<EOL>)<EOL>


payload = {<EOL>'<STR_LIT>': locale,<EOL>'<STR_LIT:name>': version_name,<EOL>'<STR_LIT>': subject<EOL>}<EOL>if html:<EOL><INDENT>payload['<STR_LIT:html>'] = html<EOL><DEDENT>if text:<EOL><INDENT>payload['<STR_LIT:text>'] = text<EOL><DEDENT>return self._api_request(<EOL>self.TEMPLATES_LOCALES_ENDPOINT % template_id,<EOL>self.HTTP_POST,<EOL>payload=payload,<EOL>timeout=timeout<EOL>)<EOL>

API call to create a new locale and version of a template


if(html):<EOL><INDENT>payload = {<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT>': subject,<EOL>'<STR_LIT:html>': html,<EOL>'<STR_LIT:text>': text<EOL>}<EOL><DEDENT>else:<EOL><INDENT>payload = {<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT>': subject,<EOL>'<STR_LIT:text>': text<EOL>}<EOL><DEDENT>if locale:<EOL><INDENT>url = self.TEMPLATES_SPECIFIC_LOCALE_VERSIONS_ENDPOINT % (<EOL>template_id,<EOL>locale<EOL>)<EOL><DEDENT>else:<EOL><INDENT>url = self.TEMPLATES_NEW_VERSION_ENDPOINT % template_id<EOL><DEDENT>return self._api_request(<EOL>url,<EOL>self.HTTP_POST,<EOL>payload=payload,<EOL>timeout=timeout<EOL>)<EOL>

API call to create a new version of a template


if(html):<EOL><INDENT>payload = {<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT>': subject,<EOL>'<STR_LIT:html>': html,<EOL>'<STR_LIT:text>': text<EOL>}<EOL><DEDENT>else:<EOL><INDENT>payload = {<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT>': subject,<EOL>'<STR_LIT:text>': text<EOL>}<EOL><DEDENT>return self._api_request(<EOL>self.TEMPLATES_VERSION_ENDPOINT % (template_id, version_id),<EOL>self.HTTP_PUT,<EOL>payload=payload,<EOL>timeout=timeout<EOL>)<EOL>


return self._api_request(<EOL>self.SNIPPETS_ENDPOINT,<EOL>self.HTTP_GET,<EOL>timeout=timeout<EOL>)<EOL>


def get_snippet(self, snippet_id, timeout=None):

return self._api_request(<EOL>self.SNIPPET_ENDPOINT % (snippet_id),<EOL>self.HTTP_GET,<EOL>timeout=timeout<EOL>)<EOL>


def create_snippet(self, name, body, timeout=None):

payload = {<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT:body>': body<EOL>}<EOL>return self._api_request(<EOL>self.SNIPPETS_ENDPOINT,<EOL>self.HTTP_POST,<EOL>payload=payload,<EOL>timeout=timeout<EOL>)<EOL>


if isinstance(f, dict):<EOL><INDENT>file_obj = f['<STR_LIT:file>']<EOL>if '<STR_LIT:filename>' in f:<EOL><INDENT>file_name = f['<STR_LIT:filename>']<EOL><DEDENT>else:<EOL><INDENT>file_name = file_obj.name<EOL><DEDENT><DEDENT>else:<EOL><INDENT>file_obj = f<EOL>file_name = f.name<EOL><DEDENT>b64_data = base64.b64encode(file_obj.read())<EOL>return {<EOL>'<STR_LIT:id>': file_name,<EOL>'<STR_LIT:data>': b64_data.decode() if six.PY3 else b64_data,<EOL>}<EOL>

Make a dictionary with filename and base64 file data


if not email_data:<EOL><INDENT>email_data = {}<EOL><DEDENT>if isinstance(recipient, string_types):<EOL><INDENT>warnings.warn(<EOL>"<STR_LIT>",<EOL>DeprecationWarning)<EOL>recipient = {'<STR_LIT:address>': recipient}<EOL><DEDENT>payload = {<EOL>'<STR_LIT>': email_id,<EOL>'<STR_LIT>': recipient,<EOL>'<STR_LIT>': email_data<EOL>}<EOL>if sender:<EOL><INDENT>payload['<STR_LIT>'] = sender<EOL><DEDENT>if cc:<EOL><INDENT>if not type(cc) == list:<EOL><INDENT>logger.error(<EOL>'<STR_LIT>' % type(cc))<EOL><DEDENT>payload['<STR_LIT>'] = cc<EOL><DEDENT>if bcc:<EOL><INDENT>if not type(bcc) == list:<EOL><INDENT>logger.error(<EOL>'<STR_LIT>' % type(bcc))<EOL><DEDENT>payload['<STR_LIT>'] = bcc<EOL><DEDENT>if tags:<EOL><INDENT>if not type(tags) == list:<EOL><INDENT>logger.error(<EOL>'<STR_LIT>' % (type(tags)))<EOL><DEDENT>payload['<STR_LIT>'] = tags<EOL><DEDENT>if headers:<EOL><INDENT>if not type(headers) == dict:<EOL><INDENT>logger.error(<EOL>'<STR_LIT>' % (<EOL>type(headers)<EOL>)<EOL>)<EOL><DEDENT>payload['<STR_LIT>'] = headers<EOL><DEDENT>if esp_account:<EOL><INDENT>if not isinstance(esp_account, string_types):<EOL><INDENT>logger.error(<EOL>'<STR_LIT>' % (<EOL>type(esp_account)<EOL>)<EOL>)<EOL><DEDENT>payload['<STR_LIT>'] = esp_account<EOL><DEDENT>if locale:<EOL><INDENT>if not isinstance(locale, string_types):<EOL><INDENT>logger.error(<EOL>'<STR_LIT>' % (type(locale))<EOL>)<EOL><DEDENT>payload['<STR_LIT>'] = locale<EOL><DEDENT>if email_version_name:<EOL><INDENT>if not isinstance(email_version_name, string_types):<EOL><INDENT>logger.error(<EOL>'<STR_LIT>' % (<EOL>type(email_version_name)))<EOL><DEDENT>payload['<STR_LIT>'] = email_version_name<EOL><DEDENT>if inline:<EOL><INDENT>payload['<STR_LIT>'] = self._make_file_dict(inline)<EOL><DEDENT>if files:<EOL><INDENT>payload['<STR_LIT>'] = [self._make_file_dict(f) for f in files]<EOL><DEDENT>return self._api_request(<EOL>self.SEND_ENDPOINT,<EOL>self.HTTP_POST,<EOL>payload=payload,<EOL>timeout=timeout<EOL>)<EOL>


logger.debug('<STR_LIT>' % endpoint)<EOL>path = self._build_request_path(endpoint, absolute=False)<EOL>logger.debug('<STR_LIT>' % path)<EOL>data = None<EOL>if '<STR_LIT>' in kwargs:<EOL><INDENT>data = kwargs['<STR_LIT>']<EOL><DEDENT>logger.debug('<STR_LIT>' % data)<EOL>command = {<EOL>"<STR_LIT:path>": path,<EOL>"<STR_LIT>": http_method<EOL>}<EOL>if data:<EOL><INDENT>command['<STR_LIT:body>'] = data<EOL><DEDENT>self._commands.append(command)<EOL>


logger.debug('<STR_LIT>' % len(self._commands))<EOL>auth = self._build_http_auth()<EOL>headers = self._build_request_headers()<EOL>logger.debug('<STR_LIT>' % headers)<EOL>logger.debug('<STR_LIT>' % len(self._commands))<EOL>path = self._build_request_path(self.BATCH_ENDPOINT)<EOL>data = json.dumps(self._commands, cls=self._json_encoder)<EOL>r = requests.post(<EOL>path,<EOL>auth=auth,<EOL>headers=headers,<EOL>data=data,<EOL>timeout=(self.DEFAULT_TIMEOUT if timeout is None else timeout)<EOL>)<EOL>self._commands = []<EOL>logger.debug('<STR_LIT>' % r.status_code)<EOL>try:<EOL><INDENT>logger.debug('<STR_LIT>' % r.json())<EOL><DEDENT>except:<EOL><INDENT>logger.debug('<STR_LIT>' % r.content)<EOL><DEDENT>return r<EOL>

Execute all currently queued batch commands


if n == <NUM_LIT:0>:<EOL><INDENT>return n<EOL><DEDENT>else:<EOL><INDENT>return foo(n - <NUM_LIT:1>)<EOL><DEDENT>


return True<EOL>


if n == <NUM_LIT:1>:<EOL><INDENT>return n<EOL><DEDENT>else:<EOL><INDENT>return foo(n - <NUM_LIT:1>)<EOL><DEDENT>


if n == <NUM_LIT:2>:<EOL><INDENT>return n<EOL><DEDENT>else:<EOL><INDENT>return foo(n)<EOL><DEDENT>


index = string.ascii_uppercase.index<EOL>col = <NUM_LIT:0><EOL>for c in name.upper():<EOL><INDENT>col = col * <NUM_LIT> + index(c) + <NUM_LIT:1><EOL><DEDENT>return col<EOL>


filename = None<EOL>if isinstance(book, str):<EOL><INDENT>filename = book<EOL>book = opxl.load_workbook(book, data_only=True)<EOL><DEDENT>elif isinstance(book, opxl.Workbook):<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>raise TypeError<EOL><DEDENT>if _is_range_address(range_):<EOL><INDENT>sheet_names = [name.upper() for name in book.sheetnames]<EOL>index = sheet_names.index(sheet.upper())<EOL>data = book.worksheets[index][range_]<EOL><DEDENT>else:<EOL><INDENT>data = _get_namedrange(book, range_, sheet)<EOL>if data is None:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>" % (range_, filename or book)<EOL>)<EOL><DEDENT><DEDENT>return data<EOL>

Return a range as nested dict of openpyxl cells.


def read_range(filepath, range_expr, sheet=None, dict_generator=None):

def default_generator(cells):<EOL><INDENT>for row_ind, row in enumerate(cells):<EOL><INDENT>for col_ind, cell in enumerate(row):<EOL><INDENT>yield (row_ind, col_ind), cell.value<EOL><DEDENT><DEDENT><DEDENT>book = opxl.load_workbook(filepath, data_only=True)<EOL>if _is_range_address(range_expr):<EOL><INDENT>sheet_names = [name.upper() for name in book.sheetnames]<EOL>index = sheet_names.index(sheet.upper())<EOL>cells = book.worksheets[index][range_expr]<EOL><DEDENT>else:<EOL><INDENT>cells = _get_namedrange(book, range_expr, sheet)<EOL><DEDENT>if isinstance(cells, opxl.cell.Cell):<EOL><INDENT>return cells.value<EOL><DEDENT>if dict_generator is None:<EOL><INDENT>dict_generator = default_generator<EOL><DEDENT>gen = dict_generator(cells)<EOL>return {keyval[<NUM_LIT:0>]: keyval[<NUM_LIT:1>] for keyval in gen}<EOL>

Read values from an Excel range into a dictionary.

    `range_expr` ie either a range address string, such as "A1", "$C$3:$E$5",
    or a defined name string for a range, such as "NamedRange1".
    If a range address is provided, `sheet` argument must also be provided.
    If a named range is provided and `sheet` is not, book level defined name
    is searched. If `sheet` is also provided, sheet level defined name for the
    specified `sheet` is searched.
    If range_expr points to a single cell, its value is returned.

    `dictgenerator` is a generator function that yields keys and values of
    the returned dictionary. the excel range, as a nested tuple of openpyxl's
    Cell objects, is passed to the generator function as its single argument.
    If not specified, default generator is used, which maps tuples of row and
    column indexes, both starting with 0, to their values.

    Args:
        filepath (str): Path to an Excel file.
        range_epxr (str): Range expression, such as "A1", "$G4:$K10",
            or named range "NamedRange1"
        sheet (str): Sheet name (case ignored).
            None if book level defined range name is passed as `range_epxr`.
        dict_generator: A generator function taking a nested tuple of cells
            as a single parameter.

    Returns:
        Nested list containing range values.


def _get_namedrange(book, rangename, sheetname=None):

def cond(namedef):<EOL><INDENT>if namedef.type.upper() == "<STR_LIT>":<EOL><INDENT>if namedef.name.upper() == rangename.upper():<EOL><INDENT>if sheetname is None:<EOL><INDENT>if not namedef.localSheetId:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>else:  <EOL><INDENT>sheet_id = [sht.upper() for sht in book.sheetnames].index(<EOL>sheetname.upper()<EOL>)<EOL>if namedef.localSheetId == sheet_id:<EOL><INDENT>return True<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return False<EOL><DEDENT>def get_destinations(name_def):<EOL><INDENT>"""<STR_LIT>"""<EOL>from openpyxl.formula import Tokenizer<EOL>from openpyxl.utils.cell import SHEETRANGE_RE<EOL>if name_def.type == "<STR_LIT>":<EOL><INDENT>tok = Tokenizer("<STR_LIT:=>" + name_def.value)<EOL>for part in tok.items:<EOL><INDENT>if part.subtype == "<STR_LIT>":<EOL><INDENT>m = SHEETRANGE_RE.match(part.value)<EOL>if m.group("<STR_LIT>"):<EOL><INDENT>sheet_name = m.group("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>sheet_name = m.group("<STR_LIT>")<EOL><DEDENT>yield sheet_name, m.group("<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT><DEDENT>namedef = next(<EOL>(item for item in book.defined_names.definedName if cond(item)), None<EOL>)<EOL>if namedef is None:<EOL><INDENT>return None<EOL><DEDENT>dests = get_destinations(namedef)<EOL>xlranges = []<EOL>sheetnames_upper = [name.upper() for name in book.sheetnames]<EOL>for sht, addr in dests:<EOL><INDENT>if sheetname:<EOL><INDENT>sht = sheetname<EOL><DEDENT>index = sheetnames_upper.index(sht.upper())<EOL>xlranges.append(book.worksheets[index][addr])<EOL><DEDENT>if len(xlranges) == <NUM_LIT:1>:<EOL><INDENT>return xlranges[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>return xlranges<EOL><DEDENT>

Get range from a workbook.

    A workbook can contain multiple definitions for a single name,
    as a name can be defined for the entire book or for
    a particular sheet.

    If sheet is None, the book-wide def is searched,
    otherwise sheet-local def is looked up.

    Args:
        book: An openpyxl workbook object.
        rangename (str): Range expression, such as "A1", "$G4:$K10",
            named range "NamedRange1".
        sheetname (str, optional): None for book-wide name def,
            sheet name for sheet-local named range.

    Returns:
        Range object specified by the name.


def cellsiter_to_dataframe(cellsiter, args, drop_allna=True):

from modelx.core.cells import shareable_parameters<EOL>if len(args):<EOL><INDENT>indexes = shareable_parameters(cellsiter)<EOL><DEDENT>else:<EOL><INDENT>indexes = get_all_params(cellsiter.values())<EOL><DEDENT>result = None<EOL>for cells in cellsiter.values():<EOL><INDENT>df = cells_to_dataframe(cells, args)<EOL>if drop_allna and df.isnull().all().all():<EOL><INDENT>continue  <EOL><DEDENT>if df.index.names != [None]:<EOL><INDENT>if isinstance(df.index, pd.MultiIndex):<EOL><INDENT>if _pd_ver < (<NUM_LIT:0>, <NUM_LIT:20>):<EOL><INDENT>df = _reset_naindex(df)<EOL><DEDENT><DEDENT>df = df.reset_index()<EOL><DEDENT>missing_params = set(indexes) - set(df)<EOL>for params in missing_params:<EOL><INDENT>df[params] = np.nan<EOL><DEDENT>if result is None:<EOL><INDENT>result = df<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>result = pd.merge(result, df, how="<STR_LIT>")<EOL><DEDENT>except MergeError:<EOL><INDENT>result = pd.concat([result, df], axis=<NUM_LIT:1>)<EOL><DEDENT>except ValueError:<EOL><INDENT>cols = set(result.columns) & set(df.columns)<EOL>for col in cols:<EOL><INDENT>if (<EOL>len(<EOL>[<EOL>str(frame[col].dtype)<EOL>for frame in (result, df)<EOL>if str(frame[col].dtype) == "<STR_LIT:object>"<EOL>]<EOL>)<EOL>== <NUM_LIT:1><EOL>):<EOL><INDENT>if str(result[col].dtype) == "<STR_LIT:object>":<EOL><INDENT>frame = df<EOL><DEDENT>else:<EOL><INDENT>frame = result<EOL><DEDENT>frame[[col]] = frame[col].astype("<STR_LIT:object>")<EOL><DEDENT><DEDENT>result = pd.merge(result, df, how="<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>if result is None:<EOL><INDENT>return pd.DataFrame()<EOL><DEDENT>else:<EOL><INDENT>return result.set_index(indexes) if indexes else result<EOL><DEDENT>

Convert multiple cells to a frame.

    If args is an empty sequence, all values are included.
    If args is specified, cellsiter must have shareable parameters.

    Args:
        cellsiter: A mapping from cells names to CellsImpl objects.
        args: A sequence of arguments


paramlen = len(cells.formula.parameters)<EOL>is_multidx = paramlen > <NUM_LIT:1><EOL>if len(cells.data) == <NUM_LIT:0>:<EOL><INDENT>data = {}<EOL>indexes = None<EOL><DEDENT>elif paramlen == <NUM_LIT:0>:  <EOL><INDENT>data = list(cells.data.values())<EOL>indexes = [np.nan]<EOL><DEDENT>else:<EOL><INDENT>if len(args) > <NUM_LIT:0>:<EOL><INDENT>defaults = tuple(<EOL>param.default<EOL>for param in cells.formula.signature.parameters.values()<EOL>)<EOL>updated_args = []<EOL>for arg in args:<EOL><INDENT>if len(arg) > paramlen:<EOL><INDENT>arg = arg[:paramlen]<EOL><DEDENT>elif len(arg) < paramlen:<EOL><INDENT>arg += defaults[len(arg) :]<EOL><DEDENT>updated_args.append(arg)<EOL><DEDENT>items = [<EOL>(arg, cells.data[arg])<EOL>for arg in updated_args<EOL>if arg in cells.data<EOL>]<EOL><DEDENT>else:<EOL><INDENT>items = [(key, value) for key, value in cells.data.items()]<EOL><DEDENT>if not is_multidx:  <EOL><INDENT>items = [(key[<NUM_LIT:0>], value) for key, value in items]<EOL><DEDENT>if len(items) == <NUM_LIT:0>:<EOL><INDENT>indexes, data = None, {}<EOL><DEDENT>else:<EOL><INDENT>indexes, data = zip(*items)<EOL>if is_multidx:<EOL><INDENT>indexes = pd.MultiIndex.from_tuples(indexes)<EOL><DEDENT><DEDENT><DEDENT>result = pd.Series(data=data, name=cells.name, index=indexes)<EOL>if indexes is not None and any(i is not np.nan for i in indexes):<EOL><INDENT>result.index.names = list(cells.formula.parameters)<EOL><DEDENT>return result<EOL>

Convert a CellImpl into a Series.

    `args` must be a sequence of argkeys.

    `args` can be longer or shorter then the number of cell's parameters.
    If shorter, then defaults are filled if any, else raise error.
    If longer, then redundant args are ignored.


if sys.version_info < (<NUM_LIT:3>, <NUM_LIT:6>, <NUM_LIT:0>):<EOL><INDENT>from collections import OrderedDict<EOL>impls = OrderedDict()<EOL>for name, obj in self.items():<EOL><INDENT>impls[name] = obj._impl<EOL><DEDENT><DEDENT>else:<EOL><INDENT>impls = get_impls(self)<EOL><DEDENT>return _to_frame_inner(impls, args)<EOL>

Convert the cells in the view into a DataFrame object.

        If ``args`` is not given, this method returns a DataFrame that
        has an Index or a MultiIndex depending of the number of
        cells parameters and columns each of which corresponds to each
        cells included in the view.

        ``args`` can be given to calculate cells values and limit the
        DataFrame indexes to the given arguments.

        The cells in this view may have different number of parameters,
        but parameters shared among multiple cells
        must appear in the same position in all the parameter lists.
        For example,
        Having ``foo()``, ``bar(x)`` and ``baz(x, y=1)`` is okay
        because the shared parameter ``x`` is always the first parameter,
        but this method does not work if the view has ``quz(x, z=2, y=1)``
        cells in addition to the first three cells, because ``y`` appears
        in different positions.

        Args:
            args(optional): multiple arguments,
               or an iterator of arguments to the cells.


return get_interfaces(self._impl.bases)<EOL>


return get_interfaces(self._impl.direct_bases)<EOL>


return self._impl.is_base(other._impl)<EOL>

True if the space is a base space of ``other``, False otherwise.


return self._impl.is_sub(other._impl)<EOL>

True if the space is a sub space of ``other``, False otherwise.


return isinstance(self._impl, StaticSpaceImpl)<EOL>

True if the space is a static space, False if dynamic.


return self._impl.is_derived<EOL>

True if the space is a derived space, False otherwise.


return self._impl.is_defined()<EOL>

True if the space is a defined space, False otherwise.


return isinstance(self._impl, RootDynamicSpaceImpl)<EOL>

True if ths space is a dynamic space, False otherwise.


return self._impl.is_dynamic()<EOL>

True if the space is in a dynamic space, False otherwise.


return self._impl.cells.interfaces<EOL>

A mapping of cells names to the cells objects in the space.


return self._impl.self_cells.interfaces<EOL>

A mapping that associates names to cells defined in the space


return self._impl.derived_cells.interfaces<EOL>

A mapping associating names to derived cells.


return self._impl.spaces.interfaces<EOL>

A mapping associating names to all(static and dynamic) spaces.


return self._impl.static_spaces.interfaces<EOL>

A mapping associating names to static spaces.


A mapping associating names to static spaces.

        Alias to :py:meth:`spaces`


return self._impl.dynamic_spaces.interfaces<EOL>

A mapping associating names to dynamic spaces.


return self._impl.self_spaces.interfaces<EOL>

A mapping associating names to self spaces.


return self._impl.derived_spaces.interfaces<EOL>

A mapping associating names to derived spaces.


return self._impl.argvalues_if<EOL>


return tuple(self._impl.formula.parameters)<EOL>


return self._impl.refs.interfaces<EOL>

A map associating names to objects accessible by the names.


return self._impl.self_refs.interfaces<EOL>

A mapping associating names to self refs.


return self._impl.formula<EOL>


<EOL>return bool(self._impl.formula)<EOL>


return self._impl.to_frame(args)<EOL>

Convert the space itself into a Pandas DataFrame object.


return self._impl.to_frame(())<EOL>


result = super()._baseattrs<EOL>result["<STR_LIT>"] = self.static_spaces._baseattrs<EOL>result["<STR_LIT>"] = self.dynamic_spaces._baseattrs<EOL>result["<STR_LIT>"] = self.cells._baseattrs<EOL>result["<STR_LIT>"] = self.refs._baseattrs<EOL>if self.has_params():<EOL><INDENT>result["<STR_LIT>"] = "<STR_LIT:U+002CU+0020>".join(self.parameters)<EOL><DEDENT>else:<EOL><INDENT>result["<STR_LIT>"] = "<STR_LIT>"<EOL><DEDENT>return result<EOL>


def new_cells(self, name=None, formula=None):

<EOL>return self._impl.new_cells(name, formula).interface<EOL>

Create a cells in the space.

        Args:
            name: If omitted, the model is named automatically ``CellsN``,
                where ``N`` is an available number.
            func: The function to define the formula of the cells.

        Returns:
            The new cells.


return self._impl.add_bases(get_impls(bases))<EOL>


return self._impl.remove_bases(bases)<EOL>


<EOL>newcells = self._impl.new_cells_from_module(module)<EOL>return get_interfaces(newcells)<EOL>


Create a cells from a module.

        Alias to :py:meth:`import_funcs`.


self._impl.reload()<EOL>return self<EOL>

Reload the source module and update the formulas.

        If the space was created from a module, reload the module and
        update the formulas of its cells.

        If a cell in the space is not created from a function definition
        in the source module of the space, it is not updated.

        If the formula of a cell in the space was created from a function
        definition in the source module of the space and the definition is
        missing from the updated module, the formula is cleared and
        values calculated directly or indirectly depending the cells
        are cleared.

        If the formula of a cell in the space has not been changed
        before and after reloading the source module, the values held
        in the cell and relevant cells are retained.

        Returns:
            This method returns the space itself.