Skip to content

Instantly share code, notes, and snippets.

@Paebbels
Created June 13, 2023 20:52
Show Gist options
  • Save Paebbels/72ac61916134a75fbcb57d265e443733 to your computer and use it in GitHub Desktop.
Save Paebbels/72ac61916134a75fbcb57d265e443733 to your computer and use it in GitHub Desktop.
Python __new__ and __init__ with meta-classes
class AbstractClassError(Exception):
pass
class M(type):
# staticmethod
def __new__(cls, className, baseClasses, members, abstract):
newClass = type.__new__(cls, className, baseClasses, members)
if abstract:
def newnew(cls, *_, **__):
raise AbstractClassError(f"Class is abstract")
# keep original __new__ and exchange it with a dummy method throwing an error
newClass.__new_orig__ = newClass.__new__
newClass.__new__ = newnew
else:
# 1. replacing __new__ with original (preserved) method doesn't work
newClass.__new__ = newClass.__new_orig__
# 2. using a wrapper
# def wrapper(cls, *args, **kwargs):
# print("wrapper: ", cls, *args, kwargs)
# return newClass.__new_orig__(cls, *args, **kwargs)
# newClass.__new__ = wrapper
return newClass
# def __call__(cls, *args, **kwargs):
# inst = cls.__new__(cls, *args, **kwargs)
# inst.__init__(*args, **kwargs)
# return inst
# print(*args, kwargs)
# return super().__call__(*args, **kwargs)
class A(metaclass=M, abstract=True):
pass
class B(A, abstract=False):
def __init__(self, arg):
self.arg = arg
print("object.__new__ ", object.__new__)
print("A.__new_orig__ ", A.__new_orig__)
print("A.__new__ ", A.__new__)
print("B.__new__ ", B.__new__)
b = B.__new__(B, 5)
print("B.__new__(B, 5) ", b)
b.__init__(5)
print("b.__init__(5) ", b.arg)
class X:
pass
class Y(X):
def __init__(self, arg):
self.arg = arg
print("X.__new__ ", X.__new__)
print("Y.__new__ ", Y.__new__)
y = Y.__new__(Y, 3)
print("Y.__new__(Y, 3) ", y)
y.__init__(3)
print("y.__init__(3) ", y.arg)
# o = object.__new__(object, 1)
# print(o)
y = Y(3)
print("y.arg ", y.arg)
print("B.__new__ ", B.__new__)
b = B(5)
print("b.arg ", y.arg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment