Skip to content

Commit

Permalink
fix for entangling
Browse files Browse the repository at this point in the history
There was a problem with class heredity and attributes was shared in
Class instead of instances. I'm changing intialization sequence to
mitigate this.

see https://en.wikipedia.org/wiki/Entangled_(Red_Dwarf)
  • Loading branch information
tomkukral committed Oct 12, 2017
1 parent f6cfefa commit 397afa2
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 24 deletions.
36 changes: 20 additions & 16 deletions kqueen/storages/etcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ def __init__(self, *args, **kwargs):
"""

self.value = None
# TODO: pass value via args[0]

self.value = kwargs.get('value', None)
self.required = kwargs.get('required', False)

# waiting for @profesor to bring bright new idea
Expand Down Expand Up @@ -100,13 +102,14 @@ def serialize(self):
class ModelMeta(type):
def __new__(cls, clsname, superclasses, attributedict):
newattributes = attributedict.copy()
fields = {}

# loop attributes and set getters and setter for Fields
for attr_name, attr in attributedict.items():
attr_class = attr.__class__
if hasattr(attr_class, 'is_field') and attr_class.is_field:
name_hidden = '_{}'.format(attr_name)
newattributes[name_hidden] = attr
fields[attr_name] = attr

def fget(self, k=attr_name):
att = getattr(self, "_{}".format(k))
Expand All @@ -119,6 +122,8 @@ def fset(self, value, k=attr_name):
newattributes[attr_name] = property(fget, fset)
logger.debug('Setting {} to point to {}'.format(attr_name, name_hidden))

newattributes['_fields'] = fields

return type.__new__(cls, clsname, superclasses, newattributes)


Expand All @@ -133,11 +138,12 @@ def __init__(self, *arfg, **kwargs):
self._db = db

# loop fields and set it
for a in self.__class__.get_field_names():
field_class = getattr(self, '_{}'.format(a)).__class__
if hasattr(field_class, 'is_field') and kwargs.get(a):
setattr(self, a, kwargs.get(a))
logger.debug('Setting {} to {}'.format(a, kwargs.get(a)))
for field_name, field in self.__class__.get_fields().items():
field_class = field.__class__
if hasattr(field_class, 'is_field'):
field_object = field_class(**field.__dict__)
field_object.set_value(kwargs.get(field_name))
setattr(self, '_{}'.format(field_name), field_object)

@classmethod
def get_model_name(cls):
Expand Down Expand Up @@ -230,19 +236,17 @@ def deserialize(cls, serialized, **kwargs):

return o

@classmethod
def get_fields(cls):
"""Return dict of fields and it classes"""

return cls._fields

@classmethod
def get_field_names(cls):
"""Return list of field names"""
fields = []

for a in cls.__dict__.keys():
field = getattr(cls, a).__class__
if hasattr(field, 'is_field'):
if a.startswith('_'):
a = a[1:]
fields.append(a)

return fields
return list(cls._fields.keys())

def get_db_key(self):
if not self.id:
Expand Down
21 changes: 13 additions & 8 deletions kqueen/storages/test_model_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def test_required(self, required):
class TestModelInit:
def setup(self):
self.model = create_model()
self.obj = self.model(**model_kwargs)

@pytest.mark.parametrize('field_name,field_value', model_kwargs.items())
def test_init_string(self, field_name, field_value):
Expand All @@ -72,7 +73,7 @@ def test_init_string(self, field_name, field_value):
def test_field_property_getters(self, attr, group):
attr_name = '{}{}'.format(group, attr)

assert hasattr(self.model, attr_name)
assert hasattr(self.obj, attr_name)


class TestGetFieldNames:
Expand Down Expand Up @@ -137,19 +138,23 @@ def test_deserialization(self, create_object):


class TestDuplicateId:
def test_write(self):
model = create_model()
def setup(self):
self.model = create_model()

self.obj1_kwargs = {'string': 'object 1', 'json': {'a': 1, 'b': 2, 'c': 'tri'}, 'secret': 'pass'}
self.obj2_kwargs = {'string': 'object 2', 'json': {'a': 1, 'b': 2, 'c': 'tri'}, 'secret': 'pass'}

obj1_kwargs = {'string': 'object 1', 'json': {'a': 1, 'b': 2, 'c': 'tri'}, 'secret': 'pass'}
obj2_kwargs = {'string': 'object2', 'json': {'a': 1, 'b': 2, 'c': 'tri'}, 'secret': 'pass'}
def test_with_save(self):
""""Save object are not same"""
obj1 = self.model(**self.obj1_kwargs)
obj2 = self.model(**self.obj2_kwargs)

assert obj1 != obj2

obj1 = model(**obj1_kwargs)
obj1.save()
obj2 = model(**obj2_kwargs)
obj2.save()

print(obj1.get_dict())
print(obj2.get_dict())

assert obj1 != obj2
assert obj1.id != obj2.id

0 comments on commit 397afa2

Please sign in to comment.