Repository: sdispater/tomlkit

Issue:
dumps() doesn't support tuple
This is almost a drop-in replacement for the [toml](https://pypi.org/project/toml/) library. But an issue I ran into is lack of support for tuples, which `toml` converts to lists.

```
In[50]: import toml
In[51]: import tomlkit
In[52]: x={'section': {'tuple_value': (1,2)}}
In[53]: tomlkit.dumps(x)
Out[53]: Traceback (most recent call last):
  File "C:\projects\foo\.venv\lib\site-packages\IPython\core\interactiveshell.py", line 3457, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-53-add147bf2e5e>", line 1, in <module>
    tomlkit.dumps(x)
  File "C:\projects\foo\.venv\lib\site-packages\tomlkit\api.py", line 49, in dumps
    data = item(dict(data), _sort_keys=sort_keys)
  File "C:\projects\foo\.venv\lib\site-packages\tomlkit\items.py", line 92, in item
    val[k] = item(v, _parent=val, _sort_keys=_sort_keys)
  File "C:\projects\foo\.venv\lib\site-packages\tomlkit\items.py", line 92, in item
    val[k] = item(v, _parent=val, _sort_keys=_sort_keys)
  File "C:\projects\foo\.venv\lib\site-packages\tomlkit\items.py", line 152, in item
    raise ValueError(f"Invalid type {type(value)}")
ValueError: Invalid type <class 'tuple'>
In[54]: toml.dumps(x)
Out[54]: '[section]\ntuple_value = [ 1, 2,]\n'
```

I think the way the toml library handles this is there's a fall back method that converts unrecognized iterables to lists, and so that catches tuples.

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 24fc8f8..1a8d064 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,8 @@
 
 ### Fixed
 
-- Fix a bug of separators not being kept when replacing the value. ([#170](https://github.com/sdispater/tomlkit/pull/170))
+- Fix a bug of separators not being kept when replacing the value. ([#170](https://github.com/sdispater/tomlkit/issues/170))
+- Tuples should be dumped as TOML arrays. ([#171](https://github.com/sdispater/tomlkit/issues/171))
 
 ## [0.9.0] - 2022-02-01
 
@@ -26,9 +27,9 @@
 
 ### Fixed
 
-- Support copy protocols for table items. ([#65](https://github.com/sdispater/tomlkit/issues/#65))
-- Escape characters in double quoted key string. ([#136](https://github.com/sdispater/tomlkit/issues/#136))
-- Fix the invalid dumping output of multiline array when it is empty. ([#139](https://github.com/sdispater/tomlkit/issues/#139))
+- Support copy protocols for table items. ([#65](https://github.com/sdispater/tomlkit/issues/65))
+- Escape characters in double quoted key string. ([#136](https://github.com/sdispater/tomlkit/issues/136))
+- Fix the invalid dumping output of multiline array when it is empty. ([#139](https://github.com/sdispater/tomlkit/issues/139))
 - Fix a bug that tomlkit accepts an invalid table with missing `=`. ([#141](https://github.com/sdispater/tomlkit/issues/141))
 - Fix the invalid dumping output when the key is empty. ([#143](https://github.com/sdispater/tomlkit/issues/143))
 - Fix incorrect string returned by dumps when moving/renaming table. ([#144](https://github.com/sdispater/tomlkit/issues/144))
diff --git a/tomlkit/items.py b/tomlkit/items.py
index ae6b902..c655784 100644
--- a/tomlkit/items.py
+++ b/tomlkit/items.py
@@ -92,7 +92,7 @@ def item(
             val[k] = item(v, _parent=val, _sort_keys=_sort_keys)
 
         return val
-    elif isinstance(value, list):
+    elif isinstance(value, (list, tuple)):
         if value and all(isinstance(v, dict) for v in value):
             a = AoT([])
             table_constructor = Table


Test patch:
diff --git a/tests/test_api.py b/tests/test_api.py
index 2cd360f..f4ecf35 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -165,6 +165,14 @@ def test_dumps_weird_object():
         dumps(object())
 
 
+def test_dump_tuple_value_as_array():
+    x = {"foo": (1, 2)}
+    assert dumps(x) == "foo = [1, 2]\n"
+
+    x = {"foo": ({"a": 1}, {"a": 2})}
+    assert dumps(x) == "[[foo]]\na = 1\n\n[[foo]]\na = 2\n"
+
+
 def test_dump_to_file_object():
     doc = {"foo": "bar"}
     fp = io.StringIO()