def RemovePlugin(bus, pattern, match_path=False): '''Removes any plugin matching the pattern in its basename, unless matches against path.''' plugins = ast.literal_eval( bus.call('kattcmd:config:load-user', bus, 'plugins')) def DoSave(new_plugins): removed = list(sorted(set(plugins) - set(new_plugins))) bus.call('kattcmd:config:add-user', bus, 'plugins', str(new_plugins)) bus.call('kattcmd:plugin:plugins-updated', new_plugins, removed) return new_plugins, removed def ShouldMatchAgainstPath(): return match_path def HandleMatchPath(): new_plugins = list(filter(lambda x: pattern not in x, plugins)) return DoSave(new_plugins) def ShouldMatchAgainstBase(): return not match_path def HandleMatchBase(): new_plugins = list( filter(lambda x: pattern not in os.path.basename(x), plugins)) return DoSave(new_plugins) return pydash.cond([(ShouldMatchAgainstBase, HandleMatchBase), (ShouldMatchAgainstPath, HandleMatchPath)])()
def unlisten(self, topic, ID): '''Stop recieving updates for a topic.''' def has_id(): return any(i == ID for i, _ in self.listeners[topic]) def remove_id(): items = self.listeners[topic] keep = lambda i, _: i != ID self.listeners[topic] = [(a, b) for a, b in items if keep(a, b)] return pydash.cond([(has_id, remove_id)])()
def unprovide(self, topic): '''Unregister a topic.''' def has_rpc(): return topic in self.providers def raise_RPC_error(): raise BusError('No RPC Provider: {}'.format(topic)) def remove_RPC(): del self.providers[topic] return pydash.cond([(has_rpc, raise_RPC_error), (pydash.stub_true, remove_RPC)])()
def InitializeKattcmdDirectory(bus, folder=None): '''Creates the directory structure for kattis solutions. If the given folder is already a kattis solution directory then nothing will happen. ''' folder = folder or os.getcwd() expected_files = ['.kattcmddir'] expected_directories = ['library', 'templates', 'kattis', 'tests', 'build'] files = [os.path.join(folder, fname) for fname in expected_files] dirs = [os.path.join(folder, d) for d in expected_directories] def IsKattcmdAlready(): return _FilesExist(files) and _DirectoriesExist(dirs) def OnDirectoryExist(): bus.call('kattcmd:init:directory-exists', folder) def IsPartialDirectory(): missing_files = _FilesExist(files, get_missing=True) missing_dirs = _DirectoriesExist(dirs, get_missing=True) current_length = len(missing_files) + len(missing_dirs) expected_length = len(files) + len(dirs) return current_length != expected_length and current_length != 0 def OnPartialExist(): missing_files = _FilesExist(files, get_missing=True) missing_dirs = _DirectoriesExist(dirs, get_missing=True) missing = missing_files + missing_dirs expected = files + dirs bus.call('kattcmd:init:directory-partial', folder, expected, missing) def DoInit(): for dpath in dirs: os.mkdir(dpath) for fpath in files: with open(fpath, 'w') as f: pass bus.call('kattcmd:init:directory-created', folder) return pydash.cond([(IsKattcmdAlready, OnDirectoryExist), (IsPartialDirectory, OnPartialExist), (pydash.stub_true, DoInit)])()
def _FilesExist(paths, get_missing=False): '''Returns true if all files exist. if get_missing is true, returns a list of all missing files. ''' def all_exist(): return all(os.path.isfile(path) for path in paths) def return_missing(): non_existing = [path for path in paths if not os.path.isfile(path)] return non_existing if not get_missing: return all_exist() return pydash.cond([(all_exist, pydash.constant([])), (pydash.stub_true, return_missing)])()
def call(self, topic, *args, **kwargs): '''Call an RPC that exists on the bus and any listeners.''' # Check if RPC exists, throw error on fault. def non_existant_rpc(): return topic not in self.providers def raise_RPC_error(): raise BusError('No RPC Provider: {}'.format(topic)) # Else call listeners and then return with RPC result. def call_listeners(): if topic in self.listeners: for _, listener in self.listeners[topic]: listener(*args, **kwargs) def call_rpc(unused): return self.providers[topic](*args, **kwargs) call_listeners_and_rpc = pydash.flow(call_listeners, call_rpc) return pydash.cond([(non_existant_rpc, raise_RPC_error), (pydash.stub_true, call_listeners_and_rpc)])()
def AddPlugin(bus, path): '''Checks the plugin at path and adds it to user config.''' type, value = core.ImportExternal(path) def IsBadExtension(): return type == 'extension' def HandleBadExtension(): bus.call('kattcmd:plugin:bad-extension', path) def IsImportError(): return type == 'error' def HandleImportError(): bus.call('kattcmd:plugin:import-error', path, value) def HandleNormalCase(): _AddPluginInConfig(bus, path) bus.call('kattcmd:plugin:plugin-loaded', path) return path return pydash.cond([(IsBadExtension, HandleBadExtension), (IsImportError, HandleImportError), (pydash.stub_true, HandleNormalCase)])()
}, 'matches B'), (([_.matches({'b': 2}), _.constant('matches B') ], [_.matches({'a': 1}), _.invert]), { 'a': 1, 'b': 3 }, { 1: 'a', 3: 'b' }), (([_.matches({'a': 1}), _.constant('matches A') ], [_.matches({'b': 2}), _.constant('matches B')]), { 'a': 1, 'b': 2 }, 'matches A')]) def test_cond(pairs, case, expected): func = _.cond(*pairs) assert func(case) == expected @parametrize( 'case,expected', [([_.matches({'b': 2})], ValueError), ([_.matches({'b': 2}), _.matches({'a': 1}), _.constant('matches B')], ValueError), ([1, 2], ValueError), ([[1, 2]], TypeError), ([_.matches({'b': 2}), 2], ValueError)]) def test_cond_exception(case, expected): with pytest.raises(expected): _.cond(case)
def test_cond_exception(case, expected): with pytest.raises(expected): _.cond(case)
def test_cond(pairs, case, expected): func = _.cond(*pairs) assert func(case) == expected