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
@@ -12,6 +12,7 @@
     build_evaluation_parameters,
     find_evaluation_parameter_dependencies,
 )
+from great_expectations.core.metric_domain_types import MetricDomainTypes
 from great_expectations.core.urn import ge_urn
 from great_expectations.core.util import (
     convert_to_json_serializable,
@@ -1402,6 +1403,22 @@ def metrics_validate(
             execution_engine=execution_engine,
         )
 
+    def get_domain_type(self) -> Optional[MetricDomainTypes]:
+        """Return "domain_type" of this expectation."""
+        if self.expectation_type.startswith("expect_table_"):
+            return MetricDomainTypes.TABLE
+
+        if "column" in self.kwargs:
+            return MetricDomainTypes.COLUMN
+
+        if "column_A" in self.kwargs and "column_B" in self.kwargs:
+            return MetricDomainTypes.COLUMN_PAIR
+
+        if "column_list" in self.kwargs:
+            return MetricDomainTypes.MULTICOLUMN
+
+        return None
+
 
 class ExpectationConfigurationSchema(Schema):
     expectation_type = fields.Str(
diff --git a/great_expectations/core/expectation_suite.py b/great_expectations/core/expectation_suite.py
--- a/great_expectations/core/expectation_suite.py
+++ b/great_expectations/core/expectation_suite.py
@@ -1,6 +1,7 @@
 import datetime
 import json
 import logging
+import pprint
 import uuid
 from copy import deepcopy
 from typing import Any, Callable, Dict, List, Optional, Tuple, Union
@@ -35,6 +36,7 @@
     pre_dump,
 )
 from great_expectations.types import SerializableDictDot
+from great_expectations.util import deep_filter_properties_iterable
 
 logger = logging.getLogger(__name__)
 
@@ -254,6 +256,7 @@ def _filter_citations(
         for citation in citations:
             if filter_key in citation and citation.get(filter_key):
                 citations_with_bk.append(citation)
+
         return citations_with_bk
 
     @staticmethod
@@ -669,29 +672,204 @@ def add_expectation(
             overwrite_existing=overwrite_existing,
         )
 
+    def show_expectations_by_domain_type(self) -> None:
+        """
+        Displays "ExpectationConfiguration" list, grouped by "domain_type", in predetermined designated order.
+        """
+        expectation_configurations_by_domain: Dict[
+            str, List[ExpectationConfiguration]
+        ] = self.get_grouped_and_ordered_expectations_by_domain_type()
+
+        domain_type: str
+        expectation_configurations: List[ExpectationConfiguration]
+        for (
+            domain_type,
+            expectation_configurations,
+        ) in expectation_configurations_by_domain.items():
+            pprint.pprint(object=MetricDomainTypes(domain_type).value.capitalize())
+            self.show_expectations_by_expectation_type(
+                expectation_configurations=expectation_configurations
+            )
+
+    def show_expectations_by_expectation_type(
+        self,
+        expectation_configurations: Optional[List[ExpectationConfiguration]] = None,
+    ) -> None:
+        """
+        Displays "ExpectationConfiguration" list, grouped by "expectation_type", in predetermined designated order.
+        """
+        if expectation_configurations is None:
+            expectation_configurations = (
+                self.get_grouped_and_ordered_expectations_by_expectation_type()
+            )
+
+        expectation_configuration: ExpectationConfiguration
+        domain_type: MetricDomainTypes
+        kwargs: dict
+        for expectation_configuration in expectation_configurations:
+            domain_type = expectation_configuration.get_domain_type()
+            kwargs = expectation_configuration.kwargs
+            pprint.pprint(
+                object={
+                    expectation_configuration.expectation_type: {
+                        "domain": domain_type.value,
+                        **kwargs,
+                    }
+                },
+                indent=2,
+                sort_dicts=False,
+            )
+
+    def get_grouped_and_ordered_expectations_by_domain_type(
+        self,
+    ) -> Dict[str, List[ExpectationConfiguration]]:
+        """
+        Returns "ExpectationConfiguration" list in predetermined order by passing appropriate methods for retrieving
+        "ExpectationConfiguration" lists by corresponding "domain_type" (with "table" first; then "column", and so on).
+        """
+        expectation_configurations_by_domain: Dict[
+            str, List[ExpectationConfiguration]
+        ] = self._get_expectations_by_domain_using_accessor_method(
+            domain_type=MetricDomainTypes.TABLE.value,
+            accessor_method=self.get_table_expectations,
+        )
+        expectation_configurations_by_domain.update(
+            self._get_expectations_by_domain_using_accessor_method(
+                domain_type=MetricDomainTypes.COLUMN.value,
+                accessor_method=self.get_column_expectations,
+            )
+        )
+        expectation_configurations_by_domain.update(
+            self._get_expectations_by_domain_using_accessor_method(
+                domain_type=MetricDomainTypes.COLUMN_PAIR.value,
+                accessor_method=self.get_column_pair_expectations,
+            )
+        )
+        expectation_configurations_by_domain.update(
+            self._get_expectations_by_domain_using_accessor_method(
+                domain_type=MetricDomainTypes.MULTICOLUMN.value,
+                accessor_method=self.get_multicolumn_expectations,
+            )
+        )
+        return expectation_configurations_by_domain
+
+    def get_grouped_and_ordered_expectations_by_expectation_type(
+        self,
+    ) -> List[ExpectationConfiguration]:
+        """
+        Returns "ExpectationConfiguration" list, grouped by "expectation_type", in predetermined designated order.
+        """
+        table_expectation_configurations: List[ExpectationConfiguration] = sorted(
+            self.get_table_expectations(),
+            key=lambda element: element["expectation_type"],
+        )
+        column_expectation_configurations: List[ExpectationConfiguration] = sorted(
+            self.get_column_expectations(),
+            key=lambda element: element["expectation_type"],
+        )
+        column_pair_expectation_configurations: List[ExpectationConfiguration] = sorted(
+            self.get_column_pair_expectations(),
+            key=lambda element: element["expectation_type"],
+        )
+        multicolumn_expectation_configurations: List[ExpectationConfiguration] = sorted(
+            self.get_multicolumn_expectations(),
+            key=lambda element: element["expectation_type"],
+        )
+        return (
+            table_expectation_configurations
+            + column_expectation_configurations
+            + column_pair_expectation_configurations
+            + multicolumn_expectation_configurations
+        )
+
     def get_table_expectations(self) -> List[ExpectationConfiguration]:
         """Return a list of table expectations."""
-        return [
-            e
-            for e in self.expectations
-            if e.expectation_type.startswith("expect_table_")
-        ]
+        expectation_configurations: List[ExpectationConfiguration] = list(
+            filter(
+                lambda element: element.get_domain_type() == MetricDomainTypes.TABLE,
+                self.expectations,
+            )
+        )
+
+        expectation_configuration: ExpectationConfiguration
+        for expectation_configuration in expectation_configurations:
+            expectation_configuration.kwargs = deep_filter_properties_iterable(
+                properties=expectation_configuration.kwargs, clean_falsy=True
+            )
+
+        return expectation_configurations
 
     def get_column_expectations(self) -> List[ExpectationConfiguration]:
         """Return a list of column map expectations."""
-        return [e for e in self.expectations if "column" in e.kwargs]
+        expectation_configurations: List[ExpectationConfiguration] = list(
+            filter(
+                lambda element: element.get_domain_type() == MetricDomainTypes.COLUMN,
+                self.expectations,
+            )
+        )
 
+        expectation_configuration: ExpectationConfiguration
+        kwargs: dict
+        column_name: str
+        for expectation_configuration in expectation_configurations:
+            kwargs = deep_filter_properties_iterable(
+                properties=expectation_configuration.kwargs, clean_falsy=True
+            )
+            column_name = kwargs.pop("column")
+            expectation_configuration.kwargs = {"column": column_name, **kwargs}
+
+        return expectation_configurations
+
+    # noinspection PyPep8Naming
     def get_column_pair_expectations(self) -> List[ExpectationConfiguration]:
         """Return a list of column_pair map expectations."""
-        return [
-            e
-            for e in self.expectations
-            if "column_A" in e.kwargs and "column_B" in e.kwargs
-        ]
+        expectation_configurations: List[ExpectationConfiguration] = list(
+            filter(
+                lambda element: element.get_domain_type()
+                == MetricDomainTypes.COLUMN_PAIR,
+                self.expectations,
+            )
+        )
+
+        expectation_configuration: ExpectationConfiguration
+        kwargs: dict
+        column_A_name: str
+        column_B_name: str
+        for expectation_configuration in expectation_configurations:
+            kwargs = deep_filter_properties_iterable(
+                properties=expectation_configuration.kwargs, clean_falsy=True
+            )
+            column_A_name = kwargs.pop("column_A")
+            column_B_name = kwargs.pop("column_B")
+            expectation_configuration.kwargs = {
+                "column_A": column_A_name,
+                "column_B": column_B_name,
+                **kwargs,
+            }
+
+        return expectation_configurations
 
     def get_multicolumn_expectations(self) -> List[ExpectationConfiguration]:
         """Return a list of multicolumn map expectations."""
-        return [e for e in self.expectations if "column_list" in e.kwargs]
+        expectation_configurations: List[ExpectationConfiguration] = list(
+            filter(
+                lambda element: element.get_domain_type()
+                == MetricDomainTypes.MULTICOLUMN,
+                self.expectations,
+            )
+        )
+
+        expectation_configuration: ExpectationConfiguration
+        kwargs: dict
+        column_list: str
+        for expectation_configuration in expectation_configurations:
+            kwargs = deep_filter_properties_iterable(
+                properties=expectation_configuration.kwargs, clean_falsy=True
+            )
+            column_list = kwargs.pop("column_list")
+            expectation_configuration.kwargs = {"column_list": column_list, **kwargs}
+
+        return expectation_configurations
 
     def get_grouped_and_ordered_expectations_by_column(
         self, expectation_type_filter: Optional[str] = None
@@ -735,68 +913,6 @@ def get_grouped_and_ordered_expectations_by_column(
 
         return expectations_by_column, sorted_columns
 
-    def get_grouped_and_ordered_expectations_by_expectation_type(
-        self,
-    ) -> List[ExpectationConfiguration]:
-        """
-        Returns "ExpectationConfiguration" list, grouped by "expectation_type", in predetermined designated order.
-        """
-        table_expectation_configurations: List[ExpectationConfiguration] = sorted(
-            self.get_table_expectations(),
-            key=lambda element: element["expectation_type"],
-        )
-        column_expectation_configurations: List[ExpectationConfiguration] = sorted(
-            self.get_column_expectations(),
-            key=lambda element: element["expectation_type"],
-        )
-        column_pair_expectation_configurations: List[ExpectationConfiguration] = sorted(
-            self.get_column_pair_expectations(),
-            key=lambda element: element["expectation_type"],
-        )
-        multicolumn_expectation_configurations: List[ExpectationConfiguration] = sorted(
-            self.get_multicolumn_expectations(),
-            key=lambda element: element["expectation_type"],
-        )
-        return (
-            table_expectation_configurations
-            + column_expectation_configurations
-            + column_pair_expectation_configurations
-            + multicolumn_expectation_configurations
-        )
-
-    def get_grouped_and_ordered_expectations_by_domain_type(
-        self,
-    ) -> Dict[str, List[ExpectationConfiguration]]:
-        """
-        Returns "ExpectationConfiguration" list in predetermined order by passing appropriate methods for retrieving
-        "ExpectationConfiguration" lists by corresponding "domain_type" (with "table" first; then "column", and so on).
-        """
-        expectation_configurations_by_domain: Dict[
-            str, List[ExpectationConfiguration]
-        ] = self._get_expectations_by_domain_using_accessor_method(
-            domain_type=MetricDomainTypes.TABLE.value,
-            accessor_method=self.get_table_expectations,
-        )
-        expectation_configurations_by_domain.update(
-            self._get_expectations_by_domain_using_accessor_method(
-                domain_type=MetricDomainTypes.COLUMN.value,
-                accessor_method=self.get_column_expectations,
-            )
-        )
-        expectation_configurations_by_domain.update(
-            self._get_expectations_by_domain_using_accessor_method(
-                domain_type=MetricDomainTypes.COLUMN_PAIR.value,
-                accessor_method=self.get_column_pair_expectations,
-            )
-        )
-        expectation_configurations_by_domain.update(
-            self._get_expectations_by_domain_using_accessor_method(
-                domain_type=MetricDomainTypes.MULTICOLUMN.value,
-                accessor_method=self.get_multicolumn_expectations,
-            )
-        )
-        return expectation_configurations_by_domain
-
     @staticmethod
     def _get_expectations_by_domain_using_accessor_method(
         domain_type: str, accessor_method: Callable
diff --git a/great_expectations/util.py b/great_expectations/util.py
--- a/great_expectations/util.py
+++ b/great_expectations/util.py
@@ -34,10 +34,6 @@
 from packaging import version
 from pkg_resources import Distribution
 
-from great_expectations.core.expectation_suite import (
-    ExpectationSuite,
-    expectationSuiteSchema,
-)
 from great_expectations.exceptions import (
     PluginClassNotFoundError,
     PluginModuleNotFoundError,
@@ -886,6 +882,11 @@ def validate(
             expectation_suite_name=expectation_suite_name
         )
     else:
+        from great_expectations.core.expectation_suite import (
+            ExpectationSuite,
+            expectationSuiteSchema,
+        )
+
         if isinstance(expectation_suite, dict):
             expectation_suite_dict: dict = expectationSuiteSchema.load(
                 expectation_suite
@@ -1070,7 +1071,7 @@ def filter_properties_dict(
         delete_fields: list of keys that must be deleted, with the understanding that all other entries will be retained
         clean_nulls: If True, then in addition to other filtering directives, delete entries, whose values are None
         clean_falsy: If True, then in addition to other filtering directives, delete entries, whose values are Falsy
-        (If the "clean_falsy" argument is specified at "True", then "clean_nulls" is assumed to be "True" as well.)
+        (If the "clean_falsy" argument is specified as "True", then "clean_nulls" is assumed to be "True" as well.)
         inplace: If True, then modify the source properties dictionary; otherwise, make a copy for filtering purposes
         keep_falsy_numerics: If True, then in addition to other filtering directives, do not delete zero-valued numerics
 


Test patch: