python3 utility: convert safely to int
I know this question/post is old, but...



Use isinstance rather than directly storing and then checking the type() output.

We can get rid of t and two of your if statements to check type by using isinstance instead, and check against all three acceptable types:

if not (isinstance(n, (float, str, int))):
    raise ValueError('Parameter must be an int, str or float')


Just a thought on this, though: If something provided is not an int, str, or float, then it's an invalid type, and should raise a TypeError, rather than a ValueError, because TypeError is more generally used when you're passing an invalid object type into a function that can't handle it.  Therefore, your raise ValueError("...") for cases where the parameter is not an int, str, or float should probably be a TypeError with the same error message.

As was mentioned, isinstance will not behave right if you are using inherited classes which are subclasses of other primary classes.  However, consider that subclasses building upon other immutable classes are rare and as long as you aren't testing for instances of a bare object, this should suit your purposes.



The final code is this:

from typing import Union


def int_exact_cast(n: Union[int, float, str]) -&gt; int:
    """
    Tries to cast parameter to int without losing decimal part or raise an exception
    :param Union[int, float] n: The value to be converted
    :type n: Union[int, float]
    :return: The converted int value
    :rtype: int
    :raises ValueError: raises ValueError exception if the parameter can't be casted exactly to int
    """

    if not (isinstance(n, (float, str, int))):
        raise ValueError('Parameter must be an int, str or float')

    f = float(n)

    if not f.is_integer():
        raise ValueError('Parameter contains a decimal part')

    return int(f)




Just keep in mind that if the string can't be converted to a number (such as if the string is 'I Am A Teapot'), then you get a different ValueError from the conversion system, because it's Not a Number.  (Which is why you don't need the NaN check with this method, but you have to be careful with what you're working with)