Closed
Description
Simple metaclass that generates an __init__
method with _attrs
class attributes:
# meta.py
from abc import ABCMeta
class GenInit(ABCMeta):
def __new__(cls, name, bases, clsdict):
attrs = clsdict.get('_attrs')
if attrs:
init_sig_template = """
def __init__(self, {attrs}):"""
init_body_template = """
self.{attr} = {attr}"""
sig = init_sig_template.format(attrs=', '.join(attrs))
body = ""
for attr in attrs:
body += init_body_template.format(attr=attr)
init_code = sig + body
exec(init_code, globals(), clsdict)
return type(name, bases, clsdict)
class Point(metaclass=GenInit):
_attrs = ['x', 'y']
p = Point(0, 0)
Mypy can't go through it:
$ mypy meta.py
meta.py:31: error: Too many arguments for "Point"
Don't know if it's possible to fix, since the init method is exec
uted in the class namespace...
And I wasn't able to get its source code:
>>> from meta import Point
>>> from inspect import getsource
>>> getsource(Point.__init__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/inspect.py", line 965, in getsource
lines, lnum = getsourcelines(object)
File "/usr/lib/python3.6/inspect.py", line 952, in getsourcelines
lines, lnum = findsource(object)
File "/usr/lib/python3.6/inspect.py", line 783, in findsource
raise OSError('could not get source code')
OSError: could not get source code
At list, how can I avoid the error without putting a #type: ignore
at the end of every call to __init__
of every class using this trick?
Metadata
Metadata
Assignees
Labels
No labels