# Copyright (C) 2013-2014 Eygene A. Ryabinkin and contributors
#
# Collection of classes that implement const-like behaviour
# for various objects.

import copy


class ConstProxy():
    """Implements read-only access to a given object
    that can be attached to each instance only once."""

    def __init__(self):
        self.__dict__['__source'] = None

    def __getattr__(self, name):
        src = self.__dict__['__source']
        if src is None:
            raise ValueError("using non-initialized ConstProxy() object")
        return copy.deepcopy(getattr(src, name))

    def __setattr__(self, name, value):
        raise AttributeError("tried to set '%s' to '%s' for constant object" % \
                             (name, value))

    def __delattr__(self, name):
        raise RuntimeError("tried to delete field '%s' from constant object" % \
                           (name))

    def set_source(self, source):
        """ Sets source object for this instance. """
        if (self.__dict__['__source'] is not None):
            raise ValueError("source object is already set")
        self.__dict__['__source'] = source