Repository: microsoft/ptvsd

Issue:
Logpoints/Tracepoints does not work in Python 2.7
This feature works in Python 3.x
OS - Mac

* Open VSC
* Add following code:
```python
print("Hello1")
print("Hello2")
```
* Add a log point to first or second line with the message `This is {__file__}`
* Start debugging
* The only messages printed are `Hello1` and `Hello2`.


Discussion:

Resolving patch:
diff --git a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py
--- a/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py
+++ b/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py
@@ -594,7 +594,9 @@ def trace_dispatch(self, frame, event, arg):
 
                         if breakpoint.expression is not None:
                             handle_breakpoint_expression(breakpoint, info, new_frame)
-                            if breakpoint.is_logpoint:
+                            if breakpoint.is_logpoint and info.pydev_message is not None and len(info.pydev_message) > 0:
+                                cmd = main_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1')
+                                main_debugger.writer.add_command(cmd)
                                 return self.trace_dispatch
                             
                     if is_call and frame.f_code.co_name in ('<module>', '<lambda>'):
diff --git a/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_tracing.py b/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_tracing.py
--- a/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_tracing.py
+++ b/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_tracing.py
@@ -33,7 +33,9 @@ def handle_breakpoint(frame, thread, global_debugger, breakpoint):
 
     if breakpoint.expression is not None:
         handle_breakpoint_expression(breakpoint, info, new_frame)
-        if breakpoint.is_logpoint:
+        if breakpoint.is_logpoint and info.pydev_message is not None and len(info.pydev_message) > 0:
+            cmd = global_debugger.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1')
+            global_debugger.writer.add_command(cmd)
             return False
 
     if breakpoint.suspend_policy == "ALL":
diff --git a/ptvsd/wrapper.py b/ptvsd/wrapper.py
--- a/ptvsd/wrapper.py
+++ b/ptvsd/wrapper.py
@@ -1992,12 +1992,12 @@ def on_setBreakpoints(self, request, args):
                 condition = None
                 expressions = re.findall('\{.*?\}', logMessage)
                 if len(expressions) == 0:
-                    expression = 'print({})'.format(repr(logMessage)) # noqa
+                    expression = '{}'.format(repr(logMessage)) # noqa
                 else:
                     raw_text = reduce(lambda a, b: a.replace(b, '{}'), expressions, logMessage) # noqa
                     raw_text = raw_text.replace('"', '\\"')
                     expression_list = ', '.join([s.strip('{').strip('}').strip() for s in expressions]) # noqa
-                    expression = 'print("{}".format({}))'.format(raw_text, expression_list) # noqa
+                    expression = '"{}".format({})'.format(raw_text, expression_list) # noqa
 
             msg = msgfmt.format(vsc_bpid, bp_type, path, line, condition,
                                 expression, hit_condition, is_logpoint)


Test patch:
diff --git a/tests/highlevel/test_live_pydevd.py b/tests/highlevel/test_live_pydevd.py
--- a/tests/highlevel/test_live_pydevd.py
+++ b/tests/highlevel/test_live_pydevd.py
@@ -467,6 +467,7 @@ class LogpointTests(TestBase, unittest.TestCase):
         b = 2
         c = 3
         d = 4
+        print('bye')
         """
 
     @contextlib.contextmanager
@@ -553,10 +554,14 @@ def test_basic(self):
             self.new_event('thread', reason='started', threadId=1),
             self.new_event('output', **dict(
                 category='stdout',
-                output='1+2=3',
+                output='1+2=3' + os.linesep,
             )),
             self.new_event('output', **dict(
                 category='stdout',
-                output='\n',
+                output='bye',
+            )),
+            self.new_event('output', **dict(
+                category='stdout',
+                output=os.linesep,
             )),
         ])
diff --git a/tests/highlevel/test_messages.py b/tests/highlevel/test_messages.py
--- a/tests/highlevel/test_messages.py
+++ b/tests/highlevel/test_messages.py
@@ -1095,13 +1095,13 @@ def test_with_logpoint(self):
         self.PYDEVD_CMD = CMD_SET_BREAK
         self.assert_received(self.debugger, [
             self.expected_pydevd_request(
-                '1\tpython-line\tspam.py\t10\tNone\tNone\tprint(' + repr("5") + ')\tNone\tTrue'), # noqa
+                '1\tpython-line\tspam.py\t10\tNone\tNone\t' + repr("5") + '\tNone\tTrue'), # noqa
             self.expected_pydevd_request(
-                '2\tpython-line\tspam.py\t15\tNone\tNone\tprint(' + repr("Hello World") + ')\tNone\tTrue'), # noqa
+                '2\tpython-line\tspam.py\t15\tNone\tNone\t' + repr("Hello World") + '\tNone\tTrue'), # noqa
             self.expected_pydevd_request(
-                '3\tpython-line\tspam.py\t20\tNone\tNone\tprint("{}".format(a))\tNone\tTrue'), # noqa
+                '3\tpython-line\tspam.py\t20\tNone\tNone\t"{}".format(a)\tNone\tTrue'), # noqa
             self.expected_pydevd_request(
-             '4\tpython-line\tspam.py\t25\tNone\tNone\tprint("{}+{}=Something".format(a, b))\tNone\tTrue'), # noqa
+             '4\tpython-line\tspam.py\t25\tNone\tNone\t"{}+{}=Something".format(a, b)\tNone\tTrue'), # noqa
         ])
 
     def test_with_existing(self):
@@ -1274,9 +1274,9 @@ def test_vs_django_logpoint(self):
         self.PYDEVD_CMD = CMD_SET_BREAK
         self.assert_received(self.debugger, [
             self.expected_pydevd_request(
-                '1\tpython-line\tspam.py\t10\tNone\tNone\tprint(' + repr("Hello World") + ')\tNone\tTrue'), # noqa
+                '1\tpython-line\tspam.py\t10\tNone\tNone\t' + repr("Hello World") + '\tNone\tTrue'), # noqa
             self.expected_pydevd_request(
-                '2\tdjango-line\teggs.html\t17\tNone\tNone\tprint(' + repr("Hello Django World") + ')\tNone\tTrue'), # noqa
+                '2\tdjango-line\teggs.html\t17\tNone\tNone\t' + repr("Hello Django World") + '\tNone\tTrue'), # noqa
         ])
 
     def test_vs_flask_jinja2(self):
@@ -1348,9 +1348,9 @@ def test_vs_flask_jinja2_logpoint(self):
         self.PYDEVD_CMD = CMD_SET_BREAK
         self.assert_received(self.debugger, [
             self.expected_pydevd_request(
-                '1\tpython-line\tspam.py\t10\tNone\tNone\tprint(' + repr("Hello World") + ')\tNone\tTrue'), # noqa
+                '1\tpython-line\tspam.py\t10\tNone\tNone\t' + repr("Hello World") + '\tNone\tTrue'), # noqa
             self.expected_pydevd_request(
-                '2\tjinja2-line\teggs.html\t17\tNone\tNone\tprint(' + repr("Hello Jinja World") + ')\tNone\tTrue'), # noqa
+                '2\tjinja2-line\teggs.html\t17\tNone\tNone\t' + repr("Hello Jinja World") + '\tNone\tTrue'), # noqa
         ])
 
     def test_vsc_flask_jinja2(self):