[Python-Dev] Possible patch for functools partial - Interested?

VanL van.lindberg at gmail.com
Fri May 7 21:53:01 CEST 2010


On 5/7/2010 12:41 PM, Steven D'Aprano wrote:

>> Now, if I write
>>
>>     def f1(x,y): return x+y
>>     def f2(x,y): return x+y
>>
>> I don't expect  f1==f2 to be True, even though f1 and f2 behave in
>> exactly the same way, and indeed it is not.

This is not what I am getting after; these (IMO) should compare unequal.
I took a fairly conservative line, testing for identity of functions and
equality of arguments when converted to a normal form:

    def __eq__(self, other):
        try:
            return ((self.func == other.func) and
                        (self.args == other.args) and
                        (self.keywords == other.keywords))
        except AttributeError:
            return False

    def __hash__(self):
        if self.keywords:
            sorted_keys = sorted(self.keywords.keys())
            values = [self.keywords[k] for k in sorted_keys]
            kwhash = tuple(sorted_keys + values)
        else:
            kwhash = None
        return hash(tuple((self.func, self.args, kwhash)))

It may be slightly controversial that I read out all the keys and values
and convert them to a normal form for the hash. This is both to get
around hashing issues (keywords is a dict, even though it is read-only)
and to allow for a dict-like object to be provided as an argument (which
happens in my application sometimes).

The repr is slightly long, too, but it was designed to support (weakly)
the idea that obj == exec(repr(obj)). Its not necessary, but I always
like it when that is true.

    def __repr__(self):
        if self.args: argstr = '*%s' % repr(tuple(self.args))
        else: argstr = ''
        if self.keywords: kwstr = '**%s' % self.keywords
        else: kwstr = ''
        if argstr and kwstr: argstr += ', '
        classname = self.__class__.__name__
        funcname = self.func.__name__
        if argstr or kwstr: funcname += ', '
        return '%s(%s%s%s)' % (classname, funcname, argstr, kwstr)

I make no effort to look for functional equality between two different
functions. too many side effects could go off trying to make that work,
and it would still be only inconsistently right. (IIRC, doing it
completely is NP-hard.)

Thanks,

Van



More information about the Python-Dev mailing list