From 870ecdc4303813e0f8137e21cb9f1bee51797dec Mon Sep 17 00:00:00 2001 From: John Richards Date: Thu, 15 Oct 2020 20:57:56 -0400 Subject: [PATCH] Handle NaN and infinity values Right now, NaN/infinity values will produce "nan" and "inf", but Python doesn't allow those in source code. This change will wrap those values in float(''), which is allowed. Tests for Python 2.7 and 3.8 have been added as well. Fixes #136 --- bytecode.cpp | 11 ++++++++++- tests/compiled/nan_inf.2.7.pyc | Bin 0 -> 352 bytes tests/compiled/nan_inf.3.8.pyc | Bin 0 -> 249 bytes tests/input/nan_inf.py | 8 ++++++++ tests/tokenized/nan_inf.txt | 8 ++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/compiled/nan_inf.2.7.pyc create mode 100644 tests/compiled/nan_inf.3.8.pyc create mode 100644 tests/input/nan_inf.py create mode 100644 tests/tokenized/nan_inf.txt diff --git a/bytecode.cpp b/bytecode.cpp index 2155901..02849c3 100644 --- a/bytecode.cpp +++ b/bytecode.cpp @@ -1,5 +1,6 @@ #include "pyc_numeric.h" #include "bytecode.h" +#include #ifdef _MSC_VER #define snprintf _snprintf @@ -268,7 +269,15 @@ void print_const(PycRef obj, PycModule* mod) obj.cast()->imag()); break; case PycObject::TYPE_BINARY_FLOAT: - fprintf(pyc_output, "%g", obj.cast()->value()); + { + // Wrap any nan/inf values in float(''). + double value = obj.cast()->value(); + if (std::isnan(value) || std::isinf(value)) { + fprintf(pyc_output, "float('%g')", value); + } else { + fprintf(pyc_output, "%g", value); + } + } break; case PycObject::TYPE_BINARY_COMPLEX: fprintf(pyc_output, "(%g+%gj)", obj.cast()->value(), diff --git a/tests/compiled/nan_inf.2.7.pyc b/tests/compiled/nan_inf.2.7.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c454f62bb4904e6883524e3edb6dec4f78b9d1f5 GIT binary patch literal 352 zcmYL^yAr`b7=_Qu#ocqHq171U0gOhsjR~8C8Ny6fp`p-t2#=@Jn9-eXRm?pG?$c1rmRM4KdEAESX;$?APyaH3k zIB4;}$VWtIuet Ge7pg$wm*6R literal 0 HcmV?d00001 diff --git a/tests/compiled/nan_inf.3.8.pyc b/tests/compiled/nan_inf.3.8.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5df44589ecc47d41a1a3f3e70dd32af8eb3ea37d GIT binary patch literal 249 zcmZ9EJr06E5QTSGke`V6pwPywbFmHk8H&A8KKI zlX>6FZr)6N-xE-NKZh6a)-1m=u#C`UAEt#8niOe68CohCo7y~)vOo)Lfi2JmZP3xq zLxqnC48Htt2a=EmO>tFr`e3tJt)0 f`)yAT=@7Brde6>aRp?z74+-C82WHZz9BS$XT~0Z8 literal 0 HcmV?d00001 diff --git a/tests/input/nan_inf.py b/tests/input/nan_inf.py new file mode 100644 index 0000000..2675b78 --- /dev/null +++ b/tests/input/nan_inf.py @@ -0,0 +1,8 @@ +a = 1e300 * 1e300 * 0 +b = -1e300 * 1e300 * 0 +c = 1e300 * 1e300 +d = -1e300 * 1e300 +e = float('nan') +f = float('-nan') +g = float('inf') +h = float('-inf') diff --git a/tests/tokenized/nan_inf.txt b/tests/tokenized/nan_inf.txt new file mode 100644 index 0000000..9c16fb9 --- /dev/null +++ b/tests/tokenized/nan_inf.txt @@ -0,0 +1,8 @@ +a = float ( '-nan' ) +b = float ( '-nan' ) +c = float ( 'inf' ) +d = float ( '-inf' ) +e = float ( 'nan' ) +f = float ( '-nan' ) +g = float ( 'inf' ) +h = float ( '-inf' )