def _setup_event_handlers(self):

        def load_handler(state, *args):
            dict_ = state.dict

            if self.key in dict_:
                return

            # if column elements aren't loaded, skip.
            # __get__() will initiate a load for those
            # columns
            for k in self._attribute_keys:
                if k not in dict_:
                    return

            # assert self.key not in dict_
            dict_[self.key] = self.composite_class(
                *[state.dict[key] for key in
                  self._attribute_keys]
            )

        def expire_handler(state, keys):
            if keys is None or set(self._attribute_keys).intersection(keys):
                state.dict.pop(self.key, None)

        def insert_update_handler(mapper, connection, state):
            """After an insert or update, some columns may be expired due
            to server side defaults, or re-populated due to client side
            defaults.  Pop out the composite value here so that it
            recreates.

            """

            state.dict.pop(self.key, None)

        event.listen(self.parent, 'after_insert',
                     insert_update_handler, raw=True)
        event.listen(self.parent, 'after_update',
                     insert_update_handler, raw=True)
        event.listen(self.parent, 'load',
                     load_handler, raw=True, propagate=True)
        event.listen(self.parent, 'refresh',
                     load_handler, raw=True, propagate=True)
        event.listen(self.parent, 'expire',
                     expire_handler, raw=True, propagate=True)

        # TODO: need a deserialize hook here
Calculate which security groups need to be removed.
dataset/ETHPy150Open RoseOu/flasky/venv/lib/python2.7/site-packages/sqlalchemy/orm/descriptor_props.py/CompositeProperty._setup_event_handlers--crossover with--dataset/ETHPy150Open openstack/neutron/neutron/agent/linux/iptables_firewall.py/IptablesFirewallDriver._determine_sg_rules_to_remove