Skip to content

Instantly share code, notes, and snippets.

@volgoweb
Last active November 12, 2018 15:26
Show Gist options
  • Save volgoweb/dcb80c4f5acdb5f4b0bfe179eedb7591 to your computer and use it in GitHub Desktop.
Save volgoweb/dcb80c4f5acdb5f4b0bfe179eedb7591 to your computer and use it in GitHub Desktop.
class BaseDataStructure(object):
"""The class is intended for definition contract objects which might be used as argument for various classes.
The example of using:
class SomeServiceInput(BaseDataStructure):
__accessible__ = {
'email': str,
'template_type': int,
}
class SomeService(object):
def __init__(self, input_contract: SomeServiceInput):
if input_contract.template_type == MARKETING_TPL:
# some code
"""
__accessible__ = dict()
__mandatory__ = []
def __new__(cls, *args, **kwargs):
if isinstance(cls.__accessible__, dict):
cls.__slots__ = list(cls.__accessible__.keys())
elif type(cls.__accessible__) in (list, set, tuple):
cls.__slots__ = cls.__accessible__
else:
TypeError('The type of attribute __accessible__ must be one of (list, set, tuple)')
if not cls.__mandatory__ and cls.__slots__:
cls.__mandatory__ = cls.__slots__
return super(BaseDataStructure, cls).__new__(cls)
def __init__(self, **kwargs):
accessible = set(self.__slots__)
mandatory = set(self.__mandatory__)
gotten = set(kwargs.keys())
unexpected = gotten - accessible
errors = []
if unexpected:
errors.append('Were gotten unexpected keyword arguments: '
'{unexpected}. '
'Expected keyword arguments: {accessible}, the mandatory are: '
'{mandatory}'.format(**locals()))
missed_mandatory = mandatory - gotten
if missed_mandatory:
errors.append('Weren\'t gotten the mandatory keyword arguments: '
'{missed_mandatory}'.format(**locals()))
for k, v in kwargs.items():
expected_type = self.__accessible__.get(k)
gotten_type = type(v)
if expected_type == gotten_type:
setattr(self, k, v)
else:
errors.append('The argument "{k}" has wrong type "{gotten_type}". Expected type is {expected_type}'.format(**locals()))
if errors:
class_name = self.__class__.__name__
error_msg = '\r\n{class_name}.__init__() errors:\r\n'.format(**locals())
error_msg += '\r\n'.join(errors)
raise TypeError(error_msg)
super(BaseDataStructure, self).__init__(**kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment