Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`


Discussion:
Done inline during improve_partitions push.

Resolving patch:
diff --git a/great_expectations/core/util.py b/great_expectations/core/util.py
--- a/great_expectations/core/util.py
+++ b/great_expectations/core/util.py
@@ -129,21 +129,15 @@ def convert_to_json_serializable(data):
     if isinstance(data, (SerializableDictDot, SerializableDotDict)):
         return data.to_json_dict()
 
-    try:
-        if not isinstance(data, list) and pd.isna(data):
-            # pd.isna is functionally vectorized, but we only want to apply this to single objects
-            # Hence, why we test for `not isinstance(list))`
-            return None
-    except TypeError:
-        pass
-    except ValueError:
-        pass
+    # Handling "float(nan)" separately is required by Python-3.6 and Pandas-0.23 versions.
+    if isinstance(data, float) and np.isnan(data):
+        return None
 
     if isinstance(data, (str, int, float, bool)):
         # No problem to encode json
         return data
 
-    elif isinstance(data, dict):
+    if isinstance(data, dict):
         new_dict = {}
         for key in data:
             # A pandas index can be numeric, and a dict key can be numeric, but a json key must be a string
@@ -151,44 +145,54 @@ def convert_to_json_serializable(data):
 
         return new_dict
 
-    elif isinstance(data, (list, tuple, set)):
+    if isinstance(data, (list, tuple, set)):
         new_list = []
         for val in data:
             new_list.append(convert_to_json_serializable(val))
 
         return new_list
 
-    elif isinstance(data, (np.ndarray, pd.Index)):
+    if isinstance(data, (np.ndarray, pd.Index)):
         # test_obj[key] = test_obj[key].tolist()
         # If we have an array or index, convert it first to a list--causing coercion to float--and then round
         # to the number of digits for which the string representation will equal the float representation
         return [convert_to_json_serializable(x) for x in data.tolist()]
 
-    # Note: This clause has to come after checking for np.ndarray or we get:
-    #      `ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`
-    elif data is None:
-        # No problem to encode json
-        return data
-
-    elif isinstance(data, (datetime.datetime, datetime.date)):
+    if isinstance(data, (datetime.datetime, datetime.date)):
         return data.isoformat()
 
-    elif isinstance(data, uuid.UUID):
+    if isinstance(data, uuid.UUID):
         return str(data)
 
     # Use built in base type from numpy, https://docs.scipy.org/doc/numpy-1.13.0/user/basics.types.html
     # https://github.com/numpy/numpy/pull/9505
-    elif np.issubdtype(type(data), np.bool_):
+    if np.issubdtype(type(data), np.bool_):
         return bool(data)
 
-    elif np.issubdtype(type(data), np.integer) or np.issubdtype(type(data), np.uint):
+    if np.issubdtype(type(data), np.integer) or np.issubdtype(type(data), np.uint):
         return int(data)
 
-    elif np.issubdtype(type(data), np.floating):
+    if np.issubdtype(type(data), np.floating):
         # Note: Use np.floating to avoid FutureWarning from numpy
         return float(round(data, sys.float_info.dig))
 
-    elif isinstance(data, pd.Series):
+    # Note: This clause has to come after checking for np.ndarray or we get:
+    #      `ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`
+    if data is None:
+        # No problem to encode json
+        return data
+
+    try:
+        if not isinstance(data, list) and pd.isna(data):
+            # pd.isna is functionally vectorized, but we only want to apply this to single objects
+            # Hence, why we test for `not isinstance(list))`
+            return None
+    except TypeError:
+        pass
+    except ValueError:
+        pass
+
+    if isinstance(data, pd.Series):
         # Converting a series is tricky since the index may not be a string, but all json
         # keys must be strings. So, we use a very ugly serialization strategy
         index_name = data.index.name or "index"
@@ -201,24 +205,24 @@ def convert_to_json_serializable(data):
             for idx, val in data.iteritems()
         ]
 
-    elif isinstance(data, pd.DataFrame):
+    if isinstance(data, pd.DataFrame):
         return convert_to_json_serializable(data.to_dict(orient="records"))
 
-    elif pyspark and isinstance(data, pyspark.sql.DataFrame):
+    if pyspark and isinstance(data, pyspark.sql.DataFrame):
         # using StackOverflow suggestion for converting pyspark df into dictionary
         # https://stackoverflow.com/questions/43679880/pyspark-dataframe-to-dictionary-columns-as-keys-and-list-of-column-values-ad-di
         return convert_to_json_serializable(
             dict(zip(data.schema.names, zip(*data.collect())))
         )
 
-    elif isinstance(data, decimal.Decimal):
+    if isinstance(data, decimal.Decimal):
         if requires_lossy_conversion(data):
             logger.warning(
                 f"Using lossy conversion for decimal {data} to float object to support serialization."
             )
         return float(data)
 
-    elif isinstance(data, RunIdentifier):
+    if isinstance(data, RunIdentifier):
         return data.to_json_dict()
 
     else:
@@ -242,61 +246,61 @@ def ensure_json_serializable(data):
     if isinstance(data, (SerializableDictDot, SerializableDotDict)):
         return
 
-    try:
-        if not isinstance(data, list) and pd.isna(data):
-            # pd.isna is functionally vectorized, but we only want to apply this to single objects
-            # Hence, why we test for `not isinstance(list))`
-            return
-    except TypeError:
-        pass
-    except ValueError:
-        pass
-
     if isinstance(data, ((str,), (int,), float, bool)):
         # No problem to encode json
         return
 
-    elif isinstance(data, dict):
+    if isinstance(data, dict):
         for key in data:
             str(key)  # key must be cast-able to string
             ensure_json_serializable(data[key])
 
         return
 
-    elif isinstance(data, (list, tuple, set)):
+    if isinstance(data, (list, tuple, set)):
         for val in data:
             ensure_json_serializable(val)
         return
 
-    elif isinstance(data, (np.ndarray, pd.Index)):
+    if isinstance(data, (np.ndarray, pd.Index)):
         # test_obj[key] = test_obj[key].tolist()
         # If we have an array or index, convert it first to a list--causing coercion to float--and then round
         # to the number of digits for which the string representation will equal the float representation
         _ = [ensure_json_serializable(x) for x in data.tolist()]
         return
 
-    # Note: This clause has to come after checking for np.ndarray or we get:
-    #      `ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`
-    elif data is None:
-        # No problem to encode json
-        return
-
-    elif isinstance(data, (datetime.datetime, datetime.date)):
+    if isinstance(data, (datetime.datetime, datetime.date)):
         return
 
     # Use built in base type from numpy, https://docs.scipy.org/doc/numpy-1.13.0/user/basics.types.html
     # https://github.com/numpy/numpy/pull/9505
-    elif np.issubdtype(type(data), np.bool_):
+    if np.issubdtype(type(data), np.bool_):
         return
 
-    elif np.issubdtype(type(data), np.integer) or np.issubdtype(type(data), np.uint):
+    if np.issubdtype(type(data), np.integer) or np.issubdtype(type(data), np.uint):
         return
 
-    elif np.issubdtype(type(data), np.floating):
+    if np.issubdtype(type(data), np.floating):
         # Note: Use np.floating to avoid FutureWarning from numpy
         return
 
-    elif isinstance(data, pd.Series):
+    # Note: This clause has to come after checking for np.ndarray or we get:
+    #      `ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`
+    if data is None:
+        # No problem to encode json
+        return
+
+    try:
+        if not isinstance(data, list) and pd.isna(data):
+            # pd.isna is functionally vectorized, but we only want to apply this to single objects
+            # Hence, why we test for `not isinstance(list))`
+            return
+    except TypeError:
+        pass
+    except ValueError:
+        pass
+
+    if isinstance(data, pd.Series):
         # Converting a series is tricky since the index may not be a string, but all json
         # keys must be strings. So, we use a very ugly serialization strategy
         index_name = data.index.name or "index"
@@ -310,20 +314,20 @@ def ensure_json_serializable(data):
         ]
         return
 
-    elif pyspark and isinstance(data, pyspark.sql.DataFrame):
+    if pyspark and isinstance(data, pyspark.sql.DataFrame):
         # using StackOverflow suggestion for converting pyspark df into dictionary
         # https://stackoverflow.com/questions/43679880/pyspark-dataframe-to-dictionary-columns-as-keys-and-list-of-column-values-ad-di
         return ensure_json_serializable(
             dict(zip(data.schema.names, zip(*data.collect())))
         )
 
-    elif isinstance(data, pd.DataFrame):
+    if isinstance(data, pd.DataFrame):
         return ensure_json_serializable(data.to_dict(orient="records"))
 
-    elif isinstance(data, decimal.Decimal):
+    if isinstance(data, decimal.Decimal):
         return
 
-    elif isinstance(data, RunIdentifier):
+    if isinstance(data, RunIdentifier):
         return
 
     else:


Test patch: