def proxify_elt(elt, bases=None, _dict=None, public=False):
    """Proxify input elt.

    :param elt: elt to proxify.
    :param bases: elt class base classes. If None, use elt type.
    :param dict _dict: specific elt class content to use.
    :param bool public: if True (default False), proxify only public members
        (where name starts with the character '_').
    :return: proxified element.
    :raises: TypeError if elt does not implement all routines of bases and
        _dict.
    """

    # ensure _dict is a dictionary
    proxy_dict = {} if _dict is None else _dict.copy()
    # set of proxified attribute names which are proxified during bases parsing
    # and avoid to proxify them twice during _dict parsing
    proxified_attribute_names = set()
    # ensure bases is a tuple of types
    if bases is None:
        bases = (elt if isclass(elt) else elt.__class__,)

    if isinstance(bases, string_types):
        bases = (lookup(bases),)

    elif isclass(bases):
        bases = (bases,)

    else:
        bases = tuple(bases)

    # fill proxy_dict with routines of bases
    for base in bases:
        # exclude object
        if base is object:
            continue
        for name, member in getmembers(base, isroutine):
            # check if name is public
            if public and not name.startswith('_'):
                continue
            eltmember = getattr(elt, name, None)
            if eltmember is None:
                raise TypeError(
                    'Wrong elt {0}. Must implement {1} ({2}) of {3}.'.
                    format(elt, name, member, base)
                )
            # proxify member if member is not a constructor
            if name not in ['__new__', '__init__']:
                # get routine from proxy_dict or eltmember
                routine = proxy_dict.get(name, eltmember)
                # exclude object methods
                if getattr(routine, '__objclass__', None) is not object:
                    # get routine proxy
                    routine_proxy = proxify_routine(routine)
                    if ismethod(routine_proxy):
                        routine_proxy = get_method_function(routine_proxy)
                    # update proxy_dict
                    proxy_dict[name] = routine_proxy
                    # and save the proxified attribute flag
                    proxified_attribute_names.add(name)

    # proxify proxy_dict
    for name in proxy_dict:
        value = proxy_dict[name]
        if not hasattr(elt, name):
            raise TypeError(
                'Wrong elt {0}. Must implement {1} ({2}).'.format(
                    elt, name, value
                )
            )
        if isroutine(value):
            # if member has not already been proxified
            if name not in proxified_attribute_names:
                # proxify it
                value = proxify_routine(value)
            proxy_dict[name] = value

    # set default constructors if not present in proxy_dict
    if '__new__' not in proxy_dict:
        proxy_dict['__new__'] = object.__new__

    if '__init__' not in proxy_dict:
        proxy_dict['__init__'] = object.__init__

    # generate a new proxy class
    cls = type('Proxy', bases, proxy_dict)
    # instantiate proxy cls
    result = cls if isclass(elt) else cls()
    # bind elt to proxy
    setattr(result, __PROXIFIED__, elt)

    return result
Proxify input elt.

    :param elt: elt to proxify.
    :param bases: elt class base classes. If None, use elt type.
    :param dict _dict: specific elt class content to use.
    :param bool public: if True (default False), proxify only public members
        (where name starts with the character '_').
    :return: proxified element.
    :raises: TypeError if elt does not implement all routines of bases and
        _dict.