We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
variables named `UNREACHABLE` can be shadowed by `raise`and `assert` when used with `UNREACHABLE`
### Version Information

* vyper Version (output of `vyper --version`): 0.3.8+commit.6020b8bb
* OS: OSX
* Python Version (output of `python --version`): 3.8.0

### What's your issue about?

`UNREACHABLE` is not a reserved keyword. For someone who is not familiar with the custom semantic of `UNREACHABLE` when used as a reason string for a `raise` or `assert` statement, the fact that in this context, any previously defined variable named `UNREACHABLE` will be shadowed by this new semantic might be confusing.
To illustrate this, in the following contract, a call to `bar` will revert with `invalid opcode` and not `this is unreachable` as one could imagine.
```Vyper
@external
def bar():
    UNREACHABLE: String[20] = "this is unreachable"
    x: uint256 = 3
    assert 2>x, UNREACHABLE
```
### How can it be fixed?

An option could be to make `UNREACHABLE` a reserved keyword but some other alternative less restrictive might be better.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `vyper/semantics/namespace.py`
Content:
```
1 import contextlib
2 import re
3 
4 from vyper.evm.opcodes import OPCODES
5 from vyper.exceptions import (
6     CompilerPanic,
7     NamespaceCollision,
8     StructureException,
9     UndeclaredDefinition,
10 )
11 from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions
12 
13 
14 class Namespace(dict):
15     """
16     Dictionary subclass that represents the namespace of a contract.
17 
18     Attributes
19     ----------
20     _scopes : List[Set]
21         List of sets containing the key names for each scope
22     """
23 
24     def __init__(self):
25         super().__init__()
26         self._scopes = []
27         # NOTE cyclic imports!
28         # TODO: break this cycle by providing an `init_vyper_namespace` in 3rd module
29         from vyper.builtins.functions import get_builtin_functions
30         from vyper.semantics import environment
31         from vyper.semantics.analysis.base import VarInfo
32         from vyper.semantics.types import get_types
33 
34         self.update(get_types())
35         self.update(environment.get_constant_vars())
36         self.update({k: VarInfo(b) for (k, b) in get_builtin_functions().items()})
37 
38     def __eq__(self, other):
39         return self is other
40 
41     def __setitem__(self, attr, obj):
42         if self._scopes:
43             self.validate_assignment(attr)
44             self._scopes[-1].add(attr)
45         assert isinstance(attr, str), f"not a string: {attr}"
46         super().__setitem__(attr, obj)
47 
48     def __getitem__(self, key):
49         if key not in self:
50             suggestions_str = get_levenshtein_error_suggestions(key, self, 0.2)
51             raise UndeclaredDefinition(f"'{key}' has not been declared. {suggestions_str}")
52         return super().__getitem__(key)
53 
54     def __enter__(self):
55         if not self._scopes:
56             raise CompilerPanic("Context manager must be invoked via namespace.enter_scope()")
57 
58     def __exit__(self, exc_type, exc_value, traceback):
59         if not self._scopes:
60             raise CompilerPanic("Bad use of namespace as a context manager")
61         for key in self._scopes.pop():
62             del self[key]
63 
64     def enter_scope(self):
65         """
66         Enter a new scope within the namespace.
67 
68         Called as a context manager, e.g. `with namespace.enter_scope():`
69         All items that are added within the context are removed upon exit.
70         """
71         # NOTE cyclic imports!
72         from vyper.semantics import environment
73 
74         self._scopes.append(set())
75 
76         if len(self._scopes) == 1:
77             # add mutable vars (`self`) to the initial scope
78             self.update(environment.get_mutable_vars())
79 
80         return self
81 
82     def update(self, other):
83         for key, value in other.items():
84             self.__setitem__(key, value)
85 
86     def clear(self):
87         super().clear()
88         self.__init__()
89 
90     def validate_assignment(self, attr):
91         validate_identifier(attr)
92         if attr in self:
93             obj = super().__getitem__(attr)
94             raise NamespaceCollision(f"'{attr}' has already been declared as a {obj}")
95 
96 
97 def get_namespace():
98     """
99     Get the active namespace object.
100     """
101     global _namespace
102     try:
103         return _namespace
104     except NameError:
105         _namespace = Namespace()
106         return _namespace
107 
108 
109 @contextlib.contextmanager
110 def override_global_namespace(ns):
111     global _namespace
112     tmp = _namespace
113     try:
114         # clobber global namespace
115         _namespace = ns
116         yield
117     finally:
118         # unclobber
119         _namespace = tmp
120 
121 
122 def validate_identifier(attr):
123     namespace = get_namespace()
124     if attr in namespace and attr not in [x for i in namespace._scopes for x in i]:
125         raise NamespaceCollision(f"Cannot assign to '{attr}', it is a builtin")
126     if attr.lower() in RESERVED_KEYWORDS or attr.upper() in OPCODES:
127         raise StructureException(f"'{attr}' is a reserved keyword")
128     if not re.match("^[_a-zA-Z][a-zA-Z0-9_]*$", attr):
129         raise StructureException(f"'{attr}' contains invalid character(s)")
130 
131 
132 # Cannot be used for variable or member naming
133 RESERVED_KEYWORDS = {
134     # decorators
135     "public",
136     "external",
137     "nonpayable",
138     "constant",
139     "immutable",
140     "internal",
141     "payable",
142     "nonreentrant",
143     # "class" keywords
144     "interface",
145     "struct",
146     "event",
147     "enum",
148     # control flow
149     "if",
150     "for",
151     "while",
152     "until",
153     "pass",
154     "def",
155     # EVM operations
156     "send",
157     "selfdestruct",
158     "assert",
159     "raise",
160     "throw",
161     # special functions (no name mangling)
162     "init",
163     "_init_",
164     "___init___",
165     "____init____",
166     "default",
167     "_default_",
168     "___default___",
169     "____default____",
170     # environment variables
171     "chainid",
172     "blockhash",
173     "timestamp",
174     "timedelta",
175     # boolean literals
176     "true",
177     "false",
178     # more control flow and special operations
179     "this",
180     "continue",
181     "range",
182     # None sentinal value
183     "none",
184     # more special operations
185     "indexed",
186     # denominations
187     "ether",
188     "wei",
189     "finney",
190     "szabo",
191     "shannon",
192     "lovelace",
193     "ada",
194     "babbage",
195     "gwei",
196     "kwei",
197     "mwei",
198     "twei",
199     "pwei",
200     # `address` members
201     "balance",
202     "codesize",
203     "codehash",
204     "code",
205     "is_contract",
206     # units
207     "units",
208     # sentinal constant values
209     "zero_address",
210     "empty_bytes32",
211     "max_int128",
212     "min_int128",
213     "max_decimal",
214     "min_decimal",
215     "max_uint256",
216     "zero_wei",
217 }
218
```
--- 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/vyper/semantics/namespace.py b/vyper/semantics/namespace.py
--- a/vyper/semantics/namespace.py
+++ b/vyper/semantics/namespace.py
@@ -158,6 +158,7 @@
     "assert",
     "raise",
     "throw",
+    "unreachable",
     # special functions (no name mangling)
     "init",
     "_init_",

{"golden_diff": "diff --git a/vyper/semantics/namespace.py b/vyper/semantics/namespace.py\n--- a/vyper/semantics/namespace.py\n+++ b/vyper/semantics/namespace.py\n@@ -158,6 +158,7 @@\n     \"assert\",\n     \"raise\",\n     \"throw\",\n+    \"unreachable\",\n     # special functions (no name mangling)\n     \"init\",\n     \"_init_\",\n", "issue": "variables named `UNREACHABLE` can be shadowed by `raise`and `assert` when used with `UNREACHABLE`\n### Version Information\r\n\r\n* vyper Version (output of `vyper --version`): 0.3.8+commit.6020b8bb\r\n* OS: OSX\r\n* Python Version (output of `python --version`): 3.8.0\r\n\r\n### What's your issue about?\r\n\r\n`UNREACHABLE` is not a reserved keyword. For someone who is not familiar with the custom semantic of `UNREACHABLE` when used as a reason string for a `raise` or `assert` statement, the fact that in this context, any previously defined variable named `UNREACHABLE` will be shadowed by this new semantic might be confusing.\r\nTo illustrate this, in the following contract, a call to `bar` will revert with `invalid opcode` and not `this is unreachable` as one could imagine.\r\n```Vyper\r\n@external\r\ndef bar():\r\n    UNREACHABLE: String[20] = \"this is unreachable\"\r\n    x: uint256 = 3\r\n    assert 2>x, UNREACHABLE\r\n```\r\n### How can it be fixed?\r\n\r\nAn option could be to make `UNREACHABLE` a reserved keyword but some other alternative less restrictive might be better.\r\n\n", "before_files": [{"content": "import contextlib\nimport re\n\nfrom vyper.evm.opcodes import OPCODES\nfrom vyper.exceptions import (\n    CompilerPanic,\n    NamespaceCollision,\n    StructureException,\n    UndeclaredDefinition,\n)\nfrom vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions\n\n\nclass Namespace(dict):\n    \"\"\"\n    Dictionary subclass that represents the namespace of a contract.\n\n    Attributes\n    ----------\n    _scopes : List[Set]\n        List of sets containing the key names for each scope\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self._scopes = []\n        # NOTE cyclic imports!\n        # TODO: break this cycle by providing an `init_vyper_namespace` in 3rd module\n        from vyper.builtins.functions import get_builtin_functions\n        from vyper.semantics import environment\n        from vyper.semantics.analysis.base import VarInfo\n        from vyper.semantics.types import get_types\n\n        self.update(get_types())\n        self.update(environment.get_constant_vars())\n        self.update({k: VarInfo(b) for (k, b) in get_builtin_functions().items()})\n\n    def __eq__(self, other):\n        return self is other\n\n    def __setitem__(self, attr, obj):\n        if self._scopes:\n            self.validate_assignment(attr)\n            self._scopes[-1].add(attr)\n        assert isinstance(attr, str), f\"not a string: {attr}\"\n        super().__setitem__(attr, obj)\n\n    def __getitem__(self, key):\n        if key not in self:\n            suggestions_str = get_levenshtein_error_suggestions(key, self, 0.2)\n            raise UndeclaredDefinition(f\"'{key}' has not been declared. {suggestions_str}\")\n        return super().__getitem__(key)\n\n    def __enter__(self):\n        if not self._scopes:\n            raise CompilerPanic(\"Context manager must be invoked via namespace.enter_scope()\")\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        if not self._scopes:\n            raise CompilerPanic(\"Bad use of namespace as a context manager\")\n        for key in self._scopes.pop():\n            del self[key]\n\n    def enter_scope(self):\n        \"\"\"\n        Enter a new scope within the namespace.\n\n        Called as a context manager, e.g. `with namespace.enter_scope():`\n        All items that are added within the context are removed upon exit.\n        \"\"\"\n        # NOTE cyclic imports!\n        from vyper.semantics import environment\n\n        self._scopes.append(set())\n\n        if len(self._scopes) == 1:\n            # add mutable vars (`self`) to the initial scope\n            self.update(environment.get_mutable_vars())\n\n        return self\n\n    def update(self, other):\n        for key, value in other.items():\n            self.__setitem__(key, value)\n\n    def clear(self):\n        super().clear()\n        self.__init__()\n\n    def validate_assignment(self, attr):\n        validate_identifier(attr)\n        if attr in self:\n            obj = super().__getitem__(attr)\n            raise NamespaceCollision(f\"'{attr}' has already been declared as a {obj}\")\n\n\ndef get_namespace():\n    \"\"\"\n    Get the active namespace object.\n    \"\"\"\n    global _namespace\n    try:\n        return _namespace\n    except NameError:\n        _namespace = Namespace()\n        return _namespace\n\n\n@contextlib.contextmanager\ndef override_global_namespace(ns):\n    global _namespace\n    tmp = _namespace\n    try:\n        # clobber global namespace\n        _namespace = ns\n        yield\n    finally:\n        # unclobber\n        _namespace = tmp\n\n\ndef validate_identifier(attr):\n    namespace = get_namespace()\n    if attr in namespace and attr not in [x for i in namespace._scopes for x in i]:\n        raise NamespaceCollision(f\"Cannot assign to '{attr}', it is a builtin\")\n    if attr.lower() in RESERVED_KEYWORDS or attr.upper() in OPCODES:\n        raise StructureException(f\"'{attr}' is a reserved keyword\")\n    if not re.match(\"^[_a-zA-Z][a-zA-Z0-9_]*$\", attr):\n        raise StructureException(f\"'{attr}' contains invalid character(s)\")\n\n\n# Cannot be used for variable or member naming\nRESERVED_KEYWORDS = {\n    # decorators\n    \"public\",\n    \"external\",\n    \"nonpayable\",\n    \"constant\",\n    \"immutable\",\n    \"internal\",\n    \"payable\",\n    \"nonreentrant\",\n    # \"class\" keywords\n    \"interface\",\n    \"struct\",\n    \"event\",\n    \"enum\",\n    # control flow\n    \"if\",\n    \"for\",\n    \"while\",\n    \"until\",\n    \"pass\",\n    \"def\",\n    # EVM operations\n    \"send\",\n    \"selfdestruct\",\n    \"assert\",\n    \"raise\",\n    \"throw\",\n    # special functions (no name mangling)\n    \"init\",\n    \"_init_\",\n    \"___init___\",\n    \"____init____\",\n    \"default\",\n    \"_default_\",\n    \"___default___\",\n    \"____default____\",\n    # environment variables\n    \"chainid\",\n    \"blockhash\",\n    \"timestamp\",\n    \"timedelta\",\n    # boolean literals\n    \"true\",\n    \"false\",\n    # more control flow and special operations\n    \"this\",\n    \"continue\",\n    \"range\",\n    # None sentinal value\n    \"none\",\n    # more special operations\n    \"indexed\",\n    # denominations\n    \"ether\",\n    \"wei\",\n    \"finney\",\n    \"szabo\",\n    \"shannon\",\n    \"lovelace\",\n    \"ada\",\n    \"babbage\",\n    \"gwei\",\n    \"kwei\",\n    \"mwei\",\n    \"twei\",\n    \"pwei\",\n    # `address` members\n    \"balance\",\n    \"codesize\",\n    \"codehash\",\n    \"code\",\n    \"is_contract\",\n    # units\n    \"units\",\n    # sentinal constant values\n    \"zero_address\",\n    \"empty_bytes32\",\n    \"max_int128\",\n    \"min_int128\",\n    \"max_decimal\",\n    \"min_decimal\",\n    \"max_uint256\",\n    \"zero_wei\",\n}\n", "path": "vyper/semantics/namespace.py"}], "after_files": [{"content": "import contextlib\nimport re\n\nfrom vyper.evm.opcodes import OPCODES\nfrom vyper.exceptions import (\n    CompilerPanic,\n    NamespaceCollision,\n    StructureException,\n    UndeclaredDefinition,\n)\nfrom vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions\n\n\nclass Namespace(dict):\n    \"\"\"\n    Dictionary subclass that represents the namespace of a contract.\n\n    Attributes\n    ----------\n    _scopes : List[Set]\n        List of sets containing the key names for each scope\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self._scopes = []\n        # NOTE cyclic imports!\n        # TODO: break this cycle by providing an `init_vyper_namespace` in 3rd module\n        from vyper.builtins.functions import get_builtin_functions\n        from vyper.semantics import environment\n        from vyper.semantics.analysis.base import VarInfo\n        from vyper.semantics.types import get_types\n\n        self.update(get_types())\n        self.update(environment.get_constant_vars())\n        self.update({k: VarInfo(b) for (k, b) in get_builtin_functions().items()})\n\n    def __eq__(self, other):\n        return self is other\n\n    def __setitem__(self, attr, obj):\n        if self._scopes:\n            self.validate_assignment(attr)\n            self._scopes[-1].add(attr)\n        assert isinstance(attr, str), f\"not a string: {attr}\"\n        super().__setitem__(attr, obj)\n\n    def __getitem__(self, key):\n        if key not in self:\n            suggestions_str = get_levenshtein_error_suggestions(key, self, 0.2)\n            raise UndeclaredDefinition(f\"'{key}' has not been declared. {suggestions_str}\")\n        return super().__getitem__(key)\n\n    def __enter__(self):\n        if not self._scopes:\n            raise CompilerPanic(\"Context manager must be invoked via namespace.enter_scope()\")\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        if not self._scopes:\n            raise CompilerPanic(\"Bad use of namespace as a context manager\")\n        for key in self._scopes.pop():\n            del self[key]\n\n    def enter_scope(self):\n        \"\"\"\n        Enter a new scope within the namespace.\n\n        Called as a context manager, e.g. `with namespace.enter_scope():`\n        All items that are added within the context are removed upon exit.\n        \"\"\"\n        # NOTE cyclic imports!\n        from vyper.semantics import environment\n\n        self._scopes.append(set())\n\n        if len(self._scopes) == 1:\n            # add mutable vars (`self`) to the initial scope\n            self.update(environment.get_mutable_vars())\n\n        return self\n\n    def update(self, other):\n        for key, value in other.items():\n            self.__setitem__(key, value)\n\n    def clear(self):\n        super().clear()\n        self.__init__()\n\n    def validate_assignment(self, attr):\n        validate_identifier(attr)\n        if attr in self:\n            obj = super().__getitem__(attr)\n            raise NamespaceCollision(f\"'{attr}' has already been declared as a {obj}\")\n\n\ndef get_namespace():\n    \"\"\"\n    Get the active namespace object.\n    \"\"\"\n    global _namespace\n    try:\n        return _namespace\n    except NameError:\n        _namespace = Namespace()\n        return _namespace\n\n\n@contextlib.contextmanager\ndef override_global_namespace(ns):\n    global _namespace\n    tmp = _namespace\n    try:\n        # clobber global namespace\n        _namespace = ns\n        yield\n    finally:\n        # unclobber\n        _namespace = tmp\n\n\ndef validate_identifier(attr):\n    namespace = get_namespace()\n    if attr in namespace and attr not in [x for i in namespace._scopes for x in i]:\n        raise NamespaceCollision(f\"Cannot assign to '{attr}', it is a builtin\")\n    if attr.lower() in RESERVED_KEYWORDS or attr.upper() in OPCODES:\n        raise StructureException(f\"'{attr}' is a reserved keyword\")\n    if not re.match(\"^[_a-zA-Z][a-zA-Z0-9_]*$\", attr):\n        raise StructureException(f\"'{attr}' contains invalid character(s)\")\n\n\n# Cannot be used for variable or member naming\nRESERVED_KEYWORDS = {\n    # decorators\n    \"public\",\n    \"external\",\n    \"nonpayable\",\n    \"constant\",\n    \"immutable\",\n    \"internal\",\n    \"payable\",\n    \"nonreentrant\",\n    # \"class\" keywords\n    \"interface\",\n    \"struct\",\n    \"event\",\n    \"enum\",\n    # control flow\n    \"if\",\n    \"for\",\n    \"while\",\n    \"until\",\n    \"pass\",\n    \"def\",\n    # EVM operations\n    \"send\",\n    \"selfdestruct\",\n    \"assert\",\n    \"raise\",\n    \"throw\",\n    \"unreachable\",\n    # special functions (no name mangling)\n    \"init\",\n    \"_init_\",\n    \"___init___\",\n    \"____init____\",\n    \"default\",\n    \"_default_\",\n    \"___default___\",\n    \"____default____\",\n    # environment variables\n    \"chainid\",\n    \"blockhash\",\n    \"timestamp\",\n    \"timedelta\",\n    # boolean literals\n    \"true\",\n    \"false\",\n    # more control flow and special operations\n    \"this\",\n    \"continue\",\n    \"range\",\n    # None sentinal value\n    \"none\",\n    # more special operations\n    \"indexed\",\n    # denominations\n    \"ether\",\n    \"wei\",\n    \"finney\",\n    \"szabo\",\n    \"shannon\",\n    \"lovelace\",\n    \"ada\",\n    \"babbage\",\n    \"gwei\",\n    \"kwei\",\n    \"mwei\",\n    \"twei\",\n    \"pwei\",\n    # `address` members\n    \"balance\",\n    \"codesize\",\n    \"codehash\",\n    \"code\",\n    \"is_contract\",\n    # units\n    \"units\",\n    # sentinal constant values\n    \"zero_address\",\n    \"empty_bytes32\",\n    \"max_int128\",\n    \"min_int128\",\n    \"max_decimal\",\n    \"min_decimal\",\n    \"max_uint256\",\n    \"zero_wei\",\n}\n", "path": "vyper/semantics/namespace.py"}]}