Repository: parogers/pgu

Issue:
Theme class doesn't support loading multiple themes
Running leveledit.py results in an immediate exception:

```
python3 scripts/leveledit.py 
pygame 2.6.1 (SDL 2.28.4, Python 3.10.12)
Hello from the pygame community. https://www.pygame.org/contribute.html
pgu.isovid - This module is alpha, and is subject to change.
pgu.hexvid - This module is alpha, and is subject to change.
Traceback (most recent call last):
  File "/home/peter/projects/pgu/scripts/leveledit.py", line 1387, in <module>
    main()
  File "/home/peter/projects/pgu/scripts/leveledit.py", line 1382, in main
    init_app()
  File "/home/peter/projects/pgu/scripts/leveledit.py", line 1297, in init_app
    e = gui.Menus(menus)
  File "/home/peter/projects/pgu/pgu/gui/menus.py", line 110, in __init__
    m = _Menu(self, basic.Label(mt, cls=menu_cls+".label"), cls=menu_cls)
  File "/home/peter/projects/pgu/pgu/gui/basic.py", line 103, in __init__
    self.style.check("font")
  File "/home/peter/projects/pgu/pgu/gui/style.py", line 26, in check
    raise StyleError("Cannot find the style attribute '%s' for '%s'" % (attr, desc))
pgu.gui.errors.StyleError: Cannot find the style attribute 'font' for 'menu.label'
```

There was a bug introduced by #50 that prevents the Theme class from loading multiple themes. Only data from the last theme is actually preserved. (leveledit.py attempts to load default and tools themes)

Discussion:

Solution patch:
diff --git a/pgu/gui/theme.py b/pgu/gui/theme.py
index b9d296c..468d768 100644
--- a/pgu/gui/theme.py
+++ b/pgu/gui/theme.py
@@ -133,13 +133,13 @@ class Theme(object):
         dname = os.path.normpath(dname)
 
         try:
-            self.config = _read_theme_config_txt(dname)
+            self.config |= _read_theme_config_txt(dname)
             return
         except NotTheme:
             pass
 
         try:
-            self.config = _read_theme_style_ini(dname)
+            self.config |= _read_theme_style_ini(dname)
             return
         except NotTheme:
             pass


Test patch:
diff --git a/tests/test_theme.py b/tests/test_theme.py
index 4cfbeae..ce80902 100644
--- a/tests/test_theme.py
+++ b/tests/test_theme.py
@@ -133,3 +133,32 @@ def test_it_raises_error_if_empty_theme_directory():
     with tempfile.TemporaryDirectory() as temp_dir:
         with pytest.raises(IOError, match='Cannot load theme: missing style.ini or config.txt'):
             Theme(temp_dir)
+
+
+def test_it_unions_multiple_themes():
+    style1_ini = '''
+[some-element]
+label1 = first
+'''
+    style2_ini = '''
+[some-element]
+label2 = second
+'''
+    with temp_theme(style1_ini) as temp_dir1, temp_theme(style2_ini) as temp_dir2:
+        theme = Theme([temp_dir1, temp_dir2])
+        assert theme.getstyle('some-element', '', 'label1') == 'first'
+        assert theme.getstyle('some-element', '', 'label2') == 'second'
+
+
+def test_it_unions_theme_and_legacy_theme():
+    style_ini = '''
+[some-element]
+label1 = first
+'''
+    config_txt = '''
+some-element label2 second
+'''
+    with temp_theme(style_ini) as temp_dir1, temp_legacy_theme(config_txt) as temp_dir2:
+        theme = Theme([temp_dir1, temp_dir2])
+        assert theme.getstyle('some-element', '', 'label1') == 'first'
+        assert theme.getstyle('some-element', '', 'label2') == 'second'