We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`hy.M` sugar for import on demand
It's annoying to have to import to a gensym when you want to use a function from another module in a macro expansion. Suppose you could say `(hy.M.math.sqrt 2)` to call `math.sqrt` without actually binding `math` or `math.sqrt` to some name in the local scope. In addition to making macros neater, this could be convenient as a general shorthand for using something from a module, particularly a module with a long name, without having to add a separate `import` form.

To get a module whose name itself has dots, one could use `/` instead of the dots, so `(hy.M.foo/bar/baz.bing)` would work like `(import foo.bar.baz) (foo.bar.baz.bing)`.

Here's a simple implementation:

```python
import hy

class M:
    def __call__(self, module_name):
        import importlib
        return importlib.import_module(module_name)
    def __getattr__(self, s):
        return self('.'.join(hy.unmangle(s).split('/')))

hy.M = M()
hy.eval(hy.read_many('''
(print hy.M.sklearn/neighbors.KNeighborsRegressor)
'''))
```

The nice thing about this feature is that it can be added without changing Hy's syntax or touching the set of core macros.

`__call__` is provided so you can also say `(hy.M "foo.bar.baz")` to get the module `foo.bar.baz`, which may be more convenient when the module name isn't known until runtime.

This sort of feature could probably be provided for requiring macros, too.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hy/__init__.py`
Content:
```
1 try:
2     from hy.version import __version__
3 except ImportError:
4     __version__ = "unknown"
5 
6 
7 def _initialize_env_var(env_var, default_val):
8     import os
9 
10     return bool(os.environ.get(env_var, default_val))
11 
12 
13 import hy.importer  # NOQA
14 
15 hy.importer._inject_builtins()
16 # we import for side-effects.
17 
18 # Import some names on demand so that the dependent modules don't have
19 # to be loaded if they're not needed.
20 
21 _jit_imports = dict(
22     read="hy.reader",
23     read_many="hy.reader",
24     mangle="hy.reader",
25     unmangle="hy.reader",
26     eval=["hy.compiler", "hy_eval"],
27     repr=["hy.core.hy_repr", "hy_repr"],
28     repr_register=["hy.core.hy_repr", "hy_repr_register"],
29     gensym="hy.core.util",
30     macroexpand="hy.core.util",
31     macroexpand_1="hy.core.util",
32     disassemble="hy.core.util",
33     as_model="hy.models",
34     REPL="hy.repl",
35 )
36 
37 
38 def __getattr__(k):
39     if k == "pyops":
40         global pyops
41         import hy.pyops
42 
43         pyops = hy.pyops
44         return pyops
45 
46     if k not in _jit_imports:
47         raise AttributeError(f"module {__name__!r} has no attribute {k!r}")
48     v = _jit_imports[k]
49     module, original_name = v if isinstance(v, list) else (v, k)
50     import importlib
51 
52     globals()[k] = getattr(importlib.import_module(module), original_name)
53     return globals()[k]
54
```

Path: `docs/conf.py`
Content:
```
1 # This file is execfile()d with the current directory set to its containing dir.
2 
3 import html
4 import os
5 import re
6 import sys
7 import time
8 
9 sys.path.insert(0, os.path.abspath(".."))
10 
11 extensions = [
12     "sphinx.ext.napoleon",
13     "sphinx.ext.intersphinx",
14     "sphinx.ext.autodoc",
15     "sphinx.ext.viewcode",
16     "sphinxcontrib.hydomain",
17 ]
18 
19 from get_version import __version__ as hy_version
20 
21 # Read the Docs might dirty its checkout, so strip the dirty flag.
22 hy_version = re.sub(r"[+.]dirty\Z", "", hy_version)
23 
24 templates_path = ["_templates"]
25 source_suffix = ".rst"
26 
27 master_doc = "index"
28 
29 # General information about the project.
30 project = "hy"
31 copyright = "%s the authors" % time.strftime("%Y")
32 
33 # The version info for the project you're documenting, acts as replacement for
34 # |version| and |release|, also used in various other places throughout the
35 # built documents.
36 #
37 # The short X.Y version.
38 version = ".".join(hy_version.split(".")[:-1])
39 # The full version, including alpha/beta/rc tags.
40 release = hy_version
41 hy_descriptive_version = html.escape(hy_version)
42 if "+" in hy_version:
43     hy_descriptive_version += " <strong style='color: red;'>(unstable)</strong>"
44 
45 exclude_patterns = ["_build", "coreteam.rst"]
46 add_module_names = True
47 
48 pygments_style = "sphinx"
49 
50 import sphinx_rtd_theme
51 
52 html_theme = "sphinx_rtd_theme"
53 html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
54 
55 # Add any paths that contain custom static files (such as style sheets) here,
56 # relative to this directory. They are copied after the builtin static files,
57 # so a file named "default.css" will overwrite the builtin "default.css".
58 html_static_path = ["_static"]
59 
60 html_use_smartypants = False
61 html_show_sphinx = False
62 
63 html_context = dict(
64     hy_descriptive_version=hy_descriptive_version)
65 
66 highlight_language = "clojure"
67 
68 intersphinx_mapping = dict(
69     py=("https://docs.python.org/3/", None),
70     py3_10=("https://docs.python.org/3.10/", None),
71     hyrule=("https://hyrule.readthedocs.io/en/master/", None),
72 )
73 # ** Generate Cheatsheet
74 import json
75 from itertools import zip_longest
76 from pathlib import Path
77 
78 
79 def refize(spec):
80     role = ":hy:func:"
81     if isinstance(spec, dict):
82         _name = spec["name"]
83         uri = spec["uri"]
84         if spec.get("internal"):
85             role = ":ref:"
86     else:
87         uri = spec
88         _name = str.split(uri, ".")[-1]
89     return "{}`{} <{}>`".format(role, _name, uri)
90 
91 
92 def format_refs(refs, indent):
93     args = [iter(map(refize, refs))]
94     ref_groups = zip_longest(*args, fillvalue="")
95     return str.join(
96         " \\\n" + " " * (indent + 3),
97         [str.join(" ", ref_group) for ref_group in ref_groups],
98     )
99 
100 
101 def format_row(category, divider_loc):
102     return "{title: <{width}} | {methods}".format(
103         width=divider_loc,
104         title=category["name"],
105         methods=format_refs(category["methods"], divider_loc),
106     )
107 
108 
109 def format_table(table_spec):
110     table_name = table_spec["name"]
111     categories = table_spec["categories"]
112     longest_cat_name = max(len(category["name"]) for category in categories)
113     table = [
114         table_name,
115         "-" * len(table_name),
116         "",
117         "=" * longest_cat_name + " " + "=" * 25,
118         *(format_row(category, longest_cat_name) for category in categories),
119         "=" * longest_cat_name + " " + "=" * 25,
120         "",
121     ]
122     return "\n".join(table)
123 
124 
125 # Modifications to the cheatsheet should be added in `cheatsheet.json`
126 cheatsheet_spec = json.loads(Path("./docs/cheatsheet.json").read_text())
127 cheatsheet = [
128     "..",
129     "    DO NOT MODIFY THIS FILE. IT IS AUTO GENERATED BY ``conf.py``",
130     "    If you need to change or add methods, modify ``cheatsheet_spec`` in ``conf.py``",
131     "",
132     ".. _cheatsheet:",
133     "",
134     "Cheatsheet",
135     "==========",
136     "",
137     *map(format_table, cheatsheet_spec),
138 ]
139 Path("./docs/cheatsheet.rst").write_text("\n".join(cheatsheet))
140 
141 
142 # ** Sphinx App Setup
143 
144 
145 def setup(app):
146     app.add_css_file("overrides.css")
147
```
--- 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/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -70,6 +70,10 @@
     py3_10=("https://docs.python.org/3.10/", None),
     hyrule=("https://hyrule.readthedocs.io/en/master/", None),
 )
+
+import hy
+hy.M = type(hy.M)  # A trick to enable `hy:autoclass:: hy.M`
+
 # ** Generate Cheatsheet
 import json
 from itertools import zip_longest
diff --git a/hy/__init__.py b/hy/__init__.py
--- a/hy/__init__.py
+++ b/hy/__init__.py
@@ -15,6 +15,23 @@
 hy.importer._inject_builtins()
 # we import for side-effects.
 
+
+class M:
+    """``hy.M`` is an object that provides syntactic sugar for imports. It allows syntax like ``(hy.M.math.sqrt 2)``  to mean ``(import math) (math.sqrt 2)``, except without bringing ``math`` or ``math.sqrt`` into scope. This is useful in macros to avoid namespace pollution. To refer to a module with dots in its name, use slashes instead: ``hy.M.os/path.basename`` gets the function ``basename`` from the module ``os.path``.
+
+    You can also call ``hy.M`` like a function, as in ``(hy.M "math")``, which is useful when the module name isn't known until run-time. This interface just calls :py:func:`importlib.import_module`, avoiding (1) mangling due to attribute lookup, and (2) the translation of ``/`` to ``.`` in the module name. The advantage of ``(hy.M modname)`` over ``importlib.import_module(modname)`` is merely that it avoids bringing ``importlib`` itself into scope."""
+    def __call__(self, module_name):
+        import importlib
+        return importlib.import_module(module_name)
+    def __getattr__(self, s):
+        import re
+        return self(hy.mangle(re.sub(
+            r'/(-*)',
+            lambda m: '.' + '_' * len(m.group(1)),
+            hy.unmangle(s))))
+M = M()
+
+
 # Import some names on demand so that the dependent modules don't have
 # to be loaded if they're not needed.

{"golden_diff": "diff --git a/docs/conf.py b/docs/conf.py\n--- a/docs/conf.py\n+++ b/docs/conf.py\n@@ -70,6 +70,10 @@\n     py3_10=(\"https://docs.python.org/3.10/\", None),\n     hyrule=(\"https://hyrule.readthedocs.io/en/master/\", None),\n )\n+\n+import hy\n+hy.M = type(hy.M)  # A trick to enable `hy:autoclass:: hy.M`\n+\n # ** Generate Cheatsheet\n import json\n from itertools import zip_longest\ndiff --git a/hy/__init__.py b/hy/__init__.py\n--- a/hy/__init__.py\n+++ b/hy/__init__.py\n@@ -15,6 +15,23 @@\n hy.importer._inject_builtins()\n # we import for side-effects.\n \n+\n+class M:\n+    \"\"\"``hy.M`` is an object that provides syntactic sugar for imports. It allows syntax like ``(hy.M.math.sqrt 2)``  to mean ``(import math) (math.sqrt 2)``, except without bringing ``math`` or ``math.sqrt`` into scope. This is useful in macros to avoid namespace pollution. To refer to a module with dots in its name, use slashes instead: ``hy.M.os/path.basename`` gets the function ``basename`` from the module ``os.path``.\n+\n+    You can also call ``hy.M`` like a function, as in ``(hy.M \"math\")``, which is useful when the module name isn't known until run-time. This interface just calls :py:func:`importlib.import_module`, avoiding (1) mangling due to attribute lookup, and (2) the translation of ``/`` to ``.`` in the module name. The advantage of ``(hy.M modname)`` over ``importlib.import_module(modname)`` is merely that it avoids bringing ``importlib`` itself into scope.\"\"\"\n+    def __call__(self, module_name):\n+        import importlib\n+        return importlib.import_module(module_name)\n+    def __getattr__(self, s):\n+        import re\n+        return self(hy.mangle(re.sub(\n+            r'/(-*)',\n+            lambda m: '.' + '_' * len(m.group(1)),\n+            hy.unmangle(s))))\n+M = M()\n+\n+\n # Import some names on demand so that the dependent modules don't have\n # to be loaded if they're not needed.\n", "issue": "`hy.M` sugar for import on demand\nIt's annoying to have to import to a gensym when you want to use a function from another module in a macro expansion. Suppose you could say `(hy.M.math.sqrt 2)` to call `math.sqrt` without actually binding `math` or `math.sqrt` to some name in the local scope. In addition to making macros neater, this could be convenient as a general shorthand for using something from a module, particularly a module with a long name, without having to add a separate `import` form.\r\n\r\nTo get a module whose name itself has dots, one could use `/` instead of the dots, so `(hy.M.foo/bar/baz.bing)` would work like `(import foo.bar.baz) (foo.bar.baz.bing)`.\r\n\r\nHere's a simple implementation:\r\n\r\n```python\r\nimport hy\r\n\r\nclass M:\r\n    def __call__(self, module_name):\r\n        import importlib\r\n        return importlib.import_module(module_name)\r\n    def __getattr__(self, s):\r\n        return self('.'.join(hy.unmangle(s).split('/')))\r\n\r\nhy.M = M()\r\nhy.eval(hy.read_many('''\r\n(print hy.M.sklearn/neighbors.KNeighborsRegressor)\r\n'''))\r\n```\r\n\r\nThe nice thing about this feature is that it can be added without changing Hy's syntax or touching the set of core macros.\r\n\r\n`__call__` is provided so you can also say `(hy.M \"foo.bar.baz\")` to get the module `foo.bar.baz`, which may be more convenient when the module name isn't known until runtime.\r\n\r\nThis sort of feature could probably be provided for requiring macros, too.\n", "before_files": [{"content": "try:\n    from hy.version import __version__\nexcept ImportError:\n    __version__ = \"unknown\"\n\n\ndef _initialize_env_var(env_var, default_val):\n    import os\n\n    return bool(os.environ.get(env_var, default_val))\n\n\nimport hy.importer  # NOQA\n\nhy.importer._inject_builtins()\n# we import for side-effects.\n\n# Import some names on demand so that the dependent modules don't have\n# to be loaded if they're not needed.\n\n_jit_imports = dict(\n    read=\"hy.reader\",\n    read_many=\"hy.reader\",\n    mangle=\"hy.reader\",\n    unmangle=\"hy.reader\",\n    eval=[\"hy.compiler\", \"hy_eval\"],\n    repr=[\"hy.core.hy_repr\", \"hy_repr\"],\n    repr_register=[\"hy.core.hy_repr\", \"hy_repr_register\"],\n    gensym=\"hy.core.util\",\n    macroexpand=\"hy.core.util\",\n    macroexpand_1=\"hy.core.util\",\n    disassemble=\"hy.core.util\",\n    as_model=\"hy.models\",\n    REPL=\"hy.repl\",\n)\n\n\ndef __getattr__(k):\n    if k == \"pyops\":\n        global pyops\n        import hy.pyops\n\n        pyops = hy.pyops\n        return pyops\n\n    if k not in _jit_imports:\n        raise AttributeError(f\"module {__name__!r} has no attribute {k!r}\")\n    v = _jit_imports[k]\n    module, original_name = v if isinstance(v, list) else (v, k)\n    import importlib\n\n    globals()[k] = getattr(importlib.import_module(module), original_name)\n    return globals()[k]\n", "path": "hy/__init__.py"}, {"content": "# This file is execfile()d with the current directory set to its containing dir.\n\nimport html\nimport os\nimport re\nimport sys\nimport time\n\nsys.path.insert(0, os.path.abspath(\"..\"))\n\nextensions = [\n    \"sphinx.ext.napoleon\",\n    \"sphinx.ext.intersphinx\",\n    \"sphinx.ext.autodoc\",\n    \"sphinx.ext.viewcode\",\n    \"sphinxcontrib.hydomain\",\n]\n\nfrom get_version import __version__ as hy_version\n\n# Read the Docs might dirty its checkout, so strip the dirty flag.\nhy_version = re.sub(r\"[+.]dirty\\Z\", \"\", hy_version)\n\ntemplates_path = [\"_templates\"]\nsource_suffix = \".rst\"\n\nmaster_doc = \"index\"\n\n# General information about the project.\nproject = \"hy\"\ncopyright = \"%s the authors\" % time.strftime(\"%Y\")\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = \".\".join(hy_version.split(\".\")[:-1])\n# The full version, including alpha/beta/rc tags.\nrelease = hy_version\nhy_descriptive_version = html.escape(hy_version)\nif \"+\" in hy_version:\n    hy_descriptive_version += \" <strong style='color: red;'>(unstable)</strong>\"\n\nexclude_patterns = [\"_build\", \"coreteam.rst\"]\nadd_module_names = True\n\npygments_style = \"sphinx\"\n\nimport sphinx_rtd_theme\n\nhtml_theme = \"sphinx_rtd_theme\"\nhtml_theme_path = [sphinx_rtd_theme.get_html_theme_path()]\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = [\"_static\"]\n\nhtml_use_smartypants = False\nhtml_show_sphinx = False\n\nhtml_context = dict(\n    hy_descriptive_version=hy_descriptive_version)\n\nhighlight_language = \"clojure\"\n\nintersphinx_mapping = dict(\n    py=(\"https://docs.python.org/3/\", None),\n    py3_10=(\"https://docs.python.org/3.10/\", None),\n    hyrule=(\"https://hyrule.readthedocs.io/en/master/\", None),\n)\n# ** Generate Cheatsheet\nimport json\nfrom itertools import zip_longest\nfrom pathlib import Path\n\n\ndef refize(spec):\n    role = \":hy:func:\"\n    if isinstance(spec, dict):\n        _name = spec[\"name\"]\n        uri = spec[\"uri\"]\n        if spec.get(\"internal\"):\n            role = \":ref:\"\n    else:\n        uri = spec\n        _name = str.split(uri, \".\")[-1]\n    return \"{}`{} <{}>`\".format(role, _name, uri)\n\n\ndef format_refs(refs, indent):\n    args = [iter(map(refize, refs))]\n    ref_groups = zip_longest(*args, fillvalue=\"\")\n    return str.join(\n        \" \\\\\\n\" + \" \" * (indent + 3),\n        [str.join(\" \", ref_group) for ref_group in ref_groups],\n    )\n\n\ndef format_row(category, divider_loc):\n    return \"{title: <{width}} | {methods}\".format(\n        width=divider_loc,\n        title=category[\"name\"],\n        methods=format_refs(category[\"methods\"], divider_loc),\n    )\n\n\ndef format_table(table_spec):\n    table_name = table_spec[\"name\"]\n    categories = table_spec[\"categories\"]\n    longest_cat_name = max(len(category[\"name\"]) for category in categories)\n    table = [\n        table_name,\n        \"-\" * len(table_name),\n        \"\",\n        \"=\" * longest_cat_name + \" \" + \"=\" * 25,\n        *(format_row(category, longest_cat_name) for category in categories),\n        \"=\" * longest_cat_name + \" \" + \"=\" * 25,\n        \"\",\n    ]\n    return \"\\n\".join(table)\n\n\n# Modifications to the cheatsheet should be added in `cheatsheet.json`\ncheatsheet_spec = json.loads(Path(\"./docs/cheatsheet.json\").read_text())\ncheatsheet = [\n    \"..\",\n    \"    DO NOT MODIFY THIS FILE. IT IS AUTO GENERATED BY ``conf.py``\",\n    \"    If you need to change or add methods, modify ``cheatsheet_spec`` in ``conf.py``\",\n    \"\",\n    \".. _cheatsheet:\",\n    \"\",\n    \"Cheatsheet\",\n    \"==========\",\n    \"\",\n    *map(format_table, cheatsheet_spec),\n]\nPath(\"./docs/cheatsheet.rst\").write_text(\"\\n\".join(cheatsheet))\n\n\n# ** Sphinx App Setup\n\n\ndef setup(app):\n    app.add_css_file(\"overrides.css\")\n", "path": "docs/conf.py"}], "after_files": [{"content": "try:\n    from hy.version import __version__\nexcept ImportError:\n    __version__ = \"unknown\"\n\n\ndef _initialize_env_var(env_var, default_val):\n    import os\n\n    return bool(os.environ.get(env_var, default_val))\n\n\nimport hy.importer  # NOQA\n\nhy.importer._inject_builtins()\n# we import for side-effects.\n\n\nclass M:\n    \"\"\"``hy.M`` is an object that provides syntactic sugar for imports. It allows syntax like ``(hy.M.math.sqrt 2)``  to mean ``(import math) (math.sqrt 2)``, except without bringing ``math`` or ``math.sqrt`` into scope. This is useful in macros to avoid namespace pollution. To refer to a module with dots in its name, use slashes instead: ``hy.M.os/path.basename`` gets the function ``basename`` from the module ``os.path``.\n\n    You can also call ``hy.M`` like a function, as in ``(hy.M \"math\")``, which is useful when the module name isn't known until run-time. This interface just calls :py:func:`importlib.import_module`, avoiding (1) mangling due to attribute lookup, and (2) the translation of ``/`` to ``.`` in the module name. The advantage of ``(hy.M modname)`` over ``importlib.import_module(modname)`` is merely that it avoids bringing ``importlib`` itself into scope.\"\"\"\n    def __call__(self, module_name):\n        import importlib\n        return importlib.import_module(module_name)\n    def __getattr__(self, s):\n        import re\n        return self(hy.mangle(re.sub(\n            r'/(-*)',\n            lambda m: '.' + '_' * len(m.group(1)),\n            hy.unmangle(s))))\nM = M()\n\n\n# Import some names on demand so that the dependent modules don't have\n# to be loaded if they're not needed.\n\n_jit_imports = dict(\n    read=\"hy.reader\",\n    read_many=\"hy.reader\",\n    mangle=\"hy.reader\",\n    unmangle=\"hy.reader\",\n    eval=[\"hy.compiler\", \"hy_eval\"],\n    repr=[\"hy.core.hy_repr\", \"hy_repr\"],\n    repr_register=[\"hy.core.hy_repr\", \"hy_repr_register\"],\n    gensym=\"hy.core.util\",\n    macroexpand=\"hy.core.util\",\n    macroexpand_1=\"hy.core.util\",\n    disassemble=\"hy.core.util\",\n    as_model=\"hy.models\",\n    REPL=\"hy.repl\",\n)\n\n\ndef __getattr__(k):\n    if k == \"pyops\":\n        global pyops\n        import hy.pyops\n\n        pyops = hy.pyops\n        return pyops\n\n    if k not in _jit_imports:\n        raise AttributeError(f\"module {__name__!r} has no attribute {k!r}\")\n    v = _jit_imports[k]\n    module, original_name = v if isinstance(v, list) else (v, k)\n    import importlib\n\n    globals()[k] = getattr(importlib.import_module(module), original_name)\n    return globals()[k]\n", "path": "hy/__init__.py"}, {"content": "# This file is execfile()d with the current directory set to its containing dir.\n\nimport html\nimport os\nimport re\nimport sys\nimport time\n\nsys.path.insert(0, os.path.abspath(\"..\"))\n\nextensions = [\n    \"sphinx.ext.napoleon\",\n    \"sphinx.ext.intersphinx\",\n    \"sphinx.ext.autodoc\",\n    \"sphinx.ext.viewcode\",\n    \"sphinxcontrib.hydomain\",\n]\n\nfrom get_version import __version__ as hy_version\n\n# Read the Docs might dirty its checkout, so strip the dirty flag.\nhy_version = re.sub(r\"[+.]dirty\\Z\", \"\", hy_version)\n\ntemplates_path = [\"_templates\"]\nsource_suffix = \".rst\"\n\nmaster_doc = \"index\"\n\n# General information about the project.\nproject = \"hy\"\ncopyright = \"%s the authors\" % time.strftime(\"%Y\")\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = \".\".join(hy_version.split(\".\")[:-1])\n# The full version, including alpha/beta/rc tags.\nrelease = hy_version\nhy_descriptive_version = html.escape(hy_version)\nif \"+\" in hy_version:\n    hy_descriptive_version += \" <strong style='color: red;'>(unstable)</strong>\"\n\nexclude_patterns = [\"_build\", \"coreteam.rst\"]\nadd_module_names = True\n\npygments_style = \"sphinx\"\n\nimport sphinx_rtd_theme\n\nhtml_theme = \"sphinx_rtd_theme\"\nhtml_theme_path = [sphinx_rtd_theme.get_html_theme_path()]\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = [\"_static\"]\n\nhtml_use_smartypants = False\nhtml_show_sphinx = False\n\nhtml_context = dict(\n    hy_descriptive_version=hy_descriptive_version)\n\nhighlight_language = \"clojure\"\n\nintersphinx_mapping = dict(\n    py=(\"https://docs.python.org/3/\", None),\n    py3_10=(\"https://docs.python.org/3.10/\", None),\n    hyrule=(\"https://hyrule.readthedocs.io/en/master/\", None),\n)\n\nimport hy\nhy.M = type(hy.M)  # A trick to enable `hy:autoclass:: hy.M`\n\n# ** Generate Cheatsheet\nimport json\nfrom itertools import zip_longest\nfrom pathlib import Path\n\n\ndef refize(spec):\n    role = \":hy:func:\"\n    if isinstance(spec, dict):\n        _name = spec[\"name\"]\n        uri = spec[\"uri\"]\n        if spec.get(\"internal\"):\n            role = \":ref:\"\n    else:\n        uri = spec\n        _name = str.split(uri, \".\")[-1]\n    return \"{}`{} <{}>`\".format(role, _name, uri)\n\n\ndef format_refs(refs, indent):\n    args = [iter(map(refize, refs))]\n    ref_groups = zip_longest(*args, fillvalue=\"\")\n    return str.join(\n        \" \\\\\\n\" + \" \" * (indent + 3),\n        [str.join(\" \", ref_group) for ref_group in ref_groups],\n    )\n\n\ndef format_row(category, divider_loc):\n    return \"{title: <{width}} | {methods}\".format(\n        width=divider_loc,\n        title=category[\"name\"],\n        methods=format_refs(category[\"methods\"], divider_loc),\n    )\n\n\ndef format_table(table_spec):\n    table_name = table_spec[\"name\"]\n    categories = table_spec[\"categories\"]\n    longest_cat_name = max(len(category[\"name\"]) for category in categories)\n    table = [\n        table_name,\n        \"-\" * len(table_name),\n        \"\",\n        \"=\" * longest_cat_name + \" \" + \"=\" * 25,\n        *(format_row(category, longest_cat_name) for category in categories),\n        \"=\" * longest_cat_name + \" \" + \"=\" * 25,\n        \"\",\n    ]\n    return \"\\n\".join(table)\n\n\n# Modifications to the cheatsheet should be added in `cheatsheet.json`\ncheatsheet_spec = json.loads(Path(\"./docs/cheatsheet.json\").read_text())\ncheatsheet = [\n    \"..\",\n    \"    DO NOT MODIFY THIS FILE. IT IS AUTO GENERATED BY ``conf.py``\",\n    \"    If you need to change or add methods, modify ``cheatsheet_spec`` in ``conf.py``\",\n    \"\",\n    \".. _cheatsheet:\",\n    \"\",\n    \"Cheatsheet\",\n    \"==========\",\n    \"\",\n    *map(format_table, cheatsheet_spec),\n]\nPath(\"./docs/cheatsheet.rst\").write_text(\"\\n\".join(cheatsheet))\n\n\n# ** Sphinx App Setup\n\n\ndef setup(app):\n    app.add_css_file(\"overrides.css\")\n", "path": "docs/conf.py"}]}