<commit_before>## @package csnGUIHandler
# Definition of GUI handling classes. 
import csnUtility
import csnContext
import csnGenerator
import csnProject
import csnPrebuilt
import RollbackImporter
import glob
import json
import inspect
import string
import os
import subprocess
import sys
from csnListener import ChangeListener, ProgressEvent, ProgressListener
import logging
import copy

class RootNotFound(IOError):
    pass

class NotARoot(IOError):
    pass

class RollbackHandler:
    """
    This helper class instantiates the RollbackImporter and extends the python search path 
    """
    def SetUp(self, _projectPath, _rootFolders, _thirdPartyFolders):
        """
        Set up the roll back. 
        """
        # set up roll back of imported modules
        self.rbi = RollbackImporter.RollbackImporter()
        self.previousPaths = list(sys.path)
        
        # extend python path with project folder, source root and third party root
        newPaths = list(_rootFolders)
        newPaths.extend(_thirdPartyFolders) 
        newPaths.extend([_projectPath]) 
        for path in newPaths:
            if not path in sys.path:
                sys.path.append(path)
    
    def TearDown(self):
        """
        Execute roll back. 
        """
        # roll back imported modules
        self.rbi.rollbackImports()

        # undo additions to the python path
        sys.path = list(self.previousPaths)
                    
class Handler:
    def __init__(self):
        self.context = None
        self.generator = csnGenerator.Generator()
        self.progressListener = ProgressListener(self)
        self.generator.AddListener(self.progressListener)
        # contains the last result of calling __GetProjectInstance
        self.cachedProjectModule = None
        self.cachedProjectInstance = dict()
        self.cachedProjectInstanceContext = None
        # logger
        self.__logger = logging.getLogger("CSnake")
        # change flags
        self.contextModified = False
        self.changeListener = ChangeListener(self)
        # listeners
        self.__listeners = []
        # progress start and range (in case of multiple actions)
        self.__progressStart = 0
        self.__progressRange = 100
        self.__userCanceled = False
        # error message
        self.__errorMessage = ""
        self.__errorFilename = "%s/errors.txt" % csnUtility.GetCSnakeUserFolder() 
    
    def LoadContext(self, filename):
        self.SetContext(csnContext.Load(filename))
        return self.context
        
    def SetContext(self, context):
        self.context = context
        self.context.AddListener(self.changeListener)
        csnProject.globalCurrentContext = self.context
        
    def Cancel(self):
        self.__userCanceled = True
        if self.__GetProjectInstance():
            self.__GetProjectInstance().installManager.Cancel()
        
    def __ResetCancel(self):
        self.__userCanceled = False
        
    def IsCanceled(self):
        return self.__userCanceled
    
    def __CheckReloadChanges(self, contextA, contextB):
        """Have there been done changes to the context that justify reloading the .py files?"""
        # changes that justify reload: src, TP-src, Compiler, Compile-Mode, csn-file
        functionsToCompare = [csnContext.ContextData.GetRootFolders,
                                csnContext.ContextData.GetThirdPartySrcFolders,
                                csnContext.ContextData.GetCompilername,
                                csnContext.ContextData.GetConfigurationName,
                                csnContext.ContextData.GetCsnakeFile]
		
        if contextA is None or contextB is None:
            return True
        for function in functionsToCompare:
            if function(contextA) != function(contextB):
                return True
        return False
    
    def __GetProjectModule(self, _forceReload = True):
        reloadFiles = _forceReload or self.__CheckReloadChanges(self.cachedProjectInstanceContext, self.context.GetData())
        
        if reloadFiles or self.cachedProjectModule is None:
            # reset cached stuff
            self.cachedProjectInstanceContext = copy.deepcopy(self.context.GetData())
            self.cachedProjectInstance = dict()
            self.DeletePycFiles()
            
            # set up roll back of imported modules
            rollbackHandler = RollbackHandler()
            rollbackHandler.SetUp(self.context.GetCsnakeFile(), self.context.GetRootFolders(), self.context.GetThirdPartyFolders())
            (projectFolder, name) = os.path.split(self.context.GetCsnakeFile())
            (name, _) = os.path.splitext(name)
            
            try:
                self.cachedProjectModule = csnUtility.LoadModule(projectFolder, name)
            finally:
                # undo additions to the python path
                rollbackHandler.TearDown()<commit_msg>Replaced tab by spaces.<commit_after>## @package csnGUIHandler
# Definition of GUI handling classes. 
import csnUtility
import csnContext
import csnGenerator
import csnProject
import csnPrebuilt
import RollbackImporter
import glob
import json
import inspect
import string
import os
import subprocess
import sys
from csnListener import ChangeListener, ProgressEvent, ProgressListener
import logging
import copy

class RootNotFound(IOError):
    pass

class NotARoot(IOError):
    pass

class RollbackHandler:
    """
    This helper class instantiates the RollbackImporter and extends the python search path 
    """
    def SetUp(self, _projectPath, _rootFolders, _thirdPartyFolders):
        """
        Set up the roll back. 
        """
        # set up roll back of imported modules
        self.rbi = RollbackImporter.RollbackImporter()
        self.previousPaths = list(sys.path)
        
        # extend python path with project folder, source root and third party root
        newPaths = list(_rootFolders)
        newPaths.extend(_thirdPartyFolders) 
        newPaths.extend([_projectPath]) 
        for path in newPaths:
            if not path in sys.path:
                sys.path.append(path)
    
    def TearDown(self):
        """
        Execute roll back. 
        """
        # roll back imported modules
        self.rbi.rollbackImports()

        # undo additions to the python path
        sys.path = list(self.previousPaths)
                    
class Handler:
    def __init__(self):
        self.context = None
        self.generator = csnGenerator.Generator()
        self.progressListener = ProgressListener(self)
        self.generator.AddListener(self.progressListener)
        # contains the last result of calling __GetProjectInstance
        self.cachedProjectModule = None
        self.cachedProjectInstance = dict()
        self.cachedProjectInstanceContext = None
        # logger
        self.__logger = logging.getLogger("CSnake")
        # change flags
        self.contextModified = False
        self.changeListener = ChangeListener(self)
        # listeners
        self.__listeners = []
        # progress start and range (in case of multiple actions)
        self.__progressStart = 0
        self.__progressRange = 100
        self.__userCanceled = False
        # error message
        self.__errorMessage = ""
        self.__errorFilename = "%s/errors.txt" % csnUtility.GetCSnakeUserFolder() 
    
    def LoadContext(self, filename):
        self.SetContext(csnContext.Load(filename))
        return self.context
        
    def SetContext(self, context):
        self.context = context
        self.context.AddListener(self.changeListener)
        csnProject.globalCurrentContext = self.context
        
    def Cancel(self):
        self.__userCanceled = True
        if self.__GetProjectInstance():
            self.__GetProjectInstance().installManager.Cancel()
        
    def __ResetCancel(self):
        self.__userCanceled = False
        
    def IsCanceled(self):
        return self.__userCanceled
    
    def __CheckReloadChanges(self, contextA, contextB):
        """Have there been done changes to the context that justify reloading the .py files?"""
        # changes that justify reload: src, TP-src, Compiler, Compile-Mode, csn-file
        functionsToCompare = [csnContext.ContextData.GetRootFolders,
                                csnContext.ContextData.GetThirdPartySrcFolders,
                                csnContext.ContextData.GetCompilername,
                                csnContext.ContextData.GetConfigurationName,
                                csnContext.ContextData.GetCsnakeFile]
        
        if contextA is None or contextB is None:
            return True
        for function in functionsToCompare:
            if function(contextA) != function(contextB):
                return True
        return False
    
    def __GetProjectModule(self, _forceReload = True):
        reloadFiles = _forceReload or self.__CheckReloadChanges(self.cachedProjectInstanceContext, self.context.GetData())
        
        if reloadFiles or self.cachedProjectModule is None:
            # reset cached stuff
            self.cachedProjectInstanceContext = copy.deepcopy(self.context.GetData())
            self.cachedProjectInstance = dict()
            self.DeletePycFiles()
            
            # set up roll back of imported modules
            rollbackHandler = RollbackHandler()
            rollbackHandler.SetUp(self.context.GetCsnakeFile(), self.context.GetRootFolders(), self.context.GetThirdPartyFolders())
            (projectFolder, name) = os.path.split(self.context.GetCsnakeFile())
            (name, _) = os.path.splitext(name)
            
            try:
                self.cachedProjectModule = csnUtility.LoadModule(projectFolder, name)
            finally:
                # undo additions to the python path
                rollbackHandler.TearDown()
{'fraction_non_alphanumeric': 0.0702445926824338, 'fraction_numerical': 0.0008085708510208206, 'mean_word_length': 2.260296540362438, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1961083', 'n_tokens_mistral': 2559, 'n_tokens_neox': 2495, 'n_words': 642}