get_int() and get_float() don't raise ConfigException if wrong type
Both get_int() and get_float() raise TypeError or ValueError (and possibly others) if the value is actually of another type, instead of raising ConfigException.
Here's a simple example:
>>> import pyhocon
>>> t = pyhocon.ConfigParser.parse('a: asdf, b: {}')
>>> t.get_int('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.7/site-packages/pyhocon/config_tree.py", line 265, in get_int
return int(value) if value is not None else None
ValueError: invalid literal for int() with base 10: 'asdf'
>>> t.get_float('b')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.7/site-packages/pyhocon/config_tree.py", line 278, in get_float
return float(value) if value is not None else None
TypeError: float() argument must be a string or a number, not 'ConfigTree'
The solution could be to either wrap the code in a try block, catching all possible exceptions, or to perform instance checks. I.e. the first option would look something like this:
def get_int(self, key, default=UndefinedKey):
…
try:
return int(value) if value is not None else None
except (TypeError, ValueError):
raise ConfigException(
u"{key} has type '{type}' rather than 'int'".format(key=key, type=type(value).__name__))
while the second approach would probably make use of isinstance().
(Note that the latter would change behaviour a bit, although that might actually fix another bug: Given a document {a: 1.5}, get_int('a') returns 1. I haven't checked how the original implementation by Lightbend handles that case, though.)
P.S.: I should be able to submit a fix, but it will take some time. Also, I'd need to know which of the suggested solutions should be chosen.
Edit: Fixed spelling.
It turns out that Lightbend's implementation handles get_int() on a float the same as pyhocon, returning only the part before the decimal point.