[hackers] [wmii] [python] Minor cleanups. || Kris Maglione

From: <hg_AT_suckless.org>
Date: Sat, 10 Jul 2010 00:00:12 +0000 (UTC)

changeset: 2760:af47966054cb
user: Kris Maglione <kris_AT_suckless.org>
date: Fri Jul 09 17:17:39 2010 -0400
files: alternative_wmiircs/python/pygmi/fs.py alternative_wmiircs/python/pygmi/menu.py alternative_wmiircs/python/pygmi/monitor.py alternative_wmiircs/python/pygmi/util.py alternative_wmiircs/python/pyxp/asyncclient.py alternative_wmiircs/python/pyxp/client.py alternative_wmiircs/python/pyxp/messages.py alternative_wmiircs/python/pyxp/mux.py alternative_wmiircs/python/wmiirc
description:
[python] Minor cleanups.

diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pygmi/fs.py
--- a/alternative_wmiircs/python/pygmi/fs.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/fs.py Fri Jul 09 17:17:39 2010 -0400
@@ -13,6 +13,11 @@
 spacere = re.compile(r'\s')
 sentinel = {}
 
+def tounicode(obj):
+ if isinstance(obj, str):
+ return obj.decode('UTF-8')
+ return unicode(obj)
+
 class utf8(object):
     def __str__(self):
         return unicode(self).encode('utf-8')
@@ -85,12 +90,10 @@
         """
         Arguments are joined by ascii spaces and written to the ctl file.
         """
- def next(file, exc=None, tb=None):
- if exc:
- print exc
+ def next(file):
             if file:
                 self.ctl_file = file
- file.awrite(u' '.join(map(unicode, args)))
+ file.awrite(u' '.join(map(tounicode, args)))
         if self.ctl_file:
             return next(self.ctl_file)
         getattr(client, self.ctl_open)(self.ctl_path, callback=next, mode=OWRITE)
@@ -687,7 +690,7 @@
         if val is False: return "off"
         if val in (Toggle, Always, Never):
             return unicode(val).lower()
- return unicode(val)
+ return tounicode(val)
 
     def __get__(self, obj, cls):
         return self
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pygmi/menu.py
--- a/alternative_wmiircs/python/pygmi/menu.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/menu.py Fri Jul 09 17:17:39 2010 -0400
@@ -3,11 +3,12 @@
 
 __all__ = 'Menu', 'ClickMenu'
 
-def inthread(args, action, **kwargs):
+def inthread(name, args, action, **kwargs):
     fn = lambda: call(*args, **kwargs)
     if not action:
         return fn()
     t = Thread(target=lambda: action(fn()))
+ t.name += '-%s' % name
     t.daemon = True
     t.start()
 
@@ -29,7 +30,7 @@
             args += ['-h', self.histfile]
         if self.nhist:
             args += ['-n', self.nhist]
- return inthread(map(str, args), self.action, input='\n'.join(choices))
+ return inthread('Menu', map(str, args), self.action, input='\n'.join(choices))
     call = __call__
 
 class ClickMenu(object):
@@ -48,7 +49,7 @@
         if self.prev:
             args += ['-i', self.prev]
         args += ['--'] + list(choices)
- return inthread(map(str, args), self.action)
+ return inthread('ClickMenu', map(str, args), self.action)
     call = __call__
 
 # vim:se sts=4 sw=4 et:
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pygmi/monitor.py
--- a/alternative_wmiircs/python/pygmi/monitor.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/monitor.py Fri Jul 09 17:17:39 2010 -0400
@@ -51,6 +51,8 @@
     side = 'right'
     interval = 1.0
 
+ define = classmethod(defmonitor)
+
     def __init__(self, name=None, interval=None, side=None,
                  action=None, colors=None, label=None):
         """
@@ -93,6 +95,7 @@
                         self.button.create(*label)
 
                     self.timer = Timer(self.interval, self.tick)
+ self.timer.name = 'Monitor-Timer-%s' % self.name
                     self.timer.daemon = True
                     self.timer.start()
 
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pygmi/util.py
--- a/alternative_wmiircs/python/pygmi/util.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/util.py Fri Jul 09 17:17:39 2010 -0400
@@ -1,3 +1,4 @@
+from functools import partial, update_wrapper, wraps
 import os
 import signal
 import subprocess
@@ -43,6 +44,7 @@
 def curry(func, *args, **kwargs):
     if _ in args:
         blank = [i for i in range(0, len(args)) if args[i] is _]
+ @wraps(func)
         def curried(*newargs, **newkwargs):
             ary = list(args)
             for k, v in zip(blank, newargs):
@@ -50,9 +52,8 @@
             ary = tuple(ary) + newargs[len(blank):]
             return func(*ary, **dict(kwargs, **newkwargs))
     else:
- def curried(*newargs, **newkwargs):
- return func(*(args + newargs), **dict(kwargs, **newkwargs))
- curried.__name__ = func.__name__ + '__curried__'
+ curried = update_wrapper(partial(func, *args, **kwargs), func)
+ curried.__name__ += '__curried__'
     return curried
 
 def find_script(name):
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pyxp/asyncclient.py
--- a/alternative_wmiircs/python/pyxp/asyncclient.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pyxp/asyncclient.py Fri Jul 09 17:17:39 2010 -0400
@@ -1,14 +1,17 @@
 from pyxp import client, fcall
 from pyxp.client import *
+from functools import wraps
 
 def awithfile(*oargs, **okwargs):
     def wrapper(fn):
+ @wraps(fn)
         def next(self, path, *args, **kwargs):
             def next(file, exc, tb):
                 fn(self, (file, exc, tb), *args, **kwargs)
             self.aopen(path, next, *oargs, **okwargs)
         return next
     return wrapper
+
 def wrap_callback(fn, file):
     def callback(data, exc, tb):
         file.close()
@@ -19,81 +22,82 @@
     ROOT_FID = 0
 
     def _awalk(self, path, callback, fail=None):
+ path = self._splitpath(path)
         ctxt = dict(path=path, fid=self._getfid(), ofid=ROOT_FID)
+
         def next(resp=None, exc=None, tb=None):
             if exc and ctxt['ofid'] != ROOT_FID:
                 self._aclunk(ctxt['fid'])
+ ctxt['fid'] = None
+
             if not ctxt['path'] and resp or exc:
- if exc and fail:
- return self.respond(fail, None, exc, tb)
- return self.respond(callback, ctxt['fid'], exc, tb)
+ return self.respond(fail if exc and fail else callback,
+ ctxt['fid'], exc, tb)
+
             wname = ctxt['path'][:fcall.MAX_WELEM]
             ofid = ctxt['ofid']
             ctxt['path'] = ctxt['path'][fcall.MAX_WELEM:]
             if resp:
                 ctxt['ofid'] = ctxt['fid']
- self._dorpc(fcall.Twalk(fid=ofid,
- newfid=ctxt['fid'],
- wname=wname),
- next)
+
+ self._dorpc(fcall.Twalk(fid=ofid, newfid=ctxt['fid'], wname=wname),
+ next)
         next()
 
     _file = property(lambda self: File)
- def _aopen(self, path, mode, open, callback, fail=None, origpath=None):
- resp = None
+ def _aopen(self, path, mode, fcall, callback, fail=None, origpath=None):
+ path = self._splitpath(path)
+
         def next(fid, exc, tb):
             def next(resp, exc, tb):
- def cleanup():
- self._clunk(fid)
- file = self._file(self, origpath or '/'.join(path), resp, fid, mode, cleanup)
+ file = self._file(self, origpath or '/'.join(path), resp, fid, mode,
+ cleanup=lambda: self._clunk(fid))
                 self.respond(callback, file)
- self._dorpc(open(fid), next, fail or callback)
+ fcall.fid = fid
+ self._dorpc(fcall, next, fail or callback)
         self._awalk(path, next, fail or callback)
 
     def aopen(self, path, callback=True, fail=None, mode=OREAD):
         assert callable(callback)
- path = self._splitpath(path)
- def open(fid):
- return fcall.Topen(fid=fid, mode=mode)
- return self._aopen(path, mode, open, fail or callback)
+ return self._aopen(path, mode, fcall.Topen(mode=mode),
+ callback, fail)
 
     def acreate(self, path, callback=True, fail=None, mode=OREAD, perm=0):
         path = self._splitpath(path)
         name = path.pop()
- def open(fid):
- return fcall.Tcreate(fid=fid, mode=mode, name=name, perm=perm)
+
         if not callable(callback):
- def callback(resp, exc, tb):
- if resp:
- resp.close()
- return self._aopen(path, mode, open, callback, fail,
- origpath='/'.join(path + [name]))
+ callback = lambda resp: resp and resp.close()
+
+ return self._aopen(path, mode, fcall.Tcreate(mode=mode, name=name, perm=perm),
+ callback, fail, origpath='/'.join(path + [name]))
 
     def aremove(self, path, callback=True, fail=None):
- path = self._splitpath(path)
- def next(fid, exc, tb):
+ def next(fid):
             self._dorpc(fcall.Tremove(fid=fid), callback, fail)
- self._awalk(path, next, callback, fail)
+ self._awalk(path, next, fail or callback)
 
- def astat(self, path, callback, fail = None):
- path = self._splitpath(path)
- def next(fid, exc, tb):
- def next(resp, exc, tb):
- callback(resp.stat, exc, tb)
- self._dorpc(fcall.Tstat(fid=fid), next, callback)
+ def astat(self, path, callback, fail=None):
+ def next(fid):
+ def next(resp):
+ self.respond(callback, resp.stat)
+ self._dorpc(fcall.Tstat(fid=fid), next, fail or callback)
+ self._awalk(self, next, fail or callback)
 
     @awithfile()
     def aread(self, (file, exc, tb), callback, *args, **kwargs):
         if exc:
- callback(file, exc, tb)
+ self.respond(callback, file, exc, tb)
         else:
             file.aread(wrap_callback(callback, file), *args, **kwargs)
+
     @awithfile(mode=OWRITE)
     def awrite(self, (file, exc, tb), data, callback=True, *args, **kwargs):
         if exc:
             self.respond(callback, file, exc, tb)
         else:
             file.awrite(data, wrap_callback(callback, file), *args, **kwargs)
+
     @awithfile()
     def areadlines(self, (file, exc, tb), fn):
         def callback(resp):
@@ -108,36 +112,35 @@
             file.sreadlines(callback)
 
 class File(client.File):
- @staticmethod
- def respond(callback, data, exc=None, tb=None):
- if callable(callback):
- callback(data, exc, tb)
 
     def stat(self, callback):
         def next(resp, exc, tb):
- callback(resp.stat, exc, tb)
+ Client.respond(callback, resp.stat, exc, tb)
         resp = self._dorpc(fcall.Tstat(), next, callback)
 
     def aread(self, callback, fail=None, count=None, offset=None, buf=''):
         ctxt = dict(res=[], count=self.iounit, offset=self.offset)
+
         if count is not None:
             ctxt['count'] = count
         if offset is not None:
             ctxt['offset'] = offset
+
         def next(resp=None, exc=None, tb=None):
             if resp and resp.data:
                 ctxt['res'].append(resp.data)
                 ctxt['offset'] += len(resp.data)
+
             if ctxt['count'] == 0:
                 if offset is None:
                     self.offset = ctxt['offset']
- return callback(''.join(ctxt['res']), exc, tb)
+ return Client.respond(callback, ''.join(ctxt['res']), exc, tb)
 
             n = min(ctxt['count'], self.iounit)
             ctxt['count'] -= n
 
             self._dorpc(fcall.Tread(offset=ctxt['offset'], count=n),
- next, fail or callback)
+ next, fail or callback)
         next()
 
     def areadlines(self, callback):
@@ -165,6 +168,7 @@
         ctxt = dict(offset=self.offset, off=0)
         if offset is not None:
             ctxt['offset'] = offset
+
         def next(resp=None, exc=None, tb=None):
             if resp:
                 ctxt['off'] += resp.count
@@ -173,21 +177,21 @@
                 n = min(len(data), self.iounit)
 
                 self._dorpc(fcall.Twrite(offset=ctxt['offset'],
- data=data[ctxt['off']:ctxt['off']+n]),
- next, fail or callback)
+ data=data[ctxt['off']:ctxt['off']+n]),
+ next, fail or callback)
             else:
                 if offset is None:
                     self.offset = ctxt['offset']
- self.respond(callback, ctxt['off'], exc, tb)
+ Client.respond(callback, ctxt['off'], exc, tb)
         next()
 
     def aremove(self, callback=True, fail=None):
         def next(resp, exc, tb):
             self.close()
             if exc and fail:
- self.respond(fail, resp and True, exc, tb)
+ Client.respond(fail, resp and True, exc, tb)
             else:
- self.respond(callback, resp and True, exc, tb)
+ Client.respond(callback, resp and True, exc, tb)
         self._dorpc(fcall.Tremove(), next)
 
 # vim:se sts=4 sw=4 et:
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pyxp/client.py
--- a/alternative_wmiircs/python/pyxp/client.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pyxp/client.py Fri Jul 09 17:17:39 2010 -0400
@@ -46,8 +46,7 @@
     @staticmethod
     def respond(callback, data, exc=None, tb=None):
         if callable(callback):
- callback(data, exc, tb)
-
+ callback(*(data, exc, tb)[0:callback.func_code.co_argcount])
 
     def __enter__(self):
         return self
@@ -77,13 +76,13 @@
             if root:
                 path = self._splitpath(root)
                 resp = self._dorpc(fcall.Twalk(fid=ROOT_FID,
- newfid=ROOT_FID,
- wname=path))
- except Exception, e:
+ newfid=ROOT_FID,
+ wname=path))
+ except Exception:
             traceback.print_exc(sys.stdout)
             if getattr(self, 'mux', None):
                 self.mux.fd.close()
- raise e
+ raise
 
     def _cleanup(self):
         try:
@@ -102,21 +101,22 @@
                 raise ProtocolException, "Missmatched RPC message types: %s => %s" % (
                     req.__class__.__name__, resp.__class__.__name__)
             return resp
+
         def next(mux, resp):
             try:
                 res = doresp(resp)
             except Exception, e:
- if error:
- self.respond(error, None, e, None)
- else:
- self.respond(callback, None, e, None)
+ self.respond(error or callback, None, e, None)
             else:
                 self.respond(callback, res)
+
         if not callback:
             return doresp(self.mux.rpc(req))
         self.mux.rpc(req, next)
 
     def _splitpath(self, path):
+ if isinstance(path, list):
+ return path
         return [v for v in path.split('/') if v != '']
 
     def _getfid(self):
@@ -163,12 +163,13 @@
         return Res
 
     _file = property(lambda self: File)
- def _open(self, path, mode, open, origpath=None):
+ def _open(self, path, mode, fcall, origpath=None):
         resp = None
 
         with self._walk(path) as nfid:
             fid = nfid
- resp = self._dorpc(open(fid))
+ fcall.fid = fid
+ resp = self._dorpc(fcall)
 
         def cleanup():
             self._aclunk(fid)
@@ -178,17 +179,14 @@
     def open(self, path, mode=OREAD):
         path = self._splitpath(path)
 
- def open(fid):
- return fcall.Topen(fid=fid, mode=mode)
- return self._open(path, mode, open)
+ return self._open(path, mode, fcall.Topen(mode=mode))
 
     def create(self, path, mode=OREAD, perm=0):
         path = self._splitpath(path)
         name = path.pop()
 
- def open(fid):
- return fcall.Tcreate(fid=fid, mode=mode, name=name, perm=perm)
- return self._open(path, mode, open, origpath='/'.join(path + [name]))
+ return self._open(path, mode, fcall.Tcreate(mode=mode, name=name, perm=perm),
+ origpath='/'.join(path + [name]))
 
     def remove(self, path):
         path = self._splitpath(path)
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pyxp/messages.py
--- a/alternative_wmiircs/python/pyxp/messages.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pyxp/messages.py Fri Jul 09 17:17:39 2010 -0400
@@ -28,7 +28,7 @@
     __metaclass__ = MessageBase
     def __init__(self, *args, **kwargs):
         if args:
- args = dict(zip([f.name for f in self.fields], args))
+ args = dict(zip((f.name for f in self.fields), args))
             args.update(kwargs)
             kwargs = args;
         for k, v in kwargs.iteritems():
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/pyxp/mux.py
--- a/alternative_wmiircs/python/pyxp/mux.py Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/pyxp/mux.py Fri Jul 09 17:17:39 2010 -0400
@@ -14,6 +14,7 @@
 # The above copyright notice and this permission notice shall be
 # included in all copies or substantial portions of the Software.
 
+import os
 import sys
 import traceback
 
@@ -26,9 +27,8 @@
 
 class Mux(object):
     def __init__(self, con, process, flush=None, mintag=0, maxtag=1<<16 - 1):
- self.queue = set()
         self.lock = RLock()
- self.rendez = Condition(self.lock)
+ self.tagcond = Condition(self.lock)
         self.outlock = RLock()
         self.inlock = RLock()
         self.process = process
@@ -50,35 +50,32 @@
             raise Exception("No connection")
 
     def mux(self, rpc):
- try:
- self.lock.acquire()
- rpc.waiting = True
- while self.muxer and self.muxer != rpc and rpc.data is None:
- rpc.wait()
+ with self.lock:
+ try:
+ rpc.waiting = True
+ while self.muxer and self.muxer != rpc and rpc.data is None:
+ rpc.wait()
 
- if rpc.data is None:
- assert not self.muxer or self.muxer is rpc
- self.muxer = rpc
- self.lock.release()
- try:
- while rpc.data is None:
- data = self.recv()
- if data is None:
- self.lock.acquire()
- self.queue.remove(rpc)
- raise Exception("unexpected eof")
- self.dispatch(data)
- finally:
- self.lock.acquire()
- self.electmuxer()
- except Exception, e:
- traceback.print_exc(sys.stderr)
- if self.flush:
- self.flush(self, rpc.data)
- raise e
- finally:
- if self.lock._is_owned():
- self.lock.release()
+ if rpc.data is None:
+ assert self.muxer in (rpc, None)
+ self.muxer = rpc
+ try:
+ self.lock.release()
+ while rpc.data is None:
+ data = self.recv()
+ if data is None:
+ raise Exception("unexpected eof")
+ self.dispatch(data)
+ finally:
+ self.lock.acquire()
+ self.electmuxer()
+ except Exception:
+ traceback.print_exc(sys.stderr)
+ if rpc.tag in self.wait:
+ self.wait.pop(rpc.tag)
+ if self.flush:
+ self.flush(self, rpc.data)
+ raise
 
         return rpc.data
 
@@ -90,11 +87,10 @@
             return self.mux(rpc)
 
     def async_dispatch(self, rpc):
- self.async_mux.pop(rpc)
         rpc.async(self, rpc.data)
 
     def electmuxer(self):
- for rpc in self.queue:
+ for rpc in self.wait.itervalues():
             if self.muxer != rpc and rpc.waiting:
                 self.muxer = rpc
                 rpc.notify()
@@ -102,22 +98,19 @@
         self.muxer = None
 
     def dispatch(self, dat):
- tag = dat.tag
- rpc = None
         with self.lock:
- rpc = self.wait.get(tag, None)
- if rpc is None or rpc not in self.queue:
- #print "bad rpc tag: %u (no one waiting on it)" % dat.tag
- return
- self.puttag(rpc)
- self.queue.remove(rpc)
- rpc.dispatch(dat)
+ rpc = self.wait.get(dat.tag, None)
+ if rpc:
+ self.puttag(rpc)
+ rpc.dispatch(dat)
+ elif False:
+ print "bad rpc tag: %u (no one waiting on it)" % dat.tag
 
     def gettag(self, r):
         tag = 0
 
         while not self.free:
- self.rendez.wait()
+ self.tagcond.wait()
 
         tag = self.free.pop()
 
@@ -134,21 +127,36 @@
         if rpc.tag in self.wait:
             del self.wait[rpc.tag]
         self.free.add(rpc.tag)
- self.rendez.notify()
+ self.tagcond.notify()
 
     def send(self, dat):
         data = ''.join(dat.marshall())
         n = self.fd.send(data)
         return n == len(data)
     def recv(self):
+ def readn(fd, n):
+ data = ''
+ while len(data) < n:
+ try:
+ s = fd.recv(n - len(data))
+ if len(s) == 0:
+ raise Exception('unexpected end of file')
+ data += s
+ except os.error, e:
+ if e.errno != os.errno.EINTR:
+ raise e
+ return data
+
         try:
             with self.inlock:
- data = self.fd.recv(4)
+ data = readn(self.fd, 4)
                 if data:
- len = fields.Int.decoders[4](data, 0)
- data += self.fd.recv(len - 4)
+ nmsg = fields.Int.decoders[4](data, 0)
+ data += readn(self.fd, nmsg - 4)
                     return self.process(data)
         except Exception, e:
+ print e.__class__.__name__
+ print repr(e)
             traceback.print_exc(sys.stderr)
             return None
 
@@ -158,13 +166,11 @@
 
         with self.lock:
             self.gettag(rpc)
- self.queue.add(rpc)
 
         if rpc.tag >= 0 and self.send(dat):
             return rpc
 
         with self.lock:
- self.queue.remove(rpc)
             self.puttag(rpc)
 
 class Rpc(Condition):
@@ -176,6 +182,9 @@
         self.async = async
         self.waiting = False
 
+ def __repr__(self):
+ return '<Rpc tag=%s orig=%s data=%s async=%s waiting=%s>' % tuple(map(repr, (self.tag, self.orig, self.data, self.async, self.waiting)))
+
     def dispatch(self, data=None):
         self.data = data
         self.notify()
@@ -183,8 +192,11 @@
             self.mux.async_dispatch(self)
 
 class Queue(Thread):
+ _id = 1
+
     def __init__(self, op):
- super(Queue, self).__init__()
+ super(Queue, self).__init__(name='Queue-%d-%s' % (Queue._id, repr(op)))
+ Queue._id += 1
         self.cond = Condition()
         self.op = op
         self.queue = []
diff -r 1f6866777547 -r af47966054cb alternative_wmiircs/python/wmiirc
--- a/alternative_wmiircs/python/wmiirc Thu Jul 08 03:07:08 2010 -0400
+++ b/alternative_wmiircs/python/wmiirc Fri Jul 09 17:17:39 2010 -0400
@@ -1,4 +1,9 @@
 #!/usr/bin/env python
+import os, sys
+path = []
+for p in os.environ.get("WMII_CONFPATH", "").split(':'):
+ path += [p, p + '/python']
+sys.path = path + sys.path
 
 from pygmi import events
 import wmiirc
Received on Sat Jul 10 2010 - 02:00:12 CEST

This archive was generated by hypermail 2.2.0 : Sat Jul 10 2010 - 02:12:03 CEST