We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Hack to keep NLTK's "tokenize" module fails 
in decorators.py file line 24:
`sys.path = [p for p in sys.path if  "nltk" not in p]`
causes an error while importing nltk when there are other objects than strings in the path variable(such as pathlib.Posixpath)
this issue can be solved simply just by replacing the above code with:
`sys.path = [p for p in sys.path if (type(p) == str and "nltk" not in p)]`


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nltk/decorators.py`
Content:
```
1 """
2 Decorator module by Michele Simionato <michelesimionato@libero.it>
3 Copyright Michele Simionato, distributed under the terms of the BSD License (see below).
4 http://www.phyast.pitt.edu/~micheles/python/documentation.html
5 
6 Included in NLTK for its support of a nice memoization decorator.
7 """
8 
9 __docformat__ = "restructuredtext en"
10 
11 ## The basic trick is to generate the source code for the decorated function
12 ## with the right signature and to evaluate it.
13 ## Uncomment the statement 'print >> sys.stderr, func_src'  in _decorator
14 ## to understand what is going on.
15 
16 __all__ = ["decorator", "new_wrapper", "getinfo"]
17 
18 import sys
19 
20 # Hack to keep NLTK's "tokenize" module from colliding with the "tokenize" in
21 # the Python standard library.
22 OLD_SYS_PATH = sys.path[:]
23 sys.path = [p for p in sys.path if p and "nltk" not in p]
24 import inspect
25 
26 sys.path = OLD_SYS_PATH
27 
28 
29 def __legacysignature(signature):
30     """
31     For retrocompatibility reasons, we don't use a standard Signature.
32     Instead, we use the string generated by this method.
33     Basically, from a Signature we create a string and remove the default values.
34     """
35     listsignature = str(signature)[1:-1].split(",")
36     for counter, param in enumerate(listsignature):
37         if param.count("=") > 0:
38             listsignature[counter] = param[0 : param.index("=")].strip()
39         else:
40             listsignature[counter] = param.strip()
41     return ", ".join(listsignature)
42 
43 
44 def getinfo(func):
45     """
46     Returns an info dictionary containing:
47     - name (the name of the function : str)
48     - argnames (the names of the arguments : list)
49     - defaults (the values of the default arguments : tuple)
50     - signature (the signature : str)
51     - fullsignature (the full signature : Signature)
52     - doc (the docstring : str)
53     - module (the module name : str)
54     - dict (the function __dict__ : str)
55 
56     >>> def f(self, x=1, y=2, *args, **kw): pass
57 
58     >>> info = getinfo(f)
59 
60     >>> info["name"]
61     'f'
62     >>> info["argnames"]
63     ['self', 'x', 'y', 'args', 'kw']
64 
65     >>> info["defaults"]
66     (1, 2)
67 
68     >>> info["signature"]
69     'self, x, y, *args, **kw'
70 
71     >>> info["fullsignature"]
72     <Signature (self, x=1, y=2, *args, **kw)>
73     """
74     assert inspect.ismethod(func) or inspect.isfunction(func)
75     argspec = inspect.getfullargspec(func)
76     regargs, varargs, varkwargs = argspec[:3]
77     argnames = list(regargs)
78     if varargs:
79         argnames.append(varargs)
80     if varkwargs:
81         argnames.append(varkwargs)
82     fullsignature = inspect.signature(func)
83     # Convert Signature to str
84     signature = __legacysignature(fullsignature)
85 
86     # pypy compatibility
87     if hasattr(func, "__closure__"):
88         _closure = func.__closure__
89         _globals = func.__globals__
90     else:
91         _closure = func.func_closure
92         _globals = func.func_globals
93 
94     return dict(
95         name=func.__name__,
96         argnames=argnames,
97         signature=signature,
98         fullsignature=fullsignature,
99         defaults=func.__defaults__,
100         doc=func.__doc__,
101         module=func.__module__,
102         dict=func.__dict__,
103         globals=_globals,
104         closure=_closure,
105     )
106 
107 
108 def update_wrapper(wrapper, model, infodict=None):
109     "akin to functools.update_wrapper"
110     infodict = infodict or getinfo(model)
111     wrapper.__name__ = infodict["name"]
112     wrapper.__doc__ = infodict["doc"]
113     wrapper.__module__ = infodict["module"]
114     wrapper.__dict__.update(infodict["dict"])
115     wrapper.__defaults__ = infodict["defaults"]
116     wrapper.undecorated = model
117     return wrapper
118 
119 
120 def new_wrapper(wrapper, model):
121     """
122     An improvement over functools.update_wrapper. The wrapper is a generic
123     callable object. It works by generating a copy of the wrapper with the
124     right signature and by updating the copy, not the original.
125     Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',
126     'dict', 'defaults'.
127     """
128     if isinstance(model, dict):
129         infodict = model
130     else:  # assume model is a function
131         infodict = getinfo(model)
132     assert (
133         not "_wrapper_" in infodict["argnames"]
134     ), '"_wrapper_" is a reserved argument name!'
135     src = "lambda %(signature)s: _wrapper_(%(signature)s)" % infodict
136     funcopy = eval(src, dict(_wrapper_=wrapper))
137     return update_wrapper(funcopy, model, infodict)
138 
139 
140 # helper used in decorator_factory
141 def __call__(self, func):
142     return new_wrapper(lambda *a, **k: self.call(func, *a, **k), func)
143 
144 
145 def decorator_factory(cls):
146     """
147     Take a class with a ``.caller`` method and return a callable decorator
148     object. It works by adding a suitable __call__ method to the class;
149     it raises a TypeError if the class already has a nontrivial __call__
150     method.
151     """
152     attrs = set(dir(cls))
153     if "__call__" in attrs:
154         raise TypeError(
155             "You cannot decorate a class with a nontrivial " "__call__ method"
156         )
157     if "call" not in attrs:
158         raise TypeError("You cannot decorate a class without a " ".call method")
159     cls.__call__ = __call__
160     return cls
161 
162 
163 def decorator(caller):
164     """
165     General purpose decorator factory: takes a caller function as
166     input and returns a decorator with the same attributes.
167     A caller function is any function like this::
168 
169      def caller(func, *args, **kw):
170          # do something
171          return func(*args, **kw)
172 
173     Here is an example of usage:
174 
175     >>> @decorator
176     ... def chatty(f, *args, **kw):
177     ...     print("Calling %r" % f.__name__)
178     ...     return f(*args, **kw)
179 
180     >>> chatty.__name__
181     'chatty'
182 
183     >>> @chatty
184     ... def f(): pass
185     ...
186     >>> f()
187     Calling 'f'
188 
189     decorator can also take in input a class with a .caller method; in this
190     case it converts the class into a factory of callable decorator objects.
191     See the documentation for an example.
192     """
193     if inspect.isclass(caller):
194         return decorator_factory(caller)
195 
196     def _decorator(func):  # the real meat is here
197         infodict = getinfo(func)
198         argnames = infodict["argnames"]
199         assert not (
200             "_call_" in argnames or "_func_" in argnames
201         ), "You cannot use _call_ or _func_ as argument names!"
202         src = "lambda %(signature)s: _call_(_func_, %(signature)s)" % infodict
203         # import sys; print >> sys.stderr, src # for debugging purposes
204         dec_func = eval(src, dict(_func_=func, _call_=caller))
205         return update_wrapper(dec_func, func, infodict)
206 
207     return update_wrapper(_decorator, caller)
208 
209 
210 def getattr_(obj, name, default_thunk):
211     "Similar to .setdefault in dictionaries."
212     try:
213         return getattr(obj, name)
214     except AttributeError:
215         default = default_thunk()
216         setattr(obj, name, default)
217         return default
218 
219 
220 @decorator
221 def memoize(func, *args):
222     dic = getattr_(func, "memoize_dic", dict)
223     # memoize_dic is created at the first call
224     if args in dic:
225         return dic[args]
226     result = func(*args)
227     dic[args] = result
228     return result
229 
230 
231 ##########################     LEGALESE    ###############################
232 
233 ##   Redistributions of source code must retain the above copyright
234 ##   notice, this list of conditions and the following disclaimer.
235 ##   Redistributions in bytecode form must reproduce the above copyright
236 ##   notice, this list of conditions and the following disclaimer in
237 ##   the documentation and/or other materials provided with the
238 ##   distribution.
239 
240 ##   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
241 ##   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
242 ##   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
243 ##   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
244 ##   HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
245 ##   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
246 ##   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
247 ##   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
248 ##   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
249 ##   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
250 ##   USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
251 ##   DAMAGE.
252
```
--- 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/nltk/decorators.py b/nltk/decorators.py
--- a/nltk/decorators.py
+++ b/nltk/decorators.py
@@ -20,7 +20,7 @@
 # Hack to keep NLTK's "tokenize" module from colliding with the "tokenize" in
 # the Python standard library.
 OLD_SYS_PATH = sys.path[:]
-sys.path = [p for p in sys.path if p and "nltk" not in p]
+sys.path = [p for p in sys.path if p and "nltk" not in str(p)]
 import inspect
 
 sys.path = OLD_SYS_PATH

{"golden_diff": "diff --git a/nltk/decorators.py b/nltk/decorators.py\n--- a/nltk/decorators.py\n+++ b/nltk/decorators.py\n@@ -20,7 +20,7 @@\n # Hack to keep NLTK's \"tokenize\" module from colliding with the \"tokenize\" in\n # the Python standard library.\n OLD_SYS_PATH = sys.path[:]\n-sys.path = [p for p in sys.path if p and \"nltk\" not in p]\n+sys.path = [p for p in sys.path if p and \"nltk\" not in str(p)]\n import inspect\n \n sys.path = OLD_SYS_PATH\n", "issue": "Hack to keep NLTK's \"tokenize\" module fails \nin decorators.py file line 24:\r\n`sys.path = [p for p in sys.path if  \"nltk\" not in p]`\r\ncauses an error while importing nltk when there are other objects than strings in the path variable(such as pathlib.Posixpath)\r\nthis issue can be solved simply just by replacing the above code with:\r\n`sys.path = [p for p in sys.path if (type(p) == str and \"nltk\" not in p)]`\r\n\n", "before_files": [{"content": "\"\"\"\nDecorator module by Michele Simionato <michelesimionato@libero.it>\nCopyright Michele Simionato, distributed under the terms of the BSD License (see below).\nhttp://www.phyast.pitt.edu/~micheles/python/documentation.html\n\nIncluded in NLTK for its support of a nice memoization decorator.\n\"\"\"\n\n__docformat__ = \"restructuredtext en\"\n\n## The basic trick is to generate the source code for the decorated function\n## with the right signature and to evaluate it.\n## Uncomment the statement 'print >> sys.stderr, func_src'  in _decorator\n## to understand what is going on.\n\n__all__ = [\"decorator\", \"new_wrapper\", \"getinfo\"]\n\nimport sys\n\n# Hack to keep NLTK's \"tokenize\" module from colliding with the \"tokenize\" in\n# the Python standard library.\nOLD_SYS_PATH = sys.path[:]\nsys.path = [p for p in sys.path if p and \"nltk\" not in p]\nimport inspect\n\nsys.path = OLD_SYS_PATH\n\n\ndef __legacysignature(signature):\n    \"\"\"\n    For retrocompatibility reasons, we don't use a standard Signature.\n    Instead, we use the string generated by this method.\n    Basically, from a Signature we create a string and remove the default values.\n    \"\"\"\n    listsignature = str(signature)[1:-1].split(\",\")\n    for counter, param in enumerate(listsignature):\n        if param.count(\"=\") > 0:\n            listsignature[counter] = param[0 : param.index(\"=\")].strip()\n        else:\n            listsignature[counter] = param.strip()\n    return \", \".join(listsignature)\n\n\ndef getinfo(func):\n    \"\"\"\n    Returns an info dictionary containing:\n    - name (the name of the function : str)\n    - argnames (the names of the arguments : list)\n    - defaults (the values of the default arguments : tuple)\n    - signature (the signature : str)\n    - fullsignature (the full signature : Signature)\n    - doc (the docstring : str)\n    - module (the module name : str)\n    - dict (the function __dict__ : str)\n\n    >>> def f(self, x=1, y=2, *args, **kw): pass\n\n    >>> info = getinfo(f)\n\n    >>> info[\"name\"]\n    'f'\n    >>> info[\"argnames\"]\n    ['self', 'x', 'y', 'args', 'kw']\n\n    >>> info[\"defaults\"]\n    (1, 2)\n\n    >>> info[\"signature\"]\n    'self, x, y, *args, **kw'\n\n    >>> info[\"fullsignature\"]\n    <Signature (self, x=1, y=2, *args, **kw)>\n    \"\"\"\n    assert inspect.ismethod(func) or inspect.isfunction(func)\n    argspec = inspect.getfullargspec(func)\n    regargs, varargs, varkwargs = argspec[:3]\n    argnames = list(regargs)\n    if varargs:\n        argnames.append(varargs)\n    if varkwargs:\n        argnames.append(varkwargs)\n    fullsignature = inspect.signature(func)\n    # Convert Signature to str\n    signature = __legacysignature(fullsignature)\n\n    # pypy compatibility\n    if hasattr(func, \"__closure__\"):\n        _closure = func.__closure__\n        _globals = func.__globals__\n    else:\n        _closure = func.func_closure\n        _globals = func.func_globals\n\n    return dict(\n        name=func.__name__,\n        argnames=argnames,\n        signature=signature,\n        fullsignature=fullsignature,\n        defaults=func.__defaults__,\n        doc=func.__doc__,\n        module=func.__module__,\n        dict=func.__dict__,\n        globals=_globals,\n        closure=_closure,\n    )\n\n\ndef update_wrapper(wrapper, model, infodict=None):\n    \"akin to functools.update_wrapper\"\n    infodict = infodict or getinfo(model)\n    wrapper.__name__ = infodict[\"name\"]\n    wrapper.__doc__ = infodict[\"doc\"]\n    wrapper.__module__ = infodict[\"module\"]\n    wrapper.__dict__.update(infodict[\"dict\"])\n    wrapper.__defaults__ = infodict[\"defaults\"]\n    wrapper.undecorated = model\n    return wrapper\n\n\ndef new_wrapper(wrapper, model):\n    \"\"\"\n    An improvement over functools.update_wrapper. The wrapper is a generic\n    callable object. It works by generating a copy of the wrapper with the\n    right signature and by updating the copy, not the original.\n    Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',\n    'dict', 'defaults'.\n    \"\"\"\n    if isinstance(model, dict):\n        infodict = model\n    else:  # assume model is a function\n        infodict = getinfo(model)\n    assert (\n        not \"_wrapper_\" in infodict[\"argnames\"]\n    ), '\"_wrapper_\" is a reserved argument name!'\n    src = \"lambda %(signature)s: _wrapper_(%(signature)s)\" % infodict\n    funcopy = eval(src, dict(_wrapper_=wrapper))\n    return update_wrapper(funcopy, model, infodict)\n\n\n# helper used in decorator_factory\ndef __call__(self, func):\n    return new_wrapper(lambda *a, **k: self.call(func, *a, **k), func)\n\n\ndef decorator_factory(cls):\n    \"\"\"\n    Take a class with a ``.caller`` method and return a callable decorator\n    object. It works by adding a suitable __call__ method to the class;\n    it raises a TypeError if the class already has a nontrivial __call__\n    method.\n    \"\"\"\n    attrs = set(dir(cls))\n    if \"__call__\" in attrs:\n        raise TypeError(\n            \"You cannot decorate a class with a nontrivial \" \"__call__ method\"\n        )\n    if \"call\" not in attrs:\n        raise TypeError(\"You cannot decorate a class without a \" \".call method\")\n    cls.__call__ = __call__\n    return cls\n\n\ndef decorator(caller):\n    \"\"\"\n    General purpose decorator factory: takes a caller function as\n    input and returns a decorator with the same attributes.\n    A caller function is any function like this::\n\n     def caller(func, *args, **kw):\n         # do something\n         return func(*args, **kw)\n\n    Here is an example of usage:\n\n    >>> @decorator\n    ... def chatty(f, *args, **kw):\n    ...     print(\"Calling %r\" % f.__name__)\n    ...     return f(*args, **kw)\n\n    >>> chatty.__name__\n    'chatty'\n\n    >>> @chatty\n    ... def f(): pass\n    ...\n    >>> f()\n    Calling 'f'\n\n    decorator can also take in input a class with a .caller method; in this\n    case it converts the class into a factory of callable decorator objects.\n    See the documentation for an example.\n    \"\"\"\n    if inspect.isclass(caller):\n        return decorator_factory(caller)\n\n    def _decorator(func):  # the real meat is here\n        infodict = getinfo(func)\n        argnames = infodict[\"argnames\"]\n        assert not (\n            \"_call_\" in argnames or \"_func_\" in argnames\n        ), \"You cannot use _call_ or _func_ as argument names!\"\n        src = \"lambda %(signature)s: _call_(_func_, %(signature)s)\" % infodict\n        # import sys; print >> sys.stderr, src # for debugging purposes\n        dec_func = eval(src, dict(_func_=func, _call_=caller))\n        return update_wrapper(dec_func, func, infodict)\n\n    return update_wrapper(_decorator, caller)\n\n\ndef getattr_(obj, name, default_thunk):\n    \"Similar to .setdefault in dictionaries.\"\n    try:\n        return getattr(obj, name)\n    except AttributeError:\n        default = default_thunk()\n        setattr(obj, name, default)\n        return default\n\n\n@decorator\ndef memoize(func, *args):\n    dic = getattr_(func, \"memoize_dic\", dict)\n    # memoize_dic is created at the first call\n    if args in dic:\n        return dic[args]\n    result = func(*args)\n    dic[args] = result\n    return result\n\n\n##########################     LEGALESE    ###############################\n\n##   Redistributions of source code must retain the above copyright\n##   notice, this list of conditions and the following disclaimer.\n##   Redistributions in bytecode form must reproduce the above copyright\n##   notice, this list of conditions and the following disclaimer in\n##   the documentation and/or other materials provided with the\n##   distribution.\n\n##   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n##   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n##   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n##   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n##   HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n##   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n##   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n##   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n##   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n##   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\n##   USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n##   DAMAGE.\n", "path": "nltk/decorators.py"}], "after_files": [{"content": "\"\"\"\nDecorator module by Michele Simionato <michelesimionato@libero.it>\nCopyright Michele Simionato, distributed under the terms of the BSD License (see below).\nhttp://www.phyast.pitt.edu/~micheles/python/documentation.html\n\nIncluded in NLTK for its support of a nice memoization decorator.\n\"\"\"\n\n__docformat__ = \"restructuredtext en\"\n\n## The basic trick is to generate the source code for the decorated function\n## with the right signature and to evaluate it.\n## Uncomment the statement 'print >> sys.stderr, func_src'  in _decorator\n## to understand what is going on.\n\n__all__ = [\"decorator\", \"new_wrapper\", \"getinfo\"]\n\nimport sys\n\n# Hack to keep NLTK's \"tokenize\" module from colliding with the \"tokenize\" in\n# the Python standard library.\nOLD_SYS_PATH = sys.path[:]\nsys.path = [p for p in sys.path if p and \"nltk\" not in str(p)]\nimport inspect\n\nsys.path = OLD_SYS_PATH\n\n\ndef __legacysignature(signature):\n    \"\"\"\n    For retrocompatibility reasons, we don't use a standard Signature.\n    Instead, we use the string generated by this method.\n    Basically, from a Signature we create a string and remove the default values.\n    \"\"\"\n    listsignature = str(signature)[1:-1].split(\",\")\n    for counter, param in enumerate(listsignature):\n        if param.count(\"=\") > 0:\n            listsignature[counter] = param[0 : param.index(\"=\")].strip()\n        else:\n            listsignature[counter] = param.strip()\n    return \", \".join(listsignature)\n\n\ndef getinfo(func):\n    \"\"\"\n    Returns an info dictionary containing:\n    - name (the name of the function : str)\n    - argnames (the names of the arguments : list)\n    - defaults (the values of the default arguments : tuple)\n    - signature (the signature : str)\n    - fullsignature (the full signature : Signature)\n    - doc (the docstring : str)\n    - module (the module name : str)\n    - dict (the function __dict__ : str)\n\n    >>> def f(self, x=1, y=2, *args, **kw): pass\n\n    >>> info = getinfo(f)\n\n    >>> info[\"name\"]\n    'f'\n    >>> info[\"argnames\"]\n    ['self', 'x', 'y', 'args', 'kw']\n\n    >>> info[\"defaults\"]\n    (1, 2)\n\n    >>> info[\"signature\"]\n    'self, x, y, *args, **kw'\n\n    >>> info[\"fullsignature\"]\n    <Signature (self, x=1, y=2, *args, **kw)>\n    \"\"\"\n    assert inspect.ismethod(func) or inspect.isfunction(func)\n    argspec = inspect.getfullargspec(func)\n    regargs, varargs, varkwargs = argspec[:3]\n    argnames = list(regargs)\n    if varargs:\n        argnames.append(varargs)\n    if varkwargs:\n        argnames.append(varkwargs)\n    fullsignature = inspect.signature(func)\n    # Convert Signature to str\n    signature = __legacysignature(fullsignature)\n\n    # pypy compatibility\n    if hasattr(func, \"__closure__\"):\n        _closure = func.__closure__\n        _globals = func.__globals__\n    else:\n        _closure = func.func_closure\n        _globals = func.func_globals\n\n    return dict(\n        name=func.__name__,\n        argnames=argnames,\n        signature=signature,\n        fullsignature=fullsignature,\n        defaults=func.__defaults__,\n        doc=func.__doc__,\n        module=func.__module__,\n        dict=func.__dict__,\n        globals=_globals,\n        closure=_closure,\n    )\n\n\ndef update_wrapper(wrapper, model, infodict=None):\n    \"akin to functools.update_wrapper\"\n    infodict = infodict or getinfo(model)\n    wrapper.__name__ = infodict[\"name\"]\n    wrapper.__doc__ = infodict[\"doc\"]\n    wrapper.__module__ = infodict[\"module\"]\n    wrapper.__dict__.update(infodict[\"dict\"])\n    wrapper.__defaults__ = infodict[\"defaults\"]\n    wrapper.undecorated = model\n    return wrapper\n\n\ndef new_wrapper(wrapper, model):\n    \"\"\"\n    An improvement over functools.update_wrapper. The wrapper is a generic\n    callable object. It works by generating a copy of the wrapper with the\n    right signature and by updating the copy, not the original.\n    Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',\n    'dict', 'defaults'.\n    \"\"\"\n    if isinstance(model, dict):\n        infodict = model\n    else:  # assume model is a function\n        infodict = getinfo(model)\n    assert (\n        not \"_wrapper_\" in infodict[\"argnames\"]\n    ), '\"_wrapper_\" is a reserved argument name!'\n    src = \"lambda %(signature)s: _wrapper_(%(signature)s)\" % infodict\n    funcopy = eval(src, dict(_wrapper_=wrapper))\n    return update_wrapper(funcopy, model, infodict)\n\n\n# helper used in decorator_factory\ndef __call__(self, func):\n    return new_wrapper(lambda *a, **k: self.call(func, *a, **k), func)\n\n\ndef decorator_factory(cls):\n    \"\"\"\n    Take a class with a ``.caller`` method and return a callable decorator\n    object. It works by adding a suitable __call__ method to the class;\n    it raises a TypeError if the class already has a nontrivial __call__\n    method.\n    \"\"\"\n    attrs = set(dir(cls))\n    if \"__call__\" in attrs:\n        raise TypeError(\n            \"You cannot decorate a class with a nontrivial \" \"__call__ method\"\n        )\n    if \"call\" not in attrs:\n        raise TypeError(\"You cannot decorate a class without a \" \".call method\")\n    cls.__call__ = __call__\n    return cls\n\n\ndef decorator(caller):\n    \"\"\"\n    General purpose decorator factory: takes a caller function as\n    input and returns a decorator with the same attributes.\n    A caller function is any function like this::\n\n     def caller(func, *args, **kw):\n         # do something\n         return func(*args, **kw)\n\n    Here is an example of usage:\n\n    >>> @decorator\n    ... def chatty(f, *args, **kw):\n    ...     print(\"Calling %r\" % f.__name__)\n    ...     return f(*args, **kw)\n\n    >>> chatty.__name__\n    'chatty'\n\n    >>> @chatty\n    ... def f(): pass\n    ...\n    >>> f()\n    Calling 'f'\n\n    decorator can also take in input a class with a .caller method; in this\n    case it converts the class into a factory of callable decorator objects.\n    See the documentation for an example.\n    \"\"\"\n    if inspect.isclass(caller):\n        return decorator_factory(caller)\n\n    def _decorator(func):  # the real meat is here\n        infodict = getinfo(func)\n        argnames = infodict[\"argnames\"]\n        assert not (\n            \"_call_\" in argnames or \"_func_\" in argnames\n        ), \"You cannot use _call_ or _func_ as argument names!\"\n        src = \"lambda %(signature)s: _call_(_func_, %(signature)s)\" % infodict\n        # import sys; print >> sys.stderr, src # for debugging purposes\n        dec_func = eval(src, dict(_func_=func, _call_=caller))\n        return update_wrapper(dec_func, func, infodict)\n\n    return update_wrapper(_decorator, caller)\n\n\ndef getattr_(obj, name, default_thunk):\n    \"Similar to .setdefault in dictionaries.\"\n    try:\n        return getattr(obj, name)\n    except AttributeError:\n        default = default_thunk()\n        setattr(obj, name, default)\n        return default\n\n\n@decorator\ndef memoize(func, *args):\n    dic = getattr_(func, \"memoize_dic\", dict)\n    # memoize_dic is created at the first call\n    if args in dic:\n        return dic[args]\n    result = func(*args)\n    dic[args] = result\n    return result\n\n\n##########################     LEGALESE    ###############################\n\n##   Redistributions of source code must retain the above copyright\n##   notice, this list of conditions and the following disclaimer.\n##   Redistributions in bytecode form must reproduce the above copyright\n##   notice, this list of conditions and the following disclaimer in\n##   the documentation and/or other materials provided with the\n##   distribution.\n\n##   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n##   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n##   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n##   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n##   HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n##   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n##   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n##   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n##   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n##   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\n##   USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n##   DAMAGE.\n", "path": "nltk/decorators.py"}]}