[Python] Why monkey patching a class's `__new__` this does not (always) work?

Discussão em 'Python' iniciado por Stack, Julho 27, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to do some monkey patch work on an existing third-party library I am using.

    Summary

    This sequence does not work:

    1. Monkey patch A.__new__ using mynew
    2. Monkey patch A.__new__ again using object.__new__ to reset the previous
    While the following sequence works:

    1. Monkey patch A.__new__ using object.__new__
    Details


    I need to override the __new__ method for that library. Assume A is a class from the third party. Everything works OK as follows:

    class A:
    def __init__(self, x):
    self.x = x

    def mynew(cls, *args, **kwargs):
    print("Calling mynew")
    return object.__new__(cls)

    A.__new__ = mynew

    A(10)
    # Calling mynew
    # <__main__.A object at 0x7f43806d8440>


    The problem is when I want to reset the class to the existing __new__ method (which the third-party class does not implement, so it should be object.__new__, I run into an error

    A.__new__ = object.__new__
    A(10)

    #TypeError: object.__new__() takes exactly one argument (the type to instantiate)


    I somehow understand this... Something to do with the difference in object's definition which does not take any arguments, while the signature is defined to take arguments for subclassing compatibility.

    What tripped me off, however, is that if I set A.__new__ = object.__new__, without first overriding it using the mynew method, it will work ok. That is running this code block ONLY, it will work

    class A:
    def __init__(self, x):
    self.x = x

    A.__new__ = object.__new__

    A(10)
    # works OK


    Anyone can help explain what is going on?

    Continue reading...

Compartilhe esta Página