diff options
-rw-r--r-- | code/__init__.pyc | bin | 125 -> 0 bytes | |||
-rw-r--r-- | code/defaultui.py | 16 | ||||
-rw-r--r-- | code/environment.py | 38 | ||||
-rw-r--r-- | code/fm.py | 65 | ||||
-rw-r--r-- | code/wdisplay.py | 34 | ||||
-rwxr-xr-x | ranger.py (renamed from ranger) | 16 | ||||
-rw-r--r-- | ranger/__init__.py (renamed from code/__init__.py) | 0 | ||||
-rw-r--r-- | ranger/cli.py | 32 | ||||
-rw-r--r-- | ranger/command.py | 77 | ||||
-rw-r--r-- | ranger/debug.py (renamed from code/debug.py) | 0 | ||||
-rw-r--r-- | ranger/defaultui.py | 39 | ||||
-rw-r--r-- | ranger/directory.py (renamed from code/directory.py) | 18 | ||||
-rw-r--r-- | ranger/directory.rb (renamed from code/directory.rb) | 0 | ||||
-rw-r--r-- | ranger/environment.py | 73 | ||||
-rw-r--r-- | ranger/file.py (renamed from code/file.py) | 4 | ||||
-rw-r--r-- | ranger/fm.py | 42 | ||||
-rw-r--r-- | ranger/fsobject.py (renamed from code/fsobject.py) | 34 | ||||
-rw-r--r-- | ranger/fstype.py (renamed from code/fstype.py) | 0 | ||||
-rw-r--r-- | ranger/keys.py | 15 | ||||
-rw-r--r-- | ranger/options.py (renamed from code/options.py) | 0 | ||||
-rw-r--r-- | ranger/ui.py (renamed from code/ui.py) | 24 | ||||
-rw-r--r-- | ranger/wdisplay.py | 51 | ||||
-rw-r--r-- | ranger/widget.py (renamed from code/widget.py) | 8 | ||||
-rw-r--r-- | ranger/wstatusbar.py | 12 | ||||
-rw-r--r-- | test/dirsize_benchmark.py | 2 | ||||
-rw-r--r-- | test/tc_directory.py | 32 | ||||
-rw-r--r-- | test4.py | 36 |
27 files changed, 475 insertions, 193 deletions
diff --git a/code/__init__.pyc b/code/__init__.pyc deleted file mode 100644 index 2479f90e..00000000 --- a/code/__init__.pyc +++ /dev/null Binary files differdiff --git a/code/defaultui.py b/code/defaultui.py deleted file mode 100644 index d46c89c8..00000000 --- a/code/defaultui.py +++ /dev/null @@ -1,16 +0,0 @@ -import ui -import widget, wdisplay - -class DefaultUI(ui.UI): - def setup(self): - self.main_display = wdisplay.WDisplay(self.win, 0) - self.add_widget(self.main_display) - self.left_display = wdisplay.WDisplay(self.win, -1) - self.add_widget(self.left_display) - - def resize(self): - ui.UI.resize(self) - y, x = self.win.getmaxyx() - self.main_display.setdim(1, 40, 3, 37) - self.left_display.setdim(1, 0, 3, 37) - diff --git a/code/environment.py b/code/environment.py deleted file mode 100644 index 515fc8c6..00000000 --- a/code/environment.py +++ /dev/null @@ -1,38 +0,0 @@ -import directory - -class Vector(): - def __init__(self, x, y): - self.x = x - self.y = y - -class Environment(): - # A collection of data which is relevant for more than - # one class. - def __init__(self, opt): - self.opt = opt - self.path = None - self.pathway = () - self.directories = {} - self.pwd = None # current directory - self.cf = None # current file - self.keybuffer = '' - self.copy = None - self.termsize = Vector(80, 24) - - def at_level(self, level): - if level <= 0: - try: - return self.pathway[level - 1] - except IndexError: - return None - else: - return self.cf - - def get_directory(self, path): - import os - path = os.path.abspath(path) - try: - return self.directories[path] - except KeyError: - self.directories[path] = directory.Directory(path) - return self.directories[path] diff --git a/code/fm.py b/code/fm.py deleted file mode 100644 index 924f6efc..00000000 --- a/code/fm.py +++ /dev/null @@ -1,65 +0,0 @@ -import sys, os -import ui, debug, file, directory, fstype - -class FM(): - def __init__(self, environment): - self.env = environment - - def feed(self, path, ui): - self.ui = ui - self.env.path = path - self.enter_dir(path) - - def enter_dir(self, path): - # get the absolute path - path = os.path.normpath(os.path.join(self.env.path, path)) - - self.env.path = path - self.env.pwd = self.env.get_directory(path) - - self.env.pwd.load_content() - - # build the pathway, a tuple of directory objects which lie - # on the path to the current directory. - pathway = [] - currentpath = '/' - for dir in path.split('/'): - currentpath = os.path.join(currentpath, dir) - debug.log(currentpath) - pathway.append(self.env.get_directory(currentpath)) - self.env.pathway = tuple(pathway) - - # set the current file. - if len(self.env.pwd) > 0: - self.env.cf = self.env.pwd[0] - else: - self.env.cf = None - - def run(self): - while 1: - try: - self.ui.draw() - except KeyboardInterrupt: - self.interrupt() - except: - raise - - try: - key = self.ui.get_next_key() - self.press(key) - except KeyboardInterrupt: - self.interrupt() - - def press(self, key): - if (key == ord('q')): - raise SystemExit() - elif (key == ord('h')): - self.enter_dir('..') - elif (key == ord('l')): - self.enter_dir(self.env.cf.path) - - def interrupt(self): - import time - self.buffer = "" - time.sleep(0.2) - diff --git a/code/wdisplay.py b/code/wdisplay.py deleted file mode 100644 index a564a6cb..00000000 --- a/code/wdisplay.py +++ /dev/null @@ -1,34 +0,0 @@ -import widget -import curses -import file, directory - -class WDisplay(widget.Widget): - def __init__(self, win, level): - widget.Widget.__init__(self,win) - self.level = level - - def feed_env(self, env): - self.target = env.at_level(self.level) - - def draw(self): - if type(self.target) == file.File: - self.draw_file() - elif type(self.target) == directory.Directory: - self.draw_directory() - elif self.target is None: - self.win.addnstr(self.y, self.x, "---", self.wid) - else: - self.win.addnstr(self.y, self.x, "unknown type.", self.wid) - - def draw_file(self): - self.win.addnstr(self.y, self.x, "this is a file.", self.wid) - - def draw_directory(self): - self.target.load_content_once() - for i in range(self.hei): - try: - f = self.target[i] - except IndexError: - break - self.win.addnstr(self.y + i, self.x, self.target[i].path, self.wid) - diff --git a/ranger b/ranger.py index d83e8a3e..65388727 100755 --- a/ranger +++ b/ranger.py @@ -3,7 +3,8 @@ # TODO: cd after exit -from code import debug, fm, defaultui, options, environment +from ranger import debug, fm, options, environment, command, keys +from ranger.defaultui import DefaultUI as UI # TODO: find out the real name of this script and include files relative to here @@ -17,18 +18,21 @@ def main(): locale.setlocale(locale.LC_ALL, 'en_US.utf8') try: - path = '/srv/music/compilations/' + path = os.path.abspath('.') opt = options.get() env = environment.Environment(opt) + commandlist = command.CommandList() + keys.initialize_commands(commandlist) - my_ui = defaultui.DefaultUI(env) + my_ui = UI(env, commandlist) my_fm = fm.FM(env) my_fm.feed(path, my_ui) my_fm.run() - except: - my_ui.exit() - raise + except BaseException as original_error: + try: my_ui.exit() + except: pass + raise original_error if __name__ == "__main__": main() diff --git a/code/__init__.py b/ranger/__init__.py index e69de29b..e69de29b 100644 --- a/code/__init__.py +++ b/ranger/__init__.py diff --git a/ranger/cli.py b/ranger/cli.py new file mode 100644 index 00000000..7f8fd77f --- /dev/null +++ b/ranger/cli.py @@ -0,0 +1,32 @@ +import curses +import _thread + +class CLIError(): pass + +class CLI(): + def __init__(self): + self.lock = _thread.allocalte_lock() + self.running = False + + def start(self): + with self.lock: + stdscr = curses.initscr() + self.running = True + + def exit(self): + self.stop_unless_running() + with self.lock: + self.running = False + curses.nocbreak() + stdscr.keypad(1) + curses.endwin() + + def stop_unless_running(self): + if not self.running: + raise CLIError("This function needs the cli to be runnig!") + + def print(self, text, x=0, y=0, attr=None): + with self.lock: + + + diff --git a/ranger/command.py b/ranger/command.py new file mode 100644 index 00000000..c57edba0 --- /dev/null +++ b/ranger/command.py @@ -0,0 +1,77 @@ +class CommandDummy(): + pass + +class CommandList(): + def __init__(self): + self.commandlist = [] + self.paths = {} + self.dummies_in_paths = False + self.dummy_object = CommandDummy + + def rebuild_paths(self): + paths = self.paths + + if self.dummies_in_paths: + self.remove_dummies() + + for cmd in self.commandlist: + for key in cmd.keys: + path = [] + for path in self.keypath(key): + try: paths[path] + except KeyError: + paths[path] = self.dummy_object + + self.dummies_in_paths = True + + def keypath(self, tup): + current = [] + all = [] + + for i in range(len(tup) - 1): + current.append(tup[i]) + all.append(tuple(current)) + + return all + + def remove_dummies(self): + for k in tuple(paths.keys()): + if paths[k] == self.dummy_object: del paths[k] + self.dummies_in_paths = False + + + def str_to_tuple(self, obj): + """splits a string into a tuple of integers""" + if type(obj) == tuple: + return obj + elif type(obj) == str: + return tuple(map(ord, list(obj))) + else: + raise TypeError('need a str or a tuple for str_to_tuple') + + def bind(self, fnc, *keys): + keys = tuple(map(self.str_to_tuple, keys)) + cmd = Command(fnc, keys) + cmd.commandlist = self + self.commandlist.append(cmd) + for key in keys: + self.paths[key] = cmd + +class Command(): + def __init__(self, fnc, keys): + self.fnc = fnc + self.keys = keys + self.commandlist = None + +# def rebind(keys): +# self.keys = keys +# self.commandlist.rebuild_paths() + + def execute(self, fm): + self.fnc(fm) + +if __name__ == '__main__': + cl = CommandList() + cl.initialize_commands() + + print(cl.paths) diff --git a/code/debug.py b/ranger/debug.py index 12d5d654..12d5d654 100644 --- a/code/debug.py +++ b/ranger/debug.py diff --git a/ranger/defaultui.py b/ranger/defaultui.py new file mode 100644 index 00000000..70ce75ff --- /dev/null +++ b/ranger/defaultui.py @@ -0,0 +1,39 @@ +import ranger.ui +from ranger.wdisplay import WDisplay +from ranger.wstatusbar import WStatusBar + +class DefaultUI(ranger.ui.UI): + def setup(self): + self.statusbar = WStatusBar(self.win) + self.add_widget(self.statusbar) + + self.displays = [ + WDisplay(self.win, -2), + WDisplay(self.win, -1), + WDisplay(self.win, 0), + WDisplay(self.win, 1) ] + self.displays[2].display_infostring = True + self.displays[2].main_display = True + for disp in self.displays: + self.add_widget(disp) + + RATIO = ( 0.15, 0.15, 0.4, 0.3 ) + + def resize(self): + ranger.ui.UI.resize(self) + y, x = self.win.getmaxyx() + + leftborder = 0 + + i = 0 + for ratio in DefaultUI.RATIO: + wid = int(ratio * x) + try: + self.displays[i].setdim(1, leftborder, y-1, wid - 1) + except KeyError: + pass + leftborder += wid + i += 1 + + self.statusbar.setdim(0, 0, 1, x) + diff --git a/code/directory.py b/ranger/directory.py index 4109ae2d..392f67bc 100644 --- a/code/directory.py +++ b/ranger/directory.py @@ -1,9 +1,9 @@ -import fsobject -import file, debug +import ranger.fsobject +from ranger import file, debug -class Directory(fsobject.FSObject): +class Directory(ranger.fsobject.FSObject): def __init__(self, path): - fsobject.FSObject.__init__(self, path) + ranger.fsobject.FSObject.__init__(self, path) self.content_loaded = False self.scheduled = False self.enterable = False @@ -20,7 +20,7 @@ class Directory(fsobject.FSObject): self.load_if_outdated() self.content_loaded = True import os - if self.exists: + if self.exists and self.runnable: basenames = os.listdir(self.path) mapped = map(lambda name: os.path.join(self.path, name), basenames) self.filenames = list(mapped) @@ -33,6 +33,10 @@ class Directory(fsobject.FSObject): f = file.File(name) f.load() self.files.append(f) + else: + self.filenames = None + self.files = None + self.infostring = ranger.fsobject.FSObject.BAD_INFO def load_content_once(self): self.stop_if_frozen() @@ -55,11 +59,11 @@ class Directory(fsobject.FSObject): return False def __len__(self): - if not self.accessible: raise fsobject.NotLoadedYet() + if not self.accessible: raise ranger.fsobject.NotLoadedYet() return len(self.filenames) def __getitem__(self, key): - if not self.accessible: raise fsobject.NotLoadedYet() + if not self.accessible: raise ranger.fsobject.NotLoadedYet() return self.files[key] if __name__ == '__main__': diff --git a/code/directory.rb b/ranger/directory.rb index 5c6e84c1..5c6e84c1 100644 --- a/code/directory.rb +++ b/ranger/directory.rb diff --git a/ranger/environment.py b/ranger/environment.py new file mode 100644 index 00000000..b5b3888c --- /dev/null +++ b/ranger/environment.py @@ -0,0 +1,73 @@ +import os +from ranger.directory import Directory + +class Vector(): + def __init__(self, x, y): + self.x = x + self.y = y + +class Environment(): + # A collection of data which is relevant for more than + # one class. + def __init__(self, opt): + self.opt = opt + self.path = None + self.pathway = () + self.directories = {} + self.pwd = None # current directory + self.cf = None # current file + self.keybuffer = () + self.copy = None + self.termsize = Vector(80, 24) + + def key_append(self, key): + self.keybuffer += (key, ) + + def key_clear(self): + self.keybuffer = () + + def at_level(self, level): + if level <= 0: + try: + return self.pathway[level - 1] + except IndexError: + return None + else: + return self.cf + + def get_directory(self, path): + import os + path = os.path.abspath(path) + try: + return self.directories[path] + except KeyError: + self.directories[path] = Directory(path) + return self.directories[path] + + def enter_dir(self, path): + # get the absolute path + path = os.path.normpath(os.path.join(self.path, path)) + + self.path = path + self.pwd = self.get_directory(path) + + self.pwd.load_content() + + # build the pathway, a tuple of directory objects which lie + # on the path to the current directory. + if path == '/': + self.pathway = (self.get_directory('/'), ) + else: + pathway = [] + currentpath = '/' + for dir in path.split('/'): + currentpath = os.path.join(currentpath, dir) +# debug.log(currentpath) + pathway.append(self.get_directory(currentpath)) + self.pathway = tuple(pathway) + + # set the current file. + if len(self.pwd) > 0: + self.cf = self.pwd[0] + else: + self.cf = None diff --git a/code/file.py b/ranger/file.py index 9d813aad..94c62f9a 100644 --- a/code/file.py +++ b/ranger/file.py @@ -1,5 +1,5 @@ -import fsobject -class File(fsobject.FSObject): +import ranger.fsobject +class File(ranger.fsobject.FSObject): pass # def __init__(self, path): # fsobject.FSObject.__init__(self, path) diff --git a/ranger/fm.py b/ranger/fm.py new file mode 100644 index 00000000..d616523e --- /dev/null +++ b/ranger/fm.py @@ -0,0 +1,42 @@ +import sys +#LOGFILE = '/tmp/errorlog' +#f = open(LOGFILE, 'a') +#f.write(str(tuple(sys.path)) + "\n") +#f.close() +#import code.ui, code.debug, code.file, code.directory, code.fstype + + +class FM(): + def __init__(self, environment): + self.env = environment + + def feed(self, path, ui): + self.ui = ui + self.env.path = path + self.env.enter_dir(path) + + def run(self): + import time + while 1: + try: + self.ui.draw() + key = self.ui.get_next_key() + self.ui.press(key, self) + except KeyboardInterrupt: + self.env.key_clear() + time.sleep(0.2) + except: + raise + + def exit(self): + raise SystemExit() + + def move_left(self): + self.env.enter_dir('..') + + def move_right(self): + self.env.enter_dir(self.env.cf.path) + + def move_relative(self): + pass + diff --git a/code/fsobject.py b/ranger/fsobject.py index f4268ef0..a21818c0 100644 --- a/code/fsobject.py +++ b/ranger/fsobject.py @@ -1,25 +1,32 @@ -import fstype +import ranger.fstype class FrozenException(Exception): pass class NotLoadedYet(Exception): pass class FSObject(object): + BAD_INFO = '' def __init__(self, path): if type(self) == FSObject: raise TypeError("FSObject is an abstract class and cannot be initialized.") + from os.path import basename self.path = path + self.basename = basename(path) self.exists = False self.accessible = False self.marked = False self.tagged = False self.frozen = False self.loaded = False + self.runnable = False self.islink = False self.brokenlink = False self.stat = None self.infostring = None self.permissions = None - self.type = fstype.Unknown + self.type = ranger.fstype.Unknown + + def __str__(self): + return str(self.path) # load() reads useful information about the file from the file system # and caches it in instance attributes. @@ -28,27 +35,36 @@ class FSObject(object): self.loaded = True import os - try: +# try: + if os.access(self.path, os.F_OK): self.stat = os.stat(self.path) self.islink = os.path.islink(self.path) self.exists = True self.accessible = True if os.path.isdir(self.path): - self.type = fstype.Directory - self.infostring = ' %d' % len(os.listdir(self.path)) + self.type = ranger.fstype.Directory + try: + self.infostring = ' %d' % len(os.listdir(self.path)) + self.runnable = True + except OSError: + self.infostring = FSObject.BAD_INFO + self.runnable = False + self.accessible = False elif os.path.isfile(self.path): - self.type = fstype.File + self.type = ranger.fstype.File self.infostring = ' %d' % self.stat.st_size else: - self.type = fstype.Unknown + self.type = ranger.fstype.Unknown self.infostring = None - except OSError: + else: +# except OSError: self.islink = False self.infostring = None - self.type = fstype.Nonexistent + self.type = ranger.fstype.Nonexistent self.exists = False + self.runnable = False self.accessible = False def load_once(self): diff --git a/code/fstype.py b/ranger/fstype.py index 4bd0988d..4bd0988d 100644 --- a/code/fstype.py +++ b/ranger/fstype.py diff --git a/ranger/keys.py b/ranger/keys.py new file mode 100644 index 00000000..b710a2aa --- /dev/null +++ b/ranger/keys.py @@ -0,0 +1,15 @@ +def initialize_commands(command_list): + from ranger.fm import FM + + cl = command_list + + # note: the bound function will be called with one parameter, which + # is the FM instance. To use functions with multiple parameters, use: + # lambda fm: myfunction(fm, param1, param2, ...) as the function + + cl.bind(FM.move_left, 'h', 'back') + cl.bind(FM.move_right, 'l', 'forward') + cl.bind(FM.exit, 'q') + + cl.rebuild_paths() + diff --git a/code/options.py b/ranger/options.py index eed79f1e..eed79f1e 100644 --- a/code/options.py +++ b/ranger/options.py diff --git a/code/ui.py b/ranger/ui.py index d9c1de4e..6bc06b19 100644 --- a/code/ui.py +++ b/ranger/ui.py @@ -1,7 +1,9 @@ -import curses, debug +import curses +from ranger.debug import log class UI(): - def __init__(self, env): + def __init__(self, env, commandlist): self.env = env + self.commandlist = commandlist self.widgets = [] self.win = curses.initscr() @@ -24,17 +26,35 @@ class UI(): def feed_env(self, env): self.env = env + def press(self, key, fm): + self.env.key_append(key) + log(self.env.keybuffer) + + try: + cmd = self.commandlist.paths[self.env.keybuffer] + except KeyError: + self.env.key_clear() + return + + if cmd == self.commandlist.dummy_object: + return + + cmd.execute(fm) + self.env.key_clear() + def exit(self): curses.nocbreak() curses.echo() curses.endwin() def draw(self): + from ranger.debug import log self.win.erase() for widg in self.widgets: widg.feed_env(self.env) widg.draw() self.win.refresh() + log(tuple(map(str, self.env.pathway))) # for i in range(1, len(self.env.pwd)): # f = self.env.pwd.files[i] diff --git a/ranger/wdisplay.py b/ranger/wdisplay.py new file mode 100644 index 00000000..4bd84044 --- /dev/null +++ b/ranger/wdisplay.py @@ -0,0 +1,51 @@ +import ranger.widget +import curses + +class WDisplay(ranger.widget.Widget): + def __init__(self, win, level): + ranger.widget.Widget.__init__(self,win) + self.level = level + self.main_display = False + self.display_infostring = False + + def feed_env(self, env): + self.target = env.at_level(self.level) + + def draw(self): + from ranger.file import File + from ranger.directory import Directory + + if self.target is None: + pass +# self.win.addnstr(self.y, self.x, "---", self.wid) + elif type(self.target) == File: + self.draw_file() + elif type(self.target) == Directory: + self.draw_directory() + else: + self.win.addnstr(self.y, self.x, "unknown type.", self.wid) + + def draw_file(self): + if not self.target.accessible: + self.win.addnstr(self.y, self.x, "not accessible", self.wid) + return + self.win.addnstr(self.y, self.x, "this is a file.", self.wid) + + def draw_directory(self): + self.target.load_content_once() + if not self.target.accessible: + self.win.addnstr(self.y, self.x, "not accessible", self.wid) + return + for i in range(self.hei): + try: + drawed = self.target[i] + except IndexError: + break + self.win.addnstr(self.y + i, self.x, drawed.basename, self.wid) + if self.display_infostring and drawed.infostring: + info = drawed.infostring + x = self.x + self.wid - 1 - len(info) + if x > self.x: + self.win.addstr(self.y + i, x, str(info) + ' ') + + diff --git a/code/widget.py b/ranger/widget.py index e95e6a9d..725810ec 100644 --- a/code/widget.py +++ b/ranger/widget.py @@ -11,8 +11,12 @@ class Widget(): maxy, maxx = self.win.getmaxyx() wid = wid or maxx - x hei = hei or maxy - y - if x + wid > maxx or y + hei > maxy: - raise OutOfBoundsException() + if x + wid > maxx and y + hei > maxy: + raise OutOfBoundsException("X and Y out of bounds!") + if x + wid > maxx: + raise OutOfBoundsException("X out of bounds!") + if y + hei > maxy: + raise OutOfBoundsException("Y out of bounds!") self.x = x self.y = y diff --git a/ranger/wstatusbar.py b/ranger/wstatusbar.py new file mode 100644 index 00000000..e68fb241 --- /dev/null +++ b/ranger/wstatusbar.py @@ -0,0 +1,12 @@ +import curses +import ranger.widget + +class WStatusBar(ranger.widget.Widget): + def feed_env(self, env): + self.pathway = env.pathway + + def draw(self): + self.win.move(self.y, self.x) + for path in self.pathway: + currentx = self.win.getyx()[1] + self.win.addnstr(path.basename + ' / ', (self.wid - currentx)) diff --git a/test/dirsize_benchmark.py b/test/dirsize_benchmark.py index 38f0bfd7..5784ee80 100644 --- a/test/dirsize_benchmark.py +++ b/test/dirsize_benchmark.py @@ -24,3 +24,5 @@ for key in paths.keys(): for i in range(4): assert Dirsize.__dict__[algo](key) == paths[key] print("algorithm %s: %20s: %f" % (algo, key, time.time() - t)) + +# a !! diff --git a/test/tc_directory.py b/test/tc_directory.py index 88c7a99e..275e3129 100644 --- a/test/tc_directory.py +++ b/test/tc_directory.py @@ -1,17 +1,22 @@ -import unittest -import sys, os, time +if __name__ == '__main__': + from os.path import abspath, join + import sys + sys.path.append(abspath(join(sys.path[0], '..'))) -sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), '../code'))) -import fsobject, file, directory +from ranger import fsobject +from ranger.file import File +from ranger.directory import Directory -TESTDIR = os.path.realpath(os.path.join(os.path.dirname(__file__), 'testdir')) -TESTFILE = os.path.join(TESTDIR, 'testfile5234148') +from os.path import realpath, join, dirname +TESTDIR = realpath(join(dirname(__file__), 'testdir')) +TESTFILE = join(TESTDIR, 'testfile5234148') NONEXISTANT_DIR = '/this/directory/will/most/certainly/not/exist' +import unittest class Test1(unittest.TestCase): def test_initial_condition(self): # Check for the expected initial condition - dir = directory.Directory(TESTDIR) + dir = Directory(TESTDIR) self.assertEqual(dir.path, TESTDIR) self.assertFalse(dir.content_loaded) @@ -21,8 +26,9 @@ class Test1(unittest.TestCase): self.assertRaises(fsobject.NotLoadedYet, dir.__getitem__, 0) def test_after_content_loaded(self): + import os # Check whether the directory has the correct list of filenames. - dir = directory.Directory(TESTDIR) + dir = Directory(TESTDIR) dir.load_content() self.assertTrue(dir.exists) @@ -41,7 +47,7 @@ class Test1(unittest.TestCase): # build a file object for each file in the list assumed_filenames # and find exactly one equivalent in dir.files for name in assumed_filenames: - f = file.File(name) + f = File(name) f.load() equal = 0 for dirfile in dir.files: @@ -50,7 +56,7 @@ class Test1(unittest.TestCase): self.assertEqual(equal, 1) def test_nonexistant_dir(self): - dir = directory.Directory(NONEXISTANT_DIR) + dir = Directory(NONEXISTANT_DIR) dir.load_content() self.assertTrue(dir.content_loaded) @@ -61,7 +67,7 @@ class Test1(unittest.TestCase): self.assertRaises(fsobject.NotLoadedYet, dir.__getitem__, 0) def test_modify_frozen_clone(self): - dir = directory.Directory(TESTDIR) + dir = Directory(TESTDIR) clone = dir.frozen_clone() # assert that their attributes are equal, except for frozen, which @@ -79,6 +85,8 @@ class Test1(unittest.TestCase): self.assertRaises(fsobject.FrozenException, clone.load_content) def test_load_if_outdated(self): + import os + import time # modify the directory. If the time between the last modification # was within the filesystems resolution of mtime, we should have a re-load. @@ -89,7 +97,7 @@ class Test1(unittest.TestCase): def mtime(): return os.stat(TESTDIR).st_mtime - dir = directory.Directory(TESTDIR) + dir = Directory(TESTDIR) dir.load() # If the modification happens to be in the same second as the diff --git a/test4.py b/test4.py new file mode 100644 index 00000000..b2390a03 --- /dev/null +++ b/test4.py @@ -0,0 +1,36 @@ +import random, time + +class DelValue(): + def a(d): + return dict((k, v) for k, v in d.items() if v is not 0) + + def b(d): + for k, v in d.copy().items(): + if v == 0: del d[k] + return d + + def c(d): + for k in tuple(d.keys()): + if d[k] == 0: del d[k] + return d + + def d(d): + for k, v in tuple(d.items()): + if v == 0: del d[k] + return d + + +basedict = {} +for i in range(200): + basedict[i] = random.randint(0, 1) + +expected = DelValue.a(basedict.copy()) + +for algo in ['a', 'b', 'c', 'd']: + copy = basedict.copy() + t = time.time() + for i in range(100): + assert DelValue.__dict__[algo](copy) == expected + print("algorithm %s: %f" % (algo, time.time() - t)) + +# c it is, although b is faster with smaller dictionaries |