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/validator/validator.py b/great_expectations/validator/validator.py
--- a/great_expectations/validator/validator.py
+++ b/great_expectations/validator/validator.py
@@ -72,6 +72,43 @@
 MAX_METRIC_COMPUTATION_RETRIES = 3
 
 
+ValidationStatistics = namedtuple(
+    "ValidationStatistics",
+    [
+        "evaluated_expectations",
+        "successful_expectations",
+        "unsuccessful_expectations",
+        "success_percent",
+        "success",
+    ],
+)
+
+
+def _calc_validation_statistics(validation_results):
+    """
+    Calculate summary statistics for the validation results and
+    return ``ExpectationStatistics``.
+    """
+    # calc stats
+    successful_expectations = sum(exp.success for exp in validation_results)
+    evaluated_expectations = len(validation_results)
+    unsuccessful_expectations = evaluated_expectations - successful_expectations
+    success = successful_expectations == evaluated_expectations
+    try:
+        success_percent = successful_expectations / evaluated_expectations * 100
+    except ZeroDivisionError:
+        # success_percent = float("nan")
+        success_percent = None
+
+    return ValidationStatistics(
+        successful_expectations=successful_expectations,
+        evaluated_expectations=evaluated_expectations,
+        unsuccessful_expectations=unsuccessful_expectations,
+        success=success,
+        success_percent=success_percent,
+    )
+
+
 class Validator:
     DEFAULT_RUNTIME_CONFIGURATION = {
         "include_config": True,
@@ -725,112 +762,6 @@ def resolve_validation_graph(
 
         return aborted_metrics_info
 
-    @staticmethod
-    def _parse_validation_graph(
-        validation_graph: ValidationGraph,
-        metrics: Dict[Tuple[str, str, str], Any],
-    ) -> Tuple[Set[MetricConfiguration], Set[MetricConfiguration]]:
-        """Given validation graph, returns the ready and needed metrics necessary for validation using a traversal of
-        validation graph (a graph structure of metric ids) edges"""
-        unmet_dependency_ids = set()
-        unmet_dependency = set()
-        maybe_ready_ids = set()
-        maybe_ready = set()
-
-        for edge in validation_graph.edges:
-            if edge.left.id not in metrics:
-                if edge.right is None or edge.right.id in metrics:
-                    if edge.left.id not in maybe_ready_ids:
-                        maybe_ready_ids.add(edge.left.id)
-                        maybe_ready.add(edge.left)
-                else:
-                    if edge.left.id not in unmet_dependency_ids:
-                        unmet_dependency_ids.add(edge.left.id)
-                        unmet_dependency.add(edge.left)
-
-        return maybe_ready - unmet_dependency, unmet_dependency
-
-    @staticmethod
-    def _resolve_metrics(
-        execution_engine: ExecutionEngine,
-        metrics_to_resolve: Iterable[MetricConfiguration],
-        metrics: Dict[Tuple[str, str, str], Any] = None,
-        runtime_configuration: dict = None,
-    ) -> Dict[Tuple[str, str, str], MetricConfiguration]:
-        """A means of accessing the Execution Engine's resolve_metrics method, where missing metric configurations are
-        resolved"""
-        return execution_engine.resolve_metrics(
-            metrics_to_resolve=metrics_to_resolve,
-            metrics=metrics,
-            runtime_configuration=runtime_configuration,
-        )
-
-    def _initialize_expectations(
-        self,
-        expectation_suite: ExpectationSuite = None,
-        expectation_suite_name: str = None,
-    ):
-        """Instantiates `_expectation_suite` as empty by default or with a specified expectation `config`.
-        In addition, this always sets the `default_expectation_args` to:
-            `include_config`: False,
-            `catch_exceptions`: False,
-            `output_format`: 'BASIC'
-
-        By default, initializes data_asset_type to the name of the implementing class, but subclasses
-        that have interoperable semantics (e.g. Dataset) may override that parameter to clarify their
-        interoperability.
-
-        Args:
-            expectation_suite (json): \
-                A json-serializable expectation config. \
-                If None, creates default `_expectation_suite` with an empty list of expectations and \
-                key value `data_asset_name` as `data_asset_name`.
-
-            expectation_suite_name (string): \
-                The name to assign to the `expectation_suite.expectation_suite_name`
-
-        Returns:
-            None
-        """
-        # Checking type of expectation_suite.
-        # Check for expectation_suite_name is already done by ExpectationSuiteIdentifier
-        if expectation_suite and not isinstance(expectation_suite, ExpectationSuite):
-            raise TypeError(
-                "expectation_suite must be of type ExpectationSuite, not {}".format(
-                    type(expectation_suite)
-                )
-            )
-        if expectation_suite is not None:
-            if isinstance(expectation_suite, dict):
-                expectation_suite = expectationSuiteSchema.load(expectation_suite)
-            else:
-                expectation_suite = copy.deepcopy(expectation_suite)
-            self._expectation_suite = expectation_suite
-
-            if expectation_suite_name is not None:
-                if (
-                    self._expectation_suite.expectation_suite_name
-                    != expectation_suite_name
-                ):
-                    logger.warning(
-                        "Overriding existing expectation_suite_name {n1} with new name {n2}".format(
-                            n1=self._expectation_suite.expectation_suite_name,
-                            n2=expectation_suite_name,
-                        )
-                    )
-                self._expectation_suite.expectation_suite_name = expectation_suite_name
-
-        else:
-            if expectation_suite_name is None:
-                expectation_suite_name = "default"
-            self._expectation_suite = ExpectationSuite(
-                expectation_suite_name=expectation_suite_name
-            )
-
-        self._expectation_suite.execution_engine_type = type(
-            self.execution_engine
-        ).__name__
-
     def append_expectation(self, expectation_config):
         """This method is a thin wrapper for ExpectationSuite.append_expectation"""
         warnings.warn(
@@ -1234,6 +1165,7 @@ def save_expectation_suite(
                 "Unable to save config: filepath or data_context must be available."
             )
 
+    # TODO: <Alex>Should "include_config" also be an argument of this method?</Alex>
     def validate(
         self,
         expectation_suite=None,
@@ -1447,13 +1379,9 @@ def validate(
             for col in columns:
                 expectations_to_evaluate.extend(columns[col])
 
-            runtime_configuration = copy.deepcopy(self.default_expectation_args)
-
-            if catch_exceptions is not None:
-                runtime_configuration.update({"catch_exceptions": catch_exceptions})
-
-            if result_format is not None:
-                runtime_configuration.update({"result_format": result_format})
+            runtime_configuration = self._get_runtime_configuration(
+                catch_exceptions=catch_exceptions, result_format=result_format
+            )
 
             results = self.graph_validate(
                 configurations=expectations_to_evaluate,
@@ -1657,42 +1585,135 @@ def head(
 
         return df.reset_index(drop=True, inplace=False)
 
+    @staticmethod
+    def _parse_validation_graph(
+        validation_graph: ValidationGraph,
+        metrics: Dict[Tuple[str, str, str], Any],
+    ) -> Tuple[Set[MetricConfiguration], Set[MetricConfiguration]]:
+        """Given validation graph, returns the ready and needed metrics necessary for validation using a traversal of
+        validation graph (a graph structure of metric ids) edges"""
+        unmet_dependency_ids = set()
+        unmet_dependency = set()
+        maybe_ready_ids = set()
+        maybe_ready = set()
 
-ValidationStatistics = namedtuple(
-    "ValidationStatistics",
-    [
-        "evaluated_expectations",
-        "successful_expectations",
-        "unsuccessful_expectations",
-        "success_percent",
-        "success",
-    ],
-)
+        for edge in validation_graph.edges:
+            if edge.left.id not in metrics:
+                if edge.right is None or edge.right.id in metrics:
+                    if edge.left.id not in maybe_ready_ids:
+                        maybe_ready_ids.add(edge.left.id)
+                        maybe_ready.add(edge.left)
+                else:
+                    if edge.left.id not in unmet_dependency_ids:
+                        unmet_dependency_ids.add(edge.left.id)
+                        unmet_dependency.add(edge.left)
 
+        return maybe_ready - unmet_dependency, unmet_dependency
 
-def _calc_validation_statistics(validation_results):
-    """
-    Calculate summary statistics for the validation results and
-    return ``ExpectationStatistics``.
-    """
-    # calc stats
-    successful_expectations = sum(exp.success for exp in validation_results)
-    evaluated_expectations = len(validation_results)
-    unsuccessful_expectations = evaluated_expectations - successful_expectations
-    success = successful_expectations == evaluated_expectations
-    try:
-        success_percent = successful_expectations / evaluated_expectations * 100
-    except ZeroDivisionError:
-        # success_percent = float("nan")
-        success_percent = None
+    @staticmethod
+    def _resolve_metrics(
+        execution_engine: ExecutionEngine,
+        metrics_to_resolve: Iterable[MetricConfiguration],
+        metrics: Dict[Tuple[str, str, str], Any] = None,
+        runtime_configuration: dict = None,
+    ) -> Dict[Tuple[str, str, str], MetricConfiguration]:
+        """A means of accessing the Execution Engine's resolve_metrics method, where missing metric configurations are
+        resolved"""
+        return execution_engine.resolve_metrics(
+            metrics_to_resolve=metrics_to_resolve,
+            metrics=metrics,
+            runtime_configuration=runtime_configuration,
+        )
 
-    return ValidationStatistics(
-        successful_expectations=successful_expectations,
-        evaluated_expectations=evaluated_expectations,
-        unsuccessful_expectations=unsuccessful_expectations,
-        success=success,
-        success_percent=success_percent,
-    )
+    def _initialize_expectations(
+        self,
+        expectation_suite: ExpectationSuite = None,
+        expectation_suite_name: str = None,
+    ):
+        """Instantiates `_expectation_suite` as empty by default or with a specified expectation `config`.
+        In addition, this always sets the `default_expectation_args` to:
+            `include_config`: False,
+            `catch_exceptions`: False,
+            `output_format`: 'BASIC'
+
+        By default, initializes data_asset_type to the name of the implementing class, but subclasses
+        that have interoperable semantics (e.g. Dataset) may override that parameter to clarify their
+        interoperability.
+
+        Args:
+            expectation_suite (json): \
+                A json-serializable expectation config. \
+                If None, creates default `_expectation_suite` with an empty list of expectations and \
+                key value `data_asset_name` as `data_asset_name`.
+
+            expectation_suite_name (string): \
+                The name to assign to the `expectation_suite.expectation_suite_name`
+
+        Returns:
+            None
+        """
+        # Checking type of expectation_suite.
+        # Check for expectation_suite_name is already done by ExpectationSuiteIdentifier
+        if expectation_suite and not isinstance(expectation_suite, ExpectationSuite):
+            raise TypeError(
+                "expectation_suite must be of type ExpectationSuite, not {}".format(
+                    type(expectation_suite)
+                )
+            )
+        if expectation_suite is not None:
+            if isinstance(expectation_suite, dict):
+                expectation_suite = expectationSuiteSchema.load(expectation_suite)
+            else:
+                expectation_suite = copy.deepcopy(expectation_suite)
+            self._expectation_suite = expectation_suite
+
+            if expectation_suite_name is not None:
+                if (
+                    self._expectation_suite.expectation_suite_name
+                    != expectation_suite_name
+                ):
+                    logger.warning(
+                        "Overriding existing expectation_suite_name {n1} with new name {n2}".format(
+                            n1=self._expectation_suite.expectation_suite_name,
+                            n2=expectation_suite_name,
+                        )
+                    )
+                self._expectation_suite.expectation_suite_name = expectation_suite_name
+
+        else:
+            if expectation_suite_name is None:
+                expectation_suite_name = "default"
+            self._expectation_suite = ExpectationSuite(
+                expectation_suite_name=expectation_suite_name
+            )
+
+        self._expectation_suite.execution_engine_type = type(
+            self.execution_engine
+        ).__name__
+
+    def _get_runtime_configuration(
+        self,
+        catch_exceptions: Optional[bool] = None,
+        result_format: Optional[Union[dict, str]] = None,
+    ) -> dict:
+        runtime_configuration = copy.deepcopy(self.default_expectation_args)
+
+        if catch_exceptions is not None:
+            runtime_configuration.update({"catch_exceptions": catch_exceptions})
+
+        if (
+            self.default_expectation_args["result_format"]
+            == Validator.DEFAULT_RUNTIME_CONFIGURATION["result_format"]
+        ):
+            if result_format is None:
+                runtime_configuration.pop("result_format")
+            else:
+                runtime_configuration.update({"result_format": result_format})
+        else:
+            if result_format is not None:
+                runtime_configuration.update({"result_format": result_format})
+
+        return runtime_configuration
 
 
 class BridgeValidator:


Test patch:
diff --git a/tests/expectations/test_expectation_arguments.py b/tests/expectations/test_expectation_arguments.py
--- a/tests/expectations/test_expectation_arguments.py
+++ b/tests/expectations/test_expectation_arguments.py
@@ -102,7 +102,9 @@ def test_spark_df(test_pandas_df, spark_session):
 
 def test_catch_exceptions_no_exceptions(in_memory_runtime_context, test_spark_df):
     catch_exceptions: bool = False  # expect exceptions to be raised
-    result_format: str = "SUMMARY"
+    result_format: dict = {
+        "result_format": "SUMMARY",
+    }
     runtime_environment_arguments = {
         "catch_exceptions": catch_exceptions,
         "result_format": result_format,
@@ -208,7 +210,9 @@ def test_catch_exceptions_exception_occurred_catch_exceptions_false(
     in_memory_runtime_context, test_spark_df
 ):
     catch_exceptions: bool = False  # expect exceptions to be raised
-    result_format: str = "SUMMARY"
+    result_format: dict = {
+        "result_format": "SUMMARY",
+    }
     runtime_environment_arguments = {
         "catch_exceptions": catch_exceptions,
         "result_format": result_format,
@@ -317,7 +321,9 @@ def test_catch_exceptions_exception_occurred_catch_exceptions_true(
     in_memory_runtime_context, test_spark_df
 ):
     catch_exceptions: bool = True  # expect exceptions to be caught
-    result_format: str = "SUMMARY"
+    result_format: dict = {
+        "result_format": "SUMMARY",
+    }
     runtime_environment_arguments = {
         "catch_exceptions": catch_exceptions,
         "result_format": result_format,
@@ -458,13 +464,19 @@ def test_result_format_configured_no_set_default_override(
     in_memory_runtime_context, test_spark_df
 ):
     catch_exceptions: bool = False  # expect exceptions to be raised
-    result_format: str = "SUMMARY"
-    runtime_environment_arguments = {
+    result_format: dict
+
+    result_format = {
+        "result_format": "SUMMARY",
+    }
+    runtime_environment_arguments: dict = {
         "catch_exceptions": catch_exceptions,
         "result_format": result_format,
     }
 
-    suite: ExpectationSuite = in_memory_runtime_context.create_expectation_suite(
+    suite: ExpectationSuite
+
+    suite = in_memory_runtime_context.create_expectation_suite(
         "test_suite", overwrite_existing=True
     )
 
@@ -499,23 +511,138 @@ def test_result_format_configured_no_set_default_override(
         },
     )
 
-    validator: Validator = in_memory_runtime_context.get_validator(
+    validator: Validator
+
+    validator = in_memory_runtime_context.get_validator(
         batch_request=runtime_batch_request,
         expectation_suite=suite,
     )
 
     # Test calling "validator.validate()" explicitly.
 
-    validator_validation: ExpectationSuiteValidationResult = validator.validate(
-        **runtime_environment_arguments
-    )
-    results: List[ExpectationValidationResult] = validator_validation.results
+    validator_validation: ExpectationSuiteValidationResult
+
+    validator_validation = validator.validate(**runtime_environment_arguments)
+
+    results: List[ExpectationValidationResult]
+
+    results = validator_validation.results
     assert len(results) == 1
 
     result: ExpectationValidationResult
 
     result = results[0]
+    assert result.success
     assert len(result.result.keys()) > 0
+    assert result.result == {
+        "element_count": 4,
+        "unexpected_count": 0,
+        "unexpected_percent": 0.0,
+        "partial_unexpected_list": [],
+        "partial_unexpected_index_list": None,
+        "partial_unexpected_counts": [],
+    }
+
+    result_format = {
+        "result_format": "BASIC",
+    }
+    runtime_environment_arguments: dict = {
+        "catch_exceptions": catch_exceptions,
+        "result_format": result_format,
+    }
+
+    suite = in_memory_runtime_context.create_expectation_suite(
+        "test_suite", overwrite_existing=True
+    )
+
+    expectation_arguments_without_meta = dict(
+        **runtime_environment_arguments, **expectation_arguments_column
+    )
+    expectation_configuration = ExpectationConfiguration(
+        expectation_type="expect_column_values_to_not_be_null",
+        kwargs=expectation_arguments_without_meta,
+        meta=expectation_meta,
+    )
+    suite.add_expectation(expectation_configuration=expectation_configuration)
+
+    validator = in_memory_runtime_context.get_validator(
+        batch_request=runtime_batch_request,
+        expectation_suite=suite,
+    )
+
+    validator_validation = validator.validate(**runtime_environment_arguments)
+
+    results = validator_validation.results
+    assert len(results) == 1
+
+    result = results[0]
+    assert result.success
+    assert len(result.result.keys()) > 0
+    assert result.result == {
+        "element_count": 4,
+        "unexpected_count": 0,
+        "unexpected_percent": 0.0,
+        "partial_unexpected_list": [],
+    }
+
+    result_format = {
+        "result_format": "BOOLEAN_ONLY",
+    }
+    runtime_environment_arguments: dict = {
+        "catch_exceptions": catch_exceptions,
+        "result_format": result_format,
+    }
+
+    suite = in_memory_runtime_context.create_expectation_suite(
+        "test_suite", overwrite_existing=True
+    )
+
+    expectation_arguments_without_meta = dict(
+        **runtime_environment_arguments, **expectation_arguments_column
+    )
+    expectation_configuration = ExpectationConfiguration(
+        expectation_type="expect_column_values_to_not_be_null",
+        kwargs=expectation_arguments_without_meta,
+        meta=expectation_meta,
+    )
+    suite.add_expectation(expectation_configuration=expectation_configuration)
+
+    validator = in_memory_runtime_context.get_validator(
+        batch_request=runtime_batch_request,
+        expectation_suite=suite,
+    )
+
+    validator_validation = validator.validate(**runtime_environment_arguments)
+
+    results = validator_validation.results
+    assert len(results) == 1
+
+    result = results[0]
+    assert result.success
+    assert result.to_json_dict() == {
+        "expectation_config": {
+            "kwargs": {
+                "catch_exceptions": False,
+                "result_format": {"result_format": "BOOLEAN_ONLY"},
+                "include_config": True,
+                "column": "Name",
+                "batch_id": "bd7b9290f981fde37aabd403e8a507ea",
+            },
+            "expectation_type": "expect_column_values_to_not_be_null",
+            "meta": {"Notes": "Some notes"},
+            "ge_cloud_id": None,
+        },
+        "meta": {},
+        "exception_info": {
+            "raised_exception": False,
+            "exception_traceback": None,
+            "exception_message": None,
+        },
+        "result": {},
+        "success": True,
+    }
+    assert len(result.result.keys()) == 0
+    assert result.result == {}
 
     # Test calling "validator.expect_*" through "validator.validate_expectation()".
 
@@ -525,20 +652,54 @@ def test_result_format_configured_no_set_default_override(
         **expectation_arguments_without_meta, **expectation_meta
     )
     result = validator.expect_column_values_to_not_be_null(**expectation_parameters)
-    assert len(result.result.keys()) > 0
+    assert result.success
+    assert result.to_json_dict() == {
+        "success": True,
+        "meta": {},
+        "expectation_config": {
+            "ge_cloud_id": None,
+            "expectation_type": "expect_column_values_to_not_be_null",
+            "meta": {},
+            "kwargs": {
+                "catch_exceptions": False,
+                "result_format": {
+                    "result_format": "BOOLEAN_ONLY",
+                    "partial_unexpected_count": 20,
+                },
+                "include_config": True,
+                "column": "Name",
+                "Notes": "Some notes",
+                "batch_id": "bd7b9290f981fde37aabd403e8a507ea",
+            },
+        },
+        "result": {},
+        "exception_info": {
+            "raised_exception": False,
+            "exception_traceback": None,
+            "exception_message": None,
+        },
+    }
+    assert len(result.result.keys()) == 0
+    assert result.result == {}
 
 
 def test_result_format_configured_with_set_default_override(
     in_memory_runtime_context, test_spark_df
 ):
     catch_exceptions: bool = False  # expect exceptions to be raised
-    result_format: str = "SUMMARY"
-    runtime_environment_arguments = {
+    result_format: dict
+
+    result_format = {
+        "result_format": "SUMMARY",
+    }
+    runtime_environment_arguments: dict = {
         "catch_exceptions": catch_exceptions,
         "result_format": result_format,
     }
 
-    suite: ExpectationSuite = in_memory_runtime_context.create_expectation_suite(
+    suite: ExpectationSuite
+
+    suite = in_memory_runtime_context.create_expectation_suite(
         "test_suite", overwrite_existing=True
     )
 
@@ -573,7 +734,9 @@ def test_result_format_configured_with_set_default_override(
         },
     )
 
-    validator: Validator = in_memory_runtime_context.get_validator(
+    validator: Validator
+
+    validator = in_memory_runtime_context.get_validator(
         batch_request=runtime_batch_request,
         expectation_suite=suite,
     )
@@ -582,12 +745,78 @@ def test_result_format_configured_with_set_default_override(
 
     # Test calling "validator.validate()" explicitly.
 
-    validator_validation: ExpectationSuiteValidationResult = validator.validate()
-    results: List[ExpectationValidationResult] = validator_validation.results
+    validator_validation: ExpectationSuiteValidationResult
+
+    validator_validation = validator.validate()
+
+    results: List[ExpectationValidationResult]
+
+    results = validator_validation.results
     assert len(results) == 1
 
     result: ExpectationValidationResult
 
+    result = results[0]
+    assert result.success
+    assert result.to_json_dict() == {
+        "result": {},
+        "expectation_config": {
+            "ge_cloud_id": None,
+            "kwargs": {
+                "catch_exceptions": False,
+                "result_format": {"result_format": "SUMMARY"},
+                "include_config": True,
+                "column": "Name",
+                "batch_id": "bd7b9290f981fde37aabd403e8a507ea",
+            },
+            "meta": {"Notes": "Some notes"},
+            "expectation_type": "expect_column_values_to_not_be_null",
+        },
+        "success": True,
+        "meta": {},
+        "exception_info": {
+            "raised_exception": False,
+            "exception_traceback": None,
+            "exception_message": None,
+        },
+    }
+    assert len(result.result.keys()) == 0
+    assert result.result == {}
+
+    result_format = {
+        "result_format": "BASIC",
+    }
+    runtime_environment_arguments: dict = {
+        "catch_exceptions": catch_exceptions,
+        "result_format": result_format,
+    }
+
+    suite = in_memory_runtime_context.create_expectation_suite(
+        "test_suite", overwrite_existing=True
+    )
+
+    expectation_arguments_without_meta = dict(
+        **runtime_environment_arguments, **expectation_arguments_column
+    )
+    expectation_configuration = ExpectationConfiguration(
+        expectation_type="expect_column_values_to_not_be_null",
+        kwargs=expectation_arguments_without_meta,
+        meta=expectation_meta,
+    )
+    suite.add_expectation(expectation_configuration=expectation_configuration)
+
+    validator = in_memory_runtime_context.get_validator(
+        batch_request=runtime_batch_request,
+        expectation_suite=suite,
+    )
+
+    validator.set_default_expectation_argument("result_format", "BOOLEAN_ONLY")
+
+    validator_validation = validator.validate()
+
+    results = validator_validation.results
+    assert len(results) == 1
+
     result = results[0]
     assert len(result.result.keys()) == 0
 
@@ -597,4 +826,27 @@ def test_result_format_configured_with_set_default_override(
 
     expectation_parameters = dict(**expectation_arguments_column, **expectation_meta)
     result = validator.expect_column_values_to_not_be_null(**expectation_parameters)
+    assert result.success
+    assert result.to_json_dict() == {
+        "result": {},
+        "expectation_config": {
+            "ge_cloud_id": None,
+            "kwargs": {
+                "include_config": True,
+                "column": "Name",
+                "Notes": "Some notes",
+                "batch_id": "bd7b9290f981fde37aabd403e8a507ea",
+            },
+            "meta": {},
+            "expectation_type": "expect_column_values_to_not_be_null",
+        },
+        "success": True,
+        "meta": {},
+        "exception_info": {
+            "raised_exception": False,
+            "exception_traceback": None,
+            "exception_message": None,
+        },
+    }
     assert len(result.result.keys()) == 0
+    assert result.result == {}