We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Import from zip files
It would be handy to be able to import .hy files from .zip archives (for those of us who like to deploy stuff in single file bundles).

Right now I'm working around this by doing:

```
BUNDLE=sushy.zip

clean:
    rm *.zip

bundle:
    hyc sushy/*.hy
    zip -r9 $(BUNDLE) . -i *.py *.pyc

test-bundle:
    PYTHONPATH=$(BUNDLE) python -m sushy
```


--- 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/importer.py`
Content:
```
1 import builtins
2 import importlib
3 import inspect
4 import os
5 import pkgutil
6 import sys
7 import types
8 from contextlib import contextmanager
9 from functools import partial
10 
11 import hy
12 from hy.compiler import hy_compile
13 from hy.reader import read_many
14 
15 
16 @contextmanager
17 def loader_module_obj(loader):
18     """Use the module object associated with a loader.
19 
20     This is intended to be used by a loader object itself, and primarily as a
21     work-around for attempts to get module and/or file code from a loader
22     without actually creating a module object.  Since Hy currently needs the
23     module object for macro importing, expansion, and whatnot, using this will
24     reconcile Hy with such attempts.
25 
26     For example, if we're first compiling a Hy script starting from
27     `runpy.run_path`, the Hy compiler will need a valid module object in which
28     to run, but, given the way `runpy.run_path` works, there might not be one
29     yet (e.g. `__main__` for a .hy file).  We compensate by properly loading
30     the module here.
31 
32     The function `inspect.getmodule` has a hidden-ish feature that returns
33     modules using their associated filenames (via `inspect.modulesbyfile`),
34     and, since the Loaders (and their delegate Loaders) carry a filename/path
35     associated with the parent package, we use it as a more robust attempt to
36     obtain an existing module object.
37 
38     When no module object is found, a temporary, minimally sufficient module
39     object is created for the duration of the `with` body.
40     """
41     tmp_mod = False
42 
43     try:
44         module = inspect.getmodule(None, _filename=loader.path)
45     except KeyError:
46         module = None
47 
48     if module is None:
49         tmp_mod = True
50         module = sys.modules.setdefault(loader.name, types.ModuleType(loader.name))
51         module.__file__ = loader.path
52         module.__name__ = loader.name
53 
54     try:
55         yield module
56     finally:
57         if tmp_mod:
58             del sys.modules[loader.name]
59 
60 
61 def _hy_code_from_file(filename, loader_type=None):
62     """Use PEP-302 loader to produce code for a given Hy source file."""
63     full_fname = os.path.abspath(filename)
64     fname_path, fname_file = os.path.split(full_fname)
65     modname = os.path.splitext(fname_file)[0]
66     sys.path.insert(0, fname_path)
67     try:
68         if loader_type is None:
69             loader = pkgutil.get_loader(modname)
70         else:
71             loader = loader_type(modname, full_fname)
72         code = loader.get_code(modname)
73     finally:
74         sys.path.pop(0)
75 
76     return code
77 
78 
79 def _get_code_from_file(run_name, fname=None, hy_src_check=lambda x: x.endswith(".hy")):
80     """A patch of `runpy._get_code_from_file` that will also run and cache Hy
81     code.
82     """
83     if fname is None and run_name is not None:
84         fname = run_name
85 
86     # Check for bytecode first.  (This is what the `runpy` version does!)
87     with open(fname, "rb") as f:
88         code = pkgutil.read_code(f)
89 
90     if code is None:
91         if hy_src_check(fname):
92             code = _hy_code_from_file(fname, loader_type=HyLoader)
93         else:
94             # Try normal source
95             with open(fname, "rb") as f:
96                 # This code differs from `runpy`'s only in that we
97                 # force decoding into UTF-8.
98                 source = f.read().decode("utf-8")
99             code = compile(source, fname, "exec")
100 
101     return (code, fname)
102 
103 
104 importlib.machinery.SOURCE_SUFFIXES.insert(0, ".hy")
105 _py_source_to_code = importlib.machinery.SourceFileLoader.source_to_code
106 
107 
108 def _could_be_hy_src(filename):
109     return os.path.isfile(filename) and (
110         filename.endswith(".hy")
111         or not any(
112             filename.endswith(ext) for ext in importlib.machinery.SOURCE_SUFFIXES[1:]
113         )
114     )
115 
116 
117 def _hy_source_to_code(self, data, path, _optimize=-1):
118     if _could_be_hy_src(path):
119         if os.environ.get("HY_MESSAGE_WHEN_COMPILING"):
120             print("Compiling", path, file=sys.stderr)
121         source = data.decode("utf-8")
122         hy_tree = read_many(source, filename=path, skip_shebang=True)
123         with loader_module_obj(self) as module:
124             data = hy_compile(hy_tree, module)
125 
126     return _py_source_to_code(self, data, path, _optimize=_optimize)
127 
128 
129 importlib.machinery.SourceFileLoader.source_to_code = _hy_source_to_code
130 
131 #  This is actually needed; otherwise, pre-created finders assigned to the
132 #  current dir (i.e. `''`) in `sys.path` will not catch absolute imports of
133 #  directory-local modules!
134 sys.path_importer_cache.clear()
135 
136 # Do this one just in case?
137 importlib.invalidate_caches()
138 
139 # These aren't truly cross-compliant.
140 # They're useful for testing, though.
141 class HyImporter(importlib.machinery.FileFinder):
142     pass
143 
144 
145 class HyLoader(importlib.machinery.SourceFileLoader):
146     pass
147 
148 
149 # We create a separate version of runpy, "runhy", that prefers Hy source over
150 # Python.
151 runhy = importlib.import_module("runpy")
152 
153 runhy._get_code_from_file = partial(_get_code_from_file, hy_src_check=_could_be_hy_src)
154 
155 del sys.modules["runpy"]
156 
157 runpy = importlib.import_module("runpy")
158 
159 _runpy_get_code_from_file = runpy._get_code_from_file
160 runpy._get_code_from_file = _get_code_from_file
161 
162 
163 def _import_from_path(name, path):
164     """A helper function that imports a module from the given path."""
165     spec = importlib.util.spec_from_file_location(name, path)
166     mod = importlib.util.module_from_spec(spec)
167     spec.loader.exec_module(mod)
168     return mod
169 
170 
171 def _inject_builtins():
172     """Inject the Hy core macros into Python's builtins if necessary"""
173     if hasattr(builtins, "__hy_injected__"):
174         return
175     hy.macros.load_macros(builtins)
176     # Set the marker so we don't inject again.
177     builtins.__hy_injected__ = True
178
```
--- 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/hy/importer.py b/hy/importer.py
--- a/hy/importer.py
+++ b/hy/importer.py
@@ -5,10 +5,12 @@
 import pkgutil
 import sys
 import types
+import zipimport
 from contextlib import contextmanager
 from functools import partial
 
 import hy
+from hy._compat import PY3_8
 from hy.compiler import hy_compile
 from hy.reader import read_many
 
@@ -107,10 +109,8 @@
 
 def _could_be_hy_src(filename):
     return os.path.isfile(filename) and (
-        filename.endswith(".hy")
-        or not any(
-            filename.endswith(ext) for ext in importlib.machinery.SOURCE_SUFFIXES[1:]
-        )
+        os.path.splitext(filename)[1]
+        not in set(importlib.machinery.SOURCE_SUFFIXES) - {".hy"}
     )
 
 
@@ -128,6 +128,27 @@
 
 importlib.machinery.SourceFileLoader.source_to_code = _hy_source_to_code
 
+
+if PY3_8 and (".hy", False, False) not in zipimport._zip_searchorder:
+    zipimport._zip_searchorder += ((".hy", False, False),)
+    _py_compile_source = zipimport._compile_source
+
+    def _hy_compile_source(pathname, source):
+        if not pathname.endswith(".hy"):
+            return _py_compile_source(pathname, source)
+        return compile(
+            hy_compile(
+                read_many(source.decode("UTF-8"), filename=pathname, skip_shebang=True),
+                f"<zip:{pathname}>",
+            ),
+            pathname,
+            "exec",
+            dont_inherit=True,
+        )
+
+    zipimport._compile_source = _hy_compile_source
+
+
 #  This is actually needed; otherwise, pre-created finders assigned to the
 #  current dir (i.e. `''`) in `sys.path` will not catch absolute imports of
 #  directory-local modules!

{"golden_diff": "diff --git a/hy/importer.py b/hy/importer.py\n--- a/hy/importer.py\n+++ b/hy/importer.py\n@@ -5,10 +5,12 @@\n import pkgutil\n import sys\n import types\n+import zipimport\n from contextlib import contextmanager\n from functools import partial\n \n import hy\n+from hy._compat import PY3_8\n from hy.compiler import hy_compile\n from hy.reader import read_many\n \n@@ -107,10 +109,8 @@\n \n def _could_be_hy_src(filename):\n     return os.path.isfile(filename) and (\n-        filename.endswith(\".hy\")\n-        or not any(\n-            filename.endswith(ext) for ext in importlib.machinery.SOURCE_SUFFIXES[1:]\n-        )\n+        os.path.splitext(filename)[1]\n+        not in set(importlib.machinery.SOURCE_SUFFIXES) - {\".hy\"}\n     )\n \n \n@@ -128,6 +128,27 @@\n \n importlib.machinery.SourceFileLoader.source_to_code = _hy_source_to_code\n \n+\n+if PY3_8 and (\".hy\", False, False) not in zipimport._zip_searchorder:\n+    zipimport._zip_searchorder += ((\".hy\", False, False),)\n+    _py_compile_source = zipimport._compile_source\n+\n+    def _hy_compile_source(pathname, source):\n+        if not pathname.endswith(\".hy\"):\n+            return _py_compile_source(pathname, source)\n+        return compile(\n+            hy_compile(\n+                read_many(source.decode(\"UTF-8\"), filename=pathname, skip_shebang=True),\n+                f\"<zip:{pathname}>\",\n+            ),\n+            pathname,\n+            \"exec\",\n+            dont_inherit=True,\n+        )\n+\n+    zipimport._compile_source = _hy_compile_source\n+\n+\n #  This is actually needed; otherwise, pre-created finders assigned to the\n #  current dir (i.e. `''`) in `sys.path` will not catch absolute imports of\n #  directory-local modules!\n", "issue": "Import from zip files\nIt would be handy to be able to import .hy files from .zip archives (for those of us who like to deploy stuff in single file bundles).\n\nRight now I'm working around this by doing:\n\n```\nBUNDLE=sushy.zip\n\nclean:\n    rm *.zip\n\nbundle:\n    hyc sushy/*.hy\n    zip -r9 $(BUNDLE) . -i *.py *.pyc\n\ntest-bundle:\n    PYTHONPATH=$(BUNDLE) python -m sushy\n```\n\n", "before_files": [{"content": "import builtins\nimport importlib\nimport inspect\nimport os\nimport pkgutil\nimport sys\nimport types\nfrom contextlib import contextmanager\nfrom functools import partial\n\nimport hy\nfrom hy.compiler import hy_compile\nfrom hy.reader import read_many\n\n\n@contextmanager\ndef loader_module_obj(loader):\n    \"\"\"Use the module object associated with a loader.\n\n    This is intended to be used by a loader object itself, and primarily as a\n    work-around for attempts to get module and/or file code from a loader\n    without actually creating a module object.  Since Hy currently needs the\n    module object for macro importing, expansion, and whatnot, using this will\n    reconcile Hy with such attempts.\n\n    For example, if we're first compiling a Hy script starting from\n    `runpy.run_path`, the Hy compiler will need a valid module object in which\n    to run, but, given the way `runpy.run_path` works, there might not be one\n    yet (e.g. `__main__` for a .hy file).  We compensate by properly loading\n    the module here.\n\n    The function `inspect.getmodule` has a hidden-ish feature that returns\n    modules using their associated filenames (via `inspect.modulesbyfile`),\n    and, since the Loaders (and their delegate Loaders) carry a filename/path\n    associated with the parent package, we use it as a more robust attempt to\n    obtain an existing module object.\n\n    When no module object is found, a temporary, minimally sufficient module\n    object is created for the duration of the `with` body.\n    \"\"\"\n    tmp_mod = False\n\n    try:\n        module = inspect.getmodule(None, _filename=loader.path)\n    except KeyError:\n        module = None\n\n    if module is None:\n        tmp_mod = True\n        module = sys.modules.setdefault(loader.name, types.ModuleType(loader.name))\n        module.__file__ = loader.path\n        module.__name__ = loader.name\n\n    try:\n        yield module\n    finally:\n        if tmp_mod:\n            del sys.modules[loader.name]\n\n\ndef _hy_code_from_file(filename, loader_type=None):\n    \"\"\"Use PEP-302 loader to produce code for a given Hy source file.\"\"\"\n    full_fname = os.path.abspath(filename)\n    fname_path, fname_file = os.path.split(full_fname)\n    modname = os.path.splitext(fname_file)[0]\n    sys.path.insert(0, fname_path)\n    try:\n        if loader_type is None:\n            loader = pkgutil.get_loader(modname)\n        else:\n            loader = loader_type(modname, full_fname)\n        code = loader.get_code(modname)\n    finally:\n        sys.path.pop(0)\n\n    return code\n\n\ndef _get_code_from_file(run_name, fname=None, hy_src_check=lambda x: x.endswith(\".hy\")):\n    \"\"\"A patch of `runpy._get_code_from_file` that will also run and cache Hy\n    code.\n    \"\"\"\n    if fname is None and run_name is not None:\n        fname = run_name\n\n    # Check for bytecode first.  (This is what the `runpy` version does!)\n    with open(fname, \"rb\") as f:\n        code = pkgutil.read_code(f)\n\n    if code is None:\n        if hy_src_check(fname):\n            code = _hy_code_from_file(fname, loader_type=HyLoader)\n        else:\n            # Try normal source\n            with open(fname, \"rb\") as f:\n                # This code differs from `runpy`'s only in that we\n                # force decoding into UTF-8.\n                source = f.read().decode(\"utf-8\")\n            code = compile(source, fname, \"exec\")\n\n    return (code, fname)\n\n\nimportlib.machinery.SOURCE_SUFFIXES.insert(0, \".hy\")\n_py_source_to_code = importlib.machinery.SourceFileLoader.source_to_code\n\n\ndef _could_be_hy_src(filename):\n    return os.path.isfile(filename) and (\n        filename.endswith(\".hy\")\n        or not any(\n            filename.endswith(ext) for ext in importlib.machinery.SOURCE_SUFFIXES[1:]\n        )\n    )\n\n\ndef _hy_source_to_code(self, data, path, _optimize=-1):\n    if _could_be_hy_src(path):\n        if os.environ.get(\"HY_MESSAGE_WHEN_COMPILING\"):\n            print(\"Compiling\", path, file=sys.stderr)\n        source = data.decode(\"utf-8\")\n        hy_tree = read_many(source, filename=path, skip_shebang=True)\n        with loader_module_obj(self) as module:\n            data = hy_compile(hy_tree, module)\n\n    return _py_source_to_code(self, data, path, _optimize=_optimize)\n\n\nimportlib.machinery.SourceFileLoader.source_to_code = _hy_source_to_code\n\n#  This is actually needed; otherwise, pre-created finders assigned to the\n#  current dir (i.e. `''`) in `sys.path` will not catch absolute imports of\n#  directory-local modules!\nsys.path_importer_cache.clear()\n\n# Do this one just in case?\nimportlib.invalidate_caches()\n\n# These aren't truly cross-compliant.\n# They're useful for testing, though.\nclass HyImporter(importlib.machinery.FileFinder):\n    pass\n\n\nclass HyLoader(importlib.machinery.SourceFileLoader):\n    pass\n\n\n# We create a separate version of runpy, \"runhy\", that prefers Hy source over\n# Python.\nrunhy = importlib.import_module(\"runpy\")\n\nrunhy._get_code_from_file = partial(_get_code_from_file, hy_src_check=_could_be_hy_src)\n\ndel sys.modules[\"runpy\"]\n\nrunpy = importlib.import_module(\"runpy\")\n\n_runpy_get_code_from_file = runpy._get_code_from_file\nrunpy._get_code_from_file = _get_code_from_file\n\n\ndef _import_from_path(name, path):\n    \"\"\"A helper function that imports a module from the given path.\"\"\"\n    spec = importlib.util.spec_from_file_location(name, path)\n    mod = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(mod)\n    return mod\n\n\ndef _inject_builtins():\n    \"\"\"Inject the Hy core macros into Python's builtins if necessary\"\"\"\n    if hasattr(builtins, \"__hy_injected__\"):\n        return\n    hy.macros.load_macros(builtins)\n    # Set the marker so we don't inject again.\n    builtins.__hy_injected__ = True\n", "path": "hy/importer.py"}], "after_files": [{"content": "import builtins\nimport importlib\nimport inspect\nimport os\nimport pkgutil\nimport sys\nimport types\nimport zipimport\nfrom contextlib import contextmanager\nfrom functools import partial\n\nimport hy\nfrom hy._compat import PY3_8\nfrom hy.compiler import hy_compile\nfrom hy.reader import read_many\n\n\n@contextmanager\ndef loader_module_obj(loader):\n    \"\"\"Use the module object associated with a loader.\n\n    This is intended to be used by a loader object itself, and primarily as a\n    work-around for attempts to get module and/or file code from a loader\n    without actually creating a module object.  Since Hy currently needs the\n    module object for macro importing, expansion, and whatnot, using this will\n    reconcile Hy with such attempts.\n\n    For example, if we're first compiling a Hy script starting from\n    `runpy.run_path`, the Hy compiler will need a valid module object in which\n    to run, but, given the way `runpy.run_path` works, there might not be one\n    yet (e.g. `__main__` for a .hy file).  We compensate by properly loading\n    the module here.\n\n    The function `inspect.getmodule` has a hidden-ish feature that returns\n    modules using their associated filenames (via `inspect.modulesbyfile`),\n    and, since the Loaders (and their delegate Loaders) carry a filename/path\n    associated with the parent package, we use it as a more robust attempt to\n    obtain an existing module object.\n\n    When no module object is found, a temporary, minimally sufficient module\n    object is created for the duration of the `with` body.\n    \"\"\"\n    tmp_mod = False\n\n    try:\n        module = inspect.getmodule(None, _filename=loader.path)\n    except KeyError:\n        module = None\n\n    if module is None:\n        tmp_mod = True\n        module = sys.modules.setdefault(loader.name, types.ModuleType(loader.name))\n        module.__file__ = loader.path\n        module.__name__ = loader.name\n\n    try:\n        yield module\n    finally:\n        if tmp_mod:\n            del sys.modules[loader.name]\n\n\ndef _hy_code_from_file(filename, loader_type=None):\n    \"\"\"Use PEP-302 loader to produce code for a given Hy source file.\"\"\"\n    full_fname = os.path.abspath(filename)\n    fname_path, fname_file = os.path.split(full_fname)\n    modname = os.path.splitext(fname_file)[0]\n    sys.path.insert(0, fname_path)\n    try:\n        if loader_type is None:\n            loader = pkgutil.get_loader(modname)\n        else:\n            loader = loader_type(modname, full_fname)\n        code = loader.get_code(modname)\n    finally:\n        sys.path.pop(0)\n\n    return code\n\n\ndef _get_code_from_file(run_name, fname=None, hy_src_check=lambda x: x.endswith(\".hy\")):\n    \"\"\"A patch of `runpy._get_code_from_file` that will also run and cache Hy\n    code.\n    \"\"\"\n    if fname is None and run_name is not None:\n        fname = run_name\n\n    # Check for bytecode first.  (This is what the `runpy` version does!)\n    with open(fname, \"rb\") as f:\n        code = pkgutil.read_code(f)\n\n    if code is None:\n        if hy_src_check(fname):\n            code = _hy_code_from_file(fname, loader_type=HyLoader)\n        else:\n            # Try normal source\n            with open(fname, \"rb\") as f:\n                # This code differs from `runpy`'s only in that we\n                # force decoding into UTF-8.\n                source = f.read().decode(\"utf-8\")\n            code = compile(source, fname, \"exec\")\n\n    return (code, fname)\n\n\nimportlib.machinery.SOURCE_SUFFIXES.insert(0, \".hy\")\n_py_source_to_code = importlib.machinery.SourceFileLoader.source_to_code\n\n\ndef _could_be_hy_src(filename):\n    return os.path.isfile(filename) and (\n        os.path.splitext(filename)[1]\n        not in set(importlib.machinery.SOURCE_SUFFIXES) - {\".hy\"}\n    )\n\n\ndef _hy_source_to_code(self, data, path, _optimize=-1):\n    if _could_be_hy_src(path):\n        if os.environ.get(\"HY_MESSAGE_WHEN_COMPILING\"):\n            print(\"Compiling\", path, file=sys.stderr)\n        source = data.decode(\"utf-8\")\n        hy_tree = read_many(source, filename=path, skip_shebang=True)\n        with loader_module_obj(self) as module:\n            data = hy_compile(hy_tree, module)\n\n    return _py_source_to_code(self, data, path, _optimize=_optimize)\n\n\nimportlib.machinery.SourceFileLoader.source_to_code = _hy_source_to_code\n\n\nif PY3_8 and (\".hy\", False, False) not in zipimport._zip_searchorder:\n    zipimport._zip_searchorder += ((\".hy\", False, False),)\n    _py_compile_source = zipimport._compile_source\n\n    def _hy_compile_source(pathname, source):\n        if not pathname.endswith(\".hy\"):\n            return _py_compile_source(pathname, source)\n        return compile(\n            hy_compile(\n                read_many(source.decode(\"UTF-8\"), filename=pathname, skip_shebang=True),\n                f\"<zip:{pathname}>\",\n            ),\n            pathname,\n            \"exec\",\n            dont_inherit=True,\n        )\n\n    zipimport._compile_source = _hy_compile_source\n\n\n#  This is actually needed; otherwise, pre-created finders assigned to the\n#  current dir (i.e. `''`) in `sys.path` will not catch absolute imports of\n#  directory-local modules!\nsys.path_importer_cache.clear()\n\n# Do this one just in case?\nimportlib.invalidate_caches()\n\n# These aren't truly cross-compliant.\n# They're useful for testing, though.\nclass HyImporter(importlib.machinery.FileFinder):\n    pass\n\n\nclass HyLoader(importlib.machinery.SourceFileLoader):\n    pass\n\n\n# We create a separate version of runpy, \"runhy\", that prefers Hy source over\n# Python.\nrunhy = importlib.import_module(\"runpy\")\n\nrunhy._get_code_from_file = partial(_get_code_from_file, hy_src_check=_could_be_hy_src)\n\ndel sys.modules[\"runpy\"]\n\nrunpy = importlib.import_module(\"runpy\")\n\n_runpy_get_code_from_file = runpy._get_code_from_file\nrunpy._get_code_from_file = _get_code_from_file\n\n\ndef _import_from_path(name, path):\n    \"\"\"A helper function that imports a module from the given path.\"\"\"\n    spec = importlib.util.spec_from_file_location(name, path)\n    mod = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(mod)\n    return mod\n\n\ndef _inject_builtins():\n    \"\"\"Inject the Hy core macros into Python's builtins if necessary\"\"\"\n    if hasattr(builtins, \"__hy_injected__\"):\n        return\n    hy.macros.load_macros(builtins)\n    # Set the marker so we don't inject again.\n    builtins.__hy_injected__ = True\n", "path": "hy/importer.py"}]}