def ungrant_role(self, principal, role, object=None):
        """Ungrant `role` to `user` (either globally, if `object` is None, or
        on the specific `object`)."""
        assert principal
        principal = unwrap(principal)
        session = object_session(object) if object is not None else db.session
        manager = self._current_user_manager(session=session)

        args = {
            "role": role,
            "object": object,
            "anonymous": False,
            "user": None,
            "group": None,
        }
        query = session.query(RoleAssignment)
        query = query.filter(
            RoleAssignment.role == role, RoleAssignment.object == object
        )

        if principal is AnonymousRole or (
            hasattr(principal, "is_anonymous") and principal.is_anonymous
        ):
            args["anonymous"] = True
            query.filter(
                RoleAssignment.anonymous == False,
                RoleAssignment.user == None,
                RoleAssignment.group == None,
            )

        elif isinstance(principal, User):
            args["user"] = principal
            query = query.filter(RoleAssignment.user == principal)
        else:
            args["group"] = principal
            query = query.filter(RoleAssignment.group == principal)

        ra = query.one()
        session.delete(ra)
        audit = SecurityAudit(manager=manager, op=SecurityAudit.REVOKE, **args)
        session.add(audit)
        self._needs_flush()
        self._clear_role_cache(principal)