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/expectation_configuration.py b/great_expectations/core/expectation_configuration.py
--- a/great_expectations/core/expectation_configuration.py
+++ b/great_expectations/core/expectation_configuration.py
@@ -1388,6 +1388,7 @@ def validate(
         runtime_configuration=None,
     ):
         expectation_impl: Expectation = self._get_expectation_impl()
+        # noinspection PyCallingNonCallable
         return expectation_impl(self).validate(
             validator=validator,
             runtime_configuration=runtime_configuration,
@@ -1401,6 +1402,7 @@ def metrics_validate(
         **kwargs: dict,
     ):
         expectation_impl: Expectation = self._get_expectation_impl()
+        # noinspection PyCallingNonCallable
         return expectation_impl(self).metrics_validate(
             metrics=metrics,
             runtime_configuration=runtime_configuration,
diff --git a/great_expectations/validator/validation_graph.py b/great_expectations/validator/validation_graph.py
--- a/great_expectations/validator/validation_graph.py
+++ b/great_expectations/validator/validation_graph.py
@@ -365,11 +365,21 @@ def __repr__(self):
 class ExpectationValidationGraph:
     def __init__(
         self,
-        execution_engine: ExecutionEngine,
         configuration: ExpectationConfiguration,
+        graph: ValidationGraph,
     ) -> None:
+        if configuration is None:
+            raise ValueError(
+                """Instantiation of "ExpectationValidationGraph" requires valid "ExpectationConfiguration" object."""
+            )
+
+        if graph is None:
+            raise ValueError(
+                """Instantiation of "ExpectationValidationGraph" requires valid "ValidationGraph" object."""
+            )
+
         self._configuration = configuration
-        self._graph = ValidationGraph(execution_engine=execution_engine)
+        self._graph = graph
 
     @property
     def configuration(self) -> ExpectationConfiguration:
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
@@ -1110,22 +1110,13 @@ def _generate_metric_dependency_subgraphs_for_each_expectation_configuration(
             )
 
             try:
-                expectation_validation_graph: ExpectationValidationGraph = (
-                    ExpectationValidationGraph(
-                        execution_engine=self._execution_engine,
-                        configuration=evaluated_config,
-                    )
-                )
-                for (
-                    metric_configuration
-                ) in validation_dependencies.get_metric_configurations():
-                    graph = ValidationGraph(execution_engine=self._execution_engine)
-                    graph.build_metric_dependency_graph(
-                        metric_configuration=metric_configuration,
+                expectation_validation_graph: ExpectationValidationGraph = ExpectationValidationGraph(
+                    configuration=evaluated_config,
+                    graph=self.metrics_calculator.build_metric_dependency_graph(
+                        metric_configurations=validation_dependencies.get_metric_configurations(),
                         runtime_configuration=runtime_configuration,
-                    )
-                    expectation_validation_graph.update(graph=graph)
-
+                    ),
+                )
                 expectation_validation_graphs.append(expectation_validation_graph)
                 processed_configurations.append(evaluated_config)
             except Exception as err:


Test patch:
diff --git a/tests/validator/test_validation_graph.py b/tests/validator/test_validation_graph.py
--- a/tests/validator/test_validation_graph.py
+++ b/tests/validator/test_validation_graph.py
@@ -30,6 +30,16 @@ def metric_edge(
     )
 
 
+@pytest.fixture
+def validation_graph_with_no_edges() -> ValidationGraph:
+    class DummyExecutionEngine:
+        pass
+
+    execution_engine = cast(ExecutionEngine, DummyExecutionEngine)
+
+    return ValidationGraph(execution_engine=execution_engine, edges=None)
+
+
 @pytest.fixture
 def validation_graph_with_single_edge(metric_edge: MetricEdge) -> ValidationGraph:
     class DummyExecutionEngine:
@@ -65,15 +75,11 @@ def expect_column_value_z_scores_to_be_less_than_expectation_config() -> Expecta
 @pytest.fixture
 def expect_column_values_to_be_unique_expectation_validation_graph(
     expect_column_values_to_be_unique_expectation_config: ExpectationConfiguration,
+    validation_graph_with_no_edges: ValidationGraph,
 ) -> ExpectationValidationGraph:
-    class DummyExecutionEngine:
-        pass
-
-    execution_engine = cast(ExecutionEngine, DummyExecutionEngine)
-
     return ExpectationValidationGraph(
-        execution_engine=execution_engine,
         configuration=expect_column_values_to_be_unique_expectation_config,
+        graph=validation_graph_with_no_edges,
     )
 
 
@@ -112,6 +118,7 @@ class PandasExecutionEngineStub:
     return graph
 
 
+# noinspection PyPep8Naming
 @pytest.mark.unit
 def test_ValidationGraph_init_no_input_edges() -> None:
     class DummyExecutionEngine:
@@ -159,10 +166,43 @@ class DummyExecutionEngine:
     assert metric_edge.id in graph.edge_ids
 
 
+def test_ExpectationValidationGraph_constructor(
+    expect_column_values_to_be_unique_expectation_config: ExpectationConfiguration,
+    validation_graph_with_no_edges: ValidationGraph,
+):
+    with pytest.raises(ValueError) as ve:
+        # noinspection PyUnusedLocal,PyTypeChecker
+        expectation_validation_graph = ExpectationValidationGraph(
+            configuration=None,
+            graph=None,
+        )
+
+    assert ve.value.args == (
+        'Instantiation of "ExpectationValidationGraph" requires valid "ExpectationConfiguration" object.',
+    )
+
+    with pytest.raises(ValueError) as ve:
+        # noinspection PyUnusedLocal,PyTypeChecker
+        expectation_validation_graph = ExpectationValidationGraph(
+            configuration=expect_column_values_to_be_unique_expectation_config,
+            graph=None,
+        )
+
+    assert ve.value.args == (
+        'Instantiation of "ExpectationValidationGraph" requires valid "ValidationGraph" object.',
+    )
+
+    expectation_validation_graph = ExpectationValidationGraph(
+        configuration=expect_column_values_to_be_unique_expectation_config,
+        graph=validation_graph_with_no_edges,
+    )
+    assert len(expectation_validation_graph.graph.edges) == 0
+
+
 @pytest.mark.unit
 def test_ExpectationValidationGraph_update(
-    expect_column_values_to_be_unique_expectation_validation_graph: ExpectationValidationGraph,
     validation_graph_with_single_edge: ValidationGraph,
+    expect_column_values_to_be_unique_expectation_validation_graph: ExpectationValidationGraph,
 ) -> None:
     assert (
         len(expect_column_values_to_be_unique_expectation_validation_graph.graph.edges)
diff --git a/tests/validator/test_validator.py b/tests/validator/test_validator.py
--- a/tests/validator/test_validator.py
+++ b/tests/validator/test_validator.py
@@ -406,6 +406,7 @@ def test_validator_with_bad_batchrequest(
         data_connector_query={"batch_filter_parameters": {"year": "2019"}},
     )
     with pytest.raises(ge_exceptions.InvalidBatchRequestError):
+        # noinspection PyUnusedLocal
         validator_multi_batch: Validator = context.get_validator(
             batch_request=multi_batch_request, expectation_suite=suite
         )