Repository: streamlit/streamlit

Issue:
On rerun, faded elements are becoming opaque one by one. Instead they become opaque all at once.
Steps to repro:
1. Run `examples/reference.py`
2. When done, rerun it.

**Expected:** on rerun, all elements fade out and then become opaque one by one even before the run is done.
**Actual:** on rerun, all elements fade out and only become opaque when the entire run is done.

I believe this bug was introduced with the Sidebar code.


Discussion:

Resolving patch:
diff --git a/lib/streamlit/watcher/LocalSourcesWatcher.py b/lib/streamlit/watcher/LocalSourcesWatcher.py
--- a/lib/streamlit/watcher/LocalSourcesWatcher.py
+++ b/lib/streamlit/watcher/LocalSourcesWatcher.py
@@ -194,9 +194,13 @@ def update_watched_modules(self):
 
 
 def _file_is_in_folder(filepath, folderpath_glob):
-    # Strip trailing slash if it exists
-    if folderpath_glob.endswith("/"):
-        folderpath_glob = folderpath_glob[:-1]
-
-    file_dir = os.path.dirname(filepath)
+    # Make the glob always end with "/*" so we match files inside subfolders of
+    # folderpath_glob.
+    if not folderpath_glob.endswith("*"):
+        if folderpath_glob.endswith("/"):
+            folderpath_glob += "*"
+        else:
+            folderpath_glob += "/*"
+
+    file_dir = os.path.dirname(filepath) + "/"
     return fnmatch.fnmatch(file_dir, folderpath_glob)


Test patch:
diff --git a/lib/tests/streamlit/watcher/LocalSourcesWatcher_test.py b/lib/tests/streamlit/watcher/LocalSourcesWatcher_test.py
--- a/lib/tests/streamlit/watcher/LocalSourcesWatcher_test.py
+++ b/lib/tests/streamlit/watcher/LocalSourcesWatcher_test.py
@@ -35,6 +35,17 @@ def test_file_in_folder(self):
         ret = LocalSourcesWatcher._file_is_in_folder("/a/b/c/foo.py", "/a/b/c")
         self.assertTrue(ret)
 
+    def test_file_in_subfolder(self):
+        # Test with and without trailing slash
+        ret = LocalSourcesWatcher._file_is_in_folder("/a/b/c/foo.py", "/a")
+        self.assertTrue(ret)
+        ret = LocalSourcesWatcher._file_is_in_folder("/a/b/c/foo.py", "/a/")
+        self.assertTrue(ret)
+        ret = LocalSourcesWatcher._file_is_in_folder("/a/b/c/foo.py", "/a/b")
+        self.assertTrue(ret)
+        ret = LocalSourcesWatcher._file_is_in_folder("/a/b/c/foo.py", "/a/b/")
+        self.assertTrue(ret)
+
     def test_file_not_in_folder(self):
         # Test with and without trailing slash
         ret = LocalSourcesWatcher._file_is_in_folder("/a/b/c/foo.py", "/d/e/f/")
diff --git a/lib/tests/streamlit/watcher/PollingFileWatcher_test.py b/lib/tests/streamlit/watcher/PollingFileWatcher_test.py
--- a/lib/tests/streamlit/watcher/PollingFileWatcher_test.py
+++ b/lib/tests/streamlit/watcher/PollingFileWatcher_test.py
@@ -147,7 +147,8 @@ def modify_mock_file():
 
         def sleep():
             try:
-                time.sleep(2 * PollingFileWatcher._POLLING_PERIOD_SECS)
+                # TODO: Remove depedency on time.sleep!
+                time.sleep(5 * PollingFileWatcher._POLLING_PERIOD_SECS)
             except AssertionError:
                 pass
 
@@ -168,8 +169,8 @@ def sleep():
         modify_mock_file()
         sleep()
 
-        assert 1 == cb1.call_count
-        assert 1 == cb2.call_count
+        self.assertEqual(cb1.call_count, 1)
+        self.assertEqual(cb2.call_count, 1)
 
         # Close watcher1. Only watcher2's callback should be called after this.
         watcher1.close()
@@ -178,8 +179,8 @@ def sleep():
         modify_mock_file()
         sleep()
 
-        assert 1 == cb1.call_count
-        assert 2 == cb2.call_count
+        self.assertEqual(cb1.call_count, 1)
+        self.assertEqual(cb2.call_count, 2)
 
         watcher2.close()
 
@@ -188,8 +189,8 @@ def sleep():
 
         # Both watchers are now closed, so their callback counts
         # should not have increased.
-        assert 1 == cb1.call_count
-        assert 2 == cb2.call_count
+        self.assertEqual(cb1.call_count, 1)
+        self.assertEqual(cb2.call_count, 2)
 
 
 class FakeStat(object):