<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def is_noncopyable(class_, already_visited_cls_vars=None):
 """ Checks if class is non copyable Args: class_ (declarations.class_t):
 the class to be checked already_visited_cls_vars (list):
 optional list of vars that should not be checked a second time, to prevent infinite recursions. In general you can ignore this argument, it is mainly used during recursive calls of is_noncopyable() done by pygccxml. Returns: bool: if the class is non copyable """

    logger = utils.loggers.cxx_parser

    class_decl = class_traits.get_declaration(class_)

    true_header = "is_noncopyable(TRUE) - %s - " % class_.decl_string

    if is_union(class_):
        return False

    if class_decl.is_abstract:
        logger.debug(true_header + "abstract client")
        return True

    # if class has public, user defined copy constructor, than this class is
    # copyable
    copy_ = find_copy_constructor(class_decl)
    if copy_ and copy_.access_type == 'public' and not copy_.is_artificial:
        return False

    if already_visited_cls_vars is None:
        already_visited_cls_vars = []

    for base_desc in class_decl.recursive_bases:
        assert isinstance(base_desc, class_declaration.hierarchy_info_t)

        if base_desc.related_class.decl_string in \
                ('::boost::noncopyable', '::boost::noncopyable_::noncopyable'):
            logger.debug(true_header + "derives from boost::noncopyable")
            return True

        if not has_copy_constructor(base_desc.related_class):

            base_copy_ = find_copy_constructor(base_desc.related_class)

            if base_copy_ and base_copy_.access_type == 'private':
                logger.debug(
                    true_header +
                    "there is private copy constructor")
                return True
            elif __is_noncopyable_single(
                    base_desc.related_class, already_visited_cls_vars):
                logger.debug(
                    true_header +
                    "__is_noncopyable_single returned True")
                return True

        if __is_noncopyable_single(
                base_desc.related_class, already_visited_cls_vars):
            logger.debug(
                true_header +
                "__is_noncopyable_single returned True")
            return True

    if not has_copy_constructor(class_decl):
        logger.debug(true_header + "does not have trivial copy constructor")
        return True
    elif not has_public_constructor(class_decl):
        logger.debug(true_header + "does not have a public constructor")
        return True
    elif has_destructor(class_decl) and not has_public_destructor(class_decl):
        logger.debug(true_header + "has private destructor")
        return True

    return __is_noncopyable_single(class_decl, already_visited_cls_vars)