We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`poutine.block` does not work in Python 3.10
### Reproducible code

```python
from pyro import poutine

class A:
    @poutine.block
    def run(self):
        return 1

a = A()
a.run()  # error
```

This causes the issue https://github.com/pyro-ppl/pyro/issues/3018
[Support for Python 3.10] MCMC example in documentation does not work: `AttributeError: __enter__`
I am following the MCMC example in the documentation: <https://docs.pyro.ai/en/stable/mcmc.html#nuts>

```python
import pyro
import pyro.distributions as dist
from pyro.infer import MCMC, NUTS
import torch

true_coefs = torch.tensor([1., 2., 3.])
data = torch.randn(2000, 3)
dim = 3
labels = dist.Bernoulli(logits=(true_coefs * data).sum(-1)).sample()

def model(data):
    coefs_mean = torch.zeros(dim)
    coefs = pyro.sample('beta', dist.Normal(coefs_mean, torch.ones(3)))
    y = pyro.sample('y', dist.Bernoulli(logits=(coefs * data).sum(-1)), obs=labels)
    return y

nuts_kernel = NUTS(model, adapt_step_size=True)
mcmc = MCMC(nuts_kernel, num_samples=500, warmup_steps=300)
mcmc.run(data)
```

But it raises an error:

```
Traceback (most recent call last):
  File "/home/ayaka/Projects/test/main.py", line 19, in <module>
    mcmc.run(data)
  File "/home/ayaka/venv/lib/python3.10/site-packages/pyro/poutine/messenger.py", line 11, in _context_wrap
    with context:
AttributeError: __enter__
```

Pyro version: 1.8.0

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyro/poutine/messenger.py`
Content:
```
1 # Copyright (c) 2017-2019 Uber Technologies, Inc.
2 # SPDX-License-Identifier: Apache-2.0
3 
4 from contextlib import contextmanager
5 from functools import partial
6 
7 from .runtime import _PYRO_STACK
8 
9 
10 def _context_wrap(context, fn, *args, **kwargs):
11     with context:
12         return fn(*args, **kwargs)
13 
14 
15 class _bound_partial(partial):
16     """
17     Converts a (possibly) bound method into a partial function to
18     support class methods as arguments to handlers.
19     """
20 
21     def __get__(self, instance, owner):
22         if instance is None:
23             return self
24         return partial(self.func, instance)
25 
26 
27 def unwrap(fn):
28     """
29     Recursively unwraps poutines.
30     """
31     while True:
32         if isinstance(fn, _bound_partial):
33             fn = fn.func
34             continue
35         if isinstance(fn, partial) and len(fn.args) >= 2:
36             fn = fn.args[1]  # extract from partial(handler, fn)
37             continue
38         return fn
39 
40 
41 class Messenger:
42     """
43     Context manager class that modifies behavior
44     and adds side effects to stochastic functions
45     i.e. callables containing Pyro primitive statements.
46 
47     This is the base Messenger class.
48     It implements the default behavior for all Pyro primitives,
49     so that the joint distribution induced by a stochastic function fn
50     is identical to the joint distribution induced by ``Messenger()(fn)``.
51 
52     Class of transformers for messages passed during inference.
53     Most inference operations are implemented in subclasses of this.
54     """
55 
56     def __call__(self, fn):
57         if not callable(fn):
58             raise ValueError(
59                 "{} is not callable, did you mean to pass it as a keyword arg?".format(
60                     fn
61                 )
62             )
63         wraps = _bound_partial(partial(_context_wrap, self, fn))
64         return wraps
65 
66     def __enter__(self):
67         """
68         :returns: self
69         :rtype: pyro.poutine.Messenger
70 
71         Installs this messenger at the bottom of the Pyro stack.
72 
73         Can be overloaded to add any additional per-call setup functionality,
74         but the derived class must always push itself onto the stack, usually
75         by calling super().__enter__().
76 
77         Derived versions cannot be overridden to take arguments
78         and must always return self.
79         """
80         if not (self in _PYRO_STACK):
81             # if this poutine is not already installed,
82             # put it on the bottom of the stack.
83             _PYRO_STACK.append(self)
84 
85             # necessary to return self because the return value of __enter__
86             # is bound to VAR in with EXPR as VAR.
87             return self
88         else:
89             # note: currently we raise an error if trying to install a poutine twice.
90             # However, this isn't strictly necessary,
91             # and blocks recursive poutine execution patterns like
92             # like calling self.__call__ inside of self.__call__
93             # or with Handler(...) as p: with p: <BLOCK>
94             # It's hard to imagine use cases for this pattern,
95             # but it could in principle be enabled...
96             raise ValueError("cannot install a Messenger instance twice")
97 
98     def __exit__(self, exc_type, exc_value, traceback):
99         """
100         :param exc_type: exception type, e.g. ValueError
101         :param exc_value: exception instance?
102         :param traceback: traceback for exception handling
103         :returns: None
104         :rtype: None
105 
106         Removes this messenger from the bottom of the Pyro stack.
107         If an exception is raised, removes this messenger and everything below it.
108         Always called after every execution of self.fn via self.__call__.
109 
110         Can be overloaded by derived classes to add any other per-call teardown functionality,
111         but the stack must always be popped by the derived class,
112         usually by calling super().__exit__(*args).
113 
114         Derived versions cannot be overridden to take other arguments,
115         and must always return None or False.
116 
117         The arguments are the mandatory arguments used by a with statement.
118         Users should never be specifying these.
119         They are all None unless the body of the with statement raised an exception.
120         """
121         if exc_type is None:  # callee or enclosed block returned successfully
122             # if the callee or enclosed block returned successfully,
123             # this poutine should be on the bottom of the stack.
124             # If so, remove it from the stack.
125             # if not, raise a ValueError because something really weird happened.
126             if _PYRO_STACK[-1] == self:
127                 _PYRO_STACK.pop()
128             else:
129                 # should never get here, but just in case...
130                 raise ValueError("This Messenger is not on the bottom of the stack")
131         else:  # the wrapped function or block raised an exception
132             # poutine exception handling:
133             # when the callee or enclosed block raises an exception,
134             # find this poutine's position in the stack,
135             # then remove it and everything below it in the stack.
136             if self in _PYRO_STACK:
137                 loc = _PYRO_STACK.index(self)
138                 for i in range(loc, len(_PYRO_STACK)):
139                     _PYRO_STACK.pop()
140 
141     def _reset(self):
142         pass
143 
144     def _process_message(self, msg):
145         """
146         :param msg: current message at a trace site
147         :returns: None
148 
149         Process the message by calling appropriate method of itself based
150         on message type. The message is updated in place.
151         """
152         method = getattr(self, "_pyro_{}".format(msg["type"]), None)
153         if method is not None:
154             return method(msg)
155         return None
156 
157     def _postprocess_message(self, msg):
158         method = getattr(self, "_pyro_post_{}".format(msg["type"]), None)
159         if method is not None:
160             return method(msg)
161         return None
162 
163     @classmethod
164     def register(cls, fn=None, type=None, post=None):
165         """
166         :param fn: function implementing operation
167         :param str type: name of the operation
168             (also passed to :func:`~pyro.poutine.runtime.effectful`)
169         :param bool post: if `True`, use this operation as postprocess
170 
171         Dynamically add operations to an effect.
172         Useful for generating wrappers for libraries.
173 
174         Example::
175 
176             @SomeMessengerClass.register
177             def some_function(msg)
178                 ...do_something...
179                 return msg
180 
181         """
182         if fn is None:
183             return lambda x: cls.register(x, type=type, post=post)
184 
185         if type is None:
186             raise ValueError("An operation type name must be provided")
187 
188         setattr(cls, "_pyro_" + ("post_" if post else "") + type, staticmethod(fn))
189         return fn
190 
191     @classmethod
192     def unregister(cls, fn=None, type=None):
193         """
194         :param fn: function implementing operation
195         :param str type: name of the operation
196             (also passed to :func:`~pyro.poutine.runtime.effectful`)
197 
198         Dynamically remove operations from an effect.
199         Useful for removing wrappers from libraries.
200 
201         Example::
202 
203             SomeMessengerClass.unregister(some_function, "name")
204         """
205         if type is None:
206             raise ValueError("An operation type name must be provided")
207 
208         try:
209             delattr(cls, "_pyro_post_" + type)
210         except AttributeError:
211             pass
212 
213         try:
214             delattr(cls, "_pyro_" + type)
215         except AttributeError:
216             pass
217 
218         return fn
219 
220 
221 @contextmanager
222 def block_messengers(predicate):
223     """
224     EXPERIMENTAL Context manager to temporarily remove matching messengers from
225     the _PYRO_STACK. Note this does not call the ``.__exit__()`` and
226     ``.__enter__()`` methods.
227 
228     This is useful to selectively block enclosing handlers.
229 
230     :param callable predicate: A predicate mapping messenger instance to boolean.
231         This mutes all messengers ``m`` for which ``bool(predicate(m)) is True``.
232     :yields: A list of matched messengers that are blocked.
233     """
234     blocked = {}
235     try:
236         for i, messenger in enumerate(_PYRO_STACK):
237             if predicate(messenger):
238                 blocked[i] = messenger
239                 _PYRO_STACK[i] = Messenger()  # trivial messenger
240         yield list(blocked.values())
241     finally:
242         for i, messenger in blocked.items():
243             _PYRO_STACK[i] = messenger
244
```
--- 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/pyro/poutine/messenger.py b/pyro/poutine/messenger.py
--- a/pyro/poutine/messenger.py
+++ b/pyro/poutine/messenger.py
@@ -18,6 +18,14 @@
     support class methods as arguments to handlers.
     """
 
+    # Use '__slots__' for func to avoid the issue
+    #   `_bound_partial(_bound_partial(f)).func is f`
+    # in Python 3.10.
+    __slots__ = "func"
+
+    def __init__(self, func):
+        self.func = func
+
     def __get__(self, instance, owner):
         if instance is None:
             return self

{"golden_diff": "diff --git a/pyro/poutine/messenger.py b/pyro/poutine/messenger.py\n--- a/pyro/poutine/messenger.py\n+++ b/pyro/poutine/messenger.py\n@@ -18,6 +18,14 @@\n     support class methods as arguments to handlers.\n     \"\"\"\n \n+    # Use '__slots__' for func to avoid the issue\n+    #   `_bound_partial(_bound_partial(f)).func is f`\n+    # in Python 3.10.\n+    __slots__ = \"func\"\n+\n+    def __init__(self, func):\n+        self.func = func\n+\n     def __get__(self, instance, owner):\n         if instance is None:\n             return self\n", "issue": "`poutine.block` does not work in Python 3.10\n### Reproducible code\r\n\r\n```python\r\nfrom pyro import poutine\r\n\r\nclass A:\r\n    @poutine.block\r\n    def run(self):\r\n        return 1\r\n\r\na = A()\r\na.run()  # error\r\n```\r\n\r\nThis causes the issue https://github.com/pyro-ppl/pyro/issues/3018\n[Support for Python 3.10] MCMC example in documentation does not work: `AttributeError: __enter__`\nI am following the MCMC example in the documentation: <https://docs.pyro.ai/en/stable/mcmc.html#nuts>\r\n\r\n```python\r\nimport pyro\r\nimport pyro.distributions as dist\r\nfrom pyro.infer import MCMC, NUTS\r\nimport torch\r\n\r\ntrue_coefs = torch.tensor([1., 2., 3.])\r\ndata = torch.randn(2000, 3)\r\ndim = 3\r\nlabels = dist.Bernoulli(logits=(true_coefs * data).sum(-1)).sample()\r\n\r\ndef model(data):\r\n    coefs_mean = torch.zeros(dim)\r\n    coefs = pyro.sample('beta', dist.Normal(coefs_mean, torch.ones(3)))\r\n    y = pyro.sample('y', dist.Bernoulli(logits=(coefs * data).sum(-1)), obs=labels)\r\n    return y\r\n\r\nnuts_kernel = NUTS(model, adapt_step_size=True)\r\nmcmc = MCMC(nuts_kernel, num_samples=500, warmup_steps=300)\r\nmcmc.run(data)\r\n```\r\n\r\nBut it raises an error:\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/home/ayaka/Projects/test/main.py\", line 19, in <module>\r\n    mcmc.run(data)\r\n  File \"/home/ayaka/venv/lib/python3.10/site-packages/pyro/poutine/messenger.py\", line 11, in _context_wrap\r\n    with context:\r\nAttributeError: __enter__\r\n```\r\n\r\nPyro version: 1.8.0\n", "before_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nfrom contextlib import contextmanager\nfrom functools import partial\n\nfrom .runtime import _PYRO_STACK\n\n\ndef _context_wrap(context, fn, *args, **kwargs):\n    with context:\n        return fn(*args, **kwargs)\n\n\nclass _bound_partial(partial):\n    \"\"\"\n    Converts a (possibly) bound method into a partial function to\n    support class methods as arguments to handlers.\n    \"\"\"\n\n    def __get__(self, instance, owner):\n        if instance is None:\n            return self\n        return partial(self.func, instance)\n\n\ndef unwrap(fn):\n    \"\"\"\n    Recursively unwraps poutines.\n    \"\"\"\n    while True:\n        if isinstance(fn, _bound_partial):\n            fn = fn.func\n            continue\n        if isinstance(fn, partial) and len(fn.args) >= 2:\n            fn = fn.args[1]  # extract from partial(handler, fn)\n            continue\n        return fn\n\n\nclass Messenger:\n    \"\"\"\n    Context manager class that modifies behavior\n    and adds side effects to stochastic functions\n    i.e. callables containing Pyro primitive statements.\n\n    This is the base Messenger class.\n    It implements the default behavior for all Pyro primitives,\n    so that the joint distribution induced by a stochastic function fn\n    is identical to the joint distribution induced by ``Messenger()(fn)``.\n\n    Class of transformers for messages passed during inference.\n    Most inference operations are implemented in subclasses of this.\n    \"\"\"\n\n    def __call__(self, fn):\n        if not callable(fn):\n            raise ValueError(\n                \"{} is not callable, did you mean to pass it as a keyword arg?\".format(\n                    fn\n                )\n            )\n        wraps = _bound_partial(partial(_context_wrap, self, fn))\n        return wraps\n\n    def __enter__(self):\n        \"\"\"\n        :returns: self\n        :rtype: pyro.poutine.Messenger\n\n        Installs this messenger at the bottom of the Pyro stack.\n\n        Can be overloaded to add any additional per-call setup functionality,\n        but the derived class must always push itself onto the stack, usually\n        by calling super().__enter__().\n\n        Derived versions cannot be overridden to take arguments\n        and must always return self.\n        \"\"\"\n        if not (self in _PYRO_STACK):\n            # if this poutine is not already installed,\n            # put it on the bottom of the stack.\n            _PYRO_STACK.append(self)\n\n            # necessary to return self because the return value of __enter__\n            # is bound to VAR in with EXPR as VAR.\n            return self\n        else:\n            # note: currently we raise an error if trying to install a poutine twice.\n            # However, this isn't strictly necessary,\n            # and blocks recursive poutine execution patterns like\n            # like calling self.__call__ inside of self.__call__\n            # or with Handler(...) as p: with p: <BLOCK>\n            # It's hard to imagine use cases for this pattern,\n            # but it could in principle be enabled...\n            raise ValueError(\"cannot install a Messenger instance twice\")\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        \"\"\"\n        :param exc_type: exception type, e.g. ValueError\n        :param exc_value: exception instance?\n        :param traceback: traceback for exception handling\n        :returns: None\n        :rtype: None\n\n        Removes this messenger from the bottom of the Pyro stack.\n        If an exception is raised, removes this messenger and everything below it.\n        Always called after every execution of self.fn via self.__call__.\n\n        Can be overloaded by derived classes to add any other per-call teardown functionality,\n        but the stack must always be popped by the derived class,\n        usually by calling super().__exit__(*args).\n\n        Derived versions cannot be overridden to take other arguments,\n        and must always return None or False.\n\n        The arguments are the mandatory arguments used by a with statement.\n        Users should never be specifying these.\n        They are all None unless the body of the with statement raised an exception.\n        \"\"\"\n        if exc_type is None:  # callee or enclosed block returned successfully\n            # if the callee or enclosed block returned successfully,\n            # this poutine should be on the bottom of the stack.\n            # If so, remove it from the stack.\n            # if not, raise a ValueError because something really weird happened.\n            if _PYRO_STACK[-1] == self:\n                _PYRO_STACK.pop()\n            else:\n                # should never get here, but just in case...\n                raise ValueError(\"This Messenger is not on the bottom of the stack\")\n        else:  # the wrapped function or block raised an exception\n            # poutine exception handling:\n            # when the callee or enclosed block raises an exception,\n            # find this poutine's position in the stack,\n            # then remove it and everything below it in the stack.\n            if self in _PYRO_STACK:\n                loc = _PYRO_STACK.index(self)\n                for i in range(loc, len(_PYRO_STACK)):\n                    _PYRO_STACK.pop()\n\n    def _reset(self):\n        pass\n\n    def _process_message(self, msg):\n        \"\"\"\n        :param msg: current message at a trace site\n        :returns: None\n\n        Process the message by calling appropriate method of itself based\n        on message type. The message is updated in place.\n        \"\"\"\n        method = getattr(self, \"_pyro_{}\".format(msg[\"type\"]), None)\n        if method is not None:\n            return method(msg)\n        return None\n\n    def _postprocess_message(self, msg):\n        method = getattr(self, \"_pyro_post_{}\".format(msg[\"type\"]), None)\n        if method is not None:\n            return method(msg)\n        return None\n\n    @classmethod\n    def register(cls, fn=None, type=None, post=None):\n        \"\"\"\n        :param fn: function implementing operation\n        :param str type: name of the operation\n            (also passed to :func:`~pyro.poutine.runtime.effectful`)\n        :param bool post: if `True`, use this operation as postprocess\n\n        Dynamically add operations to an effect.\n        Useful for generating wrappers for libraries.\n\n        Example::\n\n            @SomeMessengerClass.register\n            def some_function(msg)\n                ...do_something...\n                return msg\n\n        \"\"\"\n        if fn is None:\n            return lambda x: cls.register(x, type=type, post=post)\n\n        if type is None:\n            raise ValueError(\"An operation type name must be provided\")\n\n        setattr(cls, \"_pyro_\" + (\"post_\" if post else \"\") + type, staticmethod(fn))\n        return fn\n\n    @classmethod\n    def unregister(cls, fn=None, type=None):\n        \"\"\"\n        :param fn: function implementing operation\n        :param str type: name of the operation\n            (also passed to :func:`~pyro.poutine.runtime.effectful`)\n\n        Dynamically remove operations from an effect.\n        Useful for removing wrappers from libraries.\n\n        Example::\n\n            SomeMessengerClass.unregister(some_function, \"name\")\n        \"\"\"\n        if type is None:\n            raise ValueError(\"An operation type name must be provided\")\n\n        try:\n            delattr(cls, \"_pyro_post_\" + type)\n        except AttributeError:\n            pass\n\n        try:\n            delattr(cls, \"_pyro_\" + type)\n        except AttributeError:\n            pass\n\n        return fn\n\n\n@contextmanager\ndef block_messengers(predicate):\n    \"\"\"\n    EXPERIMENTAL Context manager to temporarily remove matching messengers from\n    the _PYRO_STACK. Note this does not call the ``.__exit__()`` and\n    ``.__enter__()`` methods.\n\n    This is useful to selectively block enclosing handlers.\n\n    :param callable predicate: A predicate mapping messenger instance to boolean.\n        This mutes all messengers ``m`` for which ``bool(predicate(m)) is True``.\n    :yields: A list of matched messengers that are blocked.\n    \"\"\"\n    blocked = {}\n    try:\n        for i, messenger in enumerate(_PYRO_STACK):\n            if predicate(messenger):\n                blocked[i] = messenger\n                _PYRO_STACK[i] = Messenger()  # trivial messenger\n        yield list(blocked.values())\n    finally:\n        for i, messenger in blocked.items():\n            _PYRO_STACK[i] = messenger\n", "path": "pyro/poutine/messenger.py"}], "after_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nfrom contextlib import contextmanager\nfrom functools import partial\n\nfrom .runtime import _PYRO_STACK\n\n\ndef _context_wrap(context, fn, *args, **kwargs):\n    with context:\n        return fn(*args, **kwargs)\n\n\nclass _bound_partial(partial):\n    \"\"\"\n    Converts a (possibly) bound method into a partial function to\n    support class methods as arguments to handlers.\n    \"\"\"\n\n    # Use '__slots__' for func to avoid the issue\n    #   `_bound_partial(_bound_partial(f)).func is f`\n    # in Python 3.10.\n    __slots__ = \"func\"\n\n    def __init__(self, func):\n        self.func = func\n\n    def __get__(self, instance, owner):\n        if instance is None:\n            return self\n        return partial(self.func, instance)\n\n\ndef unwrap(fn):\n    \"\"\"\n    Recursively unwraps poutines.\n    \"\"\"\n    while True:\n        if isinstance(fn, _bound_partial):\n            fn = fn.func\n            continue\n        if isinstance(fn, partial) and len(fn.args) >= 2:\n            fn = fn.args[1]  # extract from partial(handler, fn)\n            continue\n        return fn\n\n\nclass Messenger:\n    \"\"\"\n    Context manager class that modifies behavior\n    and adds side effects to stochastic functions\n    i.e. callables containing Pyro primitive statements.\n\n    This is the base Messenger class.\n    It implements the default behavior for all Pyro primitives,\n    so that the joint distribution induced by a stochastic function fn\n    is identical to the joint distribution induced by ``Messenger()(fn)``.\n\n    Class of transformers for messages passed during inference.\n    Most inference operations are implemented in subclasses of this.\n    \"\"\"\n\n    def __call__(self, fn):\n        if not callable(fn):\n            raise ValueError(\n                \"{} is not callable, did you mean to pass it as a keyword arg?\".format(\n                    fn\n                )\n            )\n        wraps = _bound_partial(partial(_context_wrap, self, fn))\n        return wraps\n\n    def __enter__(self):\n        \"\"\"\n        :returns: self\n        :rtype: pyro.poutine.Messenger\n\n        Installs this messenger at the bottom of the Pyro stack.\n\n        Can be overloaded to add any additional per-call setup functionality,\n        but the derived class must always push itself onto the stack, usually\n        by calling super().__enter__().\n\n        Derived versions cannot be overridden to take arguments\n        and must always return self.\n        \"\"\"\n        if not (self in _PYRO_STACK):\n            # if this poutine is not already installed,\n            # put it on the bottom of the stack.\n            _PYRO_STACK.append(self)\n\n            # necessary to return self because the return value of __enter__\n            # is bound to VAR in with EXPR as VAR.\n            return self\n        else:\n            # note: currently we raise an error if trying to install a poutine twice.\n            # However, this isn't strictly necessary,\n            # and blocks recursive poutine execution patterns like\n            # like calling self.__call__ inside of self.__call__\n            # or with Handler(...) as p: with p: <BLOCK>\n            # It's hard to imagine use cases for this pattern,\n            # but it could in principle be enabled...\n            raise ValueError(\"cannot install a Messenger instance twice\")\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        \"\"\"\n        :param exc_type: exception type, e.g. ValueError\n        :param exc_value: exception instance?\n        :param traceback: traceback for exception handling\n        :returns: None\n        :rtype: None\n\n        Removes this messenger from the bottom of the Pyro stack.\n        If an exception is raised, removes this messenger and everything below it.\n        Always called after every execution of self.fn via self.__call__.\n\n        Can be overloaded by derived classes to add any other per-call teardown functionality,\n        but the stack must always be popped by the derived class,\n        usually by calling super().__exit__(*args).\n\n        Derived versions cannot be overridden to take other arguments,\n        and must always return None or False.\n\n        The arguments are the mandatory arguments used by a with statement.\n        Users should never be specifying these.\n        They are all None unless the body of the with statement raised an exception.\n        \"\"\"\n        if exc_type is None:  # callee or enclosed block returned successfully\n            # if the callee or enclosed block returned successfully,\n            # this poutine should be on the bottom of the stack.\n            # If so, remove it from the stack.\n            # if not, raise a ValueError because something really weird happened.\n            if _PYRO_STACK[-1] == self:\n                _PYRO_STACK.pop()\n            else:\n                # should never get here, but just in case...\n                raise ValueError(\"This Messenger is not on the bottom of the stack\")\n        else:  # the wrapped function or block raised an exception\n            # poutine exception handling:\n            # when the callee or enclosed block raises an exception,\n            # find this poutine's position in the stack,\n            # then remove it and everything below it in the stack.\n            if self in _PYRO_STACK:\n                loc = _PYRO_STACK.index(self)\n                for i in range(loc, len(_PYRO_STACK)):\n                    _PYRO_STACK.pop()\n\n    def _reset(self):\n        pass\n\n    def _process_message(self, msg):\n        \"\"\"\n        :param msg: current message at a trace site\n        :returns: None\n\n        Process the message by calling appropriate method of itself based\n        on message type. The message is updated in place.\n        \"\"\"\n        method = getattr(self, \"_pyro_{}\".format(msg[\"type\"]), None)\n        if method is not None:\n            return method(msg)\n        return None\n\n    def _postprocess_message(self, msg):\n        method = getattr(self, \"_pyro_post_{}\".format(msg[\"type\"]), None)\n        if method is not None:\n            return method(msg)\n        return None\n\n    @classmethod\n    def register(cls, fn=None, type=None, post=None):\n        \"\"\"\n        :param fn: function implementing operation\n        :param str type: name of the operation\n            (also passed to :func:`~pyro.poutine.runtime.effectful`)\n        :param bool post: if `True`, use this operation as postprocess\n\n        Dynamically add operations to an effect.\n        Useful for generating wrappers for libraries.\n\n        Example::\n\n            @SomeMessengerClass.register\n            def some_function(msg)\n                ...do_something...\n                return msg\n\n        \"\"\"\n        if fn is None:\n            return lambda x: cls.register(x, type=type, post=post)\n\n        if type is None:\n            raise ValueError(\"An operation type name must be provided\")\n\n        setattr(cls, \"_pyro_\" + (\"post_\" if post else \"\") + type, staticmethod(fn))\n        return fn\n\n    @classmethod\n    def unregister(cls, fn=None, type=None):\n        \"\"\"\n        :param fn: function implementing operation\n        :param str type: name of the operation\n            (also passed to :func:`~pyro.poutine.runtime.effectful`)\n\n        Dynamically remove operations from an effect.\n        Useful for removing wrappers from libraries.\n\n        Example::\n\n            SomeMessengerClass.unregister(some_function, \"name\")\n        \"\"\"\n        if type is None:\n            raise ValueError(\"An operation type name must be provided\")\n\n        try:\n            delattr(cls, \"_pyro_post_\" + type)\n        except AttributeError:\n            pass\n\n        try:\n            delattr(cls, \"_pyro_\" + type)\n        except AttributeError:\n            pass\n\n        return fn\n\n\n@contextmanager\ndef block_messengers(predicate):\n    \"\"\"\n    EXPERIMENTAL Context manager to temporarily remove matching messengers from\n    the _PYRO_STACK. Note this does not call the ``.__exit__()`` and\n    ``.__enter__()`` methods.\n\n    This is useful to selectively block enclosing handlers.\n\n    :param callable predicate: A predicate mapping messenger instance to boolean.\n        This mutes all messengers ``m`` for which ``bool(predicate(m)) is True``.\n    :yields: A list of matched messengers that are blocked.\n    \"\"\"\n    blocked = {}\n    try:\n        for i, messenger in enumerate(_PYRO_STACK):\n            if predicate(messenger):\n                blocked[i] = messenger\n                _PYRO_STACK[i] = Messenger()  # trivial messenger\n        yield list(blocked.values())\n    finally:\n        for i, messenger in blocked.items():\n            _PYRO_STACK[i] = messenger\n", "path": "pyro/poutine/messenger.py"}]}