Great work! I had not known if those corners.

Have you tried with NumPy zero-D arrays or PyTorch Values? Both of those
should have sensible answers.

On Fri, Dec 27, 2019, 7:42 PM Steven D'Aprano <st...@pearwood.info> wrote:

> By the way, it's not as easy as you might think to test whether a value
> is a NAN or not.
>
> There are currently three ways to test whether a value is a NAN. (Four
> if you include cmath.isnan.)
>
> 1. math.isnan(x) but it can fail in annoying ways.
>
>
>     # No int is a NAN so this should return False
>     py> math.isnan(10**1000)
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     OverflowError: int too large to convert to float
>
>     # Decimal signalling NANs are NANs so this should return True
>     py> x = Decimal('snan')
>     py> math.isnan(x)
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     ValueError: cannot convert signaling NaN to float
>
>
> 2. Decimal.is_nan() but it only works with decimals. However it does
> work with signalling NANs.
>
>
> 3. Back before math.isnan existed, the idiomatic way to check for NANs
> was to test whether they were equal to themselves. Assuming that x is a
> kind of numeric type, we should expect that `x == x` except for NANs.
> But this too fails for signalling NANs:
>
>
>     # Using the default Decimal context
>     py> x == x
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
>
>
> So there is no good way to check for an arbitrary NAN that duck-types
> floats, Decimals, ints, Fractions and other numeric types.
>
> I have come up with this:
>
>
>     def isnan(x, _isnan=math.isnan):
>         try:
>             return _isnan(x)
>         except ValueError:
>             # Could be a Decimal signalling NAN.
>             try:
>                 return x.is_nan()
>             except AttributeError:
>                 return x != x
>         except OverflowError:
>             return False
>         except TypeError:
>             from cmath import isnan
>             return isnan(x)
>
>
> but I fear that there could be other landmines waiting, other odd corner
> cases I haven't thought of.
>
> See also
>
> https://bugs.python.org/issue27975
>
>
>
> --
> Steven
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/VHC4GO37ZT2UEW6RSRF4ASMTVK52UQ6H/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/AGBORBUDM2763CORRJBJPDCOJ3TSNNA5/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to