We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
'async for' requires an object with __aiter__ method, got AIOTracedCursor
## Problem
Using ddtrace and aiopg, if I do:

```python
await cur.execute(query)
async for value in cur:
    yield value
```
If my connection is not patched, I get:
```
TypeError: 'async for' requires an object with __aiter__ method, got AIOTracedCursor
(...)
  File "path/to/my/file.py", line 241, in get_many
    async for value in cur:
```
(if my connection is not patched, it works)

## Analysis

The cursor class is replaced with `AIOTracedCursor` which inherits `wrapt.ObjectProxy`.

Problem is, while thanks to `ObjectProxy`, `AIOTracedCursor().__aiter__()` would most probably work and return whatever the real proxy would return, this is not enough for Python to accept that the cursor is an iterator.

A small example with simple objects:
```python
class A():
    def iter(self):
        return iter([])

    async def aiter(self):
        return iter([])

    def __getattr__(self, attr):
        if attr.endswith("iter__"):
            return getattr(self, attr.strip("_"))
a = A()
```
We implement `a.__iter__()` and `a.__aiter__()` but Python doesn't see it:
```
In [6]: a.__iter__()                                                                                                                                                                                               
Out[6]: <list_iterator at 0x7fdff00de860>

In [7]: a.__aiter__()                                                                                                                                                                                              
Out[7]: <coroutine object A.aiter at 0x7fdff00ddba0>

In [8]: async for e in a: print(e)                                                                                                                                                                                 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
cell_name in async-def-wrapper()

TypeError: 'async for' requires an object with __aiter__ method, got A                                                                                                                                                                                                   

In [9]: iter(a)                                                                                                                                                                                                    
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-2b64cb055077> in <module>
----> 1 iter(a)

TypeError: 'A' object is not iterable

```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ddtrace/contrib/aiopg/connection.py`
Content:
```
1 import asyncio
2 from ddtrace.vendor import wrapt
3 
4 from aiopg.utils import _ContextManager
5 
6 from .. import dbapi
7 from ...constants import ANALYTICS_SAMPLE_RATE_KEY
8 from ...ext import sql, AppTypes
9 from ...pin import Pin
10 from ...settings import config
11 
12 
13 class AIOTracedCursor(wrapt.ObjectProxy):
14     """ TracedCursor wraps a psql cursor and traces its queries. """
15 
16     def __init__(self, cursor, pin):
17         super(AIOTracedCursor, self).__init__(cursor)
18         pin.onto(self)
19         name = pin.app or 'sql'
20         self._datadog_name = '%s.query' % name
21 
22     @asyncio.coroutine
23     def _trace_method(self, method, resource, extra_tags, *args, **kwargs):
24         pin = Pin.get_from(self)
25         if not pin or not pin.enabled():
26             result = yield from method(*args, **kwargs)
27             return result
28         service = pin.service
29 
30         with pin.tracer.trace(self._datadog_name, service=service,
31                               resource=resource) as s:
32             s.span_type = sql.TYPE
33             s.set_tag(sql.QUERY, resource)
34             s.set_tags(pin.tags)
35             s.set_tags(extra_tags)
36 
37             # set analytics sample rate
38             s.set_tag(
39                 ANALYTICS_SAMPLE_RATE_KEY,
40                 config.aiopg.get_analytics_sample_rate()
41             )
42 
43             try:
44                 result = yield from method(*args, **kwargs)
45                 return result
46             finally:
47                 s.set_metric('db.rowcount', self.rowcount)
48 
49     @asyncio.coroutine
50     def executemany(self, query, *args, **kwargs):
51         # FIXME[matt] properly handle kwargs here. arg names can be different
52         # with different libs.
53         result = yield from self._trace_method(
54             self.__wrapped__.executemany, query, {'sql.executemany': 'true'},
55             query, *args, **kwargs)
56         return result
57 
58     @asyncio.coroutine
59     def execute(self, query, *args, **kwargs):
60         result = yield from self._trace_method(
61             self.__wrapped__.execute, query, {}, query, *args, **kwargs)
62         return result
63 
64     @asyncio.coroutine
65     def callproc(self, proc, args):
66         result = yield from self._trace_method(
67             self.__wrapped__.callproc, proc, {}, proc, args)
68         return result
69 
70 
71 class AIOTracedConnection(wrapt.ObjectProxy):
72     """ TracedConnection wraps a Connection with tracing code. """
73 
74     def __init__(self, conn, pin=None, cursor_cls=AIOTracedCursor):
75         super(AIOTracedConnection, self).__init__(conn)
76         name = dbapi._get_vendor(conn)
77         db_pin = pin or Pin(service=name, app=name, app_type=AppTypes.db)
78         db_pin.onto(self)
79         # wrapt requires prefix of `_self` for attributes that are only in the
80         # proxy (since some of our source objects will use `__slots__`)
81         self._self_cursor_cls = cursor_cls
82 
83     def cursor(self, *args, **kwargs):
84         # unfortunately we also need to patch this method as otherwise "self"
85         # ends up being the aiopg connection object
86         coro = self._cursor(*args, **kwargs)
87         return _ContextManager(coro)
88 
89     @asyncio.coroutine
90     def _cursor(self, *args, **kwargs):
91         cursor = yield from self.__wrapped__._cursor(*args, **kwargs)
92         pin = Pin.get_from(self)
93         if not pin:
94             return cursor
95         return self._self_cursor_cls(cursor, pin)
96
```
--- 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/ddtrace/contrib/aiopg/connection.py b/ddtrace/contrib/aiopg/connection.py
--- a/ddtrace/contrib/aiopg/connection.py
+++ b/ddtrace/contrib/aiopg/connection.py
@@ -67,6 +67,9 @@
             self.__wrapped__.callproc, proc, {}, proc, args)
         return result
 
+    def __aiter__(self):
+        return self.__wrapped__.__aiter__()
+
 
 class AIOTracedConnection(wrapt.ObjectProxy):
     """ TracedConnection wraps a Connection with tracing code. """

{"golden_diff": "diff --git a/ddtrace/contrib/aiopg/connection.py b/ddtrace/contrib/aiopg/connection.py\n--- a/ddtrace/contrib/aiopg/connection.py\n+++ b/ddtrace/contrib/aiopg/connection.py\n@@ -67,6 +67,9 @@\n             self.__wrapped__.callproc, proc, {}, proc, args)\n         return result\n \n+    def __aiter__(self):\n+        return self.__wrapped__.__aiter__()\n+\n \n class AIOTracedConnection(wrapt.ObjectProxy):\n     \"\"\" TracedConnection wraps a Connection with tracing code. \"\"\"\n", "issue": "'async for' requires an object with __aiter__ method, got AIOTracedCursor\n## Problem\r\nUsing ddtrace and aiopg, if I do:\r\n\r\n```python\r\nawait cur.execute(query)\r\nasync for value in cur:\r\n    yield value\r\n```\r\nIf my connection is not patched, I get:\r\n```\r\nTypeError: 'async for' requires an object with __aiter__ method, got AIOTracedCursor\r\n(...)\r\n  File \"path/to/my/file.py\", line 241, in get_many\r\n    async for value in cur:\r\n```\r\n(if my connection is not patched, it works)\r\n\r\n## Analysis\r\n\r\nThe cursor class is replaced with `AIOTracedCursor` which inherits `wrapt.ObjectProxy`.\r\n\r\nProblem is, while thanks to `ObjectProxy`, `AIOTracedCursor().__aiter__()` would most probably work and return whatever the real proxy would return, this is not enough for Python to accept that the cursor is an iterator.\r\n\r\nA small example with simple objects:\r\n```python\r\nclass A():\r\n    def iter(self):\r\n        return iter([])\r\n\r\n    async def aiter(self):\r\n        return iter([])\r\n\r\n    def __getattr__(self, attr):\r\n        if attr.endswith(\"iter__\"):\r\n            return getattr(self, attr.strip(\"_\"))\r\na = A()\r\n```\r\nWe implement `a.__iter__()` and `a.__aiter__()` but Python doesn't see it:\r\n```\r\nIn [6]: a.__iter__()                                                                                                                                                                                               \r\nOut[6]: <list_iterator at 0x7fdff00de860>\r\n\r\nIn [7]: a.__aiter__()                                                                                                                                                                                              \r\nOut[7]: <coroutine object A.aiter at 0x7fdff00ddba0>\r\n\r\nIn [8]: async for e in a: print(e)                                                                                                                                                                                 \r\n---------------------------------------------------------------------------\r\nTypeError                                 Traceback (most recent call last)\r\ncell_name in async-def-wrapper()\r\n\r\nTypeError: 'async for' requires an object with __aiter__ method, got A                                                                                                                                                                                                   \r\n\r\nIn [9]: iter(a)                                                                                                                                                                                                    \r\n---------------------------------------------------------------------------\r\nTypeError                                 Traceback (most recent call last)\r\n<ipython-input-9-2b64cb055077> in <module>\r\n----> 1 iter(a)\r\n\r\nTypeError: 'A' object is not iterable\r\n\r\n```\n", "before_files": [{"content": "import asyncio\nfrom ddtrace.vendor import wrapt\n\nfrom aiopg.utils import _ContextManager\n\nfrom .. import dbapi\nfrom ...constants import ANALYTICS_SAMPLE_RATE_KEY\nfrom ...ext import sql, AppTypes\nfrom ...pin import Pin\nfrom ...settings import config\n\n\nclass AIOTracedCursor(wrapt.ObjectProxy):\n    \"\"\" TracedCursor wraps a psql cursor and traces its queries. \"\"\"\n\n    def __init__(self, cursor, pin):\n        super(AIOTracedCursor, self).__init__(cursor)\n        pin.onto(self)\n        name = pin.app or 'sql'\n        self._datadog_name = '%s.query' % name\n\n    @asyncio.coroutine\n    def _trace_method(self, method, resource, extra_tags, *args, **kwargs):\n        pin = Pin.get_from(self)\n        if not pin or not pin.enabled():\n            result = yield from method(*args, **kwargs)\n            return result\n        service = pin.service\n\n        with pin.tracer.trace(self._datadog_name, service=service,\n                              resource=resource) as s:\n            s.span_type = sql.TYPE\n            s.set_tag(sql.QUERY, resource)\n            s.set_tags(pin.tags)\n            s.set_tags(extra_tags)\n\n            # set analytics sample rate\n            s.set_tag(\n                ANALYTICS_SAMPLE_RATE_KEY,\n                config.aiopg.get_analytics_sample_rate()\n            )\n\n            try:\n                result = yield from method(*args, **kwargs)\n                return result\n            finally:\n                s.set_metric('db.rowcount', self.rowcount)\n\n    @asyncio.coroutine\n    def executemany(self, query, *args, **kwargs):\n        # FIXME[matt] properly handle kwargs here. arg names can be different\n        # with different libs.\n        result = yield from self._trace_method(\n            self.__wrapped__.executemany, query, {'sql.executemany': 'true'},\n            query, *args, **kwargs)\n        return result\n\n    @asyncio.coroutine\n    def execute(self, query, *args, **kwargs):\n        result = yield from self._trace_method(\n            self.__wrapped__.execute, query, {}, query, *args, **kwargs)\n        return result\n\n    @asyncio.coroutine\n    def callproc(self, proc, args):\n        result = yield from self._trace_method(\n            self.__wrapped__.callproc, proc, {}, proc, args)\n        return result\n\n\nclass AIOTracedConnection(wrapt.ObjectProxy):\n    \"\"\" TracedConnection wraps a Connection with tracing code. \"\"\"\n\n    def __init__(self, conn, pin=None, cursor_cls=AIOTracedCursor):\n        super(AIOTracedConnection, self).__init__(conn)\n        name = dbapi._get_vendor(conn)\n        db_pin = pin or Pin(service=name, app=name, app_type=AppTypes.db)\n        db_pin.onto(self)\n        # wrapt requires prefix of `_self` for attributes that are only in the\n        # proxy (since some of our source objects will use `__slots__`)\n        self._self_cursor_cls = cursor_cls\n\n    def cursor(self, *args, **kwargs):\n        # unfortunately we also need to patch this method as otherwise \"self\"\n        # ends up being the aiopg connection object\n        coro = self._cursor(*args, **kwargs)\n        return _ContextManager(coro)\n\n    @asyncio.coroutine\n    def _cursor(self, *args, **kwargs):\n        cursor = yield from self.__wrapped__._cursor(*args, **kwargs)\n        pin = Pin.get_from(self)\n        if not pin:\n            return cursor\n        return self._self_cursor_cls(cursor, pin)\n", "path": "ddtrace/contrib/aiopg/connection.py"}], "after_files": [{"content": "import asyncio\nfrom ddtrace.vendor import wrapt\n\nfrom aiopg.utils import _ContextManager\n\nfrom .. import dbapi\nfrom ...constants import ANALYTICS_SAMPLE_RATE_KEY\nfrom ...ext import sql, AppTypes\nfrom ...pin import Pin\nfrom ...settings import config\n\n\nclass AIOTracedCursor(wrapt.ObjectProxy):\n    \"\"\" TracedCursor wraps a psql cursor and traces its queries. \"\"\"\n\n    def __init__(self, cursor, pin):\n        super(AIOTracedCursor, self).__init__(cursor)\n        pin.onto(self)\n        name = pin.app or 'sql'\n        self._datadog_name = '%s.query' % name\n\n    @asyncio.coroutine\n    def _trace_method(self, method, resource, extra_tags, *args, **kwargs):\n        pin = Pin.get_from(self)\n        if not pin or not pin.enabled():\n            result = yield from method(*args, **kwargs)\n            return result\n        service = pin.service\n\n        with pin.tracer.trace(self._datadog_name, service=service,\n                              resource=resource) as s:\n            s.span_type = sql.TYPE\n            s.set_tag(sql.QUERY, resource)\n            s.set_tags(pin.tags)\n            s.set_tags(extra_tags)\n\n            # set analytics sample rate\n            s.set_tag(\n                ANALYTICS_SAMPLE_RATE_KEY,\n                config.aiopg.get_analytics_sample_rate()\n            )\n\n            try:\n                result = yield from method(*args, **kwargs)\n                return result\n            finally:\n                s.set_metric('db.rowcount', self.rowcount)\n\n    @asyncio.coroutine\n    def executemany(self, query, *args, **kwargs):\n        # FIXME[matt] properly handle kwargs here. arg names can be different\n        # with different libs.\n        result = yield from self._trace_method(\n            self.__wrapped__.executemany, query, {'sql.executemany': 'true'},\n            query, *args, **kwargs)\n        return result\n\n    @asyncio.coroutine\n    def execute(self, query, *args, **kwargs):\n        result = yield from self._trace_method(\n            self.__wrapped__.execute, query, {}, query, *args, **kwargs)\n        return result\n\n    @asyncio.coroutine\n    def callproc(self, proc, args):\n        result = yield from self._trace_method(\n            self.__wrapped__.callproc, proc, {}, proc, args)\n        return result\n\n    def __aiter__(self):\n        return self.__wrapped__.__aiter__()\n\n\nclass AIOTracedConnection(wrapt.ObjectProxy):\n    \"\"\" TracedConnection wraps a Connection with tracing code. \"\"\"\n\n    def __init__(self, conn, pin=None, cursor_cls=AIOTracedCursor):\n        super(AIOTracedConnection, self).__init__(conn)\n        name = dbapi._get_vendor(conn)\n        db_pin = pin or Pin(service=name, app=name, app_type=AppTypes.db)\n        db_pin.onto(self)\n        # wrapt requires prefix of `_self` for attributes that are only in the\n        # proxy (since some of our source objects will use `__slots__`)\n        self._self_cursor_cls = cursor_cls\n\n    def cursor(self, *args, **kwargs):\n        # unfortunately we also need to patch this method as otherwise \"self\"\n        # ends up being the aiopg connection object\n        coro = self._cursor(*args, **kwargs)\n        return _ContextManager(coro)\n\n    @asyncio.coroutine\n    def _cursor(self, *args, **kwargs):\n        cursor = yield from self.__wrapped__._cursor(*args, **kwargs)\n        pin = Pin.get_from(self)\n        if not pin:\n            return cursor\n        return self._self_cursor_cls(cursor, pin)\n", "path": "ddtrace/contrib/aiopg/connection.py"}]}