We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
curses and SIGWINCH do not work properly with Hy.
After importing curses under hy, curses is unable to detect the size of the terminal as it is resized.
This manifests as curses.LINES and curses.COLS not being updated, stdscr.getmaxyx not working and so on.

However, the workaround of launching the hy program from python with:
```
import hy
import curses
from main import main_event_loop

if __name__ == "__main__":
    curses.wrapper(main_event_loop, ...)
```
allows curses to dynamically detect the size of the terminal.

I conclude therefore the problem is with the hy binary. My (limited) understanding acquired during tracking down the source of this problem is that curses uses the SIGWINCH signal, so perhaps that is a place to look.

Void linux x86 64bit, python 3.9.0
Freebsd 12.2, python 3.8.6
hy 0.19.0 (reported by pip) installed from git master branch via pip

--- 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/completer.py`
Content:
```
1 import contextlib
2 import os
3 import re
4 import sys
5 import builtins
6 
7 import hy.macros
8 import hy.compiler
9 
10 
11 docomplete = True
12 
13 try:
14     import readline
15 except AttributeError as e:
16     # https://github.com/pyreadline/pyreadline/issues/65
17     if "module 'collections' has no attribute 'Callable'" in str(e):
18         docomplete = False
19     else:
20         raise
21 except ImportError:
22     docomplete = False
23 
24 if docomplete:
25     if sys.platform == 'darwin' and 'libedit' in readline.__doc__:
26         readline_bind = "bind ^I rl_complete"
27     else:
28         readline_bind = "tab: complete"
29 
30 
31 class Completer:
32 
33     def __init__(self, namespace={}):
34         if not isinstance(namespace, dict):
35             raise TypeError('namespace must be a dictionary')
36         self.namespace = namespace
37         self.path = [builtins.__dict__,
38                      namespace]
39 
40         namespace.setdefault('__macros__', {})
41 
42         self.path.append(namespace['__macros__'])
43 
44     def attr_matches(self, text):
45         # Borrowed from IPython's completer
46         m = re.match(r"(\S+(\.[\w-]+)*)\.([\w-]*)$", text)
47 
48         if m:
49             expr, attr = m.group(1, 3)
50             attr = attr.replace("-", "_")
51             expr = expr.replace("-", "_")
52         else:
53             return []
54 
55         try:
56             obj = eval(expr, self.namespace)
57             words = dir(obj)
58         except Exception:
59             return []
60 
61         n = len(attr)
62         matches = []
63         for w in words:
64             if w[:n] == attr:
65                 matches.append("{}.{}".format(
66                     expr.replace("_", "-"), w.replace("_", "-")))
67         return matches
68 
69     def global_matches(self, text):
70         matches = []
71         for p in self.path:
72             for k in p.keys():
73                 if isinstance(k, str):
74                     k = k.replace("_", "-")
75                     if k.startswith(text):
76                         matches.append(k)
77         return matches
78 
79     def complete(self, text, state):
80         if "." in text:
81             matches = self.attr_matches(text)
82         else:
83             matches = self.global_matches(text)
84         try:
85             return matches[state]
86         except IndexError:
87             return None
88 
89 
90 @contextlib.contextmanager
91 def completion(completer=None):
92     delims = "()[]{} "
93     if not completer:
94         completer = Completer()
95 
96     if docomplete:
97         readline.set_completer(completer.complete)
98         readline.set_completer_delims(delims)
99 
100         history = os.environ.get(
101             "HY_HISTORY", os.path.expanduser("~/.hy-history"))
102         readline.parse_and_bind("set blink-matching-paren on")
103 
104         try:
105             readline.read_history_file(history)
106         except OSError:
107             pass
108 
109         readline.parse_and_bind(readline_bind)
110 
111     try:
112         yield
113     finally:
114         if docomplete:
115             try:
116                 readline.write_history_file(history)
117             except OSError:
118                 pass
119
```
--- 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/completer.py b/hy/completer.py
--- a/hy/completer.py
+++ b/hy/completer.py
@@ -8,24 +8,19 @@
 import hy.compiler
 
 
-docomplete = True
-
-try:
-    import readline
-except AttributeError as e:
-    # https://github.com/pyreadline/pyreadline/issues/65
-    if "module 'collections' has no attribute 'Callable'" in str(e):
-        docomplete = False
-    else:
-        raise
-except ImportError:
-    docomplete = False
-
-if docomplete:
-    if sys.platform == 'darwin' and 'libedit' in readline.__doc__:
-        readline_bind = "bind ^I rl_complete"
-    else:
-        readline_bind = "tab: complete"
+# Lazily import `readline` to work around
+# https://bugs.python.org/issue2675#msg265564
+readline = None
+def init_readline():
+    global readline
+    try:
+        import readline
+    except AttributeError as e:
+        # https://github.com/pyreadline/pyreadline/issues/65
+        if "module 'collections' has no attribute 'Callable'" not in str(e):
+            raise
+    except ImportError:
+        pass
 
 
 class Completer:
@@ -86,33 +81,42 @@
         except IndexError:
             return None
 
-
 @contextlib.contextmanager
 def completion(completer=None):
     delims = "()[]{} "
+
+    init_readline()
+    if not readline:
+        # We have nothing to do. Act like a null context manager.
+        yield
+        return
+
     if not completer:
         completer = Completer()
 
-    if docomplete:
-        readline.set_completer(completer.complete)
-        readline.set_completer_delims(delims)
+    if sys.platform == 'darwin' and 'libedit' in readline.__doc__:
+        readline_bind = "bind ^I rl_complete"
+    else:
+        readline_bind = "tab: complete"
 
-        history = os.environ.get(
-            "HY_HISTORY", os.path.expanduser("~/.hy-history"))
-        readline.parse_and_bind("set blink-matching-paren on")
+    readline.set_completer(completer.complete)
+    readline.set_completer_delims(delims)
 
-        try:
-            readline.read_history_file(history)
-        except OSError:
-            pass
+    history = os.environ.get(
+        "HY_HISTORY", os.path.expanduser("~/.hy-history"))
+    readline.parse_and_bind("set blink-matching-paren on")
 
-        readline.parse_and_bind(readline_bind)
+    try:
+        readline.read_history_file(history)
+    except OSError:
+        pass
+
+    readline.parse_and_bind(readline_bind)
 
     try:
         yield
     finally:
-        if docomplete:
-            try:
-                readline.write_history_file(history)
-            except OSError:
-                pass
+        try:
+            readline.write_history_file(history)
+        except OSError:
+            pass

{"golden_diff": "diff --git a/hy/completer.py b/hy/completer.py\n--- a/hy/completer.py\n+++ b/hy/completer.py\n@@ -8,24 +8,19 @@\n import hy.compiler\n \n \n-docomplete = True\n-\n-try:\n-    import readline\n-except AttributeError as e:\n-    # https://github.com/pyreadline/pyreadline/issues/65\n-    if \"module 'collections' has no attribute 'Callable'\" in str(e):\n-        docomplete = False\n-    else:\n-        raise\n-except ImportError:\n-    docomplete = False\n-\n-if docomplete:\n-    if sys.platform == 'darwin' and 'libedit' in readline.__doc__:\n-        readline_bind = \"bind ^I rl_complete\"\n-    else:\n-        readline_bind = \"tab: complete\"\n+# Lazily import `readline` to work around\n+# https://bugs.python.org/issue2675#msg265564\n+readline = None\n+def init_readline():\n+    global readline\n+    try:\n+        import readline\n+    except AttributeError as e:\n+        # https://github.com/pyreadline/pyreadline/issues/65\n+        if \"module 'collections' has no attribute 'Callable'\" not in str(e):\n+            raise\n+    except ImportError:\n+        pass\n \n \n class Completer:\n@@ -86,33 +81,42 @@\n         except IndexError:\n             return None\n \n-\n @contextlib.contextmanager\n def completion(completer=None):\n     delims = \"()[]{} \"\n+\n+    init_readline()\n+    if not readline:\n+        # We have nothing to do. Act like a null context manager.\n+        yield\n+        return\n+\n     if not completer:\n         completer = Completer()\n \n-    if docomplete:\n-        readline.set_completer(completer.complete)\n-        readline.set_completer_delims(delims)\n+    if sys.platform == 'darwin' and 'libedit' in readline.__doc__:\n+        readline_bind = \"bind ^I rl_complete\"\n+    else:\n+        readline_bind = \"tab: complete\"\n \n-        history = os.environ.get(\n-            \"HY_HISTORY\", os.path.expanduser(\"~/.hy-history\"))\n-        readline.parse_and_bind(\"set blink-matching-paren on\")\n+    readline.set_completer(completer.complete)\n+    readline.set_completer_delims(delims)\n \n-        try:\n-            readline.read_history_file(history)\n-        except OSError:\n-            pass\n+    history = os.environ.get(\n+        \"HY_HISTORY\", os.path.expanduser(\"~/.hy-history\"))\n+    readline.parse_and_bind(\"set blink-matching-paren on\")\n \n-        readline.parse_and_bind(readline_bind)\n+    try:\n+        readline.read_history_file(history)\n+    except OSError:\n+        pass\n+\n+    readline.parse_and_bind(readline_bind)\n \n     try:\n         yield\n     finally:\n-        if docomplete:\n-            try:\n-                readline.write_history_file(history)\n-            except OSError:\n-                pass\n+        try:\n+            readline.write_history_file(history)\n+        except OSError:\n+            pass\n", "issue": "curses and SIGWINCH do not work properly with Hy.\nAfter importing curses under hy, curses is unable to detect the size of the terminal as it is resized.\r\nThis manifests as curses.LINES and curses.COLS not being updated, stdscr.getmaxyx not working and so on.\r\n\r\nHowever, the workaround of launching the hy program from python with:\r\n```\r\nimport hy\r\nimport curses\r\nfrom main import main_event_loop\r\n\r\nif __name__ == \"__main__\":\r\n    curses.wrapper(main_event_loop, ...)\r\n```\r\nallows curses to dynamically detect the size of the terminal.\r\n\r\nI conclude therefore the problem is with the hy binary. My (limited) understanding acquired during tracking down the source of this problem is that curses uses the SIGWINCH signal, so perhaps that is a place to look.\r\n\r\nVoid linux x86 64bit, python 3.9.0\r\nFreebsd 12.2, python 3.8.6\r\nhy 0.19.0 (reported by pip) installed from git master branch via pip\n", "before_files": [{"content": "import contextlib\nimport os\nimport re\nimport sys\nimport builtins\n\nimport hy.macros\nimport hy.compiler\n\n\ndocomplete = True\n\ntry:\n    import readline\nexcept AttributeError as e:\n    # https://github.com/pyreadline/pyreadline/issues/65\n    if \"module 'collections' has no attribute 'Callable'\" in str(e):\n        docomplete = False\n    else:\n        raise\nexcept ImportError:\n    docomplete = False\n\nif docomplete:\n    if sys.platform == 'darwin' and 'libedit' in readline.__doc__:\n        readline_bind = \"bind ^I rl_complete\"\n    else:\n        readline_bind = \"tab: complete\"\n\n\nclass Completer:\n\n    def __init__(self, namespace={}):\n        if not isinstance(namespace, dict):\n            raise TypeError('namespace must be a dictionary')\n        self.namespace = namespace\n        self.path = [builtins.__dict__,\n                     namespace]\n\n        namespace.setdefault('__macros__', {})\n\n        self.path.append(namespace['__macros__'])\n\n    def attr_matches(self, text):\n        # Borrowed from IPython's completer\n        m = re.match(r\"(\\S+(\\.[\\w-]+)*)\\.([\\w-]*)$\", text)\n\n        if m:\n            expr, attr = m.group(1, 3)\n            attr = attr.replace(\"-\", \"_\")\n            expr = expr.replace(\"-\", \"_\")\n        else:\n            return []\n\n        try:\n            obj = eval(expr, self.namespace)\n            words = dir(obj)\n        except Exception:\n            return []\n\n        n = len(attr)\n        matches = []\n        for w in words:\n            if w[:n] == attr:\n                matches.append(\"{}.{}\".format(\n                    expr.replace(\"_\", \"-\"), w.replace(\"_\", \"-\")))\n        return matches\n\n    def global_matches(self, text):\n        matches = []\n        for p in self.path:\n            for k in p.keys():\n                if isinstance(k, str):\n                    k = k.replace(\"_\", \"-\")\n                    if k.startswith(text):\n                        matches.append(k)\n        return matches\n\n    def complete(self, text, state):\n        if \".\" in text:\n            matches = self.attr_matches(text)\n        else:\n            matches = self.global_matches(text)\n        try:\n            return matches[state]\n        except IndexError:\n            return None\n\n\n@contextlib.contextmanager\ndef completion(completer=None):\n    delims = \"()[]{} \"\n    if not completer:\n        completer = Completer()\n\n    if docomplete:\n        readline.set_completer(completer.complete)\n        readline.set_completer_delims(delims)\n\n        history = os.environ.get(\n            \"HY_HISTORY\", os.path.expanduser(\"~/.hy-history\"))\n        readline.parse_and_bind(\"set blink-matching-paren on\")\n\n        try:\n            readline.read_history_file(history)\n        except OSError:\n            pass\n\n        readline.parse_and_bind(readline_bind)\n\n    try:\n        yield\n    finally:\n        if docomplete:\n            try:\n                readline.write_history_file(history)\n            except OSError:\n                pass\n", "path": "hy/completer.py"}], "after_files": [{"content": "import contextlib\nimport os\nimport re\nimport sys\nimport builtins\n\nimport hy.macros\nimport hy.compiler\n\n\n# Lazily import `readline` to work around\n# https://bugs.python.org/issue2675#msg265564\nreadline = None\ndef init_readline():\n    global readline\n    try:\n        import readline\n    except AttributeError as e:\n        # https://github.com/pyreadline/pyreadline/issues/65\n        if \"module 'collections' has no attribute 'Callable'\" not in str(e):\n            raise\n    except ImportError:\n        pass\n\n\nclass Completer:\n\n    def __init__(self, namespace={}):\n        if not isinstance(namespace, dict):\n            raise TypeError('namespace must be a dictionary')\n        self.namespace = namespace\n        self.path = [builtins.__dict__,\n                     namespace]\n\n        namespace.setdefault('__macros__', {})\n\n        self.path.append(namespace['__macros__'])\n\n    def attr_matches(self, text):\n        # Borrowed from IPython's completer\n        m = re.match(r\"(\\S+(\\.[\\w-]+)*)\\.([\\w-]*)$\", text)\n\n        if m:\n            expr, attr = m.group(1, 3)\n            attr = attr.replace(\"-\", \"_\")\n            expr = expr.replace(\"-\", \"_\")\n        else:\n            return []\n\n        try:\n            obj = eval(expr, self.namespace)\n            words = dir(obj)\n        except Exception:\n            return []\n\n        n = len(attr)\n        matches = []\n        for w in words:\n            if w[:n] == attr:\n                matches.append(\"{}.{}\".format(\n                    expr.replace(\"_\", \"-\"), w.replace(\"_\", \"-\")))\n        return matches\n\n    def global_matches(self, text):\n        matches = []\n        for p in self.path:\n            for k in p.keys():\n                if isinstance(k, str):\n                    k = k.replace(\"_\", \"-\")\n                    if k.startswith(text):\n                        matches.append(k)\n        return matches\n\n    def complete(self, text, state):\n        if \".\" in text:\n            matches = self.attr_matches(text)\n        else:\n            matches = self.global_matches(text)\n        try:\n            return matches[state]\n        except IndexError:\n            return None\n\n@contextlib.contextmanager\ndef completion(completer=None):\n    delims = \"()[]{} \"\n\n    init_readline()\n    if not readline:\n        # We have nothing to do. Act like a null context manager.\n        yield\n        return\n\n    if not completer:\n        completer = Completer()\n\n    if sys.platform == 'darwin' and 'libedit' in readline.__doc__:\n        readline_bind = \"bind ^I rl_complete\"\n    else:\n        readline_bind = \"tab: complete\"\n\n    readline.set_completer(completer.complete)\n    readline.set_completer_delims(delims)\n\n    history = os.environ.get(\n        \"HY_HISTORY\", os.path.expanduser(\"~/.hy-history\"))\n    readline.parse_and_bind(\"set blink-matching-paren on\")\n\n    try:\n        readline.read_history_file(history)\n    except OSError:\n        pass\n\n    readline.parse_and_bind(readline_bind)\n\n    try:\n        yield\n    finally:\n        try:\n            readline.write_history_file(history)\n        except OSError:\n            pass\n", "path": "hy/completer.py"}]}