prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <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
  
  ```
  
  </issue>
  <code>
  [start of ddtrace/contrib/aiopg/connection.py]
  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 of ddtrace/contrib/aiopg/connection.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: 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. """
  
verification_info: {"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"}]}