'Uses `np.allclose()` on number arrays.
:raises: (AssertionError) Using TestCase\'s self.failureException'

def assert_dict_equal(self, d1, d2, msg=None):

    self.assertIsInstance(d1, dict, 'First    argument    is    not    a    dictionary')
    self.assertIsInstance(d2, dict, 'Second    argument    is    not    a    dictionary')
    for (node, path) in node_generator(d1):
        try:
            comp_node = get_by_path(d2, path)
        except (KeyError, IndexError):
            standard_msg = 'Path    {}    exists    in    dict    1,    but    not    dict    2.'.format(path)
            self.fail(self._formatMessage(msg, standard_msg))
        self.assertIsInstance(comp_node, dict, 'Value    at    path    {}    is    not    a    dict.'.format(path))
        for (key, val) in node.items():
            if isinstance(val, dict):
                continue
            val_path = (path + (key,))
            try:
                comp_val = comp_node[key]
            except KeyError:
                standard_msg = 'Path    {}    exists    in    dict    1,    but    not    dict    2.'.format(self._format_path(val_path))
                self.fail(self._formatMessage(msg, standard_msg))
            if (isinstance(val, np.ndarray) or isinstance(comp_val, np.ndarray)):
                if np.array_equal(val, comp_val):
                    continue
            elif (val == comp_val):
                continue
            if (is_num_list(val) and is_num_list(comp_val)):
                if np.allclose(val, comp_val):
                    continue
            standard_msg = 'Value    comparison    failed    at    path    {}.\n{}    !=    {}'.format(self._format_path(val_path), val, comp_val)
            self.fail(self._formatMessage(msg, standard_msg))
        for key in comp_node:
            val_path = (path + (key,))
            if (key not in node):
                standard_msg = 'Path    {}    exists    in    dict    2,    but    not    dict    1.'.format(self._format_path(val_path))
                self.fail(self._formatMessage(msg, standard_msg))
