Skip to content

Commit c675d30

Browse files
authored
Merge pull request #2631 from ales-erjavec/fixes/defaults-store-version
[FIX] settings: Store settings version in the serialized defaults
2 parents f9f8e8a + 865382a commit c675d30

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

Orange/widgets/settings.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,9 @@ def write_defaults_file(self, settings_file):
424424
----------
425425
settings_file : file-like object
426426
"""
427-
pickle.dump(self.defaults, settings_file, -1)
427+
defaults = dict(self.defaults)
428+
defaults[VERSION_KEY] = self.widget_class.settings_version
429+
pickle.dump(defaults, settings_file, -1)
428430

429431
def _get_settings_filename(self):
430432
"""Return the name of the file with default settings for the widget"""
@@ -628,7 +630,15 @@ def _migrate_contexts(self, contexts):
628630
def write_defaults_file(self, settings_file):
629631
"""Call the inherited method, then add global context to the pickle."""
630632
super().write_defaults_file(settings_file)
631-
pickle.dump(self.global_contexts, settings_file, -1)
633+
634+
def add_version(context):
635+
context = copy.copy(context)
636+
context.values = dict(context.values)
637+
context.values[VERSION_KEY] = self.widget_class.settings_version
638+
return context
639+
640+
pickle.dump([add_version(context) for context in self.global_contexts],
641+
settings_file, -1)
632642

633643
def pack_data(self, widget):
634644
"""Call the inherited method, then add local contexts to the dict."""

Orange/widgets/tests/test_context_handler.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,24 @@ def test_pack_settings_stores_version(self):
163163
for c in settings["context_settings"]:
164164
self.assertIn(VERSION_KEY, c.values)
165165

166+
def test_write_defaults_stores_version(self):
167+
handler = ContextHandler()
168+
handler.bind(SimpleWidget)
169+
widget = SimpleWidget()
170+
widget.current_context = None
171+
widget.context_settings = [DummyContext() for _ in range(3)]
172+
handler.update_defaults(widget)
173+
174+
f = BytesIO()
175+
f.close = lambda: None
176+
with patch("builtins.open", Mock(return_value=f)):
177+
handler.write_defaults()
178+
f.seek(0)
179+
pickle.load(f) # settings
180+
contexts = pickle.load(f)
181+
for c in contexts:
182+
self.assertEqual(c.values.get("__version__", 0xBAD), 1)
183+
166184

167185
class TestSettingsPrinter(TestCase):
168186
def test_formats_contexts(self):

Orange/widgets/tests/test_settings_handler.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def test_write_defaults(self):
5656
fd, settings_file = mkstemp(suffix='.ini')
5757

5858
handler = SettingsHandler()
59+
handler.widget_class = SimpleWidget
5960
handler.defaults = {'a': 5, 'b': {1: 5}}
6061
handler._get_settings_filename = lambda: settings_file
6162
handler.write_defaults()
@@ -64,7 +65,9 @@ def test_write_defaults(self):
6465
default_settings = pickle.load(f)
6566
os.close(fd)
6667

67-
self.assertEqual(handler.defaults, default_settings)
68+
self.assertEqual(default_settings.pop(VERSION_KEY, -0xBAD),
69+
handler.widget_class.settings_version,)
70+
self.assertEqual(default_settings, handler.defaults)
6871

6972
os.remove(settings_file)
7073

@@ -327,7 +330,10 @@ def override_default_settings(self, widget, defaults=None):
327330
h.widget_class = widget
328331
h.defaults = defaults
329332
filename = h._get_settings_filename()
330-
h.write_defaults()
333+
334+
os.makedirs(os.path.dirname(filename), exist_ok=True)
335+
with open(filename, "wb") as f:
336+
pickle.dump(defaults, f)
331337

332338
yield
333339

0 commit comments

Comments
 (0)