from fastdebug.utils import *
from fastdebug.core import *
import inspect
03_FixSigMeta_PrePostInitMeta_AutoInit
from fastcore.meta import *
from fastcore.test import *
Initialize fastdebug objects
= locals() # g can update itself as more cells get run, like globals() in the __main__
g = Fastdb(FixSigMeta, outloc=g)
fdbF = Fastdb(PrePostInitMeta, outloc=g)
fdbP = Fastdb(AutoInit, outloc=g) fdbA
class FixSigMeta(type) vs class Foo(type)
FixSigMeta inherits __init__
, and __call__
from type
, but writes its own __new__
Foo inherits all three from type
FixSigMeta is used to create class instance not object instance
1, "FixSigMeta inherits __init__, and __call__ from type; but writes its own __new__; Foo inherits all three from type; \
fdbF.docsrc(FixSigMeta is used to create class instance not object instance.")
# fdbF.print()
======================================================== Investigating FixSigMeta ========================================================
=============================================================== on line 1 ================================================================
============================================================= with example ==============================================================
print selected srcline with expands below--------
class FixSigMeta(type): (0)
"A metaclass that fixes the signature on classes that override `__new__`"===========================================================================(1)
FixSigMeta inherits __init__, and __call__ from type; but writes its own __new__; Foo inherits all three from type; FixSigMeta is used to create class instance not object instance.
def __new__(cls, name, bases, dict): (2)
res = super().__new__(cls, name, bases, dict) (3)
print(inspect.getsource(FixSigMeta))
class FixSigMeta(type):
"A metaclass that fixes the signature on classes that override `__new__`"
def __new__(cls, name, bases, dict):
res = super().__new__(cls, name, bases, dict)
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))
return res
inspect_class(FixSigMeta)
class FixSigMeta(type):
"A metaclass that fixes the signature on classes that override `__new__`"
def __new__(cls, name, bases, dict):
res = super().__new__(cls, name, bases, dict)
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))
return res
is FixSigMeta a metaclass: True
is FixSigMeta created by a metaclass: False
FixSigMeta is created by <class 'type'>
FixSigMeta.__new__ is object.__new__: False
FixSigMeta.__new__ is type.__new__: False
FixSigMeta.__new__: <function FixSigMeta.__new__>
FixSigMeta.__init__ is object.__init__: False
FixSigMeta.__init__ is type.__init__: True
FixSigMeta.__init__: <slot wrapper '__init__' of 'type' objects>
FixSigMeta.__call__ is object.__call__: False
FixSigMeta.__call__ is type.__call__: True
FixSigMeta.__call__: <slot wrapper '__call__' of 'type' objects>
FixSigMeta.__class__: <class 'type'>
FixSigMeta.__bases__: (<class 'type'>,)
FixSigMeta.__mro__: (<class 'fastcore.meta.FixSigMeta'>, <class 'type'>, <class 'object'>)
FixSigMeta's function members are:
{'__new__': <function FixSigMeta.__new__>}
FixSigMeta's method members are:
{}
FixSigMeta's class members are:
{'__base__': <class 'type'>, '__class__': <class 'type'>}
FixSigMeta's namespace are:
mappingproxy({'__doc__': 'A metaclass that fixes the signature on classes that '
'override `__new__`',
'__module__': 'fastcore.meta',
'__new__': <staticmethod object>})
class Foo(type): pass
inspect_class(Foo)
is Foo a metaclass: True
is Foo created by a metaclass: False
Foo is created by <class 'type'>
Foo.__new__ is object.__new__: False
Foo.__new__ is type.__new__: True
Foo.__new__: <built-in method __new__ of type object>
Foo.__init__ is object.__init__: False
Foo.__init__ is type.__init__: True
Foo.__init__: <slot wrapper '__init__' of 'type' objects>
Foo.__call__ is object.__call__: False
Foo.__call__ is type.__call__: True
Foo.__call__: <slot wrapper '__call__' of 'type' objects>
Foo.__class__: <class 'type'>
Foo.__bases__: (<class 'type'>,)
Foo.__mro__: (<class '__main__.Foo'>, <class 'type'>, <class 'object'>)
Foo's function members are:
{}
Foo's method members are:
{}
Foo's class members are:
{'__base__': <class 'type'>, '__class__': <class 'type'>}
Foo's namespace are:
mappingproxy({'__module__': '__main__', '__doc__': None})
class Foo()
When Foo inherit __new__
and __new__
from object
but __call__
of Foo and __call__
of object
maybe the same but different objects
Foo is to create object instance not class instance
class Foo(): pass
inspect_class(Foo)
is Foo a metaclass: False
is Foo created by a metaclass: False
Foo is created by <class 'type'>
Foo.__new__ is object.__new__: True
Foo.__new__ is type.__new__: False
Foo.__new__: <built-in method __new__ of type object>
Foo.__init__ is object.__init__: True
Foo.__init__ is type.__init__: False
Foo.__init__: <slot wrapper '__init__' of 'object' objects>
Foo.__call__ is object.__call__: False
Foo.__call__ is type.__call__: False
Foo.__call__: <method-wrapper '__call__' of type object>
Foo.__class__: <class 'type'>
Foo.__bases__: (<class 'object'>,)
Foo.__mro__: (<class '__main__.Foo'>, <class 'object'>)
Foo's function members are:
{}
Foo's method members are:
{}
Foo's class members are:
{'__class__': <class 'type'>}
Foo's namespace are:
mappingproxy({'__dict__': <attribute '__dict__' of 'Foo' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'Foo' objects>})
class PrePostInitMeta(FixSigMeta)
PrePostInitMeta
inherit __new__
and __init__
from FixSigMeta
as a metaclass (a different type), not from type
, nor from object
PrePostInitMeta
is itself a metaclass, which is used to create class instance not object instance
PrePostInitMeta
writes its own __call__
which regulates how its class instance create and initialize object instance
1, "PrePostInitMeta inherit __new__ and __init__ from FixSigMeta as a metaclass (a different type); \
fdbP.docsrc(not from type, nor from object; PrePostInitMeta is itself a metaclass, which is used to create class instance not object instance; \
PrePostInitMeta writes its own __call__ which regulates how its class instance create and initialize object instance")
===================================================== Investigating PrePostInitMeta ======================================================
=============================================================== on line 1 ================================================================
============================================================= with example ==============================================================
print selected srcline with expands below--------
class PrePostInitMeta(FixSigMeta): (0)
"A metaclass that calls optional `__pre_init__` and `__post_init__` methods"========================================================================(1)
PrePostInitMeta inherit __new__ and __init__ from FixSigMeta as a metaclass (a different type); not from type, nor from object; PrePostInitMeta is itself a metaclass, which is used to create class instance not object instance; PrePostInitMeta writes its own __call__ which regulates how its class instance create and initialize object instance
def __call__(cls, *args, **kwargs): (2)
res = cls.__new__(cls) (3)
inspect_class(PrePostInitMeta)
class PrePostInitMeta(FixSigMeta):
"A metaclass that calls optional `__pre_init__` and `__post_init__` methods"
def __call__(cls, *args, **kwargs):
res = cls.__new__(cls)
if type(res)==cls:
if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)
res.__init__(*args,**kwargs)
if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs)
return res
is PrePostInitMeta a metaclass: True
is PrePostInitMeta created by a metaclass: False
PrePostInitMeta is created by <class 'type'>
PrePostInitMeta.__new__ is object.__new__: False
PrePostInitMeta.__new__ is type.__new__: False
PrePostInitMeta.__new__: <function FixSigMeta.__new__>
PrePostInitMeta.__init__ is object.__init__: False
PrePostInitMeta.__init__ is type.__init__: True
PrePostInitMeta.__init__: <slot wrapper '__init__' of 'type' objects>
PrePostInitMeta.__call__ is object.__call__: False
PrePostInitMeta.__call__ is type.__call__: False
PrePostInitMeta.__call__: <function PrePostInitMeta.__call__>
PrePostInitMeta.__class__: <class 'type'>
PrePostInitMeta.__bases__: (<class 'fastcore.meta.FixSigMeta'>,)
PrePostInitMeta.__mro__: (<class 'fastcore.meta.PrePostInitMeta'>, <class 'fastcore.meta.FixSigMeta'>, <class 'type'>, <class 'object'>)
PrePostInitMeta's function members are:
{'__call__': <function PrePostInitMeta.__call__>,
'__new__': <function FixSigMeta.__new__>}
PrePostInitMeta's method members are:
{}
PrePostInitMeta's class members are:
{'__base__': <class 'fastcore.meta.FixSigMeta'>, '__class__': <class 'type'>}
PrePostInitMeta's namespace are:
mappingproxy({'__call__': <function PrePostInitMeta.__call__>,
'__doc__': 'A metaclass that calls optional `__pre_init__` and '
'`__post_init__` methods',
'__module__': 'fastcore.meta'})
class Foo(FixSigMeta): pass
inspect_class(Foo)
is Foo a metaclass: True
is Foo created by a metaclass: False
Foo is created by <class 'type'>
Foo.__new__ is object.__new__: False
Foo.__new__ is type.__new__: False
Foo.__new__: <function FixSigMeta.__new__>
Foo.__init__ is object.__init__: False
Foo.__init__ is type.__init__: True
Foo.__init__: <slot wrapper '__init__' of 'type' objects>
Foo.__call__ is object.__call__: False
Foo.__call__ is type.__call__: True
Foo.__call__: <slot wrapper '__call__' of 'type' objects>
Foo.__class__: <class 'type'>
Foo.__bases__: (<class 'fastcore.meta.FixSigMeta'>,)
Foo.__mro__: (<class '__main__.Foo'>, <class 'fastcore.meta.FixSigMeta'>, <class 'type'>, <class 'object'>)
Foo's function members are:
{'__new__': <function FixSigMeta.__new__>}
Foo's method members are:
{}
Foo's class members are:
{'__base__': <class 'fastcore.meta.FixSigMeta'>, '__class__': <class 'type'>}
Foo's namespace are:
mappingproxy({'__module__': '__main__', '__doc__': None})
class Foo(metaclass=FixSigMeta)
Foo inherit __new__
, __init__
from object to create object instance
Foo uses FixSigMeta not type to create class instance FixSigMeta.__new__
determine what kind of a class is Foo
In this case, FixSigMeta.__new__
create Foo class and an attr __signature__
if Foo has its own __init__
FixSigMeta.__new__
create Foo the class, has nothing to do with the instance method Foo.__init__
class Foo(metaclass=FixSigMeta): pass
inspect_class(Foo)
is Foo a metaclass: False
is Foo created by a metaclass: True
Foo is created by metaclass <class 'fastcore.meta.FixSigMeta'>
Foo.__new__ is object.__new__: True
Foo.__new__ is type.__new__: False
Foo.__new__: <built-in method __new__ of type object>
Foo.__init__ is object.__init__: True
Foo.__init__ is type.__init__: False
Foo.__init__: <slot wrapper '__init__' of 'object' objects>
Foo.__call__ is object.__call__: False
Foo.__call__ is type.__call__: False
Foo.__call__: <method-wrapper '__call__' of FixSigMeta object>
Foo.__class__: <class 'fastcore.meta.FixSigMeta'>
Foo.__bases__: (<class 'object'>,)
Foo.__mro__: (<class '__main__.Foo'>, <class 'object'>)
Foo's metaclass <class 'fastcore.meta.FixSigMeta'>'s function members are:
{'__new__': <function FixSigMeta.__new__>}
Foo's function members are:
{}
Foo's method members are:
{}
Foo's class members are:
{'__class__': <class 'fastcore.meta.FixSigMeta'>}
Foo's namespace are:
mappingproxy({'__dict__': <attribute '__dict__' of 'Foo' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'Foo' objects>})
class Foo(metaclass=FixSigMeta):
def __init__(self, a, b): pass
inspect_class(Foo)
is Foo a metaclass: False
is Foo created by a metaclass: True
Foo is created by metaclass <class 'fastcore.meta.FixSigMeta'>
Foo.__new__ is object.__new__: True
Foo.__new__ is type.__new__: False
Foo.__new__: <built-in method __new__ of type object>
Foo.__init__ is object.__init__: False
Foo.__init__ is type.__init__: False
Foo.__init__: <function Foo.__init__>
Foo.__call__ is object.__call__: False
Foo.__call__ is type.__call__: False
Foo.__call__: <method-wrapper '__call__' of FixSigMeta object>
Foo.__class__: <class 'fastcore.meta.FixSigMeta'>
Foo.__bases__: (<class 'object'>,)
Foo.__mro__: (<class '__main__.Foo'>, <class 'object'>)
Foo's metaclass <class 'fastcore.meta.FixSigMeta'>'s function members are:
{'__new__': <function FixSigMeta.__new__>}
Foo's function members are:
{'__init__': <function Foo.__init__>}
Foo's method members are:
{}
Foo's class members are:
{'__class__': <class 'fastcore.meta.FixSigMeta'>}
Foo's namespace are:
mappingproxy({'__dict__': <attribute '__dict__' of 'Foo' objects>,
'__doc__': None,
'__init__': <function Foo.__init__>,
'__module__': '__main__',
'__signature__': <Signature (a, b)>,
'__weakref__': <attribute '__weakref__' of 'Foo' objects>})
class AutoInit(metaclass=PrePostInitMeta)
AutoInit inherit __new__
and __init__
from object
to create and initialize object instances
AutoInit uses PrePostInitMeta.__new__
or in fact FixSigMeta.__new__
to create its own class instance, which can have __signature__
AutoInit uses PrePostInitMeta.__call__
to specify how its object instance to be created and initialized (with pre_init, init, post_init)
AutoInit as a normal or non-metaclass, it writes its own __pre_init__
instance method
1, "AutoInit inherit __new__ and __init__ from object to create and initialize object instances; \
fdbA.docsrc(AutoInit uses PrePostInitMeta.__new__ or in fact FixSigMeta.__new__ to create its own class instance, which can have __signature__; \
AutoInit uses PrePostInitMeta.__call__ to specify how its object instance to be created and initialized (with pre_init, init, post_init)); \
AutoInit as a normal or non-metaclass, it writes its own __pre_init__ method")
========================================================= Investigating AutoInit =========================================================
=============================================================== on line 1 ================================================================
============================================================= with example ==============================================================
print selected srcline with expands below--------
class AutoInit(metaclass=PrePostInitMeta): (0)
"Same as `object`, but no need for subclasses to call `super().__init__`"===========================================================================(1)
AutoInit inherit __new__ and __init__ from object to create and initialize object instances; AutoInit uses PrePostInitMeta.__new__ or in fact FixSigMeta.__new__ to create its own class instance, which can have __signature__; AutoInit uses PrePostInitMeta.__call__ to specify how its object instance to be created and initialized (with pre_init, init, post_init)); AutoInit as a normal or non-metaclass, it writes its own __pre_init__ method
def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs) (2)
(3)
inspect_class(AutoInit)
class AutoInit(metaclass=PrePostInitMeta):
"Same as `object`, but no need for subclasses to call `super().__init__`"
def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
is AutoInit a metaclass: False
is AutoInit created by a metaclass: True
AutoInit is created by metaclass <class 'fastcore.meta.PrePostInitMeta'>
AutoInit.__new__ is object.__new__: True
AutoInit.__new__ is type.__new__: False
AutoInit.__new__: <built-in method __new__ of type object>
AutoInit.__init__ is object.__init__: True
AutoInit.__init__ is type.__init__: False
AutoInit.__init__: <slot wrapper '__init__' of 'object' objects>
AutoInit.__call__ is object.__call__: False
AutoInit.__call__ is type.__call__: False
AutoInit.__call__: <bound method PrePostInitMeta.__call__ of <class 'fastcore.meta.AutoInit'>>
AutoInit.__class__: <class 'fastcore.meta.PrePostInitMeta'>
AutoInit.__bases__: (<class 'object'>,)
AutoInit.__mro__: (<class 'fastcore.meta.AutoInit'>, <class 'object'>)
AutoInit's metaclass <class 'fastcore.meta.PrePostInitMeta'>'s function members are:
{'__call__': <function PrePostInitMeta.__call__>,
'__new__': <function FixSigMeta.__new__>}
AutoInit's function members are:
{'__pre_init__': <function AutoInit.__pre_init__>}
AutoInit's method members are:
{}
AutoInit's class members are:
{'__class__': <class 'fastcore.meta.PrePostInitMeta'>}
AutoInit's namespace are:
mappingproxy({'__dict__': <attribute '__dict__' of 'AutoInit' objects>,
'__doc__': 'Same as `object`, but no need for subclasses to call '
'`super().__init__`',
'__module__': 'fastcore.meta',
'__pre_init__': <function AutoInit.__pre_init__>,
'__weakref__': <attribute '__weakref__' of 'AutoInit' objects>})
class Foo(AutoInit): pass
inspect_class(Foo)
is Foo a metaclass: False
is Foo created by a metaclass: True
Foo is created by metaclass <class 'fastcore.meta.PrePostInitMeta'>
Foo.__new__ is object.__new__: True
Foo.__new__ is type.__new__: False
Foo.__new__: <built-in method __new__ of type object>
Foo.__init__ is object.__init__: True
Foo.__init__ is type.__init__: False
Foo.__init__: <slot wrapper '__init__' of 'object' objects>
Foo.__call__ is object.__call__: False
Foo.__call__ is type.__call__: False
Foo.__call__: <bound method PrePostInitMeta.__call__ of <class '__main__.Foo'>>
Foo.__class__: <class 'fastcore.meta.PrePostInitMeta'>
Foo.__bases__: (<class 'fastcore.meta.AutoInit'>,)
Foo.__mro__: (<class '__main__.Foo'>, <class 'fastcore.meta.AutoInit'>, <class 'object'>)
Foo's metaclass <class 'fastcore.meta.PrePostInitMeta'>'s function members are:
{'__call__': <function PrePostInitMeta.__call__>,
'__new__': <function FixSigMeta.__new__>}
Foo's function members are:
{'__pre_init__': <function AutoInit.__pre_init__>}
Foo's method members are:
{}
Foo's class members are:
{'__class__': <class 'fastcore.meta.PrePostInitMeta'>}
Foo's namespace are:
mappingproxy({'__module__': '__main__', '__doc__': None})
class Foo(AutoInit):
def __init__(self): pass # to enable __signature__ by FixSigMeta.__new__
inspect_class(Foo)
is Foo a metaclass: False
is Foo created by a metaclass: True
Foo is created by metaclass <class 'fastcore.meta.PrePostInitMeta'>
Foo.__new__ is object.__new__: True
Foo.__new__ is type.__new__: False
Foo.__new__: <built-in method __new__ of type object>
Foo.__init__ is object.__init__: False
Foo.__init__ is type.__init__: False
Foo.__init__: <function Foo.__init__>
Foo.__call__ is object.__call__: False
Foo.__call__ is type.__call__: False
Foo.__call__: <bound method PrePostInitMeta.__call__ of <class '__main__.Foo'>>
Foo.__class__: <class 'fastcore.meta.PrePostInitMeta'>
Foo.__bases__: (<class 'fastcore.meta.AutoInit'>,)
Foo.__mro__: (<class '__main__.Foo'>, <class 'fastcore.meta.AutoInit'>, <class 'object'>)
Foo's metaclass <class 'fastcore.meta.PrePostInitMeta'>'s function members are:
{'__call__': <function PrePostInitMeta.__call__>,
'__new__': <function FixSigMeta.__new__>}
Foo's function members are:
{'__init__': <function Foo.__init__>,
'__pre_init__': <function AutoInit.__pre_init__>}
Foo's method members are:
{}
Foo's class members are:
{'__class__': <class 'fastcore.meta.PrePostInitMeta'>}
Foo's namespace are:
mappingproxy({'__doc__': None,
'__init__': <function Foo.__init__>,
'__module__': '__main__',
'__signature__': <Signature ()>})
class TestParent():
def __init__(self): self.h = 10
class TestChild(AutoInit, TestParent):
def __init__(self): self.k = self.h + 2
inspect_class(TestChild)
is TestChild a metaclass: False
is TestChild created by a metaclass: True
TestChild is created by metaclass <class 'fastcore.meta.PrePostInitMeta'>
TestChild.__new__ is object.__new__: True
TestChild.__new__ is type.__new__: False
TestChild.__new__: <built-in method __new__ of type object>
TestChild.__init__ is object.__init__: False
TestChild.__init__ is type.__init__: False
TestChild.__init__: <function TestChild.__init__>
TestChild.__call__ is object.__call__: False
TestChild.__call__ is type.__call__: False
TestChild.__call__: <bound method PrePostInitMeta.__call__ of <class '__main__.TestChild'>>
TestChild.__class__: <class 'fastcore.meta.PrePostInitMeta'>
TestChild.__bases__: (<class 'fastcore.meta.AutoInit'>, <class '__main__.TestParent'>)
TestChild.__mro__: (<class '__main__.TestChild'>, <class 'fastcore.meta.AutoInit'>, <class '__main__.TestParent'>, <class 'object'>)
TestChild's metaclass <class 'fastcore.meta.PrePostInitMeta'>'s function members are:
{'__call__': <function PrePostInitMeta.__call__>,
'__new__': <function FixSigMeta.__new__>}
TestChild's function members are:
{'__init__': <function TestChild.__init__>,
'__pre_init__': <function AutoInit.__pre_init__>}
TestChild's method members are:
{}
TestChild's class members are:
{'__class__': <class 'fastcore.meta.PrePostInitMeta'>}
TestChild's namespace are:
mappingproxy({'__doc__': None,
'__init__': <function TestChild.__init__>,
'__module__': '__main__',
'__signature__': <Signature ()>})
class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
inspect_class(_T)
is _T a metaclass: False
is _T created by a metaclass: True
_T is created by metaclass <class 'fastcore.meta.PrePostInitMeta'>
_T.__new__ is object.__new__: True
_T.__new__ is type.__new__: False
_T.__new__: <built-in method __new__ of type object>
_T.__init__ is object.__init__: False
_T.__init__ is type.__init__: False
_T.__init__: <function _T.__init__>
_T.__call__ is object.__call__: False
_T.__call__ is type.__call__: False
_T.__call__: <bound method PrePostInitMeta.__call__ of <class '__main__._T'>>
_T.__class__: <class 'fastcore.meta.PrePostInitMeta'>
_T.__bases__: (<class 'object'>,)
_T.__mro__: (<class '__main__._T'>, <class 'object'>)
_T's metaclass <class 'fastcore.meta.PrePostInitMeta'>'s function members are:
{'__call__': <function PrePostInitMeta.__call__>,
'__new__': <function FixSigMeta.__new__>}
_T's function members are:
{'__init__': <function _T.__init__>,
'__post_init__': <function _T.__post_init__>,
'__pre_init__': <function _T.__pre_init__>}
_T's method members are:
{}
_T's class members are:
{'__class__': <class 'fastcore.meta.PrePostInitMeta'>}
_T's namespace are:
mappingproxy({'__dict__': <attribute '__dict__' of '_T' objects>,
'__doc__': None,
'__init__': <function _T.__init__>,
'__module__': '__main__',
'__post_init__': <function _T.__post_init__>,
'__pre_init__': <function _T.__pre_init__>,
'__signature__': <Signature (b=0)>,
'__weakref__': <attribute '__weakref__' of '_T' objects>})
Prepare examples for FixSigMeta, PrePostInitMeta, AutoInit
# g = locals()
# fdbF = Fastdb(FixSigMeta, outloc=g)
= """
fdbF.eg class Foo(metaclass=FixSigMeta):
def __init__(self): pass
"""
# fdbP = Fastdb(PrePostInitMeta, outloc=g)
= """
fdbP.eg class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
t = _T()
test_eq(t.a, 0) # set with __pre_init__
test_eq(t.b, 1) # set with __init__
test_eq(t.c, 3) # set with __post_init__
inspect.signature(_T)
"""
# fdbA = Fastdb(AutoInit, outloc=g)
= """
fdbA.eg class TestParent():
def __init__(self): self.h = 10
class TestChild(AutoInit, TestParent):
def __init__(self): self.k = self.h + 2
t = TestChild()
test_eq(t.h, 10) # h=10 is initialized in the parent class
test_eq(t.k, 12)
"""
Snoop them together in one go
=['res', 'type(res)', 'res.__class__', 'res.__dict__']) fdbF.snoop(watch
23:04:33.14 >>> Call to FixSigMeta.__new__ in File "/tmp/FixSigMeta.py", line 5
23:04:33.14 .......... cls = <class 'fastcore.meta.FixSigMeta'>
23:04:33.14 .......... name = 'Foo'
23:04:33.14 .......... bases = ()
23:04:33.14 .......... dict = {'__module__': '__main__', '__qualname__': 'Foo', '__init__': <function Foo.__init__>}
23:04:33.14 .......... len(dict) = 3
23:04:33.14 .......... __class__ = <class 'fastcore.meta.FixSigMeta'>
23:04:33.14 5 | def __new__(cls, name, bases, dict):
23:04:33.14 6 | res = super().__new__(cls, name, bases, dict)
23:04:33.14 .............. res = <class '__main__.Foo'>
23:04:33.14 .............. type(res) = <class 'fastcore.meta.FixSigMeta'>
23:04:33.14 .............. res.__class__ = <class 'fastcore.meta.FixSigMeta'>
23:04:33.14 .............. res.__dict__ = mappingproxy({'__module__': '__main__', '__init_...__weakref__' of 'Foo' objects>, '__doc__': None})
23:04:33.14 .............. len(res.__dict__) = 5
23:04:33.14 7 | if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))
23:04:33.14 ...... res.__dict__ = mappingproxy({'__module__': '__main__', '__init_...__doc__': None, '__signature__': <Signature ()>})
23:04:33.14 ...... len(res.__dict__) = 6
23:04:33.14 8 | return res
23:04:33.14 <<< Return value from FixSigMeta.__new__: <class '__main__.Foo'>
======================================================== Investigating FixSigMeta ========================================================
============================================================== on line None ==============================================================
============================== with example
class Foo(metaclass=FixSigMeta):
def __init__(self): pass
==============================
embed the dbsrc of FixSigMeta into PrePostInitMeta
Important!
FixSigMeta is untouched, fdbF.dbsrc.__new__
is the actual dbsrc
To use fdbF.dbsrc in other functions or classes which uses FixSigMeta, we need to assign fdbF.dbsrc
to fm.FixSigMeta
import fastcore.meta as fm
= fdbF.dbsrc fm.FixSigMeta
'res.__dict__']) fdbP.snoop([
23:04:33.18 >>> Call to FixSigMeta.__new__ in File "/tmp/FixSigMeta.py", line 5
23:04:33.18 .......... cls = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.18 .......... name = '_T'
23:04:33.18 .......... bases = ()
23:04:33.18 .......... dict = {'__module__': '__main__', '__qualname__': '_T', '__pre_init__': <function _T.__pre_init__>, '__init__': <function _T.__init__>, ...}
23:04:33.18 .......... len(dict) = 5
23:04:33.18 .......... __class__ = <class 'fastcore.meta.FixSigMeta'>
23:04:33.18 5 | def __new__(cls, name, bases, dict):
23:04:33.18 6 | res = super().__new__(cls, name, bases, dict)
23:04:33.18 .............. res = <class '__main__._T'>
23:04:33.18 .............. type(res) = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.18 .............. res.__class__ = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.18 .............. res.__dict__ = mappingproxy({'__module__': '__main__', '__pre_i...'__weakref__' of '_T' objects>, '__doc__': None})
23:04:33.18 .............. len(res.__dict__) = 7
23:04:33.18 7 | if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))
23:04:33.18 ...... res.__dict__ = mappingproxy({'__module__': '__main__', '__pre_i...oc__': None, '__signature__': <Signature (b=0)>})
23:04:33.18 ...... len(res.__dict__) = 8
23:04:33.18 8 | return res
23:04:33.18 <<< Return value from FixSigMeta.__new__: <class '__main__._T'>
23:04:33.19 >>> Call to PrePostInitMeta.__call__ in File "/tmp/PrePostInitMeta.py", line 5
23:04:33.19 .......... cls = <class '__main__._T'>
23:04:33.19 .......... args = ()
23:04:33.19 .......... kwargs = {}
23:04:33.19 5 | def __call__(cls, *args, **kwargs):
23:04:33.19 6 | res = cls.__new__(cls)
23:04:33.19 .............. res = <__main__._T object>
23:04:33.19 .............. res.__dict__ = {}
23:04:33.19 7 | if type(res)==cls:
23:04:33.19 8 | if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)
23:04:33.19 ...... res.__dict__ = {'a': 0}
23:04:33.19 ...... len(res.__dict__) = 1
23:04:33.19 9 | res.__init__(*args,**kwargs)
23:04:33.19 .................. res.__dict__ = {'a': 0, 'b': 1}
23:04:33.19 .................. len(res.__dict__) = 2
23:04:33.19 10 | if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs)
23:04:33.19 ...... res.__dict__ = {'a': 0, 'b': 1, 'c': 3}
23:04:33.19 ...... len(res.__dict__) = 3
23:04:33.19 11 | return res
23:04:33.19 <<< Return value from PrePostInitMeta.__call__: <__main__._T object>
===================================================== Investigating PrePostInitMeta ======================================================
============================================================== on line None ==============================================================
with example
class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
t = _T()
test_eq(t.a, 0) # set with __pre_init__
test_eq(t.b, 1) # set with __init__
test_eq(t.c, 3) # set with __post_init__
inspect.signature(_T)
embed dbsrc of PrePostInitMeta into AutoInit
= fdbP.dbsrc fm.PrePostInitMeta
fdbA.snoop()
23:04:33.20 >>> Call to FixSigMeta.__new__ in File "/tmp/FixSigMeta.py", line 5
23:04:33.20 .......... cls = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.20 .......... name = 'AutoInit'
23:04:33.20 .......... bases = ()
23:04:33.20 .......... dict = {'__module__': 'fastcore.meta', '__qualname__': 'AutoInit', '__doc__': 'Same as `object`, but no need for subclasses to call `super().__init__`', 'snoop': <class 'snoop.configuration.Config.__init__.<locals>.ConfiguredTracer'>, ...}
23:04:33.20 .......... len(dict) = 6
23:04:33.20 .......... __class__ = <class 'fastcore.meta.FixSigMeta'>
23:04:33.20 5 | def __new__(cls, name, bases, dict):
23:04:33.20 6 | res = super().__new__(cls, name, bases, dict)
23:04:33.20 .............. res = <class 'fastcore.meta.AutoInit'>
23:04:33.20 .............. type(res) = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.20 .............. res.__class__ = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.20 .............. res.__dict__ = mappingproxy({'__module__': 'fastcore.meta', '__...<attribute '__weakref__' of 'AutoInit' objects>})
23:04:33.20 .............. len(res.__dict__) = 6
23:04:33.20 7 | if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))
23:04:33.20 8 | return res
23:04:33.20 <<< Return value from FixSigMeta.__new__: <class 'fastcore.meta.AutoInit'>
23:04:33.20 >>> Call to FixSigMeta.__new__ in File "/tmp/FixSigMeta.py", line 5
23:04:33.20 .......... cls = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.20 .......... name = 'TestChild'
23:04:33.20 .......... bases = (<class 'fastcore.meta.AutoInit'>, <class '__main__.TestParent'>)
23:04:33.20 .......... len(bases) = 2
23:04:33.20 .......... dict = {'__module__': '__main__', '__qualname__': 'TestChild', '__init__': <function TestChild.__init__>}
23:04:33.20 .......... len(dict) = 3
23:04:33.20 .......... __class__ = <class 'fastcore.meta.FixSigMeta'>
23:04:33.20 5 | def __new__(cls, name, bases, dict):
23:04:33.20 6 | res = super().__new__(cls, name, bases, dict)
23:04:33.20 .............. res = <class '__main__.TestChild'>
23:04:33.20 .............. type(res) = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.20 .............. res.__class__ = <class 'fastcore.meta.PrePostInitMeta'>
23:04:33.20 .............. res.__dict__ = mappingproxy({'__module__': '__main__', '__init_...Child.__init__ at 0x11fbf51f0>, '__doc__': None})
23:04:33.20 .............. len(res.__dict__) = 3
23:04:33.20 7 | if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))
23:04:33.20 ...... res.__dict__ = mappingproxy({'__module__': '__main__', '__init_...__doc__': None, '__signature__': <Signature ()>})
23:04:33.20 ...... len(res.__dict__) = 4
23:04:33.20 8 | return res
23:04:33.20 <<< Return value from FixSigMeta.__new__: <class '__main__.TestChild'>
23:04:33.20 >>> Call to PrePostInitMeta.__call__ in File "/tmp/PrePostInitMeta.py", line 5
23:04:33.20 .......... cls = <class '__main__.TestChild'>
23:04:33.20 .......... args = ()
23:04:33.20 .......... kwargs = {}
23:04:33.20 5 | def __call__(cls, *args, **kwargs):
23:04:33.20 6 | res = cls.__new__(cls)
23:04:33.20 .............. res = <__main__.TestChild object>
23:04:33.20 .............. res.__dict__ = {}
23:04:33.20 7 | if type(res)==cls:
23:04:33.20 8 | if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)
23:04:33.20 >>> Call to AutoInit.__pre_init__ in File "/tmp/AutoInit.py", line 5
23:04:33.20 .......... self = <__main__.TestChild object>
23:04:33.20 .......... args = ()
23:04:33.20 .......... kwargs = {}
23:04:33.20 .......... __class__ = <class 'fastcore.meta.AutoInit'>
23:04:33.20 5 | def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
23:04:33.20 5 | def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
23:04:33.20 <<< Return value from AutoInit.__pre_init__: None
23:04:33.20 8 | if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)
23:04:33.20 ...... res.__dict__ = {'h': 10}
23:04:33.20 ...... len(res.__dict__) = 1
23:04:33.20 9 | res.__init__(*args,**kwargs)
23:04:33.20 .................. res.__dict__ = {'h': 10, 'k': 12}
23:04:33.20 .................. len(res.__dict__) = 2
23:04:33.20 10 | if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs)
23:04:33.20 11 | return res
23:04:33.20 <<< Return value from PrePostInitMeta.__call__: <__main__.TestChild object>
========================================================= Investigating AutoInit =========================================================
============================================================== on line None ==============================================================
with example
class TestParent():
def __init__(self): self.h = 10
class TestChild(AutoInit, TestParent):
def __init__(self): self.k = self.h + 2
t = TestChild()
test_eq(t.h, 10) # h=10 is initialized in the parent class
test_eq(t.k, 12)
Explore and Document on them together
4, "FixSigMeta: what is res", "'inside FixSigMeta, line 4'", "res.__name__")
fdbF.docsrc(= fdbF.dbsrc fm.FixSigMeta
======================================================== Investigating FixSigMeta ========================================================
=============================================================== on line 4 ================================================================
============================== with example
class Foo(metaclass=FixSigMeta):
def __init__(self): pass
==============================
print selected srcline with expands below--------
def __new__(cls, name, bases, dict): (2)
res = super().__new__(cls, name, bases, dict) (3)
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))===========================================(4)
FixSigMeta: what is res
return res (5)
(6)
==================================================================================================================Start of my srcline exploration:
'inside FixSigMeta, line 4' => 'inside FixSigMeta, line 4' : inside FixSigMeta, line 4
res.__name__ => res.__name__ : Foo
====================================================================================================================End of my srcline exploration:
Review srcode with all comments added so far======================================================================================================
class FixSigMeta(type):===================================================================(0)
"A metaclass that fixes the signature on classes that override `__new__`"=============(1) # FixSigMeta inherits __init__, and __call__ from type; but writes its own __new__; Foo inherits all three from type; FixSigMeta is used to create class instance not object instance.;
def __new__(cls, name, bases, dict):==================================================(2)
res = super().__new__(cls, name, bases, dict)=====================================(3)
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__)) # FixSigMeta: what is res; (4)
return res========================================================================(5)
(6)
part No.1 out of 1 parts
6, "what inside res.__dict__", "'inside PrePostInitMeta: '", "res.__dict__")
fdbP.docsrc(= fdbP.dbsrc fm.PrePostInitMeta
===================================================== Investigating PrePostInitMeta ======================================================
=============================================================== on line 6 ================================================================
with example
class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
t = _T()
test_eq(t.a, 0) # set with __pre_init__
test_eq(t.b, 1) # set with __init__
test_eq(t.c, 3) # set with __post_init__
inspect.signature(_T)
print selected srcline with expands below--------
if type(res)==cls: (4)
if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs) (5)
res.__init__(*args,**kwargs)================================================================================================================(6)
what inside res.__dict__
if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs) (7)
return res (8)
==================================================================================================================Start of my srcline exploration:
'inside FixSigMeta, line 4' => 'inside FixSigMeta, line 4' : inside FixSigMeta, line 4
res.__name__ => res.__name__ : _T
====================================================================================================================End of my srcline exploration:
==================================================================================================================Start of my srcline exploration:
'inside PrePostInitMeta: ' => 'inside PrePostInitMeta: ' : inside PrePostInitMeta:
res.__dict__ => res.__dict__ : {'a': 0}
====================================================================================================================End of my srcline exploration:
Review srcode with all comments added so far======================================================================================================
class PrePostInitMeta(FixSigMeta):========================================================(0)
"A metaclass that calls optional `__pre_init__` and `__post_init__` methods"==========(1) # PrePostInitMeta inherit __new__ and __init__ from FixSigMeta as a metaclass (a different type); not from type, nor from object; PrePostInitMeta is itself a metaclass, which is used to create class instance not object instance; PrePostInitMeta writes its own __call__ which regulates how its class instance create and initialize object instance;
def __call__(cls, *args, **kwargs):===================================================(2)
res = cls.__new__(cls)============================================================(3)
if type(res)==cls:================================================================(4)
if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)==============(5)
res.__init__(*args,**kwargs)==================================================(6) # what inside res.__dict__;
if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs)============(7)
return res========================================================================(8)
(9)
part No.1 out of 1 parts
2, "what is cls", "'Inside AutoInit'", "cls") # need to run it twice (a little bug here) fdbA.docsrc(
========================================================= Investigating AutoInit =========================================================
=============================================================== on line 2 ================================================================
with example
class TestParent():
def __init__(self): self.h = 10
class TestChild(AutoInit, TestParent):
def __init__(self): self.k = self.h + 2
t = TestChild()
test_eq(t.h, 10) # h=10 is initialized in the parent class
test_eq(t.k, 12)
print selected srcline with expands below--------
class AutoInit(metaclass=PrePostInitMeta): (0)
"Same as `object`, but no need for subclasses to call `super().__init__`" (1)
def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs)==========================================================================(2)
what is cls
(3)
==================================================================================================================Start of my srcline exploration:
'Inside AutoInit' => 'Inside AutoInit' : Inside AutoInit
cls => cls : <class '__main__._T'>
====================================================================================================================End of my srcline exploration:
==================================================================================================================Start of my srcline exploration:
'inside FixSigMeta, line 4' => 'inside FixSigMeta, line 4' : inside FixSigMeta, line 4
res.__name__ => res.__name__ : AutoInit
====================================================================================================================End of my srcline exploration:
==================================================================================================================Start of my srcline exploration:
'inside FixSigMeta, line 4' => 'inside FixSigMeta, line 4' : inside FixSigMeta, line 4
res.__name__ => res.__name__ : TestChild
====================================================================================================================End of my srcline exploration:
==================================================================================================================Start of my srcline exploration:
'inside PrePostInitMeta: ' => 'inside PrePostInitMeta: ' : inside PrePostInitMeta:
res.__dict__ => res.__dict__ : {'h': 10}
====================================================================================================================End of my srcline exploration:
Review srcode with all comments added so far======================================================================================================
class AutoInit(metaclass=PrePostInitMeta):================================================(0)
"Same as `object`, but no need for subclasses to call `super().__init__`"=============(1) # AutoInit inherit __new__ and __init__ from object to create and initialize object instances; AutoInit uses PrePostInitMeta.__new__ or in fact FixSigMeta.__new__ to create its own class instance, which can have __signature__; AutoInit uses PrePostInitMeta.__call__ to specify how its object instance to be created and initialized (with pre_init, init, post_init)); AutoInit as a normal or non-metaclass, it writes its own __pre_init__ method;
def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs)============(2) # what is cls;
(3)
part No.1 out of 1 parts
3, "how to create a new class instance with type dynamically; \
fdbF.docsrc(the rest below is how FixSigMeta as a metaclass create its own instance classes")
4, "how to check whether a class has its own __init__ function; how to remove self param from a signature") fdbF.docsrc(
======================================================== Investigating FixSigMeta ========================================================
=============================================================== on line 3 ================================================================
============================== with example
class Foo(metaclass=FixSigMeta):
def __init__(self): pass
==============================
print selected srcline with expands below--------
"A metaclass that fixes the signature on classes that override `__new__`" (1)
def __new__(cls, name, bases, dict): (2)
res = super().__new__(cls, name, bases, dict)===================================================================================================(3)
how to create a new class instance with type dynamically; the rest below is how FixSigMeta as a metaclass create its own instance classes
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__)) (4)
return res (5)
======================================================== Investigating FixSigMeta ========================================================
=============================================================== on line 4 ================================================================
============================== with example
class Foo(metaclass=FixSigMeta):
def __init__(self): pass
==============================
print selected srcline with expands below--------
def __new__(cls, name, bases, dict): (2)
res = super().__new__(cls, name, bases, dict) (3)
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__))===========================================(4)
how to check whether a class has its own __init__ function; how to remove self param from a signature
return res (5)
(6)
print() fdbF.
======================================================== Investigating FixSigMeta ========================================================
=============================================================== on line 4 ================================================================
============================== with example
class Foo(metaclass=FixSigMeta):
def __init__(self): pass
==============================
class FixSigMeta(type):===================================================================(0)
"A metaclass that fixes the signature on classes that override `__new__`"=============(1) # FixSigMeta inherits __init__, and __call__ from type; but writes its own __new__; Foo inherits all three from type; FixSigMeta is used to create class instance not object instance.;
def __new__(cls, name, bases, dict):==================================================(2)
res = super().__new__(cls, name, bases, dict)=====================================(3) # how to create a new class instance with type dynamically; the rest below is how FixSigMeta as a metaclass create its own instance classes;
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__)) # how to check whether a class has its own __init__ function; how to remove self param from a signature; (4)
return res========================================================================(5)
(6)
3, "how to create an object instance with a cls; how to check the type of an object is cls; \
fdbP.docsrc(how to run a function without knowing its params;")
print() fdbP.
===================================================== Investigating PrePostInitMeta ======================================================
=============================================================== on line 3 ================================================================
with example
class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
t = _T()
test_eq(t.a, 0) # set with __pre_init__
test_eq(t.b, 1) # set with __init__
test_eq(t.c, 3) # set with __post_init__
inspect.signature(_T)
print selected srcline with expands below--------
"A metaclass that calls optional `__pre_init__` and `__post_init__` methods" (1)
def __call__(cls, *args, **kwargs): (2)
res = cls.__new__(cls)==========================================================================================================================(3)
how to create an object instance with a cls; how to check the type of an object is cls; how to run a function without knowing its params;
if type(res)==cls: (4)
if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs) (5)
===================================================== Investigating PrePostInitMeta ======================================================
=============================================================== on line 3 ================================================================
with example
class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
t = _T()
test_eq(t.a, 0) # set with __pre_init__
test_eq(t.b, 1) # set with __init__
test_eq(t.c, 3) # set with __post_init__
inspect.signature(_T)
class PrePostInitMeta(FixSigMeta):========================================================(0)
"A metaclass that calls optional `__pre_init__` and `__post_init__` methods"==========(1) # PrePostInitMeta inherit __new__ and __init__ from FixSigMeta as a metaclass (a different type); not from type, nor from object; PrePostInitMeta is itself a metaclass, which is used to create class instance not object instance; PrePostInitMeta writes its own __call__ which regulates how its class instance create and initialize object instance;
def __call__(cls, *args, **kwargs):===================================================(2)
res = cls.__new__(cls)============================================================(3) # how to create an object instance with a cls; how to check the type of an object is cls; how to run a function without knowing its params;;
if type(res)==cls:================================================================(4)
if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)==============(5)
res.__init__(*args,**kwargs)==================================================(6) # what inside res.__dict__;
if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs)============(7)
return res========================================================================(8)
(9)
2, "how to run superclass' __init__ function") fdbA.docsrc(
========================================================= Investigating AutoInit =========================================================
=============================================================== on line 2 ================================================================
with example
class TestParent():
def __init__(self): self.h = 10
class TestChild(AutoInit, TestParent):
def __init__(self): self.k = self.h + 2
t = TestChild()
test_eq(t.h, 10) # h=10 is initialized in the parent class
test_eq(t.k, 12)
print selected srcline with expands below--------
class AutoInit(metaclass=PrePostInitMeta): (0)
"Same as `object`, but no need for subclasses to call `super().__init__`" (1)
def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs)==========================================================================(2)
how to run superclass' __init__ function
(3)
print() fdbA.
========================================================= Investigating AutoInit =========================================================
=============================================================== on line 2 ================================================================
with example
class TestParent():
def __init__(self): self.h = 10
class TestChild(AutoInit, TestParent):
def __init__(self): self.k = self.h + 2
t = TestChild()
test_eq(t.h, 10) # h=10 is initialized in the parent class
test_eq(t.k, 12)
class AutoInit(metaclass=PrePostInitMeta):================================================(0)
"Same as `object`, but no need for subclasses to call `super().__init__`"=============(1) # AutoInit inherit __new__ and __init__ from object to create and initialize object instances; AutoInit uses PrePostInitMeta.__new__ or in fact FixSigMeta.__new__ to create its own class instance, which can have __signature__; AutoInit uses PrePostInitMeta.__call__ to specify how its object instance to be created and initialized (with pre_init, init, post_init)); AutoInit as a normal or non-metaclass, it writes its own __pre_init__ method;
def __pre_init__(self, *args, **kwargs): super().__init__(*args, **kwargs)============(2) # how to run superclass' __init__ function;
(3)
6, "how to run __init__ without knowing its params") fdbP.docsrc(
===================================================== Investigating PrePostInitMeta ======================================================
=============================================================== on line 6 ================================================================
with example
class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
t = _T()
test_eq(t.a, 0) # set with __pre_init__
test_eq(t.b, 1) # set with __init__
test_eq(t.c, 3) # set with __post_init__
inspect.signature(_T)
print selected srcline with expands below--------
if type(res)==cls: (4)
if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs) (5)
res.__init__(*args,**kwargs)================================================================================================================(6)
how to run __init__ without knowing its params
if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs) (7)
return res (8)
print() fdbP.
===================================================== Investigating PrePostInitMeta ======================================================
=============================================================== on line 6 ================================================================
with example
class _T(metaclass=PrePostInitMeta):
def __pre_init__(self): self.a = 0;
def __init__(self,b=0): self.b = self.a + 1; assert self.b==1
def __post_init__(self): self.c = self.b + 2; assert self.c==3
t = _T()
test_eq(t.a, 0) # set with __pre_init__
test_eq(t.b, 1) # set with __init__
test_eq(t.c, 3) # set with __post_init__
inspect.signature(_T)
class PrePostInitMeta(FixSigMeta):========================================================(0)
"A metaclass that calls optional `__pre_init__` and `__post_init__` methods"==========(1) # PrePostInitMeta inherit __new__ and __init__ from FixSigMeta as a metaclass (a different type); not from type, nor from object; PrePostInitMeta is itself a metaclass, which is used to create class instance not object instance; PrePostInitMeta writes its own __call__ which regulates how its class instance create and initialize object instance;
def __call__(cls, *args, **kwargs):===================================================(2)
res = cls.__new__(cls)============================================================(3) # how to create an object instance with a cls; how to check the type of an object is cls; how to run a function without knowing its params;;
if type(res)==cls:================================================================(4)
if hasattr(res,'__pre_init__'): res.__pre_init__(*args,**kwargs)==============(5)
res.__init__(*args,**kwargs)==================================================(6) # how to run __init__ without knowing its params;
if hasattr(res,'__post_init__'): res.__post_init__(*args,**kwargs)============(7)
return res========================================================================(8)
(9)
print() fdbF.
======================================================== Investigating FixSigMeta ========================================================
=============================================================== on line 4 ================================================================
============================== with example
class Foo(metaclass=FixSigMeta):
def __init__(self): pass
==============================
class FixSigMeta(type):===================================================================(0)
"A metaclass that fixes the signature on classes that override `__new__`"=============(1) # FixSigMeta inherits __init__, and __call__ from type; but writes its own __new__; Foo inherits all three from type; FixSigMeta is used to create class instance not object instance.;
def __new__(cls, name, bases, dict):==================================================(2)
res = super().__new__(cls, name, bases, dict)=====================================(3) # how to create a new class instance with type dynamically; the rest below is how FixSigMeta as a metaclass create its own instance classes;
if res.__init__ is not object.__init__: res.__signature__ = _rm_self(inspect.signature(res.__init__)) # how to check whether a class has its own __init__ function; how to remove self param from a signature; (4)
return res========================================================================(5)
(6)