def _instrument_class(cls):
    """Modify methods in a class and install instrumentation."""

    # In the normal call flow, a request for any of the 3 basic collection
    # types is transformed into one of our trivial subclasses
    # (e.g. InstrumentedList).  Catch anything else that sneaks in here...
    if cls.__module__ == '__builtin__':
        raise sa_exc.ArgumentError(
            "Can not instrument a built-in type. Use a "
            "subclass, even a trivial one.")

    roles = {}
    methods = {}

    # search for _sa_instrument_role-decorated methods in
    # method resolution order, assign to roles
    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not util.callable(method):
                continue

            # note role declarations
            if hasattr(method, '_sa_instrument_role'):
                role = method._sa_instrument_role
                assert role in ('appender', 'remover', 'iterator',
                                'linker', 'converter')
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, '_sa_instrument_before'):
                op, argument = method._sa_instrument_before
                assert op in ('fire_append_event', 'fire_remove_event')
                before = op, argument
            if hasattr(method, '_sa_instrument_after'):
                op = method._sa_instrument_after
                assert op in ('fire_append_event', 'fire_remove_event')
                after = op
            if before:
                methods[name] = before[0], before[1], after
            elif after:
                methods[name] = None, None, after

    # see if this class has "canned" roles based on a known
    # collection type (dict, set, list).  Apply those roles
    # as needed to the "roles" dictionary, and also
    # prepare "decorator" methods
    collection_type = util.duck_type_collection(cls)
    if collection_type in __interfaces:
        canned_roles, decorators = __interfaces[collection_type]
        for role, name in canned_roles.items():
            roles.setdefault(role, name)

        # apply ABC auto-decoration to methods that need it
        for method, decorator in decorators.items():
            fn = getattr(cls, method, None)
            if (fn and method not in methods and
                    not hasattr(fn, '_sa_instrumented')):
                setattr(cls, method, decorator(fn))

    # ensure all roles are present, and apply implicit instrumentation if
    # needed
    if 'appender' not in roles or not hasattr(cls, roles['appender']):
        raise sa_exc.ArgumentError(
            "Type %s must elect an appender method to be "
            "a collection class" % cls.__name__)
    elif (methods not in roles['appender'] and
          not hasattr(getattr(cls, roles['appender']), '_sa_instrumented')):
        methods[roles['appender']] = ('fire_append_event', 1, None)

    if 'remover' not in roles or not hasattr(cls, roles['remover']):
        raise sa_exc.ArgumentError(
            "Type %s must elect a remover method to be "
            "a collection class" % cls.__name__)
    elif (roles['remover'] not in methods and
          not hasattr(getattr(cls, roles['remover']), '_sa_instrumented')):
        methods[roles['remover']] = ('fire_remove_event', 1, None)

    if 'iterator' not in roles or not hasattr(cls, roles['iterator']):
        raise sa_exc.ArgumentError(
            "Type %s must elect an iterator method to be "
            "a collection class" % cls.__name__)

    # apply ad-hoc instrumentation from decorators, class-level defaults
    # and implicit role declarations
    for method_name, (before, argument, after) in methods.items():
        setattr(cls, method_name,
                _instrument_membership_mutator(getattr(cls, method_name),
                                               before, argument, after))
    # intern the role map
    for role, method_name in roles.items():
        setattr(cls, '_sa_%s' % role, getattr(cls, method_name))

    cls._sa_adapter = None
    if not hasattr(cls, '_sa_linker'):
        cls._sa_linker = None
    if not hasattr(cls, '_sa_converter'):
        cls._sa_converter = None
    cls._sa_instrumented = id(cls)
dataset/ETHPy150Open goFrendiAsgard/kokoropy/kokoropy/packages/sqlalchemy/orm/collections.py/_instrument_class/swapped operands of `not in`