pyhocon icon indicating copy to clipboard operation
pyhocon copied to clipboard

get_int() and get_float() don't raise ConfigException if wrong type

Open ElkMonster opened this issue 7 years ago • 1 comments

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.

ElkMonster avatar Sep 11 '18 17:09 ElkMonster

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.

ElkMonster avatar Oct 30 '18 17:10 ElkMonster