def deep_compare(obj1: Dict[Any, Any], obj2: Dict[Any, Any]) -> bool:
    """Recursively compare two dictionaries to check if they are equal in terms of keys and values.

    .. note::
        Values are compared based on their string representation.

    :param obj1: dictionary to be compared with *obj2*.
    :param obj2: dictionary to be compared with *obj1*.

    :returns: ``True`` if all keys and values match between the two dictionaries.

    :Example:

        >>> deep_compare({'1': None}, {})
        False

        >>> deep_compare({'1': {}}, {'1': None})
        False

        >>> deep_compare({'1': [1]}, {'1': [2]})
        False

        >>> deep_compare({'1': 2}, {'1': '2'})
        True

        >>> deep_compare({'1': {'2': [3, 4]}}, {'1': {'2': [3, 4]}})
        True
    """
    if set(list(obj1.keys())) != set(list(obj2.keys())):  # Objects have different sets of keys
        return False

    for key, value in obj1.items():
        if isinstance(value, dict):
            if not (isinstance(obj2[key], dict) and deep_compare(cast(Dict[Any, Any], value), obj2[key])):
                return False
        elif str(value) != str(obj2[key]):
            return False
    return True
Recursively compare two dictionaries to check if they are equal in terms of keys and values.

    .. note::
        Values are compared based on their string representation.

    :param obj1: dictionary to be compared with *obj2*.
    :param obj2: dictionary to be compared with *obj1*.

    :returns: ``True`` if all keys and values match between the two dictionaries.

    :Example:

        >>> deep_compare({'1': None}, {})
        False

        >>> deep_compare({'1': {}}, {'1': None})
        False

        >>> deep_compare({'1': [1]}, {'1': [2]})
        False

        >>> deep_compare({'1': 2}, {'1': '2'})
        True

        >>> deep_compare({'1': {'2': [3, 4]}}, {'1': {'2': [3, 4]}})
        True
    
patroni/utils.py