Export extractExTags and updateExclTags
[ganeti-local] / lib / compat.py
index ca656ed..5f1409e 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
 #
 #
 
-# Copyright (C) 2010 Google Inc.
+# Copyright (C) 2010, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 """
 
 import itertools
 """
 
 import itertools
+import operator
 
 try:
 
 try:
+  # pylint: disable=F0401
   import functools
 except ImportError:
   functools = None
 
 try:
   import functools
 except ImportError:
   functools = None
 
 try:
+  # pylint: disable=F0401
   import roman
 except ImportError:
   roman = None
   import roman
 except ImportError:
   roman = None
@@ -42,10 +45,10 @@ except ImportError:
 # modules (hmac, for example) which have changed their behavior as well from
 # one version to the other.
 try:
 # modules (hmac, for example) which have changed their behavior as well from
 # one version to the other.
 try:
+  # Yes, these don't always exist, that's why we're testing
   # Yes, we're not using the imports in this module.
   # Yes, we're not using the imports in this module.
-  # pylint: disable-msg=W0611
-  from hashlib import md5 as md5_hash
-  from hashlib import sha1 as sha1_hash
+  from hashlib import md5 as md5_hash # pylint: disable=W0611,E0611,F0401
+  from hashlib import sha1 as sha1_hash # pylint: disable=W0611,E0611,F0401
   # this additional version is needed for compatibility with the hmac module
   sha1 = sha1_hash
 except ImportError:
   # this additional version is needed for compatibility with the hmac module
   sha1 = sha1_hash
 except ImportError:
@@ -63,6 +66,7 @@ def _all(seq):
     return False
   return True
 
     return False
   return True
 
+
 def _any(seq):
   """Returns True if any element of the iterable are True.
 
 def _any(seq):
   """Returns True if any element of the iterable are True.
 
@@ -71,17 +75,23 @@ def _any(seq):
     return True
   return False
 
     return True
   return False
 
+
 try:
 try:
-  all = all # pylint: disable-msg=W0622
+  # pylint: disable=E0601
+  # pylint: disable=W0622
+  all = all
 except NameError:
   all = _all
 
 try:
 except NameError:
   all = _all
 
 try:
-  any = any # pylint: disable-msg=W0622
+  # pylint: disable=E0601
+  # pylint: disable=W0622
+  any = any
 except NameError:
   any = _any
 
 except NameError:
   any = _any
 
-def partition(seq, pred=bool): # pylint: disable-msg=W0622
+
+def partition(seq, pred=bool): # pylint: disable=W0622
   """Partition a list in two, based on the given predicate.
 
   """
   """Partition a list in two, based on the given predicate.
 
   """
@@ -91,7 +101,7 @@ def partition(seq, pred=bool): # pylint: disable-msg=W0622
 
 # Even though we're using Python's built-in "partial" function if available,
 # this one is always defined for testing.
 
 # Even though we're using Python's built-in "partial" function if available,
 # this one is always defined for testing.
-def _partial(func, *args, **keywords): # pylint: disable-msg=W0622
+def _partial(func, *args, **keywords): # pylint: disable=W0622
   """Decorator with partial application of arguments and keywords.
 
   This function was copied from Python's documentation.
   """Decorator with partial application of arguments and keywords.
 
   This function was copied from Python's documentation.
@@ -100,7 +110,7 @@ def _partial(func, *args, **keywords): # pylint: disable-msg=W0622
   def newfunc(*fargs, **fkeywords):
     newkeywords = keywords.copy()
     newkeywords.update(fkeywords)
   def newfunc(*fargs, **fkeywords):
     newkeywords = keywords.copy()
     newkeywords.update(fkeywords)
-    return func(*(args + fargs), **newkeywords) # pylint: disable-msg=W0142
+    return func(*(args + fargs), **newkeywords) # pylint: disable=W0142
 
   newfunc.func = func
   newfunc.args = args
 
   newfunc.func = func
   newfunc.args = args
@@ -136,3 +146,28 @@ def TryToRoman(val, convert=True):
   else:
     return val
 
   else:
     return val
 
+
+def UniqueFrozenset(seq):
+  """Makes C{frozenset} from sequence after checking for duplicate elements.
+
+  @raise ValueError: When there are duplicate elements
+
+  """
+  if isinstance(seq, (list, tuple)):
+    items = seq
+  else:
+    items = list(seq)
+
+  result = frozenset(items)
+
+  if len(items) != len(result):
+    raise ValueError("Duplicate values found")
+
+  return result
+
+
+#: returns the first element of a list-like value
+fst = operator.itemgetter(0)
+
+#: returns the second element of a list-like value
+snd = operator.itemgetter(1)