From ab18149a71c810d75882cb6c48f304896cb614ae 2009-11-14 07:00:34 From: bgranger Date: 2009-11-14 07:00:34 Subject: [PATCH] Work on examples and fixed a super subtle bug in Component. * Recently, we stopped copying the config passed to a Component. This had a subtle side effect that mutable config attribute values were becoming class wide attributes. We are now doing a deep copy of all attributes as they are set on the Component instance. --- diff --git a/IPython/core/component.py b/IPython/core/component.py index b2bbeda..a928b40 100644 --- a/IPython/core/component.py +++ b/IPython/core/component.py @@ -237,14 +237,20 @@ class Component(HasTraitlets): self.config = config # We used to deepcopy, but for now we are trying to just save # by reference. This *could* have side effects as all components - # will share config. + # will share config. In fact, I did find such a side effect in + # _config_changed below. If a config attribute value was a mutable type + # all instances of a component were getting the same copy, effectively + # making that a class attribute. # self.config = deepcopy(config) else: if self.parent is not None: self.config = self.parent.config # We used to deepcopy, but for now we are trying to just save # by reference. This *could* have side effects as all components - # will share config. + # will share config. In fact, I did find such a side effect in + # _config_changed below. If a config attribute value was a mutable type + # all instances of a component were getting the same copy, effectively + # making that a class attribute. # self.config = deepcopy(self.parent.config) self.created = datetime.datetime.now() @@ -315,7 +321,10 @@ class Component(HasTraitlets): else: # print "Setting %s.%s from %s.%s=%r" % \ # (self.__class__.__name__,k,sname,k,config_value) - setattr(self, k, config_value) + # We have to do a deepcopy here if we don't deepcopy the entire + # config object. If we don't, a mutable config_value will be + # shared by all instances, effectively making it a class attribute. + setattr(self, k, deepcopy(config_value)) @property def children(self): diff --git a/docs/examples/kernel/wordfreq.py b/docs/examples/kernel/wordfreq.py index e12549f..d762f18 100644 --- a/docs/examples/kernel/wordfreq.py +++ b/docs/examples/kernel/wordfreq.py @@ -25,7 +25,7 @@ def print_wordfreq(freqs, n=10): print word, count -def wordfreq_to_weightsize(worddict, minsize=10, maxsize=50, minalpha=0.4, maxalpha=1.0): +def wordfreq_to_weightsize(worddict, minsize=25, maxsize=50, minalpha=0.5, maxalpha=1.0): mincount = min(worddict.itervalues()) maxcount = max(worddict.itervalues()) weights = {} @@ -37,7 +37,7 @@ def wordfreq_to_weightsize(worddict, minsize=10, maxsize=50, minalpha=0.4, maxal return weights -def tagcloud(worddict, n=10, minsize=10, maxsize=50, minalpha=0.4, maxalpha=1.0): +def tagcloud(worddict, n=10, minsize=25, maxsize=50, minalpha=0.5, maxalpha=1.0): from matplotlib import pyplot as plt import random @@ -55,10 +55,10 @@ def tagcloud(worddict, n=10, minsize=10, maxsize=50, minalpha=0.4, maxalpha=1.0) items = zip(alphas, sizes, words) items.sort(reverse=True) for alpha, size, word in items[:n]: - xpos = random.normalvariate(0.5, 0.3) - ypos = random.normalvariate(0.5, 0.3) - # xpos = random.uniform(0.0,1.0) - # ypos = random.uniform(0.0,1.0) + # xpos = random.normalvariate(0.5, 0.3) + # ypos = random.normalvariate(0.5, 0.3) + xpos = random.uniform(0.0,1.0) + ypos = random.uniform(0.0,1.0) ax.text(xpos, ypos, word.lower(), alpha=alpha, fontsize=size) ax.autoscale_view() return ax