[Interface-dev] Re: interface.py
Thomas Lotze
tl at gocept.com
Mon Jul 11 05:01:10 EDT 2005
Steve Alexander wrote:
> I think it is an evil trick because it is unclear code. Whenever someone
> write unclear code but has a reason for not using a clear alternative, it
> needs a comment to explain why.
OK, no arguing against that. Maybe I played around too much with closures
lately, so I didn't realize how unclear it was. However, I think the
explanation needn't necessarily rant on evility where it actually just
takes knowing why thing are done the way they are done.
> That's a really bad thing to do. With your change, the dict will be
> instantiated once only, at the time the class is first read by the
> interpreter.
Damn, that's one of the things I keep forgetting :o/ Usually I trip on
something like this when I set the default for a class member that is then
changed by instances...
I've appended a corrected patch. BTW, I start wondering whether it is OK
to send patches this size in a message; would you feel more annoyed if I
uploaded them somewhere on the web? (I'd certainly be as I read mail and
news offline.)
Thomas
36,41c36,37
< tags = f_locals.get(TAGGED_DATA)
< if tags is None:
< tags = f_locals[TAGGED_DATA] = {}
< invariants = tags.get('invariants')
< if invariants is None:
< invariants = tags['invariants'] = []
---
> tags = f_locals.setdefault(TAGGED_DATA, {})
> invariants = tags.setdefault('invariants', [])
359,363c355
< if callback is None:
< return weakref.ref(self)
< else:
< return weakref.ref(self, callback)
<
---
> return weakref.ref(self, callback)
395a388,390
> if attrs is None:
> attrs = {}
>
397,401c392,393
< if (attrs is not None and
< ('__module__' in attrs) and
< isinstance(attrs['__module__'], str)
< ):
< __module__ = attrs['__module__']
---
> __module__ = attrs.get('__module__')
> if isinstance(__module__, str):
404d395
<
415,417d405
< if attrs is None:
< attrs = {}
<
430,434c418
< if attrs.has_key(TAGGED_DATA):
< tagged_data = attrs[TAGGED_DATA]
< del attrs[TAGGED_DATA]
< else:
< tagged_data = None
---
> tagged_data = attrs.pop(TAGGED_DATA, None)
480,481d463
<
<
487,489c469
< if self == other:
< return True
< return other.extends(self)
---
> return self == other or other.extends(self)
496,498c476,477
< r = {}
< for name in self.__attrs.keys():
< r[name] = 1
---
> r = self.__attrs.copy()
>
500,501c479,480
< for name in base.names(all):
< r[name] = 1
---
> r.update(dict.fromkeys(base.names(all)))
>
513,514c492,493
< for name, d in self.__attrs.items():
< r[name] = d
---
> for base in self.__bases__[::-1]:
> r.update(dict(base.namesAndDescriptions(all)))
516,519c495
< for base in self.__bases__:
< for name, d in base.namesAndDescriptions(all):
< if name not in r:
< r[name] = d
---
> r.update(self.__attrs)
572d547
< pass
586c561,562
< for b in self.__bases__: b.__d(dict)
---
> for b in self.__bases__:
> b.__d(dict)
589,590c565,567
< r = getattr(self, '_v_repr', self)
< if r is self:
---
> try:
> return self._v_repr
> except AttributeError:
597c574
< return r
---
> return r
600,603c577,579
< # TRICK! Create the call method
< #
< # An embedded function is used to allow an optional argument to
< # __call__ without resorting to a global marker.
---
> # Mind the closure. It serves to keep a unique marker around to
> # allow for an optional argument to __call__ without resorting
> # to a global marker.
605,610c581
< # The evility of this trick is a reflection of the underlying
< # evility of "optional" arguments, arguments whose presense or
< # absense changes the behavior of the methods.
< #
< # I think the evil is necessary, and perhaps desireable to
< # provide some consistencey with the PEP 246 adapt method.
---
> # This provides some consistency with the PEP 246 adapt method.
699,702c670,674
< if adapter is None:
< if alternate is not marker:
< return alternate
<
---
> if adapter is not None:
> return adapter
> elif alternate is not marker:
> return alternate
> else:
705,706d676
< return adapter
<
709c679
< __call__ = __call__() # TRICK! Make the *real* __call__ method
---
> __call__ = __call__() # Make the closure the *real* __call__ method.
802d771
<
861c830
< sig = "("
---
> sig = []
863c832
< sig = sig + v
---
> sig.append(v)
865,866c834
< sig = sig + "=%s" % `self.optional[v]`
< sig = sig + ", "
---
> sig[-1] += "=%s" % `self.optional[v]`
868c836
< sig = sig + ("*%s, " % self.varargs)
---
> sig.append("*%s" % self.varargs)
870,874c838
< sig = sig + ("**%s, " % self.kwargs)
<
< # slice off the last comma and space
< if self.positional or self.varargs or self.kwargs:
< sig = sig[:-2]
---
> sig.append("**%s" % self.kwargs)
876,877c840
< sig = sig + ")"
< return sig
---
> return "(%s)" % ", ".join(sig)
896,897c859
< for i in range(len(defaults)):
< opt[names[i+nr]] = defaults[i]
---
> opt.update(dict(zip(names[nr:], defaults)))
More information about the Interface-dev
mailing list