Repository: microsoft/debugpy

Issue:
pp.Server() error
Issue Type: <b>Bug</b>

everytime I debug python code:

import pp
pp.Server

It will raise the error message:
Exception has occurred: RuntimeError
Communication pipe read error


Extension version: 2020.2.64397
VS Code version: Code 1.43.0 (78a4c91400152c0f27ba4d363eb56d2835f9903a, 2020-03-09T19:44:52.965Z)
OS version: Linux x64 5.3.0-40-generic

<details>
<summary>System Info</summary>

|Item|Value|
|---|---|
|CPUs|Intel(R) Xeon(R) Gold 6138 CPU @ 2.00GHz (40 x 1000)|
|GPU Status|2d_canvas: unavailable_software<br>flash_3d: disabled_software<br>flash_stage3d: disabled_software<br>flash_stage3d_baseline: disabled_software<br>gpu_compositing: disabled_software<br>multiple_raster_threads: enabled_on<br>oop_rasterization: disabled_off<br>protected_video_decode: disabled_off<br>rasterization: disabled_software<br>skia_renderer: disabled_off_ok<br>video_decode: disabled_software<br>viz_display_compositor: enabled_on<br>viz_hit_test_surface_layer: disabled_off_ok<br>webgl: unavailable_software<br>webgl2: unavailable_software|
|Load (avg)|1, 1, 1|
|Memory (System)|62.33GB (54.85GB free)|
|Process Argv|--no-sandbox --unity-launch|
|Screen Reader|no|
|VM|0%|
</details>
<!-- generated by issue reporter -->

Discussion:
sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=SECURITY_HOTSPOT) to review)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=microsoft_debugpy&pullRequest=340&metric=coverage&view=list) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo.png' alt='No Duplication information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=microsoft_debugpy&pullRequest=340&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=SECURITY_HOTSPOT) to review)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=microsoft_debugpy&pullRequest=340&metric=coverage&view=list) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo.png' alt='No Duplication information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=microsoft_debugpy&pullRequest=340&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=SECURITY_HOTSPOT) to review)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=microsoft_debugpy&pullRequest=340&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=microsoft_debugpy&pullRequest=340&metric=coverage&view=list) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo.png' alt='No Duplication information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=microsoft_debugpy&pullRequest=340&metric=duplicated_lines_density&view=list) No Duplication information



Patch:
diff --git a/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_command_line_handling.py b/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_command_line_handling.py
index 263f43fb..2afae09e 100644
--- a/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_command_line_handling.py
+++ b/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_command_line_handling.py
@@ -78,6 +78,7 @@ ACCEPTED_ARG_HANDLERS = [
     ArgHandlerBool('print-in-debugger-startup'),
     ArgHandlerBool('cmd-line'),
     ArgHandlerBool('module'),
+    ArgHandlerBool('skip-notify-stdin'),
 
     # The ones below should've been just one setting to specify the protocol, but for compatibility
     # reasons they're passed as a flag but are mutually exclusive.
diff --git a/src/debugpy/_vendored/pydevd/pydevd.py b/src/debugpy/_vendored/pydevd/pydevd.py
index 236f7de2..64579c5a 100644
--- a/src/debugpy/_vendored/pydevd/pydevd.py
+++ b/src/debugpy/_vendored/pydevd/pydevd.py
@@ -2531,6 +2531,7 @@ def settrace(
     dont_trace_end_patterns=(),
     access_token=None,
     client_access_token=None,
+    notify_stdin=True,
     **kwargs
     ):
     '''Sets the tracing function with the pydev debug function and initializes needed facilities.
@@ -2577,6 +2578,14 @@ def settrace(
 
     :param client_access_token: token to be sent from the debugger to the client (i.e.: IDE) when
         a connection is established (verified by the client).
+
+    :param notify_stdin:
+        If True sys.stdin will be patched to notify the client when a message is requested
+        from the IDE. This is done so that when reading the stdin the client is notified.
+        Clients may need this to know when something that is being written should be interpreted
+        as an input to the process or as a command to be evaluated.
+        Note that parallel-python has issues with this (because it tries to assert that sys.stdin
+        is of a given type instead of just checking that it has what it needs).
     '''
 
     stdout_to_server = stdout_to_server or kwargs.get('stdoutToServer', False)  # Backward compatibility
@@ -2602,6 +2611,7 @@ def settrace(
             access_token,
             client_access_token,
             __setup_holder__=__setup_holder__,
+            notify_stdin=notify_stdin,
         )
 
 
@@ -2624,6 +2634,7 @@ def _locked_settrace(
     access_token,
     client_access_token,
     __setup_holder__,
+    notify_stdin,
     ):
     if patch_multiprocessing:
         try:
@@ -2653,6 +2664,7 @@ def _locked_settrace(
                 'server': False,
                 'port': int(port),
                 'multiprocess': patch_multiprocessing,
+                'skip-notify-stdin': not notify_stdin,
             }
             SetupHolder.setup = setup
 
@@ -2682,7 +2694,8 @@ def _locked_settrace(
         if _global_redirect_stderr_to_server:
             _init_stderr_redirect()
 
-        patch_stdin()
+        if notify_stdin:
+            patch_stdin()
 
         t = threadingCurrentThread()
         additional_info = set_additional_thread_info(t)
@@ -3130,7 +3143,8 @@ def main():
             pass
 
     is_module = setup['module']
-    patch_stdin()
+    if not setup['skip-notify-stdin']:
+        patch_stdin()
 
     if setup[pydevd_constants.ARGUMENT_JSON_PROTOCOL]:
         PyDevdAPI().set_protocol(debugger, 0, JSON_PROTOCOL)
diff --git a/src/debugpy/server/api.py b/src/debugpy/server/api.py
index 65794c7c..b1cf20a7 100644
--- a/src/debugpy/server/api.py
+++ b/src/debugpy/server/api.py
@@ -40,6 +40,8 @@ _adapter_process = None
 
 def _settrace(*args, **kwargs):
     log.debug("pydevd.settrace(*{0!r}, **{1!r})", args, kwargs)
+    # The stdin in notification is not acted upon in debugpy, so, disable it.
+    kwargs.setdefault('notify_stdin', False)
     try:
         return pydevd.settrace(*args, **kwargs)
     except Exception:


Test patch:
diff --git a/src/debugpy/_vendored/pydevd/tests_python/debugger_unittest.py b/src/debugpy/_vendored/pydevd/tests_python/debugger_unittest.py
index e248e0a8..71c1111a 100644
--- a/src/debugpy/_vendored/pydevd/tests_python/debugger_unittest.py
+++ b/src/debugpy/_vendored/pydevd/tests_python/debugger_unittest.py
@@ -477,6 +477,7 @@ class DebuggerRunner(object):
             args,
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE,
+            stdin=subprocess.PIPE,
             cwd=writer.get_cwd() if writer is not None else '.',
             env=env,
         )
diff --git a/src/debugpy/_vendored/pydevd/tests_python/test_debugger.py b/src/debugpy/_vendored/pydevd/tests_python/test_debugger.py
index 72a502de..e1726a78 100644
--- a/src/debugpy/_vendored/pydevd/tests_python/test_debugger.py
+++ b/src/debugpy/_vendored/pydevd/tests_python/test_debugger.py
@@ -19,7 +19,7 @@ from tests_python.debugger_unittest import (CMD_SET_PROPERTY_TRACE, REASON_CAUGH
     CMD_THREAD_RESUME_SINGLE_NOTIFICATION, REASON_STEP_RETURN, REASON_STEP_RETURN_MY_CODE,
     REASON_STEP_OVER_MY_CODE, REASON_STEP_INTO, CMD_THREAD_KILL, IS_PYPY, REASON_STOP_ON_START)
 from _pydevd_bundle.pydevd_constants import IS_WINDOWS, IS_PY38_OR_GREATER, IS_PY39_OR_GREATER
-from _pydevd_bundle.pydevd_comm_constants import CMD_RELOAD_CODE
+from _pydevd_bundle.pydevd_comm_constants import CMD_RELOAD_CODE, CMD_INPUT_REQUESTED
 import json
 import pydevd_file_utils
 import subprocess
@@ -3931,6 +3931,36 @@ def test_asyncio_step_return(case_setup, target_filename):
         writer.write_run_thread(hit.thread_id)
         writer.finished_ok = True
 
+
+def test_notify_stdin(case_setup, pyfile):
+
+    @pyfile
+    def case_stdin():
+        import sys
+        print('Write something:')
+        contents = sys.stdin.readline()
+        print('Found: ' + contents)
+
+        print('TEST SUCEEDED')
+
+    def additional_output_checks(writer, stdout, stderr):
+        assert 'Found: foo' in stdout
+
+    with case_setup.test_file(
+            case_stdin,
+            additional_output_checks=additional_output_checks,
+        ) as writer:
+            writer.write_make_initial_run()
+            msg = writer.wait_for_message(CMD_INPUT_REQUESTED, expect_xml=False)
+            assert msg.split('\t')[-1] == 'True'
+            process = writer.process
+            process.stdin.write(b'foo\n')
+            process.stdin.flush()
+            msg = writer.wait_for_message(CMD_INPUT_REQUESTED, expect_xml=False)
+            assert msg.split('\t')[-1] == 'False'
+
+            writer.finished_ok = True
+
 # Jython needs some vars to be set locally.
 # set JAVA_HOME=c:\bin\jdk1.8.0_172
 # set PATH=%PATH%;C:\bin\jython2.7.0\bin
diff --git a/src/debugpy/_vendored/pydevd/tests_python/test_pydev_monkey.py b/src/debugpy/_vendored/pydevd/tests_python/test_pydev_monkey.py
index e5666bb3..f4e90320 100644
--- a/src/debugpy/_vendored/pydevd/tests_python/test_pydev_monkey.py
+++ b/src/debugpy/_vendored/pydevd/tests_python/test_pydev_monkey.py
@@ -61,7 +61,7 @@ def test_monkey_patch_args_indc():
     original = SetupHolder.setup
 
     try:
-        SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True}
+        SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True}
         check = ['C:\\bin\\python.exe', '-u', '-c', 'connect("127.0.0.1")']
         debug_command = (
             "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.PydevdCustomization.DEFAULT_PROTOCOL='quoted-line'; "
@@ -86,7 +86,7 @@ def test_monkey_patch_args_module():
     original = SetupHolder.setup
 
     try:
-        SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True}
+        SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True, 'skip-notify-stdin': True}
         check = ['C:\\bin\\python.exe', '-m', 'test']
         from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file
         assert pydev_monkey.patch_args(check) == [
@@ -100,6 +100,7 @@ def test_monkey_patch_args_module():
             '--client',
             '127.0.0.1',
             '--multiprocess',
+            '--skip-notify-stdin',
             '--protocol-quoted-line',
             '--file',
             'test',
diff --git a/tests/debugpy/test_output.py b/tests/debugpy/test_output.py
index 43b1ea9e..c208725d 100644
--- a/tests/debugpy/test_output.py
+++ b/tests/debugpy/test_output.py
@@ -122,6 +122,24 @@ def test_non_ascii_output(pyfile, target, run):
     )
 
 
+def test_stdin_not_patched(pyfile, target, run):
+    @pyfile
+    def code_to_debug():
+        import sys
+        import debuggee
+        from debuggee import backchannel
+
+        debuggee.setup()
+        backchannel.send(sys.stdin == sys.__stdin__)
+
+    with debug.Session() as session:
+        backchannel = session.open_backchannel()
+        with run(session, target(code_to_debug)):
+            pass
+        is_original_stdin = backchannel.receive()
+        assert is_original_stdin, 'Expected sys.stdin and sys.__stdin__ to be the same.'
+
+
 if sys.platform == "win32":
 
     @pytest.mark.parametrize("redirect_output", ["", "redirect_output"])