python 3 compatibility
authorgwen <gremond@cadoles.com>
Wed, 28 Aug 2013 09:33:43 +0000 (11:33 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Wed, 28 Aug 2013 19:13:42 +0000 (21:13 +0200)
remove __eq__ and __ne__ in Option

16 files changed:
test/test_config.py
test/test_freeze.py
test/test_mandatory.py
test/test_option.py
test/test_option_type.py
test/test_permissive.py
test/test_requires.py
test/test_symlink.py
tiramisu/autolib.py
tiramisu/config.py
tiramisu/error.py
tiramisu/i18n.py
tiramisu/option.py
tiramisu/setting.py
tiramisu/storage/dictionary/storage.py
tiramisu/value.py

index b50b7d0..98f2095 100644 (file)
@@ -9,6 +9,7 @@ from py.test import raises
 from tiramisu.config import Config
 from tiramisu.option import IntOption, FloatOption, StrOption, ChoiceOption, \
     BoolOption, UnicodeOption, OptionDescription
+from tiramisu.error import ConflictError
 
 
 def make_description():
@@ -199,3 +200,14 @@ def test_values_not_setitem():
     root = OptionDescription('root', '', [d1])
     config = Config(root)
     raises(ValueError, "config.cfgimpl_get_values()[g1] = 2")
+
+
+def test_duplicated_option():
+    g1 = IntOption('g1', '', 1)
+    #in same OptionDescription
+    raises(ConflictError, "d1 = OptionDescription('od', '', [g1, g1])")
+    d1 = OptionDescription('od1', '', [g1])
+    d2 = OptionDescription('od2', '', [g1])
+    root = OptionDescription('root', '', [d1, d2])
+    #in different OptionDescription
+    raises(ConflictError, "config = Config(root)")
index b79138f..cda1406 100644 (file)
@@ -44,7 +44,7 @@ def test_freeze_whole_config():
     prop = []
     try:
         conf.gc.dummy = True
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'frozen' in prop
     setting.remove('everything_frozen')
@@ -65,7 +65,7 @@ def test_freeze_one_option():
     prop = []
     try:
         conf.gc.dummy = True
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'frozen' in prop
 
@@ -82,7 +82,7 @@ def test_frozen_value():
     prop = []
     try:
         config.string = "egg"
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'frozen' in prop
 
@@ -99,7 +99,7 @@ def test_freeze():
     prop = []
     try:
         conf.gc.name = 'framework'
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'frozen' in prop
 
@@ -115,7 +115,7 @@ def test_freeze_multi():
     prop = []
     try:
         conf.boolop = [True]
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'frozen' in prop
 
@@ -133,7 +133,7 @@ def test_freeze_get_multi():
     prop = []
     try:
         valmulti.append(False)
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'frozen' in prop
 
index aad04ee..c535e31 100644 (file)
@@ -2,7 +2,7 @@ import autopath
 
 #from py.test import raises
 from tiramisu.config import Config, mandatory_warnings
-from tiramisu.option import StrOption, OptionDescription, UnicodeOption
+from tiramisu.option import StrOption, UnicodeOption, OptionDescription
 from tiramisu.error import PropertiesOptionError
 
 
@@ -26,7 +26,7 @@ def test_mandatory_ro():
     prop = []
     try:
         config.str1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
     config.read_write()
@@ -61,7 +61,7 @@ def test_mandatory_default():
     prop = []
     try:
         config.str
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
 
@@ -76,7 +76,7 @@ def test_mandatory_none():
     prop = []
     try:
         config.str1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
 
@@ -90,7 +90,7 @@ def test_mandatory_empty():
     prop = []
     try:
         config.str1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
 
@@ -104,7 +104,7 @@ def test_mandatory_multi_none():
     prop = []
     try:
         config.str3
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
     config.read_write()
@@ -114,7 +114,7 @@ def test_mandatory_multi_none():
     prop = []
     try:
         config.str3
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
 
@@ -128,7 +128,7 @@ def test_mandatory_multi_empty():
     prop = []
     try:
         config.str3
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
     config.read_write()
@@ -138,7 +138,7 @@ def test_mandatory_multi_empty():
     prop = []
     try:
         config.str3
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'mandatory' in prop
 
@@ -160,16 +160,16 @@ def test_mandatory_disabled():
     prop = []
     try:
         config.str1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert prop == ['mandatory']
     setting[descr.str1].append('disabled')
     prop = []
     try:
         config.str1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
-    assert prop == ['disabled', 'mandatory']
+    assert set(prop) == set(['disabled', 'mandatory'])
 
 
 def test_mandatory_unicode():
@@ -180,7 +180,7 @@ def test_mandatory_unicode():
     prop = []
     try:
         config.unicode2
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert prop == ['mandatory']
     config.read_write()
@@ -189,7 +189,7 @@ def test_mandatory_unicode():
     prop = []
     try:
         config.unicode2
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert prop == ['mandatory']
 
@@ -202,7 +202,7 @@ def test_mandatory_warnings_ro():
     proc = []
     try:
         config.str
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         proc = err.proptype
     assert proc == ['mandatory']
     assert list(mandatory_warnings(config)) == ['str', 'str1', 'unicode2', 'str3']
index e4dc66b..0492ed2 100644 (file)
@@ -6,33 +6,33 @@ import autopath
 from tiramisu.option import BoolOption, IntOption
 
 
-def test_option_comparison():
-    "compare :class:`tiramisu.option.BoolOption`"
-    dummy1 = BoolOption('dummy1', 'doc dummy')
-    dummy2 = BoolOption('dummy2', 'doc dummy')
-    dummy3 = BoolOption('dummy1', 'doc dummy')
-    assert dummy1 != dummy2
-    assert dummy1 == dummy3
+#def test_option_comparison():
+#    "compare :class:`tiramisu.option.BoolOption`"
+#    dummy1 = BoolOption('dummy1', 'doc dummy')
+#    dummy2 = BoolOption('dummy2', 'doc dummy')
+#    dummy3 = BoolOption('dummy1', 'doc dummy')
+#    assert dummy1 != dummy2
+#    assert dummy1 == dummy3
 
 
-def test_option_comparison_obj():
-    "compare :class:`tiramisu.option.IntOption`"
-    dummy1 = BoolOption('dummy1', 'doc dummy')
-    dummy2 = IntOption('dummy1', 'doc dummy')
-    assert dummy1 != dummy2
+#def test_option_comparison_obj():
+#    "compare :class:`tiramisu.option.IntOption`"
+#    dummy1 = BoolOption('dummy1', 'doc dummy')
+#    dummy2 = IntOption('dummy1', 'doc dummy')
+#    assert dummy1 != dummy2
 
 
-def test_option_comparison_advanced():
-    dummy1 = BoolOption('dummy1', 'doc dummy')
-    dummy2 = BoolOption('dummy1', 'doc dummy')
-    dummy3 = BoolOption('dummy1', 'doc dummy', None)
-    dummy4 = BoolOption('dummy1', 'doc dummy', True)
-    dummy5 = BoolOption('dummy1', 'doc dummy', multi=True)
-    dummy6 = BoolOption('dummy1', 'doc dummy', properties=tuple())
-    dummy7 = BoolOption('dummy1', 'doc dummy', properties=tuple('new',))
-    assert dummy1 == dummy2
-    assert dummy1 == dummy3
-    assert dummy1 != dummy4
-    assert dummy1 != dummy5
-    assert dummy1 == dummy6
-    assert dummy1 != dummy7
+#def test_option_comparison_advanced():
+#    dummy1 = BoolOption('dummy1', 'doc dummy')
+#    dummy2 = BoolOption('dummy1', 'doc dummy')
+#    dummy3 = BoolOption('dummy1', 'doc dummy', None)
+#    dummy4 = BoolOption('dummy1', 'doc dummy', True)
+#    dummy5 = BoolOption('dummy1', 'doc dummy', multi=True)
+#    dummy6 = BoolOption('dummy1', 'doc dummy', properties=tuple())
+#    dummy7 = BoolOption('dummy1', 'doc dummy', properties=tuple('new',))
+#    assert dummy1 == dummy2
+#    assert dummy1 == dummy3
+#    assert dummy1 != dummy4
+#    assert dummy1 != dummy5
+#    assert dummy1 == dummy6
+#    assert dummy1 != dummy7
index 071563f..6f1970a 100644 (file)
@@ -71,7 +71,7 @@ def test_group_is_hidden():
     prop = []
     try:
         config.gc.dummy = False
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'hidden' in prop
 
@@ -89,7 +89,7 @@ def test_group_is_hidden_multi():
     prop = []
     try:
         objspace.append('std')
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         prop = err.proptype
     assert 'hidden' in prop
     setting[obj].remove('hidden')
index 7365531..88507ef 100644 (file)
@@ -20,14 +20,14 @@ def test_permissive():
     props = []
     try:
         config.u1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     setting.setpermissive(('disabled',))
     props = []
     try:
         config.u1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     setting.append('permissive')
@@ -36,7 +36,7 @@ def test_permissive():
     props = []
     try:
         config.u1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -49,18 +49,18 @@ def test_permissive_mandatory():
     props = []
     try:
         config.u1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
-    assert props == ['disabled', 'mandatory']
+    assert set(props) == set(['disabled', 'mandatory'])
     setting.setpermissive(('mandatory', 'disabled',))
     setting.append('permissive')
     config.u1
     setting.remove('permissive')
     try:
         config.u1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
-    assert props == ['disabled', 'mandatory']
+    assert set(props) == set(['disabled', 'mandatory'])
 
 
 def test_permissive_frozen():
@@ -71,7 +71,7 @@ def test_permissive_frozen():
     setting.setpermissive(('frozen', 'disabled',))
     try:
         config.u1 = 1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['frozen', 'disabled']
     setting.append('permissive')
@@ -80,7 +80,7 @@ def test_permissive_frozen():
     setting.remove('permissive')
     try:
         config.u1 = 1
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['frozen', 'disabled']
 
index 804c767..0f9af61 100644 (file)
@@ -21,7 +21,7 @@ def test_requires():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -47,14 +47,14 @@ def test_requires_same_action():
     props = []
     try:
         c.activate_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['new']
     #
     props = []
     try:
         c.ip_address_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -72,7 +72,7 @@ def test_multiple_requires():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -80,7 +80,7 @@ def test_multiple_requires():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -99,7 +99,7 @@ def test_multiple_requires_inverse():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -113,7 +113,7 @@ def test_multiple_requires_inverse():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -136,14 +136,14 @@ def test_requires_transitive():
     props = []
     try:
         c.activate_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     #
     props = []
     try:
         c.ip_address_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -167,14 +167,14 @@ def test_requires_transitive_bis():
     props = []
     try:
         c.activate_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     #
     props = []
     try:
         c.ip_address_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -196,7 +196,7 @@ def test_requires_transitive_hidden_disabled():
     props = []
     try:
         c.activate_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['hidden']
     raises(RequirementError, 'c.ip_address_service_web')
@@ -220,7 +220,7 @@ def test_requires_not_transitive():
     props = []
     try:
         c.activate_service_web
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     #
@@ -237,7 +237,7 @@ def test_requires_None():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     c.activate_service = False
@@ -260,7 +260,7 @@ def test_requires_multi_disabled():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -271,7 +271,7 @@ def test_requires_multi_disabled():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -279,7 +279,7 @@ def test_requires_multi_disabled():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -299,7 +299,7 @@ def test_requires_multi_disabled_inverse():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -307,7 +307,7 @@ def test_requires_multi_disabled_inverse():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -315,7 +315,7 @@ def test_requires_multi_disabled_inverse():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -323,7 +323,7 @@ def test_requires_multi_disabled_inverse():
     props = []
     try:
         c.ip_address_service
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -362,7 +362,7 @@ def test_requires_multi_disabled_2():
         props = []
         try:
             cfg.z
-        except PropertiesOptionError, err:
+        except PropertiesOptionError as err:
             props = err.proptype
         assert props == ['disabled']
     for boo in list_bools:
@@ -373,7 +373,7 @@ def test_requires_multi_disabled_2():
             props = []
             try:
                 cfg.z
-            except PropertiesOptionError, err:
+            except PropertiesOptionError as err:
                 props = err.proptype
             assert props == ['disabled']
 
@@ -407,7 +407,7 @@ def test_requires_multi_disabled_inverse_2():
     props = []
     try:
         cfg.z
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     for boo in list_bools:
@@ -418,7 +418,7 @@ def test_requires_multi_disabled_inverse_2():
             props = []
             try:
                 cfg.z
-            except PropertiesOptionError, err:
+            except PropertiesOptionError as err:
                 props = err.proptype
             assert props == ['disabled']
     for boo in list_bools:
@@ -426,7 +426,7 @@ def test_requires_multi_disabled_inverse_2():
         props = []
         try:
             cfg.z
-        except PropertiesOptionError, err:
+        except PropertiesOptionError as err:
             props = err.proptype
         assert props == ['disabled']
 
index fcbcc03..3283f6d 100644 (file)
@@ -46,14 +46,14 @@ def test_symlink_requires():
     props = []
     try:
         config.s
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
     #
     props = []
     try:
         config.c
-    except PropertiesOptionError, err:
+    except PropertiesOptionError as err:
         props = err.proptype
     assert props == ['disabled']
 
@@ -113,7 +113,7 @@ def test_symlink_master():
 
 def test_symlink_slaves():
     a = StrOption('a', "", multi=True)
-    ip_admin_eth0 = StrOption('ip_admin_eth0', u"ip réseau autorisé", multi=True)
+    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
     netmask_admin_eth0 = SymLinkOption('netmask_admin_eth0', a)
     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
     raises(ValueError, 'interface1.impl_set_group_type(groups.master)')
index 6c0080b..2cf41ca 100644 (file)
@@ -59,7 +59,7 @@ def carry_out_calculation(name,
                 try:
                     opt_value = config._getattr(path, force_permissive=True)
                     opt = config.unwrap_from_path(path, force_permissive=True)
-                except PropertiesOptionError, err:
+                except PropertiesOptionError as err:
                     if check_disabled:
                         continue
                     raise ConfigError(_('unable to carry out a calculation, '
index a0c3982..ae68e98 100644 (file)
@@ -646,7 +646,7 @@ def mandatory_warnings(config):
             include_groups=True):
         try:
             config._getattr(path, force_properties=frozenset(('mandatory',)))
-        except PropertiesOptionError, err:
+        except PropertiesOptionError as err:
             if err.proptype == ['mandatory']:
                 yield path
     config.cfgimpl_reset_cache(only=('values',))
index 3a29159..6c92be3 100644 (file)
@@ -32,28 +32,28 @@ class PropertiesOptionError(AttributeError):
 
 #____________________________________________________________
 # Exceptions for a Config
-class ConfigError(StandardError):
+class ConfigError(Exception):
     """attempt to change an option's owner without a value
     or in case of `_cfgimpl_descr` is None
     or if a calculation cannot be carried out"""
     pass
 
 
-class ConflictError(StandardError):
+class ConflictError(Exception):
     "duplicate options are present in a single config"
     pass
 
 
 #____________________________________________________________
 # miscellaneous exceptions
-class RequirementError(StandardError):
+class RequirementError(Exception):
     """a recursive loop occurs in the requirements tree
     requires
     """
     pass
 
 
-class SlaveError(StandardError):
+class SlaveError(Exception):
     "problem with a slave's value length"
     pass
 
index 4f8bc26..a1fd01a 100644 (file)
@@ -25,7 +25,11 @@ if lc:
 languages += DEFAULT_LANG
 mo_location = LOCALE_DIR
 
-gettext.install(True, localedir=None, unicode=1)
+
+if sys.version_info[0] >= 3:
+    gettext.install(True, localedir=None)
+else:
+    gettext.install(True, localedir=None, unicode=1)
 gettext.find(APP_NAME, mo_location)
 gettext.textdomain(APP_NAME)
 gettext.bind_textdomain_codeset(APP_NAME, "UTF-8")
index 724c691..031fb50 100644 (file)
@@ -21,6 +21,7 @@
 # the whole pypy projet is under MIT licence
 # ____________________________________________________________
 import re
+import sys
 from copy import copy, deepcopy
 from types import FunctionType
 from IPy import IP
@@ -98,7 +99,7 @@ class Option(BaseInformation):
     """
     __slots__ = ('_name', '_requires', '_multi', '_validator',
                  '_default_multi', '_default', '_properties', '_callback',
-                 '_multitype', '_master_slaves', '_consistencies', '_empty',
+                 '_multitype', '_master_slaves', '_consistencies',
                  '_calc_properties', '__weakref__')
     _empty = ''
 
@@ -147,7 +148,7 @@ class Option(BaseInformation):
         if default_multi is not None:
             try:
                 self._validate(default_multi)
-            except ValueError, err:
+            except ValueError as err:
                 raise ValueError(_("invalid default_multi value {0} "
                                    "for option {1}: {2}").format(
                                        str(default_multi), name, err))
@@ -184,36 +185,6 @@ class Option(BaseInformation):
                                 self._name))
         self._properties = properties  # 'hidden', 'disabled'...
 
-    def __eq__(self, other):
-        "Option comparison"
-        if not isinstance(other, Option):
-            return False
-        slots = list(self.__slots__ +
-                     Option.__slots__ +
-                     BaseInformation.__slots__)
-        for var in slots:
-            try:
-                val1 = getattr(self, var)
-                not_in1 = False
-            except:
-                not_in1 = True
-            try:
-                val2 = getattr(other, var)
-                not_in2 = False
-            except:
-                not_in2 = True
-            if True in (not_in1, not_in2):
-                if not_in1 != not_in2:
-                    return False
-            elif val1 != val2:
-                return False
-        return True
-
-    def __ne__(self, other):
-        if not isinstance(other, Option):
-            return False
-        return not self == other
-
     def _launch_consistency(self, func, opt, vals, context, index, opt_):
         if context is not None:
             descr = context.cfgimpl_get_description()
@@ -288,7 +259,7 @@ class Option(BaseInformation):
                                             self.__class__.__name__))
             try:
                 self._validate(_value)
-            except ValueError, err:
+            except ValueError as err:
                 raise ValueError(_("invalid value {0} for option {1}: {2}"
                                    "").format(_value, self._name, err))
             if context is not None:
@@ -381,7 +352,7 @@ class ChoiceOption(Option):
     The option can also have the value ``None``
     """
 
-    __slots__ = ('_values', '_open_values', '_opt_type')
+    __slots__ = ('_values', '_open_values')
     _opt_type = 'string'
 
     def __init__(self, name, doc, values, default=None, default_multi=None,
@@ -423,7 +394,7 @@ class ChoiceOption(Option):
 
 class BoolOption(Option):
     "represents a choice between ``True`` and ``False``"
-    __slots__ = ('_opt_type',)
+    __slots__ = tuple()
     _opt_type = 'bool'
 
     def _validate(self, value):
@@ -433,7 +404,7 @@ class BoolOption(Option):
 
 class IntOption(Option):
     "represents a choice of an integer"
-    __slots__ = ('_opt_type',)
+    __slots__ = tuple()
     _opt_type = 'int'
 
     def _validate(self, value):
@@ -443,7 +414,7 @@ class IntOption(Option):
 
 class FloatOption(Option):
     "represents a choice of a floating point number"
-    __slots__ = ('_opt_type',)
+    __slots__ = tuple()
     _opt_type = 'float'
 
     def _validate(self, value):
@@ -453,7 +424,7 @@ class FloatOption(Option):
 
 class StrOption(Option):
     "represents the choice of a string"
-    __slots__ = ('_opt_type',)
+    __slots__ = tuple()
     _opt_type = 'string'
 
     def _validate(self, value):
@@ -462,19 +433,25 @@ class StrOption(Option):
                                '{0}').format(type(value)))
 
 
-class UnicodeOption(Option):
-    "represents the choice of a unicode string"
-    __slots__ = ('_opt_type',)
-    _opt_type = 'unicode'
-    _empty = u''
+if sys.version_info[0] >= 3:
+    #UnicodeOption is same has StrOption in python 3+
+    class UnicodeOption(StrOption):
+        __slots__ = tuple()
+        pass
+else:
+    class UnicodeOption(Option):
+        "represents the choice of a unicode string"
+        __slots__ = tuple()
+        _opt_type = 'unicode'
+        _empty = u''
 
-    def _validate(self, value):
-        if not isinstance(value, unicode):
-            raise ValueError(_('value must be an unicode'))
+        def _validate(self, value):
+            if not isinstance(value, unicode):
+                raise ValueError(_('value must be an unicode'))
 
 
 class SymLinkOption(object):
-    __slots__ = ('_name', '_opt', '_consistencies')
+    __slots__ = ('_name', '_opt')
     _opt_type = 'symlink'
     _consistencies = None
 
@@ -495,7 +472,7 @@ class SymLinkOption(object):
 
 class IPOption(Option):
     "represents the choice of an ip"
-    __slots__ = ('_opt_type', '_only_private')
+    __slots__ = ('_only_private',)
     _opt_type = 'ip'
 
     def __init__(self, name, doc, default=None, default_multi=None,
@@ -531,8 +508,7 @@ class PortOption(Option):
     Port number 0 is reserved and can't be used.
     see: http://en.wikipedia.org/wiki/Port_numbers
     """
-    __slots__ = ('_opt_type', '_allow_range', '_allow_zero', '_min_value',
-                 '_max_value')
+    __slots__ = ('_allow_range', '_allow_zero', '_min_value', '_max_value')
     _opt_type = 'port'
 
     def __init__(self, name, doc, default=None, default_multi=None,
@@ -593,7 +569,7 @@ class PortOption(Option):
 
 class NetworkOption(Option):
     "represents the choice of a network"
-    __slots__ = ('_opt_type',)
+    __slots__ = tuple()
     _opt_type = 'network'
 
     def _validate(self, value):
@@ -604,7 +580,7 @@ class NetworkOption(Option):
 
 class NetmaskOption(Option):
     "represents the choice of a netmask"
-    __slots__ = ('_opt_type',)
+    __slots__ = tuple()
     _opt_type = 'netmask'
 
     def _validate(self, value):
@@ -651,7 +627,7 @@ class NetmaskOption(Option):
 
 class DomainnameOption(Option):
     "represents the choice of a domain name"
-    __slots__ = ('_opt_type', '_type', '_allow_ip')
+    __slots__ = ('_type', '_allow_ip')
     _opt_type = 'domainname'
 
     def __init__(self, name, doc, default=None, default_multi=None,
@@ -733,7 +709,7 @@ class OptionDescription(BaseInformation):
         valid_child.sort()
         old = None
         for child in valid_child:
-            if id(child) == id(old):
+            if child == old:
                 raise ConflictError(_('duplicate option name: '
                                       '{0}').format(child))
             old = child
@@ -807,6 +783,9 @@ class OptionDescription(BaseInformation):
             attr = option._name
             if attr.startswith('_cfgimpl'):
                 continue
+            if option in cache_option:
+                raise ConflictError(_('duplicate option: {0}').format(option))
+
             cache_option.append(option)
             cache_path.append(str('.'.join(_currpath + [attr])))
             if not isinstance(option, OptionDescription):
@@ -826,15 +805,6 @@ class OptionDescription(BaseInformation):
                                         _consistencies)
                 _currpath.pop()
         if save:
-            #valid no duplicated option
-            valid_child = copy(cache_option)
-            valid_child.sort()
-            old = None
-            for child in valid_child:
-                if id(child) == id(old):
-                    raise ConflictError(_('duplicate option: '
-                                          '{0}').format(child))
-                old = child
             self._cache_paths = (tuple(cache_option), tuple(cache_path))
             self._consistencies = _consistencies
 
@@ -971,7 +941,6 @@ def validate_requires_arg(requires, name):
                                ' same_action must be boolean'))
 
         if not isinstance(option, Option):
-            print option, type(option)
             raise ValueError(_('malformed requirements '
                                'must be an option in option {0}').format(name))
         if option.impl_is_multi():
@@ -980,7 +949,7 @@ def validate_requires_arg(requires, name):
         if expected is not None:
             try:
                 option._validate(expected)
-            except ValueError, err:
+            except ValueError as err:
                 raise ValueError(_('malformed requirements second argument '
                                    'must be valid for option {0}'
                                    ': {1}').format(name, err))
index 86f900e..d6ee8ac 100644 (file)
@@ -206,7 +206,7 @@ class Property(object):
 def set_storage(name, **args):
     storage_type.set_storage(name)
     settings = __import__(storage_type.get_storage(), globals(), locals(),
-                          ['Setting'], -1).Setting()
+                          ['Setting']).Setting()
     for option, value in args.items():
         try:
             getattr(settings, option)
@@ -223,17 +223,17 @@ def get_storage(context, session_id, persistent):
     if session_id is None:
         session_id = gen_id(context)
     return __import__(storage_type.get_storage(), globals(), locals(),
-                      ['Storage'], -1).Storage(session_id, persistent)
+                      ['Storage']).Storage(session_id, persistent)
 
 
 def list_sessions():
     return __import__(storage_type.get_storage(), globals(), locals(),
-                      ['list_sessions'], -1).list_sessions()
+                      ['list_sessions']).list_sessions()
 
 
 def delete_session(session_id):
     return __import__(storage_type.get_storage(), globals(), locals(),
-                      ['delete_session'], -1).delete_session(session_id)
+                      ['delete_session']).delete_session(session_id)
 
 
 #____________________________________________________________
@@ -255,8 +255,8 @@ class Settings(object):
         self._owner = owners.user
         self.context = weakref.ref(context)
         import_lib = 'tiramisu.storage.{0}.setting'.format(storage.storage)
-        self._p_ = __import__(import_lib, globals(), locals(), ['Settings'],
-                              -1).Settings(storage)
+        self._p_ = __import__(import_lib, globals(), locals(), ['Settings']
+                              ).Settings(storage)
 
     #____________________________________________________________
     # properties methods
@@ -496,7 +496,7 @@ class Settings(object):
                 try:
                     value = self.context()._getattr(reqpath,
                                                     force_permissive=True)
-                except PropertiesOptionError, err:
+                except PropertiesOptionError as err:
                     if not transitive:
                         continue
                     properties = err.proptype
index 4006a02..d4904c6 100644 (file)
@@ -17,8 +17,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 # ____________________________________________________________
-
-
 from tiramisu.i18n import _
 from tiramisu.error import ConfigError
 
@@ -84,8 +82,7 @@ class Cache(object):
         return path in self._cache
 
     def reset_expired_cache(self, cache_type, exp):
-        keys = self._cache.keys()
-        for key in keys:
+        for key in tuple(self._cache.keys()):
             val, created = self._cache[key]
             if exp > created:
                 del(self._cache[key])
index 1d1babc..6bbce3c 100644 (file)
@@ -19,6 +19,7 @@
 # ____________________________________________________________
 from time import time
 from copy import copy
+import sys
 import weakref
 from tiramisu.error import ConfigError, SlaveError
 from tiramisu.setting import owners, multitypes, expires_time
@@ -45,7 +46,7 @@ class Values(object):
         # the storage type is dictionary or sqlite3
         import_lib = 'tiramisu.storage.{0}.value'.format(storage.storage)
         self._p_ = __import__(import_lib, globals(), locals(), ['Values'],
-                              -1).Values(storage)
+                              ).Values(storage)
 
     def _getdefault(self, opt):
         """
@@ -427,7 +428,12 @@ class Multi(list):
                                              multitypes.master]:
             raise SlaveError(_("cannot sort multi option {0} if master or slave"
                                "").format(self.opt._name))
-        super(Multi, self).sort(cmp=cmp, key=key, reverse=reverse)
+        if sys.version_info[0] >= 3:
+            if cmp is not None:
+                raise ValueError(_('cmp is not permitted in python v3 or greater'))
+            super(Multi, self).sort(key=key, reverse=reverse)
+        else:
+            super(Multi, self).sort(cmp=cmp, key=key, reverse=reverse)
         self.context().cfgimpl_get_values()._setvalue(self.opt, self.path, self)
 
     def reverse(self):
@@ -458,7 +464,7 @@ class Multi(list):
         if value is not None:
             try:
                 self.opt._validate(value)
-            except ValueError, err:
+            except ValueError as err:
                 raise ValueError(_("invalid value {0} "
                                    "for option {1}: {2}"
                                    "").format(str(value),