diff --git a/Orange/widgets/settings.py b/Orange/widgets/settings.py index 6381e0a0e13..68e1060fcb6 100644 --- a/Orange/widgets/settings.py +++ b/Orange/widgets/settings.py @@ -424,7 +424,9 @@ def write_defaults_file(self, settings_file): ---------- settings_file : file-like object """ - pickle.dump(self.defaults, settings_file, -1) + defaults = dict(self.defaults) + defaults[VERSION_KEY] = self.widget_class.settings_version + pickle.dump(defaults, settings_file, -1) def _get_settings_filename(self): """Return the name of the file with default settings for the widget""" @@ -628,7 +630,15 @@ def _migrate_contexts(self, contexts): def write_defaults_file(self, settings_file): """Call the inherited method, then add global context to the pickle.""" super().write_defaults_file(settings_file) - pickle.dump(self.global_contexts, settings_file, -1) + + def add_version(context): + context = copy.copy(context) + context.values = dict(context.values) + context.values[VERSION_KEY] = self.widget_class.settings_version + return context + + pickle.dump([add_version(context) for context in self.global_contexts], + settings_file, -1) def pack_data(self, widget): """Call the inherited method, then add local contexts to the dict.""" diff --git a/Orange/widgets/tests/test_context_handler.py b/Orange/widgets/tests/test_context_handler.py index 538f1b00e8b..0b492c7962d 100644 --- a/Orange/widgets/tests/test_context_handler.py +++ b/Orange/widgets/tests/test_context_handler.py @@ -163,6 +163,24 @@ def test_pack_settings_stores_version(self): for c in settings["context_settings"]: self.assertIn(VERSION_KEY, c.values) + def test_write_defaults_stores_version(self): + handler = ContextHandler() + handler.bind(SimpleWidget) + widget = SimpleWidget() + widget.current_context = None + widget.context_settings = [DummyContext() for _ in range(3)] + handler.update_defaults(widget) + + f = BytesIO() + f.close = lambda: None + with patch("builtins.open", Mock(return_value=f)): + handler.write_defaults() + f.seek(0) + pickle.load(f) # settings + contexts = pickle.load(f) + for c in contexts: + self.assertEqual(c.values.get("__version__", 0xBAD), 1) + class TestSettingsPrinter(TestCase): def test_formats_contexts(self): diff --git a/Orange/widgets/tests/test_settings_handler.py b/Orange/widgets/tests/test_settings_handler.py index 575c4740b54..6f4667b7c2d 100644 --- a/Orange/widgets/tests/test_settings_handler.py +++ b/Orange/widgets/tests/test_settings_handler.py @@ -56,6 +56,7 @@ def test_write_defaults(self): fd, settings_file = mkstemp(suffix='.ini') handler = SettingsHandler() + handler.widget_class = SimpleWidget handler.defaults = {'a': 5, 'b': {1: 5}} handler._get_settings_filename = lambda: settings_file handler.write_defaults() @@ -64,7 +65,9 @@ def test_write_defaults(self): default_settings = pickle.load(f) os.close(fd) - self.assertEqual(handler.defaults, default_settings) + self.assertEqual(default_settings.pop(VERSION_KEY, -0xBAD), + handler.widget_class.settings_version,) + self.assertEqual(default_settings, handler.defaults) os.remove(settings_file) @@ -327,7 +330,10 @@ def override_default_settings(self, widget, defaults=None): h.widget_class = widget h.defaults = defaults filename = h._get_settings_filename() - h.write_defaults() + + os.makedirs(os.path.dirname(filename), exist_ok=True) + with open(filename, "wb") as f: + pickle.dump(defaults, f) yield