Repository: ucfopen/canvasapi

Issue:
Combine Kwargs Alternating Nesting Dictionaries and Lists
Multiple users have reported issues with the [Create Quiz Question method](https://canvasapi.readthedocs.io/en/latest/quiz-ref.html#canvasapi.quiz.Quiz.create_question). In particular, the issue appears to be with the `question[answers]` parameter.

We originally diagnosed this as an issue with Canvas handling nested lists weird, but upon further inspection it looks like the issue actually lies with our implementation of `combine_kwargs`.

```
canvasapi_function(
    dict_list_dict={
        'key1': [
            {'subkey1a': 'value1a'},
            {'subkey1b': 'value1b'}
        ],
        'key2': [
            {'subkey2a': 'value2a'},
            {'subkey2b': 'value2b'}
        ]
    }
)
```

Given the above code, we would expect `combine_kwargs` to output the following:

```
dict_list_dict[key1][][subkey1a]=value1a
dict_list_dict[key1][][subkey1b]=value1b
dict_list_dict[key2][][subkey2a]=value2a
dict_list_dict[key2][][subkey2b]=value2b
```

However, it appears to actually be returning this (incorrect) response:
```
dict_list_dict[key1][subkey1a][]=value1a
dict_list_dict[key1][subkey1b][]=value1b
dict_list_dict[key2][subkey2a][]=value2a
dict_list_dict[key2][subkey2b][]=value2b
```

Discussion:

Patch:
diff --git a/canvasapi/util.py b/canvasapi/util.py
index 0431db8..5ee291e 100644
--- a/canvasapi/util.py
+++ b/canvasapi/util.py
@@ -89,8 +89,8 @@ def flatten_kwarg(key, obj):
         # Add empty brackets (i.e. "[]")
         new_list = []
         for i in obj:
-            for tup in flatten_kwarg(key, i):
-                new_list.append((tup[0] + '[]', tup[1]))
+            for tup in flatten_kwarg(key + '][', i):
+                new_list.append((tup[0], tup[1]))
         return new_list
     else:
         # Base case. Return list with tuple containing the value


Test patch:
diff --git a/tests/test_util.py b/tests/test_util.py
index 6a9d835..caca94d 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -252,6 +252,25 @@ class TestUtil(unittest.TestCase):
         self.assertEqual(len(result), 1)
         self.assertIn(('big_dict[a][b][c][d][e]', 'We need to go deeper'), result)
 
+    def test_combine_kwargs_dict_list_dict(self, m):
+        result = combine_kwargs(
+            dict_list_dict={
+                'key1': [
+                    {'subkey1a': 'value1a'},
+                    {'subkey1b': 'value1b'}
+                ],
+                'key2': [
+                    {'subkey2a': ['value2a1', 'value2a2']}
+                ]
+            }
+        )
+        self.assertIsInstance(result, list)
+        self.assertEqual(len(result), 4)
+        self.assertIn(('dict_list_dict[key1][][subkey1a]', 'value1a'), result)
+        self.assertIn(('dict_list_dict[key1][][subkey1b]', 'value1b'), result)
+        self.assertIn(('dict_list_dict[key2][][subkey2a][]', 'value2a1'), result)
+        self.assertIn(('dict_list_dict[key2][][subkey2a][]', 'value2a2'), result)
+
     def test_combine_kwargs_the_gauntlet(self, m):
         result = combine_kwargs(
             foo='bar',
@@ -310,9 +329,19 @@ class TestUtil(unittest.TestCase):
             dict_list={
                 'key': ['item1', 'item2']
             },
+            dict_list_dict={
+                'key1': [
+                    {'subkey1a': 'value1a'},
+                    {'subkey1b': 'value1b'}
+                ],
+                'key2': [
+                    {'subkey2a': 'value2a'},
+                    {'subkey2b': 'value2b'}
+                ]
+            }
         )
         self.assertIsInstance(result, list)
-        self.assertEqual(len(result), 39)
+        self.assertEqual(len(result), 43)
 
         # Check that all keys were generated correctly
         self.assertIn(('foo', 'bar'), result)
@@ -354,6 +383,10 @@ class TestUtil(unittest.TestCase):
         self.assertIn(('generator[]', 'g3'), result)
         self.assertIn(('dict_list[key][]', 'item1'), result)
         self.assertIn(('dict_list[key][]', 'item2'), result)
+        self.assertIn(('dict_list_dict[key1][][subkey1a]', 'value1a'), result)
+        self.assertIn(('dict_list_dict[key1][][subkey1b]', 'value1b'), result)
+        self.assertIn(('dict_list_dict[key2][][subkey2a]', 'value2a'), result)
+        self.assertIn(('dict_list_dict[key2][][subkey2b]', 'value2b'), result)
 
         # Ensure list kwargs are in correct order
         self.assertTrue(