I was playing with the library, and I noticed that expressions seem to require these boilerplate __getinitargs__ and init_arg_names methods. Given that this is Python 3.6+ it should be easy to automate that via introspection. Here is a proof of concpet:
from pymbolic.primitives import Expression
class AutoInspectable(object):
"""
Helper to provide automatic defaults for pymbolic expressions
"""
def init_arg_names(self):
return tuple(self._initkw().keys())
def __getinitargs__(self):
return tuple(self._initkw().values())
def _initkw(self):
import inspect
from collections import OrderedDict
sig = inspect.signature(self.__class__)
initkw = OrderedDict()
for name, info in sig.parameters.items():
if not hasattr(self, name):
raise NotImplementedError((
'Unable to introspect init args because the class '
'did not have attributes with the same names as the '
'constructor arguments'))
initkw[name] = getattr(self, name)
return initkw
class AutoExpression(AutoInspectable, Expression):
pass
Now classes that inherit from AutoInspectable will introspect their __init__ functions and as long a there are no *args **kwargs and all arguments have instance attributes with the same name, it provides a function to return an "initkw" dictionary (i.e. keyword arguments that you could pass to the class to construct a new instance).
There are edge cases where this doesn't work. Namely *args, **kwargs, and when the instance doesn't exactly register the constructor arguments with the same names, but in those cases it raises a NotImplementedError indicating that the user can fill these out manually.
Just thought I'd throw that out there.
I was playing with the library, and I noticed that expressions seem to require these boilerplate
__getinitargs__andinit_arg_namesmethods. Given that this is Python 3.6+ it should be easy to automate that via introspection. Here is a proof of concpet:Now classes that inherit from
AutoInspectablewill introspect their__init__functions and as long a there are no*args**kwargsand all arguments have instance attributes with the same name, it provides a function to return an "initkw" dictionary (i.e. keyword arguments that you could pass to the class to construct a new instance).There are edge cases where this doesn't work. Namely *args, **kwargs, and when the instance doesn't exactly register the constructor arguments with the same names, but in those cases it raises a
NotImplementedErrorindicating that the user can fill these out manually.Just thought I'd throw that out there.