Register a new user.

        Parameters
        ----------
        username: str
            The username.
        password: str
            The password.

        Returns
        -------
        bool
            True if the new user is successfully registered, False otherwise.
        result
            An empty dict if the new user is successfully registered, a dict
            containing the error string with the key ERROR_KEY otherwise.

        Note
        ----
        Possible error strings are listed as below:

        -  ERROR_USERNAME_ALREADY_EXISTS.format(username)
        -  ERROR_WEAK_PASSWORD

def register(self, username, password):
        """Register a new user.

        Parameters
        ----------
        username: str
            The username.
        password: str
            The password.

        Returns
        -------
        bool
            True if the new user is successfully registered, False otherwise.
        result
            An empty dict if the new user is successfully registered, a dict
            containing the error string with the key ERROR_KEY otherwise.

        Note
        ----
        Possible error strings are listed as below:

        -  ERROR_USERNAME_ALREADY_EXISTS.format(username)
        -  ERROR_WEAK_PASSWORD
        """
        result = {pytwis_constants.ERROR_KEY: None}

        # Check the username.
        if not Pytwis._check_username(username):
            result[pytwis_constants.ERROR_KEY] = pytwis_constants.ERROR_INVALID_USERNAME
            return (False, result)

        # Check the password.
        if not Pytwis._check_password(password):
            result[pytwis_constants.ERROR_KEY] = pytwis_constants.ERROR_WEAK_PASSWORD
            return (False, result)

        # Update the username-to-userid mapping.
        with self._rc.pipeline() as pipe:
            while True:
                try:
                    # Put a watch on the Hash 'users': username -> user-id, in case that
                    # multiple clients are registering with the same username.
                    pipe.watch(pytwis_constants.USERS_KEY)
                    username_exists = pipe.hexists(pytwis_constants.USERS_KEY, username)
                    if username_exists:
                        result[pytwis_constants.ERROR_KEY] = \
                            pytwis_constants.ERROR_USERNAME_ALREADY_EXISTS.format(username)
                        return (False, result)

                    # Get the next user-id. If the key "next_user_id" doesn't exist,
                    # it will be created and initialized as 0, and then incremented by 1.
                    userid = pipe.incr(pytwis_constants.NEXT_USER_ID_KEY)

                    # Set the username-to-userid pair in USERS_HASH_KEY.
                    pipe.multi()
                    pipe.hset(pytwis_constants.USERS_KEY, username, userid)
                    pipe.execute()

                    break
                except WatchError:
                    continue

            # Generate the authentication secret.
            auth_secret = secrets.token_hex()
            userid_profile_key = pytwis_constants.USER_PROFILE_KEY_FORMAT.format(userid)

            # Generate the password hash.
            # The format of the password hash looks like "method$salt$hash".
            password_hash = generate_password_hash(password,
                                                   method=\
                                                   pytwis_constants.PASSWORD_HASH_METHOD)

            pipe.multi()
            # Update the authentication_secret-to-userid mapping.
            pipe.hset(pytwis_constants.AUTHS_KEY, auth_secret, userid)
            # Create the user profile.
            pipe.hmset(userid_profile_key,
                       {pytwis_constants.USERNAME_KEY: username,
                        pytwis_constants.PASSWORD_HASH_KEY: password_hash,
                        pytwis_constants.AUTH_KEY: auth_secret})
            pipe.execute()

        return (True, result)