derks/cement — Issue #87: Refactor Meta handling
Author: derks
Created: 2011-12-23 06:16:54+00:00
State: open
Labels: 2.x, refactoring

Right now handlers require a Meta class to provide metadata attributes ... should refactor how that works to say.. have default 'self._meta' which is a Meta() class... any data set via self.Meta would be merge (override self._meta.attr if self.Meta.attr exists) ... and then on the backend use self._meta as the final meta data.

For example, this is pulled from Slumber:

class Meta(object):
"""
Model that acts as a container class for a meta attributes for a larger
class. It stuffs any kwarg it gets in it's init as an attribute of itself.
"""

def __init__(self, **kwargs):
for key, value in kwargs.iteritems():
setattr(self, key, value)

class MetaMixin(object):
"""
Mixin that provides the Meta class support to add settings to instances
of slumber objects. Meta settings cannot start with a _.
"""

def __init__(self, *args, **kwargs):
# Get a List of all the Classes we in our MRO, find any attribute named
# Meta on them, and then merge them together in order of MRO
metas = reversed([x.Meta for x in self.__class__.mro() if hasattr(x, "Meta")])
final_meta = {}

# Merge the Meta classes into one dict
for meta in metas:
final_meta.update(dict([x for x in meta.__dict__.items() if not x[0].startswith("_")]))

# Update the final Meta with any kwargs passed in
for key in final_meta.keys():
if key in kwargs:
final_meta[key] = kwargs.pop(key)

self._meta = Meta(**final_meta)

# Finally Pass anything unused along the MRO
super(MetaMixin, self).__init__(*args, **kwargs)

Something like that... not exactly, but something more structured.