@@ -50,3 +50,17 @@ class ExampleStubber(Stubber):
         """When using stubs, verify no more responses are waiting in the queue."""
         if self.use_stubs:
             super().assert_no_pending_responses()
+
+    def _stub_bifurcator(
+            self, method, expected_params=None, response=None, error_code=None):
+        if not expected_params:
+            expected_params = {}
+        if not response:
+            response = {}
+        if not error_code:
+            self.add_response(
+                method, expected_params=expected_params, service_response=response)
+        else:
+            self.add_client_error(
+                method, expected_params=expected_params, service_error_code=error_code)
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

"""
A base class for stubbers that are used by the Python code example unit tests.
"""

from botocore.stub import Stubber


class ExampleStubber(Stubber):
    """
    A base class that wraps the botocore Stubber and either uses the Stubber to
    intercept requests during tests or pass calls through to AWS.

    All stubbers used in Python unit tests must inherit from this base class.
    """
    def __init__(self, client, use_stubs=True):
        """
        Initializes the object with a specific client and configures it for
        stubbing or AWS passthrough.

        :param client: A Boto 3 service client.
        :param use_stubs: When True, use stubs to intercept requests. Otherwise,
                          pass requests through to AWS.
        """
        self.use_stubs = use_stubs
        self.region_name = client.meta.region_name
        if self.use_stubs:
            super().__init__(client)
        else:
            self.client = client

    def add_response(self, method, service_response, expected_params=None):
        """When using stubs, add a stubbed response."""
        if self.use_stubs:
            super().add_response(method, service_response, expected_params)

    def add_client_error(self, method, service_error_code='',
                         service_message='', http_status_code=400,
                         service_error_meta=None, expected_params=None,
                         response_meta=None):
        """When using stubs, add a stubbed error response."""
        if self.use_stubs:
            super().add_client_error(method, service_error_code, service_message,
                                     http_status_code, service_error_meta,
                                     expected_params, response_meta)

    def assert_no_pending_responses(self):
        """When using stubs, verify no more responses are waiting in the queue."""
        if self.use_stubs:
            super().assert_no_pending_responses()

Minor python nit. It'd be considered more idiomatic to use `if expected_params is not None` when initializing default args. Otherwise, the interpreter evaluates `expected_params` as every applicable type and then executes equivalency on those to make the best decision. `is not None` is an explicit equivalency check against a singleton so it doesn't need to do any guess work. It also prevents cases where you accidentally execute unneeded code. e.g. I pass in `{}` as my argument, and then you redeclare the same value (and execute any other code in your if statement) because `{}` is false-y.