We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `assets/scripts/build_gallery.py`
Content:
```
1 import ast
2 import importlib
3 import json
4 import logging
5 import os
6 import sys
7 import traceback
8 from io import StringIO
9 from subprocess import CalledProcessError, CompletedProcess, run
10 from typing import Dict
11 
12 import pkg_resources
13 
14 logger = logging.getLogger(__name__)
15 chandler = logging.StreamHandler(stream=sys.stdout)
16 chandler.setLevel(logging.DEBUG)
17 chandler.setFormatter(
18     logging.Formatter("%(asctime)s - %(levelname)s - %(message)s", "%Y-%m-%dT%H:%M:%S")
19 )
20 logger.addHandler(chandler)
21 logger.setLevel(logging.DEBUG)
22 
23 
24 expectation_tracebacks = StringIO()
25 expectation_checklists = StringIO()
26 
27 
28 def execute_shell_command(command: str) -> int:
29     """
30     Wrap subprocess command in a try/except block to provide a convenient method for pip installing dependencies.
31 
32     :param command: bash command -- as if typed in a shell/Terminal window
33     :return: status code -- 0 if successful; all other values (1 is the most common) indicate an error
34     """
35     cwd: str = os.getcwd()
36 
37     path_env_var: str = os.pathsep.join([os.environ.get("PATH", os.defpath), cwd])
38     env: dict = dict(os.environ, PATH=path_env_var)
39 
40     status_code: int = 0
41     try:
42         res: CompletedProcess = run(
43             args=["bash", "-c", command],
44             stdin=None,
45             input=None,
46             # stdout=None, # commenting out to prevent issues with `subprocess.run` in python <3.7.4
47             # stderr=None, # commenting out to prevent issues with `subprocess.run` in python <3.7.4
48             capture_output=True,
49             shell=False,
50             cwd=cwd,
51             timeout=None,
52             check=True,
53             encoding=None,
54             errors=None,
55             text=None,
56             env=env,
57             universal_newlines=True,
58         )
59         sh_out: str = res.stdout.strip()
60         logger.info(sh_out)
61     except CalledProcessError as cpe:
62         status_code = cpe.returncode
63         sys.stderr.write(cpe.output)
64         sys.stderr.flush()
65         exception_message: str = "A Sub-Process call Exception occurred.\n"
66         exception_traceback: str = traceback.format_exc()
67         exception_message += (
68             f'{type(cpe).__name__}: "{str(cpe)}".  Traceback: "{exception_traceback}".'
69         )
70         logger.error(exception_message)
71 
72     return status_code
73 
74 
75 def get_contrib_requirements(filepath: str) -> Dict:
76     """
77     Parse the python file from filepath to identify a "library_metadata" dictionary in any defined classes, and return a requirements_info object that includes a list of pip-installable requirements for each class that defines them.
78 
79     Note, currently we are handling all dependencies at the module level. To support future expandability and detail, this method also returns per-class requirements in addition to the concatenated list.
80 
81     Args:
82         filepath: the path to the file to parse and analyze
83 
84     Returns:
85         A dictionary:
86         {
87             "requirements": [ all_requirements_found_in_any_library_metadata_in_file ],
88             class_name: [ requirements ]
89         }
90 
91     """
92     with open(filepath) as file:
93         tree = ast.parse(file.read())
94 
95     requirements_info = {"requirements": []}
96     for child in ast.iter_child_nodes(tree):
97         if not isinstance(child, ast.ClassDef):
98             continue
99         current_class = child.name
100         for node in ast.walk(child):
101             if isinstance(node, ast.Assign):
102                 try:
103                     target_ids = [target.id for target in node.targets]
104                 except (ValueError, AttributeError):
105                     # some assignment types assign to non-node objects (e.g. Tuple)
106                     target_ids = []
107                 if "library_metadata" in target_ids:
108                     library_metadata = ast.literal_eval(node.value)
109                     requirements = library_metadata.get("requirements", [])
110                     requirements_info[current_class] = requirements
111                     requirements_info["requirements"] += requirements
112 
113     return requirements_info
114 
115 
116 def build_gallery(include_core: bool = True, include_contrib: bool = True) -> Dict:
117     """
118     Build the gallery object by running diagnostics for each Expectation and returning the resulting reports.
119 
120     Args:
121         include_core: if true, include Expectations defined in the core module
122         include_contrib_experimental: if true, include Expectations defined in contrib_experimental:
123 
124     Returns:
125         None
126 
127     """
128     gallery_info = dict()
129     requirements_dict = {}
130     logger.info("Loading great_expectations library.")
131     installed_packages = pkg_resources.working_set
132     installed_packages_txt = sorted(f"{i.key}=={i.version}" for i in installed_packages)
133     logger.debug(f"Found the following packages: {installed_packages_txt}")
134 
135     import great_expectations
136 
137     if include_core:
138         print("\n\n\n=== (Core) ===")
139         logger.info("Getting base registered expectations list")
140         core_expectations = (
141             great_expectations.expectations.registry.list_registered_expectation_implementations()
142         )
143         logger.debug(f"Found the following expectations: {sorted(core_expectations)}")
144         for expectation in core_expectations:
145             requirements_dict[expectation] = {"group": "core"}
146 
147     just_installed = set()
148 
149     if include_contrib:
150         print("\n\n\n=== (Contrib) ===")
151         logger.info("Finding contrib modules")
152         skip_dirs = ("cli", "tests")
153         contrib_dir = os.path.join(
154             os.path.dirname(__file__),
155             "..",
156             "..",
157             "contrib",
158         )
159 
160         for root, dirs, files in os.walk(contrib_dir):
161             for dirname in skip_dirs:
162                 if dirname in dirs:
163                     dirs.remove(dirname)
164             if "expectations" in dirs:
165                 if root.endswith("great_expectations_experimental"):
166                     sys.path.append(root)
167                 else:
168                     # A package in contrib that may contain more Expectations
169                     sys.path.append(os.path.dirname(root))
170             for filename in files:
171                 if filename.endswith(".py") and filename.startswith("expect_"):
172                     logger.debug(f"Getting requirements for module {filename}")
173                     contrib_subdir_name = os.path.basename(os.path.dirname(root))
174                     requirements_dict[filename[:-3]] = get_contrib_requirements(
175                         os.path.join(root, filename)
176                     )
177                     requirements_dict[filename[:-3]]["group"] = contrib_subdir_name
178 
179     for expectation in sorted(requirements_dict):
180         group = requirements_dict[expectation]["group"]
181         print(f"\n\n\n=== {expectation} ({group}) ===")
182         requirements = requirements_dict[expectation].get("requirements", [])
183         parsed_requirements = pkg_resources.parse_requirements(requirements)
184         for req in parsed_requirements:
185             is_satisfied = any(
186                 [installed_pkg in req for installed_pkg in installed_packages]
187             )
188             if is_satisfied or req in just_installed:
189                 continue
190             logger.debug(f"Executing command: 'pip install \"{req}\"'")
191             status_code = execute_shell_command(f'pip install "{req}"')
192             if status_code == 0:
193                 just_installed.add(req)
194             else:
195                 expectation_tracebacks.write(
196                     f"\n\n----------------\n{expectation} ({group})\n"
197                 )
198                 expectation_tracebacks.write(f"Failed to pip install {req}\n\n")
199 
200         if group != "core":
201             logger.debug(f"Importing {expectation}")
202             try:
203                 if group == "great_expectations_experimental":
204                     importlib.import_module(f"expectations.{expectation}", group)
205                 else:
206                     importlib.import_module(f"{group}.expectations")
207             except ModuleNotFoundError as e:
208                 logger.error(f"Failed to load expectation: {expectation}")
209                 print(traceback.format_exc())
210                 expectation_tracebacks.write(
211                     f"\n\n----------------\n{expectation} ({group})\n"
212                 )
213                 expectation_tracebacks.write(traceback.format_exc())
214                 continue
215 
216         logger.debug(f"Running diagnostics for expectation: {expectation}")
217         impl = great_expectations.expectations.registry.get_expectation_impl(
218             expectation
219         )
220         try:
221             diagnostics = impl().run_diagnostics(return_only_gallery_examples=True)
222             checklist_string = diagnostics.generate_checklist()
223             expectation_checklists.write(
224                 f"\n\n----------------\n{expectation} ({group})\n"
225             )
226             expectation_checklists.write(f"{checklist_string}\n")
227             gallery_info[expectation] = diagnostics.to_json_dict()
228         except Exception:
229             logger.error(f"Failed to run diagnostics for: {expectation}")
230             print(traceback.format_exc())
231             expectation_tracebacks.write(
232                 f"\n\n----------------\n{expectation} ({group})\n"
233             )
234             expectation_tracebacks.write(traceback.format_exc())
235 
236     if just_installed:
237         print("\n\n\n=== (Uninstalling) ===")
238         logger.info(
239             f"Uninstalling packages that were installed while running this script..."
240         )
241         for req in just_installed:
242             logger.debug(f"Executing command: 'pip uninstall -y \"{req}\"'")
243             execute_shell_command(f'pip uninstall -y "{req}"')
244 
245     expectation_filenames_set = set(requirements_dict.keys())
246     registered_expectations_set = set(
247         great_expectations.expectations.registry.list_registered_expectation_implementations()
248     )
249     non_matched_filenames = expectation_filenames_set - registered_expectations_set
250     if non_matched_filenames:
251         expectation_tracebacks.write(f"\n\n----------------\n(Not a traceback)\n")
252         expectation_tracebacks.write(
253             "Expectation filenames that don't match their defined Expectation name:\n"
254         )
255         for fname in sorted(non_matched_filenames):
256             expectation_tracebacks.write(f"- {fname}\n")
257 
258         bad_names = sorted(
259             list(registered_expectations_set - expectation_filenames_set)
260         )
261         expectation_tracebacks.write(
262             f"\nRegistered Expectation names that don't match:\n"
263         )
264         for exp_name in bad_names:
265             expectation_tracebacks.write(f"- {exp_name}\n")
266 
267     if include_core:
268         core_dir = os.path.join(
269             os.path.dirname(__file__),
270             "..",
271             "..",
272             "great_expectations",
273             "expectations",
274             "core",
275         )
276         core_expectations_filename_set = set(
277             [
278                 fname.rsplit(".", 1)[0]
279                 for fname in os.listdir(core_dir)
280                 if fname.startswith("expect_")
281             ]
282         )
283         core_expectations_not_in_gallery = core_expectations_filename_set - set(
284             core_expectations
285         )
286         if core_expectations_not_in_gallery:
287             expectation_tracebacks.write(f"\n\n----------------\n(Not a traceback)\n")
288             expectation_tracebacks.write(
289                 f"Core Expectation files not included in core_expectations:\n"
290             )
291             for exp_name in sorted(core_expectations_not_in_gallery):
292                 expectation_tracebacks.write(f"- {exp_name}\n")
293 
294     return gallery_info
295 
296 
297 if __name__ == "__main__":
298     gallery_info = build_gallery(include_core=True, include_contrib=True)
299     tracebacks = expectation_tracebacks.getvalue()
300     checklists = expectation_checklists.getvalue()
301     if tracebacks != "":
302         print("\n\n\n" + "#" * 30 + "   T R A C E B A C K S   " + "#" * 30 + "\n")
303         print(tracebacks)
304         print(
305             "\n\n" + "#" * 30 + "   E N D   T R A C E B A C K S   " + "#" * 30 + "\n\n"
306         )
307         with open("./gallery-errors.txt", "w") as outfile:
308             outfile.write(tracebacks)
309     if checklists != "":
310         print(checklists)
311         with open("./checklists.txt", "w") as outfile:
312             outfile.write(checklists)
313     with open("./expectation_library_v2.json", "w") as outfile:
314         json.dump(gallery_info, outfile)
315
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/assets/scripts/build_gallery.py b/assets/scripts/build_gallery.py
--- a/assets/scripts/build_gallery.py
+++ b/assets/scripts/build_gallery.py
@@ -3,6 +3,7 @@
 import json
 import logging
 import os
+import re
 import sys
 import traceback
 from io import StringIO
@@ -224,6 +225,10 @@
                 f"\n\n----------------\n{expectation} ({group})\n"
             )
             expectation_checklists.write(f"{checklist_string}\n")
+            if diagnostics["description"]["docstring"]:
+                diagnostics["description"]["docstring"] = format_docstring_to_markdown(
+                    diagnostics["description"]["docstring"]
+                )
             gallery_info[expectation] = diagnostics.to_json_dict()
         except Exception:
             logger.error(f"Failed to run diagnostics for: {expectation}")
@@ -294,6 +299,77 @@
     return gallery_info
 
 
+def format_docstring_to_markdown(docstr: str) -> str:
+    """
+    Add markdown formatting to a provided docstring
+
+    Args:
+        docstr: the original docstring that needs to be converted to markdown.
+
+    Returns:
+        str of Docstring formatted as markdown
+
+    """
+    r = re.compile(r"\s\s+", re.MULTILINE)
+    clean_docstr_list = []
+    prev_line = None
+    in_code_block = False
+    in_param = False
+    first_code_indentation = None
+
+    # Parse each line to determine if it needs formatting
+    for original_line in docstr.split("\n"):
+        # Remove excess spaces from lines formed by concatenated docstring lines.
+        line = r.sub(" ", original_line)
+        # In some old docstrings, this indicates the start of an example block.
+        if line.strip() == "::":
+            in_code_block = True
+            clean_docstr_list.append("```")
+
+        # All of our parameter/arg/etc lists start after a line ending in ':'.
+        elif line.strip().endswith(":"):
+            in_param = True
+            # This adds a blank line before the header if one doesn't already exist.
+            if prev_line != "":
+                clean_docstr_list.append("")
+            # Turn the line into an H4 header
+            clean_docstr_list.append(f"#### {line.strip()}")
+        elif line.strip() == "" and prev_line != "::":
+            # All of our parameter groups end with a line break, but we don't want to exit a parameter block due to a
+            # line break in a code block.  However, some code blocks start with a blank first line, so we want to make
+            # sure we aren't immediately exiting the code block (hence the test for '::' on the previous line.
+            in_param = False
+            # Add the markdown indicator to close a code block, since we aren't in one now.
+            if in_code_block:
+                clean_docstr_list.append("```")
+            in_code_block = False
+            first_code_indentation = None
+            clean_docstr_list.append(line)
+        else:
+            if in_code_block:
+                # Determine the number of spaces indenting the first line of code so they can be removed from all lines
+                # in the code block without wrecking the hierarchical indentation levels of future lines.
+                if first_code_indentation == None and line.strip() != "":
+                    first_code_indentation = len(
+                        re.match(r"\s*", original_line, re.UNICODE).group(0)
+                    )
+                if line.strip() == "" and prev_line == "::":
+                    # If the first line of the code block is a blank one, just skip it.
+                    pass
+                else:
+                    # Append the line of code, minus the extra indentation from being written in an indented docstring.
+                    clean_docstr_list.append(original_line[first_code_indentation:])
+            elif ":" in line.replace(":ref:", "") and in_param:
+                # This indicates a parameter. arg. or other definition.
+                clean_docstr_list.append(f"- {line.strip()}")
+            else:
+                # This indicates a regular line of text.
+                clean_docstr_list.append(f"{line.strip()}")
+        prev_line = line.strip()
+    clean_docstr = "\n".join(clean_docstr_list)
+    return clean_docstr
+
+
 if __name__ == "__main__":
     gallery_info = build_gallery(include_core=True, include_contrib=True)
     tracebacks = expectation_tracebacks.getvalue()

{"golden_diff": "diff --git a/assets/scripts/build_gallery.py b/assets/scripts/build_gallery.py\n--- a/assets/scripts/build_gallery.py\n+++ b/assets/scripts/build_gallery.py\n@@ -3,6 +3,7 @@\n import json\n import logging\n import os\n+import re\n import sys\n import traceback\n from io import StringIO\n@@ -224,6 +225,10 @@\n                 f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n             )\n             expectation_checklists.write(f\"{checklist_string}\\n\")\n+            if diagnostics[\"description\"][\"docstring\"]:\n+                diagnostics[\"description\"][\"docstring\"] = format_docstring_to_markdown(\n+                    diagnostics[\"description\"][\"docstring\"]\n+                )\n             gallery_info[expectation] = diagnostics.to_json_dict()\n         except Exception:\n             logger.error(f\"Failed to run diagnostics for: {expectation}\")\n@@ -294,6 +299,77 @@\n     return gallery_info\n \n \n+def format_docstring_to_markdown(docstr: str) -> str:\n+    \"\"\"\n+    Add markdown formatting to a provided docstring\n+\n+    Args:\n+        docstr: the original docstring that needs to be converted to markdown.\n+\n+    Returns:\n+        str of Docstring formatted as markdown\n+\n+    \"\"\"\n+    r = re.compile(r\"\\s\\s+\", re.MULTILINE)\n+    clean_docstr_list = []\n+    prev_line = None\n+    in_code_block = False\n+    in_param = False\n+    first_code_indentation = None\n+\n+    # Parse each line to determine if it needs formatting\n+    for original_line in docstr.split(\"\\n\"):\n+        # Remove excess spaces from lines formed by concatenated docstring lines.\n+        line = r.sub(\" \", original_line)\n+        # In some old docstrings, this indicates the start of an example block.\n+        if line.strip() == \"::\":\n+            in_code_block = True\n+            clean_docstr_list.append(\"```\")\n+\n+        # All of our parameter/arg/etc lists start after a line ending in ':'.\n+        elif line.strip().endswith(\":\"):\n+            in_param = True\n+            # This adds a blank line before the header if one doesn't already exist.\n+            if prev_line != \"\":\n+                clean_docstr_list.append(\"\")\n+            # Turn the line into an H4 header\n+            clean_docstr_list.append(f\"#### {line.strip()}\")\n+        elif line.strip() == \"\" and prev_line != \"::\":\n+            # All of our parameter groups end with a line break, but we don't want to exit a parameter block due to a\n+            # line break in a code block.  However, some code blocks start with a blank first line, so we want to make\n+            # sure we aren't immediately exiting the code block (hence the test for '::' on the previous line.\n+            in_param = False\n+            # Add the markdown indicator to close a code block, since we aren't in one now.\n+            if in_code_block:\n+                clean_docstr_list.append(\"```\")\n+            in_code_block = False\n+            first_code_indentation = None\n+            clean_docstr_list.append(line)\n+        else:\n+            if in_code_block:\n+                # Determine the number of spaces indenting the first line of code so they can be removed from all lines\n+                # in the code block without wrecking the hierarchical indentation levels of future lines.\n+                if first_code_indentation == None and line.strip() != \"\":\n+                    first_code_indentation = len(\n+                        re.match(r\"\\s*\", original_line, re.UNICODE).group(0)\n+                    )\n+                if line.strip() == \"\" and prev_line == \"::\":\n+                    # If the first line of the code block is a blank one, just skip it.\n+                    pass\n+                else:\n+                    # Append the line of code, minus the extra indentation from being written in an indented docstring.\n+                    clean_docstr_list.append(original_line[first_code_indentation:])\n+            elif \":\" in line.replace(\":ref:\", \"\") and in_param:\n+                # This indicates a parameter. arg. or other definition.\n+                clean_docstr_list.append(f\"- {line.strip()}\")\n+            else:\n+                # This indicates a regular line of text.\n+                clean_docstr_list.append(f\"{line.strip()}\")\n+        prev_line = line.strip()\n+    clean_docstr = \"\\n\".join(clean_docstr_list)\n+    return clean_docstr\n+\n+\n if __name__ == \"__main__\":\n     gallery_info = build_gallery(include_core=True, include_contrib=True)\n     tracebacks = expectation_tracebacks.getvalue()\n", "issue": "Use cleaner solution for non-truncating division in python 2\nPrefer `from __future__ import division` to `1.*x/y`\n", "before_files": [{"content": "import ast\nimport importlib\nimport json\nimport logging\nimport os\nimport sys\nimport traceback\nfrom io import StringIO\nfrom subprocess import CalledProcessError, CompletedProcess, run\nfrom typing import Dict\n\nimport pkg_resources\n\nlogger = logging.getLogger(__name__)\nchandler = logging.StreamHandler(stream=sys.stdout)\nchandler.setLevel(logging.DEBUG)\nchandler.setFormatter(\n    logging.Formatter(\"%(asctime)s - %(levelname)s - %(message)s\", \"%Y-%m-%dT%H:%M:%S\")\n)\nlogger.addHandler(chandler)\nlogger.setLevel(logging.DEBUG)\n\n\nexpectation_tracebacks = StringIO()\nexpectation_checklists = StringIO()\n\n\ndef execute_shell_command(command: str) -> int:\n    \"\"\"\n    Wrap subprocess command in a try/except block to provide a convenient method for pip installing dependencies.\n\n    :param command: bash command -- as if typed in a shell/Terminal window\n    :return: status code -- 0 if successful; all other values (1 is the most common) indicate an error\n    \"\"\"\n    cwd: str = os.getcwd()\n\n    path_env_var: str = os.pathsep.join([os.environ.get(\"PATH\", os.defpath), cwd])\n    env: dict = dict(os.environ, PATH=path_env_var)\n\n    status_code: int = 0\n    try:\n        res: CompletedProcess = run(\n            args=[\"bash\", \"-c\", command],\n            stdin=None,\n            input=None,\n            # stdout=None, # commenting out to prevent issues with `subprocess.run` in python <3.7.4\n            # stderr=None, # commenting out to prevent issues with `subprocess.run` in python <3.7.4\n            capture_output=True,\n            shell=False,\n            cwd=cwd,\n            timeout=None,\n            check=True,\n            encoding=None,\n            errors=None,\n            text=None,\n            env=env,\n            universal_newlines=True,\n        )\n        sh_out: str = res.stdout.strip()\n        logger.info(sh_out)\n    except CalledProcessError as cpe:\n        status_code = cpe.returncode\n        sys.stderr.write(cpe.output)\n        sys.stderr.flush()\n        exception_message: str = \"A Sub-Process call Exception occurred.\\n\"\n        exception_traceback: str = traceback.format_exc()\n        exception_message += (\n            f'{type(cpe).__name__}: \"{str(cpe)}\".  Traceback: \"{exception_traceback}\".'\n        )\n        logger.error(exception_message)\n\n    return status_code\n\n\ndef get_contrib_requirements(filepath: str) -> Dict:\n    \"\"\"\n    Parse the python file from filepath to identify a \"library_metadata\" dictionary in any defined classes, and return a requirements_info object that includes a list of pip-installable requirements for each class that defines them.\n\n    Note, currently we are handling all dependencies at the module level. To support future expandability and detail, this method also returns per-class requirements in addition to the concatenated list.\n\n    Args:\n        filepath: the path to the file to parse and analyze\n\n    Returns:\n        A dictionary:\n        {\n            \"requirements\": [ all_requirements_found_in_any_library_metadata_in_file ],\n            class_name: [ requirements ]\n        }\n\n    \"\"\"\n    with open(filepath) as file:\n        tree = ast.parse(file.read())\n\n    requirements_info = {\"requirements\": []}\n    for child in ast.iter_child_nodes(tree):\n        if not isinstance(child, ast.ClassDef):\n            continue\n        current_class = child.name\n        for node in ast.walk(child):\n            if isinstance(node, ast.Assign):\n                try:\n                    target_ids = [target.id for target in node.targets]\n                except (ValueError, AttributeError):\n                    # some assignment types assign to non-node objects (e.g. Tuple)\n                    target_ids = []\n                if \"library_metadata\" in target_ids:\n                    library_metadata = ast.literal_eval(node.value)\n                    requirements = library_metadata.get(\"requirements\", [])\n                    requirements_info[current_class] = requirements\n                    requirements_info[\"requirements\"] += requirements\n\n    return requirements_info\n\n\ndef build_gallery(include_core: bool = True, include_contrib: bool = True) -> Dict:\n    \"\"\"\n    Build the gallery object by running diagnostics for each Expectation and returning the resulting reports.\n\n    Args:\n        include_core: if true, include Expectations defined in the core module\n        include_contrib_experimental: if true, include Expectations defined in contrib_experimental:\n\n    Returns:\n        None\n\n    \"\"\"\n    gallery_info = dict()\n    requirements_dict = {}\n    logger.info(\"Loading great_expectations library.\")\n    installed_packages = pkg_resources.working_set\n    installed_packages_txt = sorted(f\"{i.key}=={i.version}\" for i in installed_packages)\n    logger.debug(f\"Found the following packages: {installed_packages_txt}\")\n\n    import great_expectations\n\n    if include_core:\n        print(\"\\n\\n\\n=== (Core) ===\")\n        logger.info(\"Getting base registered expectations list\")\n        core_expectations = (\n            great_expectations.expectations.registry.list_registered_expectation_implementations()\n        )\n        logger.debug(f\"Found the following expectations: {sorted(core_expectations)}\")\n        for expectation in core_expectations:\n            requirements_dict[expectation] = {\"group\": \"core\"}\n\n    just_installed = set()\n\n    if include_contrib:\n        print(\"\\n\\n\\n=== (Contrib) ===\")\n        logger.info(\"Finding contrib modules\")\n        skip_dirs = (\"cli\", \"tests\")\n        contrib_dir = os.path.join(\n            os.path.dirname(__file__),\n            \"..\",\n            \"..\",\n            \"contrib\",\n        )\n\n        for root, dirs, files in os.walk(contrib_dir):\n            for dirname in skip_dirs:\n                if dirname in dirs:\n                    dirs.remove(dirname)\n            if \"expectations\" in dirs:\n                if root.endswith(\"great_expectations_experimental\"):\n                    sys.path.append(root)\n                else:\n                    # A package in contrib that may contain more Expectations\n                    sys.path.append(os.path.dirname(root))\n            for filename in files:\n                if filename.endswith(\".py\") and filename.startswith(\"expect_\"):\n                    logger.debug(f\"Getting requirements for module {filename}\")\n                    contrib_subdir_name = os.path.basename(os.path.dirname(root))\n                    requirements_dict[filename[:-3]] = get_contrib_requirements(\n                        os.path.join(root, filename)\n                    )\n                    requirements_dict[filename[:-3]][\"group\"] = contrib_subdir_name\n\n    for expectation in sorted(requirements_dict):\n        group = requirements_dict[expectation][\"group\"]\n        print(f\"\\n\\n\\n=== {expectation} ({group}) ===\")\n        requirements = requirements_dict[expectation].get(\"requirements\", [])\n        parsed_requirements = pkg_resources.parse_requirements(requirements)\n        for req in parsed_requirements:\n            is_satisfied = any(\n                [installed_pkg in req for installed_pkg in installed_packages]\n            )\n            if is_satisfied or req in just_installed:\n                continue\n            logger.debug(f\"Executing command: 'pip install \\\"{req}\\\"'\")\n            status_code = execute_shell_command(f'pip install \"{req}\"')\n            if status_code == 0:\n                just_installed.add(req)\n            else:\n                expectation_tracebacks.write(\n                    f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n                )\n                expectation_tracebacks.write(f\"Failed to pip install {req}\\n\\n\")\n\n        if group != \"core\":\n            logger.debug(f\"Importing {expectation}\")\n            try:\n                if group == \"great_expectations_experimental\":\n                    importlib.import_module(f\"expectations.{expectation}\", group)\n                else:\n                    importlib.import_module(f\"{group}.expectations\")\n            except ModuleNotFoundError as e:\n                logger.error(f\"Failed to load expectation: {expectation}\")\n                print(traceback.format_exc())\n                expectation_tracebacks.write(\n                    f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n                )\n                expectation_tracebacks.write(traceback.format_exc())\n                continue\n\n        logger.debug(f\"Running diagnostics for expectation: {expectation}\")\n        impl = great_expectations.expectations.registry.get_expectation_impl(\n            expectation\n        )\n        try:\n            diagnostics = impl().run_diagnostics(return_only_gallery_examples=True)\n            checklist_string = diagnostics.generate_checklist()\n            expectation_checklists.write(\n                f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n            )\n            expectation_checklists.write(f\"{checklist_string}\\n\")\n            gallery_info[expectation] = diagnostics.to_json_dict()\n        except Exception:\n            logger.error(f\"Failed to run diagnostics for: {expectation}\")\n            print(traceback.format_exc())\n            expectation_tracebacks.write(\n                f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n            )\n            expectation_tracebacks.write(traceback.format_exc())\n\n    if just_installed:\n        print(\"\\n\\n\\n=== (Uninstalling) ===\")\n        logger.info(\n            f\"Uninstalling packages that were installed while running this script...\"\n        )\n        for req in just_installed:\n            logger.debug(f\"Executing command: 'pip uninstall -y \\\"{req}\\\"'\")\n            execute_shell_command(f'pip uninstall -y \"{req}\"')\n\n    expectation_filenames_set = set(requirements_dict.keys())\n    registered_expectations_set = set(\n        great_expectations.expectations.registry.list_registered_expectation_implementations()\n    )\n    non_matched_filenames = expectation_filenames_set - registered_expectations_set\n    if non_matched_filenames:\n        expectation_tracebacks.write(f\"\\n\\n----------------\\n(Not a traceback)\\n\")\n        expectation_tracebacks.write(\n            \"Expectation filenames that don't match their defined Expectation name:\\n\"\n        )\n        for fname in sorted(non_matched_filenames):\n            expectation_tracebacks.write(f\"- {fname}\\n\")\n\n        bad_names = sorted(\n            list(registered_expectations_set - expectation_filenames_set)\n        )\n        expectation_tracebacks.write(\n            f\"\\nRegistered Expectation names that don't match:\\n\"\n        )\n        for exp_name in bad_names:\n            expectation_tracebacks.write(f\"- {exp_name}\\n\")\n\n    if include_core:\n        core_dir = os.path.join(\n            os.path.dirname(__file__),\n            \"..\",\n            \"..\",\n            \"great_expectations\",\n            \"expectations\",\n            \"core\",\n        )\n        core_expectations_filename_set = set(\n            [\n                fname.rsplit(\".\", 1)[0]\n                for fname in os.listdir(core_dir)\n                if fname.startswith(\"expect_\")\n            ]\n        )\n        core_expectations_not_in_gallery = core_expectations_filename_set - set(\n            core_expectations\n        )\n        if core_expectations_not_in_gallery:\n            expectation_tracebacks.write(f\"\\n\\n----------------\\n(Not a traceback)\\n\")\n            expectation_tracebacks.write(\n                f\"Core Expectation files not included in core_expectations:\\n\"\n            )\n            for exp_name in sorted(core_expectations_not_in_gallery):\n                expectation_tracebacks.write(f\"- {exp_name}\\n\")\n\n    return gallery_info\n\n\nif __name__ == \"__main__\":\n    gallery_info = build_gallery(include_core=True, include_contrib=True)\n    tracebacks = expectation_tracebacks.getvalue()\n    checklists = expectation_checklists.getvalue()\n    if tracebacks != \"\":\n        print(\"\\n\\n\\n\" + \"#\" * 30 + \"   T R A C E B A C K S   \" + \"#\" * 30 + \"\\n\")\n        print(tracebacks)\n        print(\n            \"\\n\\n\" + \"#\" * 30 + \"   E N D   T R A C E B A C K S   \" + \"#\" * 30 + \"\\n\\n\"\n        )\n        with open(\"./gallery-errors.txt\", \"w\") as outfile:\n            outfile.write(tracebacks)\n    if checklists != \"\":\n        print(checklists)\n        with open(\"./checklists.txt\", \"w\") as outfile:\n            outfile.write(checklists)\n    with open(\"./expectation_library_v2.json\", \"w\") as outfile:\n        json.dump(gallery_info, outfile)\n", "path": "assets/scripts/build_gallery.py"}], "after_files": [{"content": "import ast\nimport importlib\nimport json\nimport logging\nimport os\nimport re\nimport sys\nimport traceback\nfrom io import StringIO\nfrom subprocess import CalledProcessError, CompletedProcess, run\nfrom typing import Dict\n\nimport pkg_resources\n\nlogger = logging.getLogger(__name__)\nchandler = logging.StreamHandler(stream=sys.stdout)\nchandler.setLevel(logging.DEBUG)\nchandler.setFormatter(\n    logging.Formatter(\"%(asctime)s - %(levelname)s - %(message)s\", \"%Y-%m-%dT%H:%M:%S\")\n)\nlogger.addHandler(chandler)\nlogger.setLevel(logging.DEBUG)\n\n\nexpectation_tracebacks = StringIO()\nexpectation_checklists = StringIO()\n\n\ndef execute_shell_command(command: str) -> int:\n    \"\"\"\n    Wrap subprocess command in a try/except block to provide a convenient method for pip installing dependencies.\n\n    :param command: bash command -- as if typed in a shell/Terminal window\n    :return: status code -- 0 if successful; all other values (1 is the most common) indicate an error\n    \"\"\"\n    cwd: str = os.getcwd()\n\n    path_env_var: str = os.pathsep.join([os.environ.get(\"PATH\", os.defpath), cwd])\n    env: dict = dict(os.environ, PATH=path_env_var)\n\n    status_code: int = 0\n    try:\n        res: CompletedProcess = run(\n            args=[\"bash\", \"-c\", command],\n            stdin=None,\n            input=None,\n            # stdout=None, # commenting out to prevent issues with `subprocess.run` in python <3.7.4\n            # stderr=None, # commenting out to prevent issues with `subprocess.run` in python <3.7.4\n            capture_output=True,\n            shell=False,\n            cwd=cwd,\n            timeout=None,\n            check=True,\n            encoding=None,\n            errors=None,\n            text=None,\n            env=env,\n            universal_newlines=True,\n        )\n        sh_out: str = res.stdout.strip()\n        logger.info(sh_out)\n    except CalledProcessError as cpe:\n        status_code = cpe.returncode\n        sys.stderr.write(cpe.output)\n        sys.stderr.flush()\n        exception_message: str = \"A Sub-Process call Exception occurred.\\n\"\n        exception_traceback: str = traceback.format_exc()\n        exception_message += (\n            f'{type(cpe).__name__}: \"{str(cpe)}\".  Traceback: \"{exception_traceback}\".'\n        )\n        logger.error(exception_message)\n\n    return status_code\n\n\ndef get_contrib_requirements(filepath: str) -> Dict:\n    \"\"\"\n    Parse the python file from filepath to identify a \"library_metadata\" dictionary in any defined classes, and return a requirements_info object that includes a list of pip-installable requirements for each class that defines them.\n\n    Note, currently we are handling all dependencies at the module level. To support future expandability and detail, this method also returns per-class requirements in addition to the concatenated list.\n\n    Args:\n        filepath: the path to the file to parse and analyze\n\n    Returns:\n        A dictionary:\n        {\n            \"requirements\": [ all_requirements_found_in_any_library_metadata_in_file ],\n            class_name: [ requirements ]\n        }\n\n    \"\"\"\n    with open(filepath) as file:\n        tree = ast.parse(file.read())\n\n    requirements_info = {\"requirements\": []}\n    for child in ast.iter_child_nodes(tree):\n        if not isinstance(child, ast.ClassDef):\n            continue\n        current_class = child.name\n        for node in ast.walk(child):\n            if isinstance(node, ast.Assign):\n                try:\n                    target_ids = [target.id for target in node.targets]\n                except (ValueError, AttributeError):\n                    # some assignment types assign to non-node objects (e.g. Tuple)\n                    target_ids = []\n                if \"library_metadata\" in target_ids:\n                    library_metadata = ast.literal_eval(node.value)\n                    requirements = library_metadata.get(\"requirements\", [])\n                    requirements_info[current_class] = requirements\n                    requirements_info[\"requirements\"] += requirements\n\n    return requirements_info\n\n\ndef build_gallery(include_core: bool = True, include_contrib: bool = True) -> Dict:\n    \"\"\"\n    Build the gallery object by running diagnostics for each Expectation and returning the resulting reports.\n\n    Args:\n        include_core: if true, include Expectations defined in the core module\n        include_contrib_experimental: if true, include Expectations defined in contrib_experimental:\n\n    Returns:\n        None\n\n    \"\"\"\n    gallery_info = dict()\n    requirements_dict = {}\n    logger.info(\"Loading great_expectations library.\")\n    installed_packages = pkg_resources.working_set\n    installed_packages_txt = sorted(f\"{i.key}=={i.version}\" for i in installed_packages)\n    logger.debug(f\"Found the following packages: {installed_packages_txt}\")\n\n    import great_expectations\n\n    if include_core:\n        print(\"\\n\\n\\n=== (Core) ===\")\n        logger.info(\"Getting base registered expectations list\")\n        core_expectations = (\n            great_expectations.expectations.registry.list_registered_expectation_implementations()\n        )\n        logger.debug(f\"Found the following expectations: {sorted(core_expectations)}\")\n        for expectation in core_expectations:\n            requirements_dict[expectation] = {\"group\": \"core\"}\n\n    just_installed = set()\n\n    if include_contrib:\n        print(\"\\n\\n\\n=== (Contrib) ===\")\n        logger.info(\"Finding contrib modules\")\n        skip_dirs = (\"cli\", \"tests\")\n        contrib_dir = os.path.join(\n            os.path.dirname(__file__),\n            \"..\",\n            \"..\",\n            \"contrib\",\n        )\n\n        for root, dirs, files in os.walk(contrib_dir):\n            for dirname in skip_dirs:\n                if dirname in dirs:\n                    dirs.remove(dirname)\n            if \"expectations\" in dirs:\n                if root.endswith(\"great_expectations_experimental\"):\n                    sys.path.append(root)\n                else:\n                    # A package in contrib that may contain more Expectations\n                    sys.path.append(os.path.dirname(root))\n            for filename in files:\n                if filename.endswith(\".py\") and filename.startswith(\"expect_\"):\n                    logger.debug(f\"Getting requirements for module {filename}\")\n                    contrib_subdir_name = os.path.basename(os.path.dirname(root))\n                    requirements_dict[filename[:-3]] = get_contrib_requirements(\n                        os.path.join(root, filename)\n                    )\n                    requirements_dict[filename[:-3]][\"group\"] = contrib_subdir_name\n\n    for expectation in sorted(requirements_dict):\n        group = requirements_dict[expectation][\"group\"]\n        print(f\"\\n\\n\\n=== {expectation} ({group}) ===\")\n        requirements = requirements_dict[expectation].get(\"requirements\", [])\n        parsed_requirements = pkg_resources.parse_requirements(requirements)\n        for req in parsed_requirements:\n            is_satisfied = any(\n                [installed_pkg in req for installed_pkg in installed_packages]\n            )\n            if is_satisfied or req in just_installed:\n                continue\n            logger.debug(f\"Executing command: 'pip install \\\"{req}\\\"'\")\n            status_code = execute_shell_command(f'pip install \"{req}\"')\n            if status_code == 0:\n                just_installed.add(req)\n            else:\n                expectation_tracebacks.write(\n                    f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n                )\n                expectation_tracebacks.write(f\"Failed to pip install {req}\\n\\n\")\n\n        if group != \"core\":\n            logger.debug(f\"Importing {expectation}\")\n            try:\n                if group == \"great_expectations_experimental\":\n                    importlib.import_module(f\"expectations.{expectation}\", group)\n                else:\n                    importlib.import_module(f\"{group}.expectations\")\n            except ModuleNotFoundError as e:\n                logger.error(f\"Failed to load expectation: {expectation}\")\n                print(traceback.format_exc())\n                expectation_tracebacks.write(\n                    f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n                )\n                expectation_tracebacks.write(traceback.format_exc())\n                continue\n\n        logger.debug(f\"Running diagnostics for expectation: {expectation}\")\n        impl = great_expectations.expectations.registry.get_expectation_impl(\n            expectation\n        )\n        try:\n            diagnostics = impl().run_diagnostics(return_only_gallery_examples=True)\n            checklist_string = diagnostics.generate_checklist()\n            expectation_checklists.write(\n                f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n            )\n            expectation_checklists.write(f\"{checklist_string}\\n\")\n            if diagnostics[\"description\"][\"docstring\"]:\n                diagnostics[\"description\"][\"docstring\"] = format_docstring_to_markdown(\n                    diagnostics[\"description\"][\"docstring\"]\n                )\n            gallery_info[expectation] = diagnostics.to_json_dict()\n        except Exception:\n            logger.error(f\"Failed to run diagnostics for: {expectation}\")\n            print(traceback.format_exc())\n            expectation_tracebacks.write(\n                f\"\\n\\n----------------\\n{expectation} ({group})\\n\"\n            )\n            expectation_tracebacks.write(traceback.format_exc())\n\n    if just_installed:\n        print(\"\\n\\n\\n=== (Uninstalling) ===\")\n        logger.info(\n            f\"Uninstalling packages that were installed while running this script...\"\n        )\n        for req in just_installed:\n            logger.debug(f\"Executing command: 'pip uninstall -y \\\"{req}\\\"'\")\n            execute_shell_command(f'pip uninstall -y \"{req}\"')\n\n    expectation_filenames_set = set(requirements_dict.keys())\n    registered_expectations_set = set(\n        great_expectations.expectations.registry.list_registered_expectation_implementations()\n    )\n    non_matched_filenames = expectation_filenames_set - registered_expectations_set\n    if non_matched_filenames:\n        expectation_tracebacks.write(f\"\\n\\n----------------\\n(Not a traceback)\\n\")\n        expectation_tracebacks.write(\n            \"Expectation filenames that don't match their defined Expectation name:\\n\"\n        )\n        for fname in sorted(non_matched_filenames):\n            expectation_tracebacks.write(f\"- {fname}\\n\")\n\n        bad_names = sorted(\n            list(registered_expectations_set - expectation_filenames_set)\n        )\n        expectation_tracebacks.write(\n            f\"\\nRegistered Expectation names that don't match:\\n\"\n        )\n        for exp_name in bad_names:\n            expectation_tracebacks.write(f\"- {exp_name}\\n\")\n\n    if include_core:\n        core_dir = os.path.join(\n            os.path.dirname(__file__),\n            \"..\",\n            \"..\",\n            \"great_expectations\",\n            \"expectations\",\n            \"core\",\n        )\n        core_expectations_filename_set = set(\n            [\n                fname.rsplit(\".\", 1)[0]\n                for fname in os.listdir(core_dir)\n                if fname.startswith(\"expect_\")\n            ]\n        )\n        core_expectations_not_in_gallery = core_expectations_filename_set - set(\n            core_expectations\n        )\n        if core_expectations_not_in_gallery:\n            expectation_tracebacks.write(f\"\\n\\n----------------\\n(Not a traceback)\\n\")\n            expectation_tracebacks.write(\n                f\"Core Expectation files not included in core_expectations:\\n\"\n            )\n            for exp_name in sorted(core_expectations_not_in_gallery):\n                expectation_tracebacks.write(f\"- {exp_name}\\n\")\n\n    return gallery_info\n\n\ndef format_docstring_to_markdown(docstr: str) -> str:\n    \"\"\"\n    Add markdown formatting to a provided docstring\n\n    Args:\n        docstr: the original docstring that needs to be converted to markdown.\n\n    Returns:\n        str of Docstring formatted as markdown\n\n    \"\"\"\n    r = re.compile(r\"\\s\\s+\", re.MULTILINE)\n    clean_docstr_list = []\n    prev_line = None\n    in_code_block = False\n    in_param = False\n    first_code_indentation = None\n\n    # Parse each line to determine if it needs formatting\n    for original_line in docstr.split(\"\\n\"):\n        # Remove excess spaces from lines formed by concatenated docstring lines.\n        line = r.sub(\" \", original_line)\n        # In some old docstrings, this indicates the start of an example block.\n        if line.strip() == \"::\":\n            in_code_block = True\n            clean_docstr_list.append(\"```\")\n\n        # All of our parameter/arg/etc lists start after a line ending in ':'.\n        elif line.strip().endswith(\":\"):\n            in_param = True\n            # This adds a blank line before the header if one doesn't already exist.\n            if prev_line != \"\":\n                clean_docstr_list.append(\"\")\n            # Turn the line into an H4 header\n            clean_docstr_list.append(f\"#### {line.strip()}\")\n        elif line.strip() == \"\" and prev_line != \"::\":\n            # All of our parameter groups end with a line break, but we don't want to exit a parameter block due to a\n            # line break in a code block.  However, some code blocks start with a blank first line, so we want to make\n            # sure we aren't immediately exiting the code block (hence the test for '::' on the previous line.\n            in_param = False\n            # Add the markdown indicator to close a code block, since we aren't in one now.\n            if in_code_block:\n                clean_docstr_list.append(\"```\")\n            in_code_block = False\n            first_code_indentation = None\n            clean_docstr_list.append(line)\n        else:\n            if in_code_block:\n                # Determine the number of spaces indenting the first line of code so they can be removed from all lines\n                # in the code block without wrecking the hierarchical indentation levels of future lines.\n                if first_code_indentation == None and line.strip() != \"\":\n                    first_code_indentation = len(\n                        re.match(r\"\\s*\", original_line, re.UNICODE).group(0)\n                    )\n                if line.strip() == \"\" and prev_line == \"::\":\n                    # If the first line of the code block is a blank one, just skip it.\n                    pass\n                else:\n                    # Append the line of code, minus the extra indentation from being written in an indented docstring.\n                    clean_docstr_list.append(original_line[first_code_indentation:])\n            elif \":\" in line.replace(\":ref:\", \"\") and in_param:\n                # This indicates a parameter. arg. or other definition.\n                clean_docstr_list.append(f\"- {line.strip()}\")\n            else:\n                # This indicates a regular line of text.\n                clean_docstr_list.append(f\"{line.strip()}\")\n        prev_line = line.strip()\n    clean_docstr = \"\\n\".join(clean_docstr_list)\n    return clean_docstr\n\n\nif __name__ == \"__main__\":\n    gallery_info = build_gallery(include_core=True, include_contrib=True)\n    tracebacks = expectation_tracebacks.getvalue()\n    checklists = expectation_checklists.getvalue()\n    if tracebacks != \"\":\n        print(\"\\n\\n\\n\" + \"#\" * 30 + \"   T R A C E B A C K S   \" + \"#\" * 30 + \"\\n\")\n        print(tracebacks)\n        print(\n            \"\\n\\n\" + \"#\" * 30 + \"   E N D   T R A C E B A C K S   \" + \"#\" * 30 + \"\\n\\n\"\n        )\n        with open(\"./gallery-errors.txt\", \"w\") as outfile:\n            outfile.write(tracebacks)\n    if checklists != \"\":\n        print(checklists)\n        with open(\"./checklists.txt\", \"w\") as outfile:\n            outfile.write(checklists)\n    with open(\"./expectation_library_v2.json\", \"w\") as outfile:\n        json.dump(gallery_info, outfile)\n", "path": "assets/scripts/build_gallery.py"}]}