Repository: microsoft/ptvsd

Issue:
Error in debugging in flask (in VS Code)
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Traceback (most recent call last):
  File "/Users/donjayamanne/.vscode/extensions/ms-python.python-2018.4.0-rc/pythonFiles/experimental/ptvsd/ptvsd/pydevd/pydevd.py", line 387, in check_output
    v = out.getvalue()
  File "/Users/donjayamanne/.vscode/extensions/ms-python.python-2018.4.0-rc/pythonFiles/experimental/ptvsd/ptvsd/pydevd/_pydevd_bundle/pydevd_io.py", line 46, in getvalue
    return ''.join(b)
TypeError: sequence item 0: expected str instance, bytes found


Discussion:
May be something like:
```py
''.join((bytes.decode(e) if isinstance(e, bytes) else e for e in b))
```
Is this something you want me to try? Either way, its an issue in pydevd.
Note, when decoding you'd need to specify the encoding.
I was wondering if this is a solution. I have tried it, but I was not able to repro the original issue.
This is what we get back from flask. First few lines are written as bytes.
```
[<class 'bytes'>]: b''
[<class 'bytes'>]: b' * Serving Flask app "runserver.py"\r\n'
[<class 'bytes'>]: b' * Environment: production\r\n'
[<class 'bytes'>]: b'   WARNING: Do not use the development server in a production environment.\r\n'
[<class 'bytes'>]: b'   Use a production WSGI server instead.\r\n'
[<class 'bytes'>]: b' * Debug mode: off\r\n'
[<class 'str'>]:  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[<class 'str'>]: 

[<class 'str'>]: Traceback (most recent call last):

[<class 'str'>]: 
[<class 'str'>]:   File "C:\git\ptvsd\ptvsd\_vendored\pydevd\pydevd.py", line 387, in check_output
    v = out.getvalue()

[<class 'str'>]: 
[<class 'str'>]:   File "C:\git\ptvsd\ptvsd\_vendored\pydevd\_pydevd_bundle\pydevd_io.py", line 50, in getvalue
    return ''.join(b)

[<class 'str'>]: 
[<class 'str'>]: TypeError: sequence item 0: expected str instance, bytes found

[<class 'str'>]: 

```
It looks like the first set of messages are written to stdout and the runserver message is written to stderr
Here 1 = stdout, 2 = stderr
```
check_output[1]:
 * Serving Flask app "runserver.py"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
check_output[2]:  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

Resolving patch:
diff --git a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py
--- a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py
+++ b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py
@@ -625,11 +625,10 @@ def make_variable_changed_message(self, seq, payload):
         # notify debugger that value was changed successfully
         return NetCommand(CMD_RETURN, seq, payload)
 
-    def make_io_message(self, v, ctx, dbg=None):
+    def make_io_message(self, v, ctx):
         '''
         @param v: the message to pass to the debug server
         @param ctx: 1 for stdio 2 for stderr
-        @param dbg: If not none, add to the writer
         '''
 
         try:
@@ -638,14 +637,9 @@ def make_io_message(self, v, ctx, dbg=None):
                 v += '...'
 
             v = pydevd_xml.make_valid_xml_value(quote(v, '/>_= \t'))
-            net = NetCommand(str(CMD_WRITE_TO_CONSOLE), 0, '<xml><io s="%s" ctx="%s"/></xml>' % (v, ctx))
+            return NetCommand(str(CMD_WRITE_TO_CONSOLE), 0, '<xml><io s="%s" ctx="%s"/></xml>' % (v, ctx))
         except:
-            net = self.make_error_message(0, get_exception_traceback_str())
-
-        if dbg:
-            dbg.writer.add_command(net)
-
-        return net
+            return self.make_error_message(0, get_exception_traceback_str())
 
     def make_version_message(self, seq):
         try:
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
@@ -41,7 +41,7 @@ def __init__(self):
         self.encoding = os.environ.get('PYTHONIOENCODING', 'utf-8')
 
     def getvalue(self):
-        b = self.buflist
+        b = (bytes.decode(v, self.encoding) if isinstance(v, bytes) else v for v in self.buflist)
         self.buflist = [] #clear it
         return ''.join(b)
     
diff --git a/ptvsd/_vendored/pydevd/pydevd.py b/ptvsd/_vendored/pydevd/pydevd.py
--- a/ptvsd/_vendored/pydevd/pydevd.py
+++ b/ptvsd/_vendored/pydevd/pydevd.py
@@ -387,7 +387,8 @@ def check_output(self, out, outCtx):
             v = out.getvalue()
 
             if v:
-                self.cmd_factory.make_io_message(v, outCtx, self)
+                cmd = self.cmd_factory.make_io_message(v, outCtx)
+                self.writer.add_command(cmd)
         except:
             traceback.print_exc()
 


Test patch: