Patch __call__ of a function

后端 未结 3 1778
离开以前
离开以前 2020-12-11 00:44

I need to patch current datetime in tests. I am using this solution:

def _utcnow():
    return datetime.datetime.utcnow()


def utcnow():
    \"\"\"A proxy w         


        
3条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-11 01:18

    When you patch __call__ of a function, you are setting the __call__ attribute of that instance. Python actually calls the __call__ method defined on the class.

    For example:

    >>> class A(object):
    ...     def __call__(self):
    ...         print 'a'
    ...
    >>> a = A()
    >>> a()
    a
    >>> def b(): print 'b'
    ...
    >>> b()
    b
    >>> a.__call__ = b
    >>> a()
    a
    >>> a.__call__ = b.__call__
    >>> a()
    a
    

    Assigning anything to a.__call__ is pointless.

    However:

    >>> A.__call__ = b.__call__
    >>> a()
    b
    

    TLDR;

    a() does not call a.__call__. It calls type(a).__call__(a).

    Links

    There is a good explanation of why that happens in answer to "Why type(x).__enter__(x) instead of x.__enter__() in Python standard contextlib?".

    This behaviour is documented in Python documentation on Special method lookup.

提交回复
热议问题