prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  pwnlib.term.text throws exceptions on attribute accesses
  ```
  >>> import pwnlib
  >>> pwnlib.term.text.__lol__
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "pwnlib/term/text.py", line 99, in __getattr__
      init += self._fg_color(c())
    File "pwnlib/term/text.py", line 93, in c
      return self._colors[c] + bright
  KeyError: ''
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pwnlib/term/text.py`
  Content:
  ```
  1 import types, sys, functools
  2 from . import termcap
  3 
  4 def eval_when(when):
  5     if isinstance(when, file) or \
  6       when in ('always', 'never', 'auto', sys.stderr, sys.stdout):
  7         if   when == 'always':
  8             return True
  9         elif when == 'never':
  10             return False
  11         elif when == 'auto':
  12             return sys.stdout.isatty()
  13         else:
  14             return when.isatty()
  15     else:
  16         raise ValueError('text.when: must be a file-object or "always", "never" or "auto"')
  17 
  18 class Module(types.ModuleType):
  19     def __init__(self):
  20         self.__file__ = __file__
  21         self.__name__ = __name__
  22         self.num_colors = termcap.get('colors', default = 8)
  23         self.has_bright = self.num_colors >= 16
  24         self.has_gray = self.has_bright
  25         self.when = 'auto'
  26         self._colors = {
  27             'black': 0,
  28             'red': 1,
  29             'green': 2,
  30             'yellow': 3,
  31             'blue': 4,
  32             'magenta': 5,
  33             'cyan': 6,
  34             'white': 7,
  35             }
  36         self._reset = '\x1b[m'
  37         self._attributes = {}
  38         for x, y in [('italic'   , 'sitm'),
  39                      ('bold'     , 'bold'),
  40                      ('underline', 'smul'),
  41                      ('reverse'  , 'rev')]:
  42             s = termcap.get(y)
  43             self._attributes[x] = s
  44         self._cache = {}
  45 
  46     @property
  47     def when(self):
  48         return self._when
  49 
  50     @when.setter
  51     def when(self, val):
  52         self._when = eval_when(val)
  53 
  54     def _fg_color(self, c):
  55         return termcap.get('setaf', c) or termcap.get('setf', c)
  56 
  57     def _bg_color(self, c):
  58         return termcap.get('setab', c) or termcap.get('setb', c)
  59 
  60     def _decorator(self, desc, init):
  61         def f(self, s, when = None):
  62             if when:
  63                 if eval_when(when):
  64                     return init + s + self._reset
  65                 else:
  66                     return s
  67             else:
  68                 if self.when:
  69                     return init + s + self._reset
  70                 else:
  71                     return s
  72         setattr(Module, desc, f)
  73         return functools.partial(f, self)
  74 
  75     def __getattr__(self, desc):
  76         ds = desc.replace('gray', 'bright_black').split('_')
  77         init = ''
  78         while ds:
  79             d = ds[0]
  80             try:
  81                 init += self._attributes[d]
  82                 ds.pop(0)
  83             except KeyError:
  84                 break
  85         def c():
  86             bright = 0
  87             c = ds.pop(0)
  88             if c == 'bright':
  89                 c = ds.pop(0)
  90                 if self.has_bright:
  91                     bright = 8
  92             return self._colors[c] + bright
  93         if ds:
  94             if ds[0] == 'on':
  95                 ds.pop(0)
  96                 init += self._bg_color(c())
  97             else:
  98                 init += self._fg_color(c())
  99                 if len(ds):
  100                     assert ds.pop(0) == 'on'
  101                     init += self._bg_color(c())
  102         return self._decorator(desc, init)
  103 
  104     def get(self, desc):
  105         return self.__getattr__(desc)
  106 
  107 tether = sys.modules[__name__]
  108 sys.modules[__name__] = Module()
  109
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/pwnlib/term/text.py b/pwnlib/term/text.py
  --- a/pwnlib/term/text.py
  +++ b/pwnlib/term/text.py
  @@ -73,33 +73,36 @@
           return functools.partial(f, self)
   
       def __getattr__(self, desc):
  -        ds = desc.replace('gray', 'bright_black').split('_')
  -        init = ''
  -        while ds:
  -            d = ds[0]
  -            try:
  -                init += self._attributes[d]
  -                ds.pop(0)
  -            except KeyError:
  -                break
  -        def c():
  -            bright = 0
  -            c = ds.pop(0)
  -            if c == 'bright':
  +        try:
  +            ds = desc.replace('gray', 'bright_black').split('_')
  +            init = ''
  +            while ds:
  +                d = ds[0]
  +                try:
  +                    init += self._attributes[d]
  +                    ds.pop(0)
  +                except KeyError:
  +                    break
  +            def c():
  +                bright = 0
                   c = ds.pop(0)
  -                if self.has_bright:
  -                    bright = 8
  -            return self._colors[c] + bright
  -        if ds:
  -            if ds[0] == 'on':
  -                ds.pop(0)
  -                init += self._bg_color(c())
  -            else:
  -                init += self._fg_color(c())
  -                if len(ds):
  -                    assert ds.pop(0) == 'on'
  +                if c == 'bright':
  +                    c = ds.pop(0)
  +                    if self.has_bright:
  +                        bright = 8
  +                return self._colors[c] + bright
  +            if ds:
  +                if ds[0] == 'on':
  +                    ds.pop(0)
                       init += self._bg_color(c())
  -        return self._decorator(desc, init)
  +                else:
  +                    init += self._fg_color(c())
  +                    if len(ds):
  +                        assert ds.pop(0) == 'on'
  +                        init += self._bg_color(c())
  +            return self._decorator(desc, init)
  +        except (IndexError, KeyError):
  +            raise AttributeError("'module' object has no attribute %r" % desc)
   
       def get(self, desc):
           return self.__getattr__(desc)
  
verification_info: {"golden_diff": "diff --git a/pwnlib/term/text.py b/pwnlib/term/text.py\n--- a/pwnlib/term/text.py\n+++ b/pwnlib/term/text.py\n@@ -73,33 +73,36 @@\n         return functools.partial(f, self)\n \n     def __getattr__(self, desc):\n-        ds = desc.replace('gray', 'bright_black').split('_')\n-        init = ''\n-        while ds:\n-            d = ds[0]\n-            try:\n-                init += self._attributes[d]\n-                ds.pop(0)\n-            except KeyError:\n-                break\n-        def c():\n-            bright = 0\n-            c = ds.pop(0)\n-            if c == 'bright':\n+        try:\n+            ds = desc.replace('gray', 'bright_black').split('_')\n+            init = ''\n+            while ds:\n+                d = ds[0]\n+                try:\n+                    init += self._attributes[d]\n+                    ds.pop(0)\n+                except KeyError:\n+                    break\n+            def c():\n+                bright = 0\n                 c = ds.pop(0)\n-                if self.has_bright:\n-                    bright = 8\n-            return self._colors[c] + bright\n-        if ds:\n-            if ds[0] == 'on':\n-                ds.pop(0)\n-                init += self._bg_color(c())\n-            else:\n-                init += self._fg_color(c())\n-                if len(ds):\n-                    assert ds.pop(0) == 'on'\n+                if c == 'bright':\n+                    c = ds.pop(0)\n+                    if self.has_bright:\n+                        bright = 8\n+                return self._colors[c] + bright\n+            if ds:\n+                if ds[0] == 'on':\n+                    ds.pop(0)\n                     init += self._bg_color(c())\n-        return self._decorator(desc, init)\n+                else:\n+                    init += self._fg_color(c())\n+                    if len(ds):\n+                        assert ds.pop(0) == 'on'\n+                        init += self._bg_color(c())\n+            return self._decorator(desc, init)\n+        except (IndexError, KeyError):\n+            raise AttributeError(\"'module' object has no attribute %r\" % desc)\n \n     def get(self, desc):\n         return self.__getattr__(desc)\n", "issue": "pwnlib.term.text throws exceptions on attribute accesses\n```\n>>> import pwnlib\n>>> pwnlib.term.text.__lol__\nTraceback (most recent call last):\n  File \"<stdin>\", line 1, in <module>\n  File \"pwnlib/term/text.py\", line 99, in __getattr__\n    init += self._fg_color(c())\n  File \"pwnlib/term/text.py\", line 93, in c\n    return self._colors[c] + bright\nKeyError: ''\n```\n\n", "before_files": [{"content": "import types, sys, functools\nfrom . import termcap\n\ndef eval_when(when):\n    if isinstance(when, file) or \\\n      when in ('always', 'never', 'auto', sys.stderr, sys.stdout):\n        if   when == 'always':\n            return True\n        elif when == 'never':\n            return False\n        elif when == 'auto':\n            return sys.stdout.isatty()\n        else:\n            return when.isatty()\n    else:\n        raise ValueError('text.when: must be a file-object or \"always\", \"never\" or \"auto\"')\n\nclass Module(types.ModuleType):\n    def __init__(self):\n        self.__file__ = __file__\n        self.__name__ = __name__\n        self.num_colors = termcap.get('colors', default = 8)\n        self.has_bright = self.num_colors >= 16\n        self.has_gray = self.has_bright\n        self.when = 'auto'\n        self._colors = {\n            'black': 0,\n            'red': 1,\n            'green': 2,\n            'yellow': 3,\n            'blue': 4,\n            'magenta': 5,\n            'cyan': 6,\n            'white': 7,\n            }\n        self._reset = '\\x1b[m'\n        self._attributes = {}\n        for x, y in [('italic'   , 'sitm'),\n                     ('bold'     , 'bold'),\n                     ('underline', 'smul'),\n                     ('reverse'  , 'rev')]:\n            s = termcap.get(y)\n            self._attributes[x] = s\n        self._cache = {}\n\n    @property\n    def when(self):\n        return self._when\n\n    @when.setter\n    def when(self, val):\n        self._when = eval_when(val)\n\n    def _fg_color(self, c):\n        return termcap.get('setaf', c) or termcap.get('setf', c)\n\n    def _bg_color(self, c):\n        return termcap.get('setab', c) or termcap.get('setb', c)\n\n    def _decorator(self, desc, init):\n        def f(self, s, when = None):\n            if when:\n                if eval_when(when):\n                    return init + s + self._reset\n                else:\n                    return s\n            else:\n                if self.when:\n                    return init + s + self._reset\n                else:\n                    return s\n        setattr(Module, desc, f)\n        return functools.partial(f, self)\n\n    def __getattr__(self, desc):\n        ds = desc.replace('gray', 'bright_black').split('_')\n        init = ''\n        while ds:\n            d = ds[0]\n            try:\n                init += self._attributes[d]\n                ds.pop(0)\n            except KeyError:\n                break\n        def c():\n            bright = 0\n            c = ds.pop(0)\n            if c == 'bright':\n                c = ds.pop(0)\n                if self.has_bright:\n                    bright = 8\n            return self._colors[c] + bright\n        if ds:\n            if ds[0] == 'on':\n                ds.pop(0)\n                init += self._bg_color(c())\n            else:\n                init += self._fg_color(c())\n                if len(ds):\n                    assert ds.pop(0) == 'on'\n                    init += self._bg_color(c())\n        return self._decorator(desc, init)\n\n    def get(self, desc):\n        return self.__getattr__(desc)\n\ntether = sys.modules[__name__]\nsys.modules[__name__] = Module()\n", "path": "pwnlib/term/text.py"}], "after_files": [{"content": "import types, sys, functools\nfrom . import termcap\n\ndef eval_when(when):\n    if isinstance(when, file) or \\\n      when in ('always', 'never', 'auto', sys.stderr, sys.stdout):\n        if   when == 'always':\n            return True\n        elif when == 'never':\n            return False\n        elif when == 'auto':\n            return sys.stdout.isatty()\n        else:\n            return when.isatty()\n    else:\n        raise ValueError('text.when: must be a file-object or \"always\", \"never\" or \"auto\"')\n\nclass Module(types.ModuleType):\n    def __init__(self):\n        self.__file__ = __file__\n        self.__name__ = __name__\n        self.num_colors = termcap.get('colors', default = 8)\n        self.has_bright = self.num_colors >= 16\n        self.has_gray = self.has_bright\n        self.when = 'auto'\n        self._colors = {\n            'black': 0,\n            'red': 1,\n            'green': 2,\n            'yellow': 3,\n            'blue': 4,\n            'magenta': 5,\n            'cyan': 6,\n            'white': 7,\n            }\n        self._reset = '\\x1b[m'\n        self._attributes = {}\n        for x, y in [('italic'   , 'sitm'),\n                     ('bold'     , 'bold'),\n                     ('underline', 'smul'),\n                     ('reverse'  , 'rev')]:\n            s = termcap.get(y)\n            self._attributes[x] = s\n        self._cache = {}\n\n    @property\n    def when(self):\n        return self._when\n\n    @when.setter\n    def when(self, val):\n        self._when = eval_when(val)\n\n    def _fg_color(self, c):\n        return termcap.get('setaf', c) or termcap.get('setf', c)\n\n    def _bg_color(self, c):\n        return termcap.get('setab', c) or termcap.get('setb', c)\n\n    def _decorator(self, desc, init):\n        def f(self, s, when = None):\n            if when:\n                if eval_when(when):\n                    return init + s + self._reset\n                else:\n                    return s\n            else:\n                if self.when:\n                    return init + s + self._reset\n                else:\n                    return s\n        setattr(Module, desc, f)\n        return functools.partial(f, self)\n\n    def __getattr__(self, desc):\n        try:\n            ds = desc.replace('gray', 'bright_black').split('_')\n            init = ''\n            while ds:\n                d = ds[0]\n                try:\n                    init += self._attributes[d]\n                    ds.pop(0)\n                except KeyError:\n                    break\n            def c():\n                bright = 0\n                c = ds.pop(0)\n                if c == 'bright':\n                    c = ds.pop(0)\n                    if self.has_bright:\n                        bright = 8\n                return self._colors[c] + bright\n            if ds:\n                if ds[0] == 'on':\n                    ds.pop(0)\n                    init += self._bg_color(c())\n                else:\n                    init += self._fg_color(c())\n                    if len(ds):\n                        assert ds.pop(0) == 'on'\n                        init += self._bg_color(c())\n            return self._decorator(desc, init)\n        except (IndexError, KeyError):\n            raise AttributeError(\"'module' object has no attribute %r\" % desc)\n\n    def get(self, desc):\n        return self.__getattr__(desc)\n\ntether = sys.modules[__name__]\nsys.modules[__name__] = Module()\n", "path": "pwnlib/term/text.py"}]}