Error message is confusing to users unfamiliar with toml
A user using some_tool might need to change its configuration some day. They write:
[some_tool]
show = all
which results in the error message:
$ python3 -c "import toml; toml.loads('show = all')"
Traceback (most recent call last):
File "C:\Python38\lib\site-packages\toml\decoder.py", line 510, in loads
ret = decoder.load_line(line, currentlevel, multikey,
File "C:\Python38\lib\site-packages\toml\decoder.py", line 777, in load_line
value, vtype = self.load_value(pair[1], strictly_valid)
File "C:\Python38\lib\site-packages\toml\decoder.py", line 913, in load_value
v = int(v, 0)
ValueError: invalid literal for int() with base 0: 'all'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Python38\lib\site-packages\toml\decoder.py", line 513, in loads
raise TomlDecodeError(str(err), original, pos)
toml.decoder.TomlDecodeError: invalid literal for int() with base 0: 'all' (line 1 column 1 char 0)
Users dealing with some_tool aren't experts in configuration languages; they don't know that JSON+TOML need quotes whereas INI+YAML don't. It would be helpful if the error message could mention that string values need quotes.
Another one:
$ python3 -c "import toml; toml.loads('quality = best')"
Traceback (most recent call last):
File "C:\Python38\lib\site-packages\toml\decoder.py", line 510, in loads
ret = decoder.load_line(line, currentlevel, multikey,
File "C:\Python38\lib\site-packages\toml\decoder.py", line 777, in load_line
value, vtype = self.load_value(pair[1], strictly_valid)
File "C:\Python38\lib\site-packages\toml\decoder.py", line 905, in load_value
raise ValueError("This float doesn't have a leading "
ValueError: This float doesn't have a leading digit
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Python38\lib\site-packages\toml\decoder.py", line 513, in loads
raise TomlDecodeError(str(err), original, pos)
toml.decoder.TomlDecodeError: This float doesn't have a leading digit (line 1 column 1 char 0)
The first thought here was "this is a bug in some_tool" until a colleague spotted the missing quotes.
Hey, maybe it's not an ideal solution, but you should do the parsing within a try / except block, so you could catch the data contained in the exception, which you can see here: https://github.com/uiri/toml/blob/9be64582fff86b9c5bd94ce52a5fedcb3d4fac01/toml/decoder.py#L50-L62
It would be great to document this, by the way!
So, you can do something like this.
try:
parsed_toml = toml.loads(toml_string)
except toml.decoder.TomlDecodeError as e:
print("Error when parsing the TOML file!")
print(f"The error is on line {e.lineno} at column {e.colno}.")
exit(1)
# You can also do a 'raise' to raise the exception after the prints, for example.
Hope it helps!
Another one (tested in release 0.10.2 and in current master):
In [1]: import toml
In [2]: toml.__version__
Out[2]: '0.10.2'
In [3]: dct = {'foo': 'bar', 'baz': ['qux', {'quux': 10}]}
In [4]: toml.dumps(dct)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-90f518bedf96> in <module>
----> 1 toml.dumps(dct)
~/mambaforge/envs/dev/lib/python3.7/site-packages/toml/encoder.py in dumps(o, encoder)
58 if encoder is None:
59 encoder = TomlEncoder(o.__class__)
---> 60 addtoretval, sections = encoder.dump_sections(o, "")
61 retval += addtoretval
62 outer_objs = [id(o)]
~/mambaforge/envs/dev/lib/python3.7/site-packages/toml/encoder.py in dump_sections(self, o, sup)
201 arraytabstr = "\n"
202 arraystr += "[[" + sup + qsection + "]]\n"
--> 203 s, d = self.dump_sections(a, sup + qsection)
204 if s:
205 if s[0] == "[":
~/mambaforge/envs/dev/lib/python3.7/site-packages/toml/encoder.py in dump_sections(self, o, sup)
191 if not re.match(r'^[A-Za-z0-9_-]+$', section):
192 qsection = _dump_str(section)
--> 193 if not isinstance(o[section], dict):
194 arrayoftables = False
195 if isinstance(o[section], list):
TypeError: string indices must be integers
I now understand my error (mixing types in an array) but my request is: Could you catch this and report a more user-friendly error? "TypeError: string indices must be integers" doesn't help me much. Something like TomlError: arrays can not include mixed types would be a huge step forward here. Lucky for me, I caught this in a minimal test suite, so it was easy to form a hypothesis, isolate the error, and confirm the problem by searching the web.