From 9fe9ab8376c2853710022122bb77d8cdf7f6cff2 Mon Sep 17 00:00:00 2001 From: Richard Darst Date: Thu, 9 Dec 2010 21:59:24 -0800 Subject: [PATCH] supybotconfig - fix __init__ order Ignore-this: 684574bdf546a62ee97c3fbd8ac5f637 - This fixes a problem where writer_map was not properly being read from the supybot config system. It was caused by __init__ in the Config class not being able to get data from the supybot config proxy. - This patch rebinds __init__ to use the supybot config proxy __getattr__ scheme. - As part of fixing this, I had to add code to rebind descriptors/properties to use the config proxy, too. darcs-hash:20101210055924-82ea9-e10c282c4803cb987f6dd423838b474b686d9c50.gz --- MeetBot/supybotconfig.py | 24 +++++++++++++++++++++--- ircmeeting/meeting.py | 4 ++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/MeetBot/supybotconfig.py b/MeetBot/supybotconfig.py index 9d03293..b82039e 100644 --- a/MeetBot/supybotconfig.py +++ b/MeetBot/supybotconfig.py @@ -77,15 +77,20 @@ class SupybotConfigProxy(object): def __init__(self, *args, **kwargs): """Do the regular default configuration, and sta""" OriginalConfig = self.__OriginalConfig - self.__C = OriginalConfig(*args, **kwargs) + self.__C = OriginalConfig.__new__(OriginalConfig, *args, **kwargs) + # We need to call the __init__ *after* we have rebound the + # method to get variables from the config proxy. + old_init = self.__C.__init__ + new_init = types.MethodType(old_init.im_func, self, old_init.im_class) + new_init(*args, **kwargs) def __getattr__(self, attrname): """Try to get the value from the supybot registry. If it's in the registry, return it. If it's not, then proxy it to th. """ if attrname in settable_attributes: - value = self.__C.M._registryValue(attrname, - channel=self.__C.M.channel) + M = self.M + value = M._registryValue(attrname, channel=M.channel) if not isinstance(value, (str, unicode)): return value # '.' is used to mean "this is not set, use the default @@ -93,6 +98,19 @@ class SupybotConfigProxy(object): if value != '.': value = value.replace('\\n', '\n') return value + # If the attribute is a _property_, we need to rebind the + # "fget" method to the proxy class. + # See http://docs.python.org/library/functions.html#property + # http://docs.python.org/reference/datamodel.html#descriptors + C = self.__C + # is this a class attribute AND does it have a fget ? + if hasattr(C.__class__, attrname) and \ + hasattr(getattr(C.__class__, attrname), 'fget'): + # Get the 'fget' descriptor, rebind it to self, return its + # value. + fget = getattr(C.__class__, attrname).fget + fget = types.MethodType(fget, self, C.__class__) + return fget() # We don't have this value in the registry. So, proxy it to # the normal config object. This is also the path that all # functions take. diff --git a/ircmeeting/meeting.py b/ircmeeting/meeting.py index d40eb08..b1f980a 100644 --- a/ircmeeting/meeting.py +++ b/ircmeeting/meeting.py @@ -460,8 +460,6 @@ class Meeting(MeetingCommands, object): setTopic=None, sendReply=None, getRegistryValue=None, safeMode=False, channelNicks=None, extraConfig={}, network='nonetwork'): - self.config = Config(self, writeRawLog=writeRawLog, safeMode=safeMode, - extraConfig=extraConfig) if getRegistryValue is not None: self._registryValue = getRegistryValue if sendReply is not None: @@ -472,6 +470,8 @@ class Meeting(MeetingCommands, object): self.channel = channel self.network = network self.currenttopic = "" + self.config = Config(self, writeRawLog=writeRawLog, safeMode=safeMode, + extraConfig=extraConfig) if oldtopic: self.oldtopic = self.config.dec(oldtopic) else: