12

If I define my function as below:

def myfunc(arg1, arg2):
    pass

then myfunc == myfunc will return True

But functools.partial(myfunc, arg2=1) == functools.partial(myfunc, arg2=1) will return False.

For unittest purpose, is there an easy way to test if the partial function is the one I expect?

Lydia
  • 2,377
  • 16
  • 13

2 Answers2

16

Test if the func, args and keywords attributes are the same:

p1.func == p2.func and p1.args == p2.args and p1.keywords == p2.keywords

where p1 and p2 are both partial() objects:

>>> from functools import partial
>>> def myfunc(arg1, arg2):
...     pass
... 
>>> partial(myfunc, arg2=1).func == partial(myfunc, arg2=1).func
True
>>> partial(myfunc, arg2=1).args == partial(myfunc, arg2=1).args
True
>>> partial(myfunc, arg2=1).keywords == partial(myfunc, arg2=1).keywords
True

There was a bug filed in the Python tracker to add equality testing to partial objects that does essentially that, but it was rejected on the grounds that not having an __eq__ method shadows the behaviour of functions, which also are only equal if their id() matches.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Is there any good reason why `functools.partial` objects don't implement that in the standard `__eq__`? –  Sep 25 '15 at 16:01
3

A helper function to compare

def partial_functions_equal(func1, func2):
    if not (isinstance(func1, partial) and isinstance(func2, partial)):
        return False
    are_equal = all([getattr(func1, attr) == getattr(func2, attr) for attr in ['func', 'args', 'keywords']])
    return are_equal