Multiple published documents search
sv9388 opened this issue · comments
Multiple document search is supported by EPO 3.2. But I don't see an interface for the same in the code. A constructor overloading in Docdb would help achieve the same in Python3. Here is an edited version of models.py
that I am using to achieve the same.
import inspect
import types
class MultiMethod:
'''
Represents a single multimethod.
'''
def __init__(self, name):
self._methods = {}
self.__name__ = name
def register(self, meth):
'''
Register a new method as a multimethod
'''
sig = inspect.signature(meth)
# Build a type-signature from the method's annotations
types = []
for name, parm in sig.parameters.items():
if name == 'self':
continue
if parm.annotation is inspect.Parameter.empty:
raise TypeError(
'Argument {} must be annotated with a type'.format(name)
)
if not isinstance(parm.annotation, type):
raise TypeError(
'Argument {} annotation must be a type'.format(name)
)
if parm.default is not inspect.Parameter.empty:
self._methods[tuple(types)] = meth
types.append(parm.annotation)
self._methods[tuple(types)] = meth
def __call__(self, *args):
'''
Call a method based on type signature of the arguments
'''
types = tuple(type(arg) for arg in args[1:])
meth = self._methods.get(types, None)
if meth:
return meth(*args)
else:
raise TypeError('No matching method for types {}'.format(types))
def __get__(self, instance, cls):
'''
Descriptor method needed to make calls work in a class
'''
if instance is not None:
return types.MethodType(self, instance)
else:
return self
class MultiDict(dict):
'''
Special dictionary to build multimethods in a metaclass
'''
def __setitem__(self, key, value):
if key in self:
# If key already exists, it must be a multimethod or callable
current_value = self[key]
if isinstance(current_value, MultiMethod):
current_value.register(value)
else:
mvalue = MultiMethod(key)
mvalue.register(current_value)
mvalue.register(value)
super().__setitem__(key, mvalue)
else:
super().__setitem__(key, value)
class MultipleMeta(type):
'''
Metaclass that allows multiple dispatch of methods
'''
def __new__(cls, clsname, bases, clsdict):
return type.__new__(cls, clsname, bases, dict(clsdict))
@classmethod
def __prepare__(cls, clsname, bases):
return MultiDict()
## Actual Docdb change
class Docdb(BaseInput, metaclass=MultipleMeta):
def __init__(self, number:str, country_code:str, kind_code:str, date:str=None):
if not all([country_code, kind_code]):
raise MissingRequiredValue(
'number, country_code, and kind_code must be present'
)
super(Docdb, self).__init__(number, country_code, kind_code, date)
def __init__(self, data_points:list):
self.data_points = []
for dp in data_points:
d = Docdb(dp[0], dp[1], dp[2])
self.data_points.append(d)
def as_api_input(self):
print(self.__dict__.keys(), )
if hasattr(self, 'data_points'):
print(self.data_points)
print("#" * 20)
return '\n'.join([x.as_api_input() for x in self.data_points])
return super(Docdb, self).as_api_input()
Will you consider making a PR for this?
Sure. Will do this week sometime. This interface was quite useful for some of my project. Kudos.
Dear @sv9388,
thanks for your suggestions, and a belated happy new year. Are you still using this library in one way or another, and would you be up for submitting a corresponding patch? Maintenance is boringhard, and we appreciate any support on this or other matters.
With kind regards,
Andreas.
On the topic of maintenance, I had co-pilot draft several docstrings. Shall I submit them as a PR?