def open_bucket(self, bucket_name, **kwargs):
        # type: (str, str) -> Bucket
        """
        Open a new connection to a Couchbase bucket
        :param bucket_name: The name of the bucket to open
        :param kwargs: Additional arguments to provide to the constructor
        :return: An instance of the `bucket_class` object provided to
            :meth:`__init__`
        """
        if self.authenticator:
            auth_credentials_full = self.authenticator.get_auto_credentials(bucket_name)
        else:
            auth_credentials_full = {'options': {}}

        auth_credentials = auth_credentials_full['options']

        connstr = ConnectionString.parse(str(self.connstr))

        connstr.bucket = bucket_name
        for attrib in set(auth_credentials) - {'password'}:
            connstr.set_option(attrib, auth_credentials[attrib])

        # Check if there are conflicting authentication types in any of the parameters
        # Also sets its own 'auth_type' field to the type of authentication it
        # thinks is being specified

        normalizer = Cluster.ParamNormaliser(self.authenticator, connstr, **kwargs)

        # we don't do anything with this information unless the Normaliser thinks
        # Cert Auth is involved as this is outside the remit of PYCBC-487/488/489

        if issubclass(normalizer.auth_type, CertAuthenticator) or issubclass(type(self.authenticator),
                                                                             CertAuthenticator):
            # TODO: check_clash_free_params/check_no_unwanted_keys including connstr options
            # should probably apply to PasswordAuthenticator as well,
            # but outside remit of PYCBC-487

            # TODO: do we accept clashing/unwanted options in connstr/kwargs e.g. password?
            # Here, we throw an exception
            # in the case of any clash/unwanted options, but we could scrub
            # clashing/unwanted options from connstr/kwargs

            normalizer.check_no_unwanted_keys()
            normalizer.check_clash_free_params()
            normalizer.assert_no_critical_complaints()

        if 'password' in kwargs:
            if isinstance(self.authenticator, PasswordAuthenticator):
                raise MixedAuthError("Cannot override "
                                     "PasswordAuthenticators password")
        else:
            kwargs['password'] = auth_credentials.get('password', None)
        connstr.scheme = auth_credentials_full.get('scheme', connstr.scheme)
        rv = self.bucket_class(str(connstr), **kwargs)
        self._buckets[bucket_name] = weakref.ref(rv)
        if isinstance(self.authenticator, ClassicAuthenticator):
            for bucket, passwd in self.authenticator.buckets.items():
                if passwd:
                    rv.add_bucket_creds(bucket, passwd)
        return rv
Open a new connection to a Couchbase bucket
        :param bucket_name: The name of the bucket to open
        :param kwargs: Additional arguments to provide to the constructor
        :return: An instance of the `bucket_class` object provided to
            :meth:`__init__`