Repository: biolab/orange3

Issue:
File should not autoload the last file used, if file too large.
##### Orange version

3.3.7
##### Expected bahavior

Adding File should not autoload the last file used, if loading that file requires too much time,
##### Actual behavior

Adding File makes Orange to completely freezes since it tries to load the last file I tried (a csv that is 1.5GB and it's malformed). Orange enter the "(Not Responding)" state and will never complete.
##### Steps to reproduce the behavior

Add a very big CVS file , kill Canvas, and add a File and it will freeze right away (since it's trying to load the last file again). 
##### Additional info (worksheets, data, screenshots, ...)

I guess that there is no point of loading the whole CSV until it's really needed so I would suggest to defer the loading. Probably is loaded for preview purposes (?), maybe it's possible to check size of file first and load only first 100 rows. 

Right now I'm was forced to move the file so that Canvas fails gracefully to load it. But the hardest part was to figure out what was happening, I didn't realize straight away that it was trying to load the last recently used file. And I had to guess which file it was. 



Discussion:
You can always use Options - Reset widget settings... to clear widget settings and start anew. The scripting alternative is `orange-canvas --clear-widget-settings`.
However, I agree Orange might refer from loading excessively large data sets by default.

It should be possible to check the size first, and defer if too large.


Resolving patch:
diff --git a/Orange/widgets/data/owfile.py b/Orange/widgets/data/owfile.py
--- a/Orange/widgets/data/owfile.py
+++ b/Orange/widgets/data/owfile.py
@@ -91,7 +91,7 @@ class OWFile(widget.OWWidget, RecentPathsWComboMixin):
     want_main_area = False
 
     SEARCH_PATHS = [("sample-datasets", get_sample_datasets_dir())]
-
+    SIZE_LIMIT = 1e7
     LOCAL_FILE, URL = range(2)
 
     settingsHandler = PerfectDomainContextHandler()
@@ -118,6 +118,10 @@ class OWFile(widget.OWWidget, RecentPathsWComboMixin):
                   for f in sorted(set(FileFormat.readers.values()),
                                   key=list(FileFormat.readers.values()).index)))
 
+    class Warning(widget.OWWidget.Warning):
+        file_too_big = widget.Msg("The file is too large to load automatically."
+                                  " Press Reload to load.")
+
     def __init__(self):
         super().__init__()
         RecentPathsWComboMixin.__init__(self)
@@ -214,10 +218,16 @@ def __init__(self):
         self.set_file_list()
         # Must not call open_file from within __init__. open_file
         # explicitly re-enters the event loop (by a progress bar)
-        QTimer.singleShot(0, self.load_data)
 
         self.setAcceptDrops(True)
 
+        if self.source == self.LOCAL_FILE and \
+                        os.path.getsize(self.last_path()) > self.SIZE_LIMIT:
+            self.Warning.file_too_big()
+            return
+
+        QTimer.singleShot(0, self.load_data)
+
     def sizeHint(self):
         return QSize(600, 550)
 
@@ -263,7 +273,7 @@ def load_data(self):
         # file readers
         # pylint: disable=broad-except
         self.editor_model.set_domain(None)
-
+        self.Warning.file_too_big.clear()
         error = None
         try:
             self.reader = self._get_reader()


Test patch:
diff --git a/Orange/widgets/data/tests/test_owfile.py b/Orange/widgets/data/tests/test_owfile.py
--- a/Orange/widgets/data/tests/test_owfile.py
+++ b/Orange/widgets/data/tests/test_owfile.py
@@ -64,4 +64,8 @@ def _drop_event(self, url):
             QPoint(0, 0), Qt.MoveAction, data,
             Qt.NoButton, Qt.NoModifier, QDropEvent.Drop)
 
-
+    def test_check_file_size(self):
+        self.assertFalse(self.widget.Warning.file_too_big.is_shown())
+        self.widget.SIZE_LIMIT = 4000
+        self.widget.__init__()
+        self.assertTrue(self.widget.Warning.file_too_big.is_shown())