Repository: aws/chalice

Issue:
Blueprint.route() no longer retains __doc__
Code snippet below succeeds on chalice `v1.19.0` and fails on chalice `v1.20.0`. This does not seem to affect `Chalice` objects (the snippet succeeds if `b = Chalice(__name__)` on both versions)

```python
from chalice import Blueprint

b = Blueprint(__name__)

@b.route("/test", methods=["POST"])
def x():
    """a"""
    pass

assert x.__doc__ == "a"
```

Discussion:

Patch:
diff --git a/.changes/next-release/21697515329-bugfix-Blueprints-30428.json b/.changes/next-release/21697515329-bugfix-Blueprints-30428.json
new file mode 100644
index 0000000..9cb3fe4
--- /dev/null
+++ b/.changes/next-release/21697515329-bugfix-Blueprints-30428.json
@@ -0,0 +1,5 @@
+{
+  "type": "bugfix",
+  "category": "Blueprints",
+  "description": "Preserve docstring in blueprints (#1525)"
+}
diff --git a/chalice/app.py b/chalice/app.py
index 6ae3359..b75bf09 100644
--- a/chalice/app.py
+++ b/chalice/app.py
@@ -1776,6 +1776,7 @@ class Blueprint(DecoratorAPI):
         # Blueprint.register() and provide an app object.  Once
         # we have access to an app, we can call the actual _wrap_handler
         # which will have access to middleware.
+        @functools.wraps(user_handler)
         def _defer_wrap_handler(app):
             # pylint: disable=protected-access
             return app._wrap_handler(handler_type, handler_name,


Test patch:
diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py
index c7ae84d..9853101 100644
--- a/tests/unit/test_app.py
+++ b/tests/unit/test_app.py
@@ -2015,6 +2015,27 @@ def test_can_combine_multiple_blueprints_in_single_app():
     assert sorted(list(myapp.routes)) == ['/bar', '/foo']
 
 
+def test_doc_saved_on_route():
+    myapp = app.Chalice('myapp')
+
+    @myapp.route('/')
+    def index():
+        """My index docstring."""
+        pass
+
+    assert index.__doc__ == 'My index docstring.'
+
+
+def test_blueprint_docstring_is_preserved():
+    foo = app.Blueprint('foo')
+
+    @foo.route('/foo')
+    def first():
+        """Blueprint docstring."""
+
+    assert first.__doc__ == 'Blueprint docstring.'
+
+
 def test_can_mount_apis_at_url_prefix():
     myapp = app.Chalice('myapp')
     foo = app.Blueprint('foo')