Repository: great-expectations/great_expectations

Issue:
Rendering crashes for `expect_column_values_to_be_in_type_list` `type_list=None`
DescriptiveOverviewSectionRenderer._get_column_types crashes when one of the EVRs is:

```
{'success': True, 'result': {'observed_value': 'DATE'}, 'exception_info': {'raised_exception': False, 'exception_message': None, 'exception_traceback': None}, 'expectation_config': {'expectation_type': 'expect_column_values_to_be_in_type_list', 'kwargs': {'column': 'release_date', 'type_list': None, 'result_format': 'SUMMARY'}, 'meta': {'BasicDatasetProfiler': {'confidence': 'very low'}}}}
```


Discussion:
Previous error message was:
```
Traceback (most recent call last):
  File "/Users/talgluck/Documents/movie_db/venv/bin/great_expectations", line 11, in <module>
    load_entry_point('great-expectations', 'console_scripts', 'great_expectations')()
  File "/Users/talgluck/Documents/ge_main/great_expectations/great_expectations/cli/cli.py", line 300, in main
    cli()
  File "/Users/talgluck/Documents/movie_db/venv/lib/python3.6/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/Users/talgluck/Documents/movie_db/venv/lib/python3.6/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/Users/talgluck/Documents/movie_db/venv/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/talgluck/Documents/movie_db/venv/lib/python3.6/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/talgluck/Documents/movie_db/venv/lib/python3.6/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/Users/talgluck/Documents/ge_main/great_expectations/great_expectations/cli/cli.py", line 271, in documentation
    build_documentation(context)
  File "/Users/talgluck/Documents/ge_main/great_expectations/great_expectations/cli/datasource.py", line 311, in build_documentation
    context.render_full_static_site()
  File "/Users/talgluck/Documents/ge_main/great_expectations/great_expectations/data_context/data_context.py", line 1515, in render_full_static_site
    model = DescriptivePageRenderer.render(validation)
  File "/Users/talgluck/Documents/ge_main/great_expectations/great_expectations/render/renderer/page_renderer.py", line 116, in render
    column_types = DescriptiveOverviewSectionRenderer._get_column_types(validation_results)
  File "/Users/talgluck/Documents/ge_main/great_expectations/great_expectations/render/renderer/other_section_renderer.py", line 261, in _get_column_types
    expected_types = set(evr["expectation_config"]["kwargs"]["type_list"])
TypeError: 'NoneType' object is not iterable
```

Resolving patch:
diff --git a/great_expectations/render/renderer/content_block/bullet_list_content_block.py b/great_expectations/render/renderer/content_block/bullet_list_content_block.py
--- a/great_expectations/render/renderer/content_block/bullet_list_content_block.py
+++ b/great_expectations/render/renderer/content_block/bullet_list_content_block.py
@@ -445,7 +445,8 @@ def expect_column_values_to_be_in_type_list(cls, expectation, styling=None, incl
             expectation["kwargs"],
             ["column", "type_list", "mostly"],
         )
-        if params["type_list"] is not None:    
+
+        if params["type_list"] is not None:
             for i, v in enumerate(params["type_list"]):
                 params["v__"+str(i)] = v
             values_string = " ".join(


Test patch:
diff --git a/tests/render/test_render_BulletListContentBlock.py b/tests/render/test_render_BulletListContentBlock.py
--- a/tests/render/test_render_BulletListContentBlock.py
+++ b/tests/render/test_render_BulletListContentBlock.py
@@ -1,3 +1,9 @@
+import pytest
+import glob
+import json
+from string import Template as pTemplate
+
+
 from great_expectations.render.renderer.content_block import (
     PrescriptiveBulletListContentBlockRenderer,
 )
@@ -5,10 +11,6 @@
     substitute_none_for_missing,
 )
 
-import glob
-import json
-import pytest
-from string import Template as pTemplate
 from six import PY2
 
 def test_substitute_none_for_missing():
@@ -80,4 +82,4 @@ def test_all_expectations_using_test_definitions():
         return
     
     with open('./tests/render/output/test_render_bullet_list_content_block.json', 'w') as f:
-       json.dump(test_results, f, indent=2)
\ No newline at end of file
+       json.dump(test_results, f, indent=2)
diff --git a/tests/test_definitions/column_map_expectations/expect_column_values_to_be_in_type_list.json b/tests/test_definitions/column_map_expectations/expect_column_values_to_be_in_type_list.json
--- a/tests/test_definitions/column_map_expectations/expect_column_values_to_be_in_type_list.json
+++ b/tests/test_definitions/column_map_expectations/expect_column_values_to_be_in_type_list.json
@@ -3,16 +3,44 @@
   "datasets": [
     {
       "data": {
-        "x" : [1,2,4],
-        "y" : [1.0,2.2,5.3],
-        "z" : ["hello", "jello", "mello"],
-        "n" : [null, null, null],
-        "b" : [false, true, false],
-        "s" : ["hello", "jello", 1],
-        "s1" : ["hello", 2.0, 1]
+        "x": [
+          1,
+          2,
+          4
+        ],
+        "y": [
+          1.0,
+          2.2,
+          5.3
+        ],
+        "z": [
+          "hello",
+          "jello",
+          "mello"
+        ],
+        "n": [
+          null,
+          null,
+          null
+        ],
+        "b": [
+          false,
+          true,
+          false
+        ],
+        "s": [
+          "hello",
+          "jello",
+          1
+        ],
+        "s1": [
+          "hello",
+          2.0,
+          1
+        ]
       },
       "schemas": {
-        "pandas" : {
+        "pandas": {
           "x": "int",
           "y": "float",
           "z": "str",
@@ -62,223 +90,313 @@
         {
           "title": "positive_test_pandas_integer_column",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "x",
-            "type_list": ["int"]
+            "type_list": [
+              "int"
+            ]
           },
-          "out":{
-            "success":true
+          "out": {
+            "success": true
           },
-          "only_for": ["pandas"]
+          "only_for": [
+            "pandas"
+          ]
         },
         {
           "title": "positive_test_sqlalchemy_integer_column",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "x",
-            "type_list": ["INTEGER"]
+            "type_list": [
+              "INTEGER"
+            ]
           },
-          "out":{
-            "success":true
+          "out": {
+            "success": true
           },
-          "only_for": ["sqlalchemy"]
+          "only_for": [
+            "sqlalchemy"
+          ]
         },
         {
           "title": "positive_test_spark_integer_column",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "x",
-            "type_list": ["IntegerType"]
+            "type_list": [
+              "IntegerType"
+            ]
           },
-          "out":{
-            "success":true
+          "out": {
+            "success": true
           },
-          "only_for": ["spark"]
+          "only_for": [
+            "spark"
+          ]
         },
         {
           "title": "negative_test_pandas_float_values_are_not_strings",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "x",
-            "type_list": ["string"]
+            "type_list": [
+              "string"
+            ]
           },
-          "out":{
+          "out": {
             "success": false
           },
-          "only_for": ["pandas"]
+          "only_for": [
+            "pandas"
+          ]
         },
         {
           "title": "negative_test_sqlalchemy_float_values_are_not_TEXT",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "x",
-            "type_list": ["TEXT"]
+            "type_list": [
+              "TEXT"
+            ]
           },
-          "out":{
+          "out": {
             "success": false
           },
-          "only_for": ["sqlalchemy"]
+          "only_for": [
+            "sqlalchemy"
+          ]
         },
         {
           "title": "negative_test_spark_float_values_are_not_StringType",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "x",
-            "type_list": ["StringType"]
+            "type_list": [
+              "StringType"
+            ]
           },
-          "out":{
+          "out": {
             "success": false
           },
-          "only_for": ["spark"]
+          "only_for": [
+            "spark"
+          ]
         },
         {
           "title": "positive_test_float_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "y",
-            "type_list": ["float"]
+            "type_list": [
+              "float"
+            ]
           },
-          "out":{
-            "success":true
+          "out": {
+            "success": true
           },
-          "only_for": ["pandas"]
+          "only_for": [
+            "pandas"
+          ]
         },
         {
           "title": "positive_test_float_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "y",
-            "type_list": ["DOUBLE_PRECISION", "FLOAT"]
+            "type_list": [
+              "DOUBLE_PRECISION",
+              "FLOAT"
+            ]
           },
-          "out":{
-            "success":true
+          "out": {
+            "success": true
           },
-          "only_for": ["sqlalchemy"]
+          "only_for": [
+            "sqlalchemy"
+          ]
         },
         {
           "title": "positive_test_float_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "y",
-            "type_list": ["FloatType"]
+            "type_list": [
+              "FloatType"
+            ]
           },
-          "out":{
-            "success":true
+          "out": {
+            "success": true
           },
-          "only_for": ["spark"]
+          "only_for": [
+            "spark"
+          ]
         },
         {
           "title": "positive_test_string_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "z",
-            "type_list": ["str"]
+            "type_list": [
+              "str"
+            ]
           },
-          "out":{
+          "out": {
             "success": true,
             "unexpected_list": [],
             "unexpected_index_list": []
           },
-          "only_for": ["pandas"]
+          "only_for": [
+            "pandas"
+          ]
         },
         {
           "title": "positive_test_TEXT_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "z",
-            "type_list": ["TEXT", "VARCHAR"]
+            "type_list": [
+              "TEXT",
+              "VARCHAR"
+            ]
           },
-          "out":{
+          "out": {
             "success": true
           },
-          "only_for": ["sqlalchemy"]
+          "only_for": [
+            "sqlalchemy"
+          ]
         },
         {
           "title": "positive_test_StringType_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "z",
-            "type_list": ["StringType"]
+            "type_list": [
+              "StringType"
+            ]
           },
-          "out":{
+          "out": {
             "success": true
           },
-          "only_for": ["spark"]
+          "only_for": [
+            "spark"
+          ]
         },
         {
           "title": "positive_test_boolean_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "b",
-            "type_list": ["bool"]
+            "type_list": [
+              "bool"
+            ]
           },
-          "out":{
+          "out": {
             "success": true
           },
-          "only_for": ["pandas"]
+          "only_for": [
+            "pandas"
+          ]
         },
         {
           "title": "positive_test_boolean_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "b",
-            "type_list": ["BOOLEAN"]
+            "type_list": [
+              "BOOLEAN"
+            ]
           },
-          "out":{
+          "out": {
             "success": true
           },
-          "only_for": ["sqlalchemy"]
+          "only_for": [
+            "sqlalchemy"
+          ]
         },
         {
           "title": "positive_test_boolean_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "b",
-            "type_list": ["BooleanType"]
+            "type_list": [
+              "BooleanType"
+            ]
           },
-          "out":{
+          "out": {
             "success": true
           },
-          "only_for": ["spark"]
+          "only_for": [
+            "spark"
+          ]
         },
         {
           "title": "positive_test_string_and_int_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "s",
-            "type_list": ["str", "int"]
+            "type_list": [
+              "str",
+              "int"
+            ]
           },
-          "out":{
+          "out": {
             "success": true,
             "unexpected_list": [],
             "unexpected_index_list": []
           },
-          "only_for": ["pandas"]
+          "only_for": [
+            "pandas"
+          ]
         },
         {
           "title": "positive_test_TEXT_and_INTEGER_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "s",
-            "type_list": ["TEXT", "VARCHAR", "INTEGER"]
+            "type_list": [
+              "TEXT",
+              "VARCHAR",
+              "INTEGER"
+            ]
           },
-          "out":{
+          "out": {
             "success": true
           },
-          "only_for": ["sqlalchemy"]
+          "only_for": [
+            "sqlalchemy"
+          ]
         },
         {
           "title": "positive_test_StringType_and_IntegerType_values",
           "exact_match_out": false,
-          "in":{
+          "in": {
             "column": "s",
-            "type_list": ["StringType", "IntegerType"]
+            "type_list": [
+              "StringType",
+              "IntegerType"
+            ]
           },
-          "out":{
+          "out": {
             "success": true
           },
-          "only_for": ["spark"]
+          "only_for": [
+            "spark"
+          ]
+        },
+        {
+          "title": "positive_test_placeholder_expectation",
+          "exact_match_out": false,
+          "in": {
+            "column": "s",
+            "type_list": null
+          },
+          "out": {
+            "success": true
+          }
         }
       ]
-    }]
-}
\ No newline at end of file
+    }
+  ]
+}