Repository: streamlit/streamlit

Issue:
Echo doesn't echo all methods of class
# Summary

Some methods of a class defined inside the echo scope aren't echoed

# Steps to reproduce

## Not working

![image](https://user-images.githubusercontent.com/11019190/70231716-2648f600-175b-11ea-929e-4d4f0cecee78.png)

## Working

![image](https://user-images.githubusercontent.com/11019190/70231754-3a8cf300-175b-11ea-82a1-8932280064f8.png)


## Expected behavior:

All the code inside the echo scope should be echoed

## Actual behavior:

Some methods of the class aren't echoed


# Debug info

- Streamlit: version 0.51.0
- Python version: 3.7.4
- Using pip
- OS version: Manjaro Linux 18.1.3
- Browser version: Chrome



Discussion:

Resolving patch:
diff --git a/lib/streamlit/__init__.py b/lib/streamlit/__init__.py
--- a/lib/streamlit/__init__.py
+++ b/lib/streamlit/__init__.py
@@ -610,7 +610,9 @@ def echo():
             lines_to_display.extend(source_lines[start_line:end_line])
             initial_spaces = _SPACES_RE.match(lines_to_display[0]).end()
             for line in source_lines[end_line:]:
-                if _SPACES_RE.match(line).end() < initial_spaces:
+                indentation = _SPACES_RE.match(line).end()
+                # The > 1 is because we want to allow '\n' between sections.
+                if indentation > 1 and indentation < initial_spaces:
                     break
                 lines_to_display.append(line)
         lines_to_display = _textwrap.dedent("".join(lines_to_display))


Test patch:
diff --git a/lib/tests/streamlit/echo_test.py b/lib/tests/streamlit/echo_test.py
new file mode 100644
--- /dev/null
+++ b/lib/tests/streamlit/echo_test.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Copyright 2018-2019 Streamlit Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from tests import testutil
+import streamlit as st
+
+
+class DeltaGeneratorWriteTest(testutil.DeltaGeneratorTestCase):
+    def test_echo(self):
+        # The empty lines below are part of the test. Do not remove them.
+        with st.echo():
+            st.write("Hello")
+
+            "hi"
+
+            def foo(x):
+                y = x + 10
+
+                print(y)
+
+            class MyClass(object):
+                def do_x(self):
+                    pass
+
+                def do_y(self):
+                    pass
+
+        expected = """```python
+st.write("Hello")
+
+"hi"
+
+def foo(x):
+    y = x + 10
+
+    print(y)
+
+class MyClass(object):
+    def do_x(self):
+        pass
+
+    def do_y(self):
+        pass
+
+
+```"""
+
+        element = self.get_delta_from_queue(0).new_element
+        self.assertEqual(expected, element.markdown.body)
+
+        element = self.get_delta_from_queue(1).new_element
+        self.assertEqual("Hello", element.markdown.body)