Major plugin restructuring.
[hooke.git] / hooke / config.py
index 766177136d81e0a238a55ef0245a025faf5fb796..66f0b4ced67e00de44998636d7e8de5d014ec07b 100644 (file)
@@ -1,24 +1,38 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-'''
-config.py
-
-Configuration defaults, read/write, and template file creation for Hooke.
-
-COPYRIGHT
-'''
+# Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
+#
+# This file is part of Hooke.
+#
+# Hooke is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation, either
+# version 3 of the License, or (at your option) any later version.
+#
+# Hooke is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Hooke.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+"""Configuration defaults, read/write, and template file creation for
+Hooke.
+"""
 
 import ConfigParser as configparser
 import os.path
 import textwrap
+import unittest
 
 from .compat.odict import odict as OrderedDict
 
+
 DEFAULT_PATHS = [
     '/usr/share/hooke/hooke.cfg',
     '/etc/hooke/hooke.cfg',
     '~/.hooke.cfg',
+    '.hooke.cfg',
     ]
 """We start with the system files, and work our way to the more
 specific user files, so the user can override the sysadmin who
@@ -31,10 +45,18 @@ class Setting (object):
     def __init__(self, section, option=None, value=None, help=None, wrap=True):
         self.section = section
         self.option = option
-        self.value = value
+        self.value = str(value)
         self.help = help
         self.wrap = wrap
 
+    def __eq__(self, other):
+        for attr in ['__class__', 'section', 'option', 'value', 'help']:
+            value = getattr(self, attr)
+            o_value = getattr(other, attr)
+            if o_value != value:
+                return False
+        return True
+
     def is_section(self):
         return self.option == None
 
@@ -230,9 +252,8 @@ class HookeConfigParser (configparser.SafeConfigParser):
         """
         local_fp = fp == None
         if local_fp:
-            fp = open(self._config_paths[-1], 'w')
+            fp = open(os.path.expanduser(self._config_paths[-1]), 'w')
         if self._defaults:
-            print self._defaults
             self._write_setting(fp, configparser.DEFAULTSECT,
                                 help="Miscellaneous options")
             for (key, value) in self._defaults.items():
@@ -246,3 +267,22 @@ class HookeConfigParser (configparser.SafeConfigParser):
             fp.write("\n")
         if local_fp:
             fp.close()
+
+class TestHookeConfigParser (unittest.TestCase):
+    def test_queue_safe(self):
+        """Ensure :class:`HookeConfigParser` is Queue-safe.
+        """
+        from multiprocessing import Queue
+        q = Queue()
+        a = HookeConfigParser(
+            paths=DEFAULT_PATHS, default_settings=DEFAULT_SETTINGS)
+        q.put(a)
+        b = q.get(a)
+        for attr in ['_dict', '_defaults', '_sections', '_config_paths',
+                     '_default_settings']:
+            a_value = getattr(a, attr)
+            b_value = getattr(b, attr)
+            self.failUnless(
+                a_value == b_value,
+                'HookeConfigParser.%s did not survive Queue: %s != %s'
+                % (attr, a_value, b_value))