def watchObject(self, object, identifier, callback): """Watch the given object. Whenever I think the object might have changed, I'll send an ObjectLink of it to the callback. The identifier argument is used to generate identifiers for objects which are members of this one. """ if type(object) is not types.InstanceType: raise TypeError, "Sorry, can only place a watch on Instances." # uninstallers = [] dct = {} reflect.addMethodNamesToDict(object.__class__, dct, '') for k in object.__dict__.keys(): dct[k] = 1 members = dct.keys() clazzNS = {} clazz = new.classobj( 'Watching%s%X' % (object.__class__.__name__, id(object)), ( _MonkeysSetattrMixin, object.__class__, ), clazzNS) clazzNS['_watchEmitChanged'] = new.instancemethod( lambda slf, i=identifier, b=self, cb=callback: cb( b.browseObject(slf, i)), None, clazz) # orig_class = object.__class__ object.__class__ = clazz for name in members: m = getattr(object, name) # Only hook bound methods. if ((type(m) is types.MethodType) and (m.im_self is not None)): # What's the use of putting watch monkeys on methods # in addition to __setattr__? Well, um, uh, if the # methods modify their attributes (i.e. add a key to # a dictionary) instead of [re]setting them, then # we wouldn't know about it unless we did this. # (Is that convincing?) monkey = _WatchMonkey(object) monkey.install(name)
def _gather_handlers(self): """Gather up options with their own handler methods. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} dct = {} reflect.addMethodNamesToDict(self.__class__, dct, "opt_") for name in dct.keys(): method = getattr(self, 'opt_'+name) takesArg = not flagFunction(method, name) prettyName = string.replace(name, '_', '-') doc = getattr(method, '__doc__', None) if doc: docs[prettyName] = doc else: docs[prettyName] = self.docs.get(prettyName) synonyms[prettyName] = prettyName if takesArg: fn = lambda name, value, m=method: m(value) else: fn = lambda name, value=None, m=method: m() dispatch[prettyName] = fn if len(name) == 1: shortOpt = shortOpt + name if takesArg: shortOpt = shortOpt + ':' else: if takesArg: prettyName = prettyName + '=' longOpt.append(prettyName) reverse_dct = {} for name in dct.keys(): method = getattr(self, 'opt_'+name) if not reverse_dct.has_key(method): reverse_dct[method] = [] reverse_dct[method].append(name) cmpLength = lambda a, b: cmp(len(a), len(b)) for method, names in reverse_dct.items(): if len(names) < 2: continue names_ = names[:] names_.sort(cmpLength) longest = names_.pop() for name in names_: synonyms[name] = longest return longOpt, shortOpt, docs, settings, synonyms, dispatch
def watchObject(self, object, identifier, callback): """Watch the given object. Whenever I think the object might have changed, I'll send an ObjectLink of it to the callback. The identifier argument is used to generate identifiers for objects which are members of this one. """ if type(object) is not types.InstanceType: raise TypeError, "Sorry, can only place a watch on Instances." # uninstallers = [] dct = {} reflect.addMethodNamesToDict(object.__class__, dct, "") for k in object.__dict__.keys(): dct[k] = 1 members = dct.keys() clazzNS = {} clazz = new.classobj( "Watching%s%X" % (object.__class__.__name__, id(object)), (_MonkeysSetattrMixin, object.__class__), clazzNS ) clazzNS["_watchEmitChanged"] = new.instancemethod( lambda slf, i=identifier, b=self, cb=callback: cb(b.browseObject(slf, i)), None, clazz ) # orig_class = object.__class__ object.__class__ = clazz for name in members: m = getattr(object, name) # Only hook bound methods. if (type(m) is types.MethodType) and (m.im_self is not None): # What's the use of putting watch monkeys on methods # in addition to __setattr__? Well, um, uh, if the # methods modify their attributes (i.e. add a key to # a dictionary) instead of [re]setting them, then # we wouldn't know about it unless we did this. # (Is that convincing?) monkey = _WatchMonkey(object) monkey.install(name)
def _gather_handlers(self): """Gather up options with their own handler methods. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} dct = {} reflect.addMethodNamesToDict(self.__class__, dct, "opt_") for name in dct.keys(): method = getattr(self, 'opt_' + name) takesArg = not flagFunction(method, name) prettyName = string.replace(name, '_', '-') doc = getattr(method, '__doc__', None) if doc: ## Only use the first line. #docs[name] = string.split(doc, '\n')[0] docs[prettyName] = doc else: docs[prettyName] = self.docs.get(prettyName) synonyms[prettyName] = prettyName # A little slight-of-hand here makes dispatching much easier # in parseOptions, as it makes all option-methods have the # same signature. if takesArg: fn = lambda name, value, m=method: m(value) else: # XXX: This won't raise a TypeError if it's called # with a value when it shouldn't be. fn = lambda name, value=None, m=method: m() dispatch[prettyName] = fn if len(name) == 1: shortOpt = shortOpt + name if takesArg: shortOpt = shortOpt + ':' else: if takesArg: prettyName = prettyName + '=' longOpt.append(prettyName) reverse_dct = {} # Map synonyms for name in dct.keys(): method = getattr(self, 'opt_' + name) if not reverse_dct.has_key(method): reverse_dct[method] = [] reverse_dct[method].append(name) cmpLength = lambda a, b: cmp(len(a), len(b)) for method, names in reverse_dct.items(): if len(names) < 2: continue names_ = names[:] names_.sort(cmpLength) longest = names_.pop() for name in names_: synonyms[name] = longest return longOpt, shortOpt, docs, settings, synonyms, dispatch
def _gather_handlers(self): """Gather up options with their own handler methods. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} dct = {} reflect.addMethodNamesToDict(self.__class__, dct, "opt_") for name in dct.keys(): method = getattr(self, 'opt_'+name) takesArg = not flagFunction(method, name) prettyName = string.replace(name, '_', '-') doc = getattr(method, '__doc__', None) if doc: ## Only use the first line. #docs[name] = string.split(doc, '\n')[0] docs[prettyName] = doc else: docs[prettyName] = self.docs.get(prettyName) synonyms[prettyName] = prettyName # A little slight-of-hand here makes dispatching much easier # in parseOptions, as it makes all option-methods have the # same signature. if takesArg: fn = lambda name, value, m=method: m(value) else: # XXX: This won't raise a TypeError if it's called # with a value when it shouldn't be. fn = lambda name, value=None, m=method: m() dispatch[prettyName] = fn if len(name) == 1: shortOpt = shortOpt + name if takesArg: shortOpt = shortOpt + ':' else: if takesArg: prettyName = prettyName + '=' longOpt.append(prettyName) reverse_dct = {} # Map synonyms for name in dct.keys(): method = getattr(self, 'opt_'+name) if not reverse_dct.has_key(method): reverse_dct[method] = [] reverse_dct[method].append(name) cmpLength = lambda a, b: cmp(len(a), len(b)) for method, names in reverse_dct.items(): if len(names) < 2: continue names_ = names[:] names_.sort(cmpLength) longest = names_.pop() for name in names_: synonyms[name] = longest return longOpt, shortOpt, docs, settings, synonyms, dispatch
def _gather_handlers(self): """Gather up options with their own handler methods. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} dct = {} reflect.addMethodNamesToDict(self.__class__, dct, "opt_") for name in dct.keys(): method = getattr(self, 'opt_' + name) reqArgs = method.im_func.func_code.co_argcount if reqArgs > 2: raise error, 'invalid Option function for %s' % name if reqArgs == 2: # argName = method.im_func.func_code.co_varnames[1] takesArg = 1 else: takesArg = 0 doc = getattr(method, '__doc__', None) if doc: ## Only use the first line. #docs[name] = string.split(doc, '\n')[0] docs[name] = doc else: docs[name] = None synonyms[name] = name # A little slight-of-hand here makes dispatching much easier # in parseOptions, as it makes all option-methods have the # same signature. if takesArg: fn = lambda self, name, value, m=method: m(value) else: # XXX: This won't raise a TypeError if it's called # with a value when it shouldn't be. fn = lambda self, name, value=None, m=method: m() dispatch[name] = new.instancemethod(fn, self, self.__class__) if len(name) == 1: shortOpt = shortOpt + name if takesArg: shortOpt = shortOpt + ':' else: if takesArg: name = name + '=' longOpt.append(name) reverse_dct = {} # Map synonyms for name in dct.keys(): method = getattr(self, 'opt_' + name) if not reverse_dct.has_key(method): reverse_dct[method] = [] reverse_dct[method].append(name) cmpLength = lambda a, b: cmp(len(a), len(b)) for method, names in reverse_dct.items(): if len(names) < 2: continue names_ = names[:] names_.sort(cmpLength) longest = names_.pop() for name in names_: synonyms[name] = longest return longOpt, shortOpt, docs, settings, synonyms, dispatch
def _gather_handlers(self): """Gather up options with their own handler methods. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} dct = {} reflect.addMethodNamesToDict(self.__class__, dct, "opt_") for name in dct.keys(): method = getattr(self, 'opt_'+name) reqArgs = method.im_func.func_code.co_argcount if reqArgs > 2: raise error, 'invalid Option function for %s' % name if reqArgs == 2: # argName = method.im_func.func_code.co_varnames[1] takesArg = 1 else: takesArg = 0 doc = getattr(method, '__doc__', None) if doc: ## Only use the first line. #docs[name] = string.split(doc, '\n')[0] docs[name] = doc else: docs[name] = None synonyms[name] = name # A little slight-of-hand here makes dispatching much easier # in parseOptions, as it makes all option-methods have the # same signature. if takesArg: fn = lambda self, name, value, m=method: m(value) else: # XXX: This won't raise a TypeError if it's called # with a value when it shouldn't be. fn = lambda self, name, value=None, m=method: m() dispatch[name] = new.instancemethod(fn, self, self.__class__) if len(name) == 1: shortOpt = shortOpt + name if takesArg: shortOpt = shortOpt + ':' else: if takesArg: name = name + '=' longOpt.append(name) reverse_dct = {} # Map synonyms for name in dct.keys(): method = getattr(self, 'opt_'+name) if not reverse_dct.has_key(method): reverse_dct[method] = [] reverse_dct[method].append(name) cmpLength = lambda a, b: cmp(len(a), len(b)) for method, names in reverse_dct.items(): if len(names) < 2: continue names_ = names[:] names_.sort(cmpLength) longest = names_.pop() for name in names_: synonyms[name] = longest return longOpt, shortOpt, docs, settings, synonyms, dispatch