def assert_d_member(klass, binding, readable, writable):
    """ Assert binding points to a valid declarative member.

    Parameters
    ----------
    klass : Declarative
        The declarative class which owns the binding.

    binding : BindingConstruct
        The binding construct created by the resolver.

    readable : bool
        Whether the member should have the 'd_readable' metadata flag.

    writable : bool
        Whether the member should have the 'd_writable' metadata flag.

    Returns
    -------
    result : tuple
        A 2-tuple of (name, member) on which the binding should operate.

    Raises
    ------
    DeclarativeError
        This will be raised if the member is not valid for the spec.

    """
    members = klass.members()
    m = members.get(binding.name)

    # TODO remove this backwards compatibility mod in Enaml 0.8.0
    if m is None:
        if binding.name == 'fgcolor' and 'foreground' in members:
            _warn_color_binding(binding)
            binding.name = 'foreground'
            m = members['foreground']
        elif binding.name == 'bgcolor' and 'background' in members:
            _warn_color_binding(binding)
            binding.name = 'background'
            m = members['background']

    if m is None or m.metadata is None or not m.metadata.get('d_member'):
        msg = "'%s' is not a declarative member" % binding.name
        root = binding.root()
        filename = root.filename
        context = root.typename
        lineno = binding.lineno
        raise DeclarativeError(msg, filename, context, lineno)
    if readable and not m.metadata.get('d_readable'):
        msg = "'%s' is not readable from enaml" % binding.name
        root = binding.root()
        filename = root.filename
        context = root.typename
        lineno = binding.lineno
        raise DeclarativeError(msg, filename, context, lineno)
    if writable and not m.metadata.get('d_writable'):
        msg = "'%s' is not writable from enaml" % binding.name
        root = binding.root()
        filename = root.filename
        context = root.typename
        lineno = binding.lineno
        raise DeclarativeError(msg, filename, context, lineno)
    return m
dataset/ETHPy150Open ContinuumIO/ashiba/enaml/enaml/core/operators.py/assert_d_member/original