prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Errors logged on VSTS 
  ```
  2018-07-05T19:13:17.5780150Z .Traceback (most recent call last):
  2018-07-05T19:13:17.5795340Z   File "/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command.py", line 749, in process_net_command
  2018-07-05T19:13:17.5813150Z     py_db.enable_output_redirection('STDOUT' in text, 'STDERR' in text)
  2018-07-05T19:13:17.5831030Z   File "/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/pydevd.py", line 361, in enable_output_redirection
  2018-07-05T19:13:17.5847040Z     init_stdout_redirect()
  2018-07-05T19:13:17.5862230Z   File "/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/pydevd.py", line 1199, in init_stdout_redirect
  2018-07-05T19:13:17.5878570Z     sys.stdout = pydevd_io.IORedirector(original, sys._pydevd_out_buffer_, wrap_buffer) #@UndefinedVariable
  2018-07-05T19:13:17.5895080Z   File "/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py", line 24, in __init__
  2018-07-05T19:13:17.5913010Z     self.buffer = IORedirector(original.buffer, new_redirect.buffer, False)
  2018-07-05T19:13:17.5939400Z AttributeError: '_DuplicateWriter' object has no attribute 'buffer'
  ```
  
  The same errors are logged for Linux and Mac OS.
  I'm using a Mac and cannot replicate this error.
  
  /cc @fabioz 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py`
  Content:
  ```
  1 from _pydevd_bundle import pydevd_constants
  2 
  3 IS_PY3K = pydevd_constants.IS_PY3K
  4 
  5 class IORedirector:
  6     '''
  7     This class works to wrap a stream (stdout/stderr) with an additional redirect.
  8     '''
  9 
  10     def __init__(self, original, new_redirect, wrap_buffer=False):
  11         '''
  12         :param stream original:
  13             The stream to be wrapped (usually stdout/stderr).
  14 
  15         :param stream new_redirect:
  16             Usually IOBuf (below).
  17 
  18         :param bool wrap_buffer:
  19             Whether to create a buffer attribute (needed to mimick python 3 s
  20             tdout/stderr which has a buffer to write binary data).
  21         '''
  22         self._redirect_to = (original, new_redirect)
  23         if wrap_buffer:
  24             self.buffer = IORedirector(original.buffer, new_redirect.buffer, False)
  25 
  26     def write(self, s):
  27         # Note that writing to the original stream may fail for some reasons
  28         # (such as trying to write something that's not a string or having it closed).
  29         for r in self._redirect_to:
  30             r.write(s)
  31 
  32     def isatty(self):
  33         return self._redirect_to[0].isatty()
  34 
  35     def flush(self):
  36         for r in self._redirect_to:
  37             r.flush()
  38 
  39     def __getattr__(self, name):
  40         for r in self._redirect_to:
  41             if hasattr(r, name):
  42                 return getattr(r, name)
  43         raise AttributeError(name)
  44 
  45 class IOBuf:
  46     '''This class works as a replacement for stdio and stderr.
  47     It is a buffer and when its contents are requested, it will erase what
  48     it has so far so that the next return will not return the same contents again.
  49     '''
  50     def __init__(self):
  51         self.buflist = []
  52         import os
  53         self.encoding = os.environ.get('PYTHONIOENCODING', 'utf-8')
  54 
  55     def getvalue(self):
  56         b = self.buflist
  57         self.buflist = []  # clear it
  58         return ''.join(b)  # bytes on py2, str on py3.
  59     
  60     def write(self, s):
  61         if not IS_PY3K:
  62             if isinstance(s, unicode):
  63                 # can't use 'errors' as kwargs in py 2.6
  64                 s = s.encode(self.encoding, 'replace')
  65         else:
  66             if isinstance(s, bytes):
  67                 s = s.decode(self.encoding, errors='replace')
  68         self.buflist.append(s)
  69 
  70     def isatty(self):
  71         return False
  72 
  73     def flush(self):
  74         pass
  75 
  76     def empty(self):
  77         return len(self.buflist) == 0
  78 
  79 class _RedirectionsHolder:
  80     _stack_stdout = []
  81     _stack_stderr = []
  82 
  83 
  84 def start_redirect(keep_original_redirection=False, std='stdout'):
  85     '''
  86     @param std: 'stdout', 'stderr', or 'both'
  87     '''
  88     import sys
  89     buf = IOBuf()
  90 
  91     if std == 'both':
  92         config_stds = ['stdout', 'stderr']
  93     else:
  94         config_stds = [std]
  95 
  96     for std in config_stds:
  97         original = getattr(sys, std)
  98         stack = getattr(_RedirectionsHolder, '_stack_%s' % std)
  99         stack.append(original)
  100 
  101         if keep_original_redirection:
  102             setattr(sys, std, IORedirector(getattr(sys, std), buf))
  103         else:
  104             setattr(sys, std, buf)
  105     return buf
  106 
  107 
  108 def end_redirect(std='stdout'):
  109     import sys
  110     if std == 'both':
  111         config_stds = ['stdout', 'stderr']
  112     else:
  113         config_stds = [std]
  114     for std in config_stds:
  115         stack = getattr(_RedirectionsHolder, '_stack_%s' % std)
  116         setattr(sys, std, stack.pop())
  117 
  118
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py
  --- a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py
  +++ b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py
  @@ -20,7 +20,7 @@
               tdout/stderr which has a buffer to write binary data).
           '''
           self._redirect_to = (original, new_redirect)
  -        if wrap_buffer:
  +        if wrap_buffer and hasattr(original, 'buffer'):
               self.buffer = IORedirector(original.buffer, new_redirect.buffer, False)
   
       def write(self, s):
  
verification_info: {"golden_diff": "diff --git a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py\n--- a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py\n+++ b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py\n@@ -20,7 +20,7 @@\n             tdout/stderr which has a buffer to write binary data).\n         '''\n         self._redirect_to = (original, new_redirect)\n-        if wrap_buffer:\n+        if wrap_buffer and hasattr(original, 'buffer'):\n             self.buffer = IORedirector(original.buffer, new_redirect.buffer, False)\n \n     def write(self, s):\n", "issue": "Errors logged on VSTS \n```\r\n2018-07-05T19:13:17.5780150Z .Traceback (most recent call last):\r\n2018-07-05T19:13:17.5795340Z   File \"/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command.py\", line 749, in process_net_command\r\n2018-07-05T19:13:17.5813150Z     py_db.enable_output_redirection('STDOUT' in text, 'STDERR' in text)\r\n2018-07-05T19:13:17.5831030Z   File \"/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/pydevd.py\", line 361, in enable_output_redirection\r\n2018-07-05T19:13:17.5847040Z     init_stdout_redirect()\r\n2018-07-05T19:13:17.5862230Z   File \"/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/pydevd.py\", line 1199, in init_stdout_redirect\r\n2018-07-05T19:13:17.5878570Z     sys.stdout = pydevd_io.IORedirector(original, sys._pydevd_out_buffer_, wrap_buffer) #@UndefinedVariable\r\n2018-07-05T19:13:17.5895080Z   File \"/Users/vsts/agent/2.134.2/work/1/s/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py\", line 24, in __init__\r\n2018-07-05T19:13:17.5913010Z     self.buffer = IORedirector(original.buffer, new_redirect.buffer, False)\r\n2018-07-05T19:13:17.5939400Z AttributeError: '_DuplicateWriter' object has no attribute 'buffer'\r\n```\r\n\r\nThe same errors are logged for Linux and Mac OS.\r\nI'm using a Mac and cannot replicate this error.\r\n\r\n/cc @fabioz \n", "before_files": [{"content": "from _pydevd_bundle import pydevd_constants\n\nIS_PY3K = pydevd_constants.IS_PY3K\n\nclass IORedirector:\n    '''\n    This class works to wrap a stream (stdout/stderr) with an additional redirect.\n    '''\n\n    def __init__(self, original, new_redirect, wrap_buffer=False):\n        '''\n        :param stream original:\n            The stream to be wrapped (usually stdout/stderr).\n\n        :param stream new_redirect:\n            Usually IOBuf (below).\n\n        :param bool wrap_buffer:\n            Whether to create a buffer attribute (needed to mimick python 3 s\n            tdout/stderr which has a buffer to write binary data).\n        '''\n        self._redirect_to = (original, new_redirect)\n        if wrap_buffer:\n            self.buffer = IORedirector(original.buffer, new_redirect.buffer, False)\n\n    def write(self, s):\n        # Note that writing to the original stream may fail for some reasons\n        # (such as trying to write something that's not a string or having it closed).\n        for r in self._redirect_to:\n            r.write(s)\n\n    def isatty(self):\n        return self._redirect_to[0].isatty()\n\n    def flush(self):\n        for r in self._redirect_to:\n            r.flush()\n\n    def __getattr__(self, name):\n        for r in self._redirect_to:\n            if hasattr(r, name):\n                return getattr(r, name)\n        raise AttributeError(name)\n\nclass IOBuf:\n    '''This class works as a replacement for stdio and stderr.\n    It is a buffer and when its contents are requested, it will erase what\n    it has so far so that the next return will not return the same contents again.\n    '''\n    def __init__(self):\n        self.buflist = []\n        import os\n        self.encoding = os.environ.get('PYTHONIOENCODING', 'utf-8')\n\n    def getvalue(self):\n        b = self.buflist\n        self.buflist = []  # clear it\n        return ''.join(b)  # bytes on py2, str on py3.\n    \n    def write(self, s):\n        if not IS_PY3K:\n            if isinstance(s, unicode):\n                # can't use 'errors' as kwargs in py 2.6\n                s = s.encode(self.encoding, 'replace')\n        else:\n            if isinstance(s, bytes):\n                s = s.decode(self.encoding, errors='replace')\n        self.buflist.append(s)\n\n    def isatty(self):\n        return False\n\n    def flush(self):\n        pass\n\n    def empty(self):\n        return len(self.buflist) == 0\n\nclass _RedirectionsHolder:\n    _stack_stdout = []\n    _stack_stderr = []\n\n\ndef start_redirect(keep_original_redirection=False, std='stdout'):\n    '''\n    @param std: 'stdout', 'stderr', or 'both'\n    '''\n    import sys\n    buf = IOBuf()\n\n    if std == 'both':\n        config_stds = ['stdout', 'stderr']\n    else:\n        config_stds = [std]\n\n    for std in config_stds:\n        original = getattr(sys, std)\n        stack = getattr(_RedirectionsHolder, '_stack_%s' % std)\n        stack.append(original)\n\n        if keep_original_redirection:\n            setattr(sys, std, IORedirector(getattr(sys, std), buf))\n        else:\n            setattr(sys, std, buf)\n    return buf\n\n\ndef end_redirect(std='stdout'):\n    import sys\n    if std == 'both':\n        config_stds = ['stdout', 'stderr']\n    else:\n        config_stds = [std]\n    for std in config_stds:\n        stack = getattr(_RedirectionsHolder, '_stack_%s' % std)\n        setattr(sys, std, stack.pop())\n\n", "path": "ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py"}], "after_files": [{"content": "from _pydevd_bundle import pydevd_constants\n\nIS_PY3K = pydevd_constants.IS_PY3K\n\nclass IORedirector:\n    '''\n    This class works to wrap a stream (stdout/stderr) with an additional redirect.\n    '''\n\n    def __init__(self, original, new_redirect, wrap_buffer=False):\n        '''\n        :param stream original:\n            The stream to be wrapped (usually stdout/stderr).\n\n        :param stream new_redirect:\n            Usually IOBuf (below).\n\n        :param bool wrap_buffer:\n            Whether to create a buffer attribute (needed to mimick python 3 s\n            tdout/stderr which has a buffer to write binary data).\n        '''\n        self._redirect_to = (original, new_redirect)\n        if wrap_buffer and hasattr(original, 'buffer'):\n            self.buffer = IORedirector(original.buffer, new_redirect.buffer, False)\n\n    def write(self, s):\n        # Note that writing to the original stream may fail for some reasons\n        # (such as trying to write something that's not a string or having it closed).\n        for r in self._redirect_to:\n            r.write(s)\n\n    def isatty(self):\n        return self._redirect_to[0].isatty()\n\n    def flush(self):\n        for r in self._redirect_to:\n            r.flush()\n\n    def __getattr__(self, name):\n        for r in self._redirect_to:\n            if hasattr(r, name):\n                return getattr(r, name)\n        raise AttributeError(name)\n\nclass IOBuf:\n    '''This class works as a replacement for stdio and stderr.\n    It is a buffer and when its contents are requested, it will erase what\n    it has so far so that the next return will not return the same contents again.\n    '''\n    def __init__(self):\n        self.buflist = []\n        import os\n        self.encoding = os.environ.get('PYTHONIOENCODING', 'utf-8')\n\n    def getvalue(self):\n        b = self.buflist\n        self.buflist = []  # clear it\n        return ''.join(b)  # bytes on py2, str on py3.\n    \n    def write(self, s):\n        if not IS_PY3K:\n            if isinstance(s, unicode):\n                # can't use 'errors' as kwargs in py 2.6\n                s = s.encode(self.encoding, 'replace')\n        else:\n            if isinstance(s, bytes):\n                s = s.decode(self.encoding, errors='replace')\n        self.buflist.append(s)\n\n    def isatty(self):\n        return False\n\n    def flush(self):\n        pass\n\n    def empty(self):\n        return len(self.buflist) == 0\n\nclass _RedirectionsHolder:\n    _stack_stdout = []\n    _stack_stderr = []\n\n\ndef start_redirect(keep_original_redirection=False, std='stdout'):\n    '''\n    @param std: 'stdout', 'stderr', or 'both'\n    '''\n    import sys\n    buf = IOBuf()\n\n    if std == 'both':\n        config_stds = ['stdout', 'stderr']\n    else:\n        config_stds = [std]\n\n    for std in config_stds:\n        original = getattr(sys, std)\n        stack = getattr(_RedirectionsHolder, '_stack_%s' % std)\n        stack.append(original)\n\n        if keep_original_redirection:\n            setattr(sys, std, IORedirector(getattr(sys, std), buf))\n        else:\n            setattr(sys, std, buf)\n    return buf\n\n\ndef end_redirect(std='stdout'):\n    import sys\n    if std == 'both':\n        config_stds = ['stdout', 'stderr']\n    else:\n        config_stds = [std]\n    for std in config_stds:\n        stack = getattr(_RedirectionsHolder, '_stack_%s' % std)\n        setattr(sys, std, stack.pop())\n\n", "path": "ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_io.py"}]}