from abc import ABCMeta, abstractmethod


class Store():

    def __init__(self, parent={}):
        self._values = parent

    def set(self, key, new):
        path = key.split("/")
        value = self._values
        for node in path[:-1]:
            if node not in value:
                value[node] = {}
            value = value[node]

        value[path[-1]] = new

    def get(self, key, default=None):
        path = key.split("/")
        value = self._values
        try:
            for node in path:
                if ((not isinstance(value, dict)) or
                        node not in value):
                    return default
                value = value[node]
            return value
        except KeyError:
            return default

    def has_key(self, key):
        path = key.split("/")
        value = self._values
        try:
            for node in path:
                if ((not isinstance(value, dict)) or
                        node not in value):
                    return False
                value = value[node]
            return True
        except KeyError:
            pass
        return False

    def merge(self, iteratable, overwrite=True, root=None):
        values = self._values
        if root:
            values = self._values[root]

        for key, value in iteratable.items():
            if not overwrite and key in values:
                continue
            values[key] = value

    def derive(self, key):
        return Store(parent=self.get(key))

    def values(self):
        return self._values

    def dump(self):
        import pprint
        pprint.pprint(self._values)


class HasStore():
    __metaclass__ = ABCMeta

    @abstractmethod
    def store(self):
        pass

    def get(self, key, default=None):
        return self.store().get(key, default)

    def set(self, key, value):
        return self.store().set(key, value)

from abc import ABCMeta, abstractmethod


class Store(object):
    def __init__(self, parent={}):
        self._values = parent

    def set(self, key, new):
        path = key.split("/")
        value = self._values
        for node in path[:-1]:
            if node not in value:
                value[node] = {}
            value = value[node]

        value[path[-1]] = new

    def get(self, key, default=None):
        path = key.split("/")
        value = self._values
        try:
            for node in path:
                if ((not isinstance(value, dict)) or
                        node not in value):
                    return default
                value = value[node]
            return value
        except KeyError:
            return default

    def has_key(self, key):
        path = key.split("/")
        value = self._values
        try:
            for node in path:
                if ((not isinstance(value, dict)) or
                        node not in value):
                    return False
                value = value[node]
            return True
        except KeyError:
            pass
        return False

    def merge(self, iteratable, overwrite=True, root=None):
        values = self._values
        if root:
            values = self._values[root]

        for key, value in iteratable.items():
            if not overwrite and key in values:
                continue
            values[key] = value

    def derive(self, key):
        return Store(parent=self.get(key))

    def values(self):
        return self._values

    def dump(self):
        import pprint
        pprint.pprint(self._values)


class HasStore(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def store(self):
        pass

    def get(self, key, default=None):
        return self.store().get(key, default)

    def set(self, key, value):
        return self.store().set(key, value)

Fix metaclass for Store and HasStore