Hello community,

here is the log from the commit of package python-configobj for 
openSUSE:Factory checked in at 2014-07-24 06:58:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-configobj (Old)
 and      /work/SRC/openSUSE:Factory/.python-configobj.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-configobj"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-configobj/python-configobj.changes        
2012-05-31 17:09:21.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-configobj.new/python-configobj.changes   
2014-07-24 06:58:53.000000000 +0200
@@ -1,0 +2,21 @@
+Wed Jul 23 13:04:31 UTC 2014 - fcaste...@suse.com
+
+- Update to version 5.0.5:
+  * BUGFIX: error in writing out config files to disk with non-ascii
+    characters
+  * BUGFIX: correcting that the code path fixed in 5.0.3 didn’t cover
+    reading in config files
+  * BUGFIX: not handling unicode encoding well, especially with respect to
+    writing out files
+  * Specific error message for installing version this version on Python
+    versions older than 2.5
+  * Documentation corrections
+  * BUGFIX: Fixed regression on python 2.x where passing an encoding parameter
+    did not convert a bytestring config file (which is the most common) to
+    unicode. Added unit tests for this and related cases
+  * BUGFIX: A particular error message would fail to display with a type error
+    on python 2.6 only
+  * Python 3 single-source compatibility at the cost of a more restrictive set
+    of versions: 2.6, 2.7, 3.2, 3.3 (otherwise unchanged)
+
+-------------------------------------------------------------------

Old:
----
  configobj-4.7.2.tar.gz

New:
----
  configobj-5.0.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-configobj.spec ++++++
--- /var/tmp/diff_new_pack.dAqhm0/_old  2014-07-24 06:58:54.000000000 +0200
+++ /var/tmp/diff_new_pack.dAqhm0/_new  2014-07-24 06:58:54.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-configobj
 #
-# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -15,12 +15,12 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
 
+
 %define modname configobj
 Name:           python-%{modname}
-Version:        4.7.2
+Version:        5.0.5
 Release:        0
-# FIXME: Change python-cofigobj-docs Obsoletes to < with next version update. 
Obsoletes introduced with version 4.7.2.
-Url:            http://www.voidspace.org.uk/python/configobj.html
+Url:            https://github.com/DiffSK/configobj
 Summary:        Config file reading, writing and validation
 License:        BSD-3-Clause
 Group:          Development/Languages/Python
@@ -29,7 +29,7 @@
 BuildRequires:  python-devel
 # There are no real docs!
 Provides:       python-%{modname}-docs = %{version}
-Obsoletes:      python-%{modname}-docs <= %{version}
+Obsoletes:      python-%{modname}-docs < %{version}
 %if 0%{?suse_version} <= 1110
 %{!?python_sitelib: %global python_sitelib %(python -c "from 
distutils.sysconfig import get_python_lib; print(get_python_lib())")}
 %else
@@ -69,6 +69,7 @@
 %defattr(-,root,root,-)
 %{python_sitelib}/%{modname}.py*
 %{python_sitelib}/validate.py*
+%{python_sitelib}/_version.py*
 %{python_sitelib}/%{modname}-%{version}-py%{py_ver}.egg-info
 
 %changelog

++++++ configobj-4.7.2.tar.gz -> configobj-5.0.5.tar.gz ++++++
Files old/configobj-4.7.2/._configobj.py and new/configobj-5.0.5/._configobj.py 
differ
Files old/configobj-4.7.2/._setup.py and new/configobj-5.0.5/._setup.py differ
Files old/configobj-4.7.2/._validate.py and new/configobj-5.0.5/._validate.py 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/configobj-4.7.2/PKG-INFO new/configobj-5.0.5/PKG-INFO
--- old/configobj-4.7.2/PKG-INFO        2010-03-02 00:18:57.000000000 +0100
+++ new/configobj-5.0.5/PKG-INFO        2014-04-28 13:18:13.000000000 +0200
@@ -1,12 +1,11 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
 Name: configobj
-Version: 4.7.2
+Version: 5.0.5
 Summary: Config file reading, writing and validation.
-Home-page: http://www.voidspace.org.uk/python/configobj.html
-Author: Michael Foord & Nicola Larosa
-Author-email: fuzzy...@voidspace.org.uk
+Home-page: https://github.com/DiffSK/configobj
+Author: Rob Dennis, Eli Courtwright (Michael Foord & Nicola Larosa original 
maintainers)
+Author-email: rdennis+config...@gmail.com, e...@courtwright.org, 
fuzzy...@voidspace.co.uk, n...@teknico.net
 License: UNKNOWN
-Download-URL: http://www.voidspace.org.uk/downloads/configobj-4.7.2.zip
 Description: **ConfigObj** is a simple but powerful config file reader and 
writer: an *ini
         file round tripper*. Its main feature is that it is very easy to use, 
with a
         straightforward programmer's interface and a simple syntax for config 
files.
@@ -19,14 +18,25 @@
         * String interpolation (substitution)
         * Integrated with a powerful validation system
         
-        - including automatic type checking/conversion
-        - and allowing default values
-        - repeated sections
+            - including automatic type checking/conversion
+            - and allowing default values
+            - repeated sections
         
         * All comments in the file are preserved
         * The order of keys/sections is preserved
         * Powerful ``unrepr`` mode for storing/retrieving Python data-types
         
+        | Release 5.0.5 corrects a unicode-bug that still existed in writing 
files
+        | Release 5.0.4 corrects a unicode-bug that still existed in reading 
files after
+        | fixing lists of string in 5.0.3
+        | Release 5.0.3 corrects errors related to the incorrectly handling 
unicode
+        | encoding and writing out files
+        | Release 5.0.2 adds a specific error message when trying to install on
+        | Python versions older than 2.5
+        | Release 5.0.1 fixes a regression with unicode conversion not 
happening
+        | in certain cases PY2
+        | Release 5.0.0 updates the supported Python versions to 2.6, 2.7, 
3.2, 3.3
+        | and is otherwise unchanged
         | Release 4.7.2 fixes several bugs in 4.7.1
         | Release 4.7.1 fixes a bug with the deprecated options keyword in
         | 4.7.0.
@@ -38,10 +48,12 @@
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.3
-Classifier: Programming Language :: Python :: 2.4
-Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
 Classifier: Operating System :: OS Independent
 Classifier: Topic :: Software Development :: Libraries
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/configobj-4.7.2/_version.py 
new/configobj-5.0.5/_version.py
--- old/configobj-4.7.2/_version.py     1970-01-01 01:00:00.000000000 +0100
+++ new/configobj-5.0.5/_version.py     2014-04-26 19:06:01.000000000 +0200
@@ -0,0 +1 @@
+__version__ = '5.0.5'
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/configobj-4.7.2/configobj.py 
new/configobj-5.0.5/configobj.py
--- old/configobj-4.7.2/configobj.py    2010-02-27 22:36:16.000000000 +0100
+++ new/configobj-5.0.5/configobj.py    2014-04-26 19:06:01.000000000 +0200
@@ -1,22 +1,17 @@
 # configobj.py
 # A config file reader/writer that supports nested sections in config files.
-# Copyright (C) 2005-2010 Michael Foord, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         nico AT tekNico DOT net
-
-# ConfigObj 4
-# http://www.voidspace.org.uk/python/configobj.html
-
-# Released subject to the BSD License
-# Please see http://www.voidspace.org.uk/python/license.shtml
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# For information about bugfixes, updates and support, please join the
-# ConfigObj mailing list:
-# http://lists.sourceforge.net/lists/listinfo/configobj-develop
-# Comments, suggestions and bug reports welcome.
+# Copyright (C) 2005-2014:
+# (name) : (email)
+# Michael Foord: fuzzyman AT voidspace DOT org DOT uk
+# Nicola Larosa: nico AT tekNico DOT net
+# Rob Dennis: rdennis AT gmail DOT com
+# Eli Courtwright: eli AT courtwright DOT org
 
-from __future__ import generators
+# This software is licensed under the terms of the BSD license.
+# http://opensource.org/licenses/BSD-3-Clause
+
+# ConfigObj 5 - main repository for documentation and issue tracking:
+# https://github.com/DiffSK/configobj
 
 import os
 import re
@@ -24,6 +19,8 @@
 
 from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
 
+import six
+from _version import __version__
 
 # imported lazily to avoid startup performance hit if it isn't used
 compiler = None
@@ -83,20 +80,7 @@
 # Sentinel for use in getattr calls to replace hasattr
 MISSING = object()
 
-__version__ = '4.7.2'
-
-try:
-    any
-except NameError:
-    def any(iterable):
-        for entry in iterable:
-            if entry:
-                return True
-        return False
-
-
 __all__ = (
-    '__version__',
     'DEFAULT_INDENT_TYPE',
     'DEFAULT_INTERPOLATION',
     'ConfigObjError',
@@ -137,6 +121,8 @@
     'write_empty_values': False,
 }
 
+# this could be replaced if six is used for compatibility, or there are no
+# more assertions about items being a string
 
 
 def getObj(s):
@@ -155,13 +141,12 @@
 class Builder(object):
     
     def build(self, o):
-        m = getattr(self, 'build_' + o.__class__.__name__, None)
         if m is None:
             raise UnknownType(o.__class__.__name__)
         return m(o)
     
     def build_List(self, o):
-        return map(self.build, o.getChildren())
+        return list(map(self.build, o.getChildren()))
     
     def build_Const(self, o):
         return o.value
@@ -170,7 +155,7 @@
         d = {}
         i = iter(map(self.build, o.getChildren()))
         for el in i:
-            d[el] = i.next()
+            d[el] = next(i)
         return d
     
     def build_Tuple(self, o):
@@ -188,7 +173,7 @@
         raise UnknownType('Undefined Name')
     
     def build_Add(self, o):
-        real, imag = map(self.build_Const, o.getChildren())
+        real, imag = list(map(self.build_Const, o.getChildren()))
         try:
             real = float(real)
         except TypeError:
@@ -214,8 +199,10 @@
 def unrepr(s):
     if not s:
         return s
-    return _builder.build(getObj(s))
-
+    
+    # this is supposed to be safe
+    import ast
+    return ast.literal_eval(s)
 
 
 class ConfigObjError(SyntaxError):
@@ -518,7 +505,7 @@
         self._initialise()
         # we do this explicitly so that __setitem__ is used properly
         # (rather than just passing to ``dict.__init__``)
-        for entry, value in indict.iteritems():
+        for entry, value in indict.items():
             self[entry] = value
             
             
@@ -566,11 +553,11 @@
         """Fetch the item and do string interpolation."""
         val = dict.__getitem__(self, key)
         if self.main.interpolation: 
-            if isinstance(val, basestring):
+            if isinstance(val, six.string_types):
                 return self._interpolate(key, val)
             if isinstance(val, list):
                 def _check(entry):
-                    if isinstance(entry, basestring):
+                    if isinstance(entry, six.string_types):
                         return self._interpolate(key, entry)
                     return entry
                 new = [_check(entry) for entry in val]
@@ -593,7 +580,7 @@
         ``unrepr`` must be set when setting a value to a dictionary, without
         creating a new sub-section.
         """
-        if not isinstance(key, basestring):
+        if not isinstance(key, six.string_types):
             raise ValueError('The key "%s" is not a string.' % key)
         
         # add the comment
@@ -627,11 +614,11 @@
             if key not in self:
                 self.scalars.append(key)
             if not self.main.stringify:
-                if isinstance(value, basestring):
+                if isinstance(value, six.string_types):
                     pass
                 elif isinstance(value, (list, tuple)):
                     for entry in value:
-                        if not isinstance(entry, basestring):
+                        if not isinstance(entry, six.string_types):
                             raise TypeError('Value is not a string "%s".' % 
entry)
                 else:
                     raise TypeError('Value is not a string "%s".' % value)
@@ -721,7 +708,7 @@
 
     def items(self):
         """D.items() -> list of D's (key, value) pairs, as 2-tuples"""
-        return zip((self.scalars + self.sections), self.values())
+        return list(zip((self.scalars + self.sections), list(self.values())))
 
 
     def keys(self):
@@ -736,7 +723,7 @@
 
     def iteritems(self):
         """D.iteritems() -> an iterator over the (key, value) items of D"""
-        return iter(self.items())
+        return iter(list(self.items()))
 
 
     def iterkeys(self):
@@ -748,7 +735,7 @@
 
     def itervalues(self):
         """D.itervalues() -> an iterator over the values of D"""
-        return iter(self.values())
+        return iter(list(self.values()))
 
 
     def __repr__(self):
@@ -814,7 +801,7 @@
         >>> c2
         ConfigObj({'section1': {'option1': 'False', 'subsection': 
{'more_options': 'False'}}})
         """
-        for key, val in indict.items():
+        for key, val in list(indict.items()):
             if (key in self and isinstance(self[key], dict) and
                                 isinstance(val, dict)):
                 self[key].merge(val)
@@ -972,7 +959,7 @@
             return False
         else:
             try:
-                if not isinstance(val, basestring):
+                if not isinstance(val, six.string_types):
                     # TODO: Why do we raise a KeyError here?
                     raise KeyError()
                 else:
@@ -1013,15 +1000,15 @@
         
         >>> a = ConfigObj()
         >>> a['a'] = 'fish'
-        >>> a.as_float('a')
+        >>> a.as_float('a')  #doctest: +IGNORE_EXCEPTION_DETAIL
         Traceback (most recent call last):
         ValueError: invalid literal for float(): fish
         >>> a['b'] = '1'
         >>> a.as_float('b')
         1.0
         >>> a['b'] = '3.2'
-        >>> a.as_float('b')
-        3.2000000000000002
+        >>> a.as_float('b')  #doctest: +ELLIPSIS
+        3.2...
         """
         return float(self[key])
     
@@ -1224,7 +1211,7 @@
             for entry in options:
                 if entry not in OPTION_DEFAULTS:
                     raise TypeError('Unrecognised option "%s".' % entry)
-            for entry, value in OPTION_DEFAULTS.items():
+            for entry, value in list(OPTION_DEFAULTS.items()):
                 if entry not in options:
                     options[entry] = value
                 keyword_value = _options[entry]
@@ -1243,12 +1230,11 @@
         
         
     def _load(self, infile, configspec):
-        if isinstance(infile, basestring):
+        if isinstance(infile, six.string_types):
             self.filename = infile
             if os.path.isfile(infile):
-                h = open(infile, 'rb')
-                infile = h.read() or []
-                h.close()
+                with open(infile, 'rb') as h:
+                    content = h.readlines() or []
             elif self.file_error:
                 # raise an error if the file doesn't exist
                 raise IOError('Config file not found: "%s".' % self.filename)
@@ -1257,13 +1243,12 @@
                 if self.create_empty:
                     # this is a good test that the filename specified
                     # isn't impossible - like on a non-existent device
-                    h = open(infile, 'w')
-                    h.write('')
-                    h.close()
-                infile = []
+                    with open(infile, 'w') as h:
+                        h.write('')
+                content = []
                 
         elif isinstance(infile, (list, tuple)):
-            infile = list(infile)
+            content = list(infile)
             
         elif isinstance(infile, dict):
             # initialise self
@@ -1291,21 +1276,21 @@
         
         elif getattr(infile, 'read', MISSING) is not MISSING:
             # This supports file like objects
-            infile = infile.read() or []
+            content = infile.read() or []
             # needs splitting into lines - but needs doing *after* decoding
             # in case it's not an 8 bit encoding
         else:
             raise TypeError('infile must be a filename, file like object, or 
list of lines.')
-        
-        if infile:
+
+        if content:
             # don't do it for the empty ConfigObj
-            infile = self._handle_bom(infile)
+            content = self._handle_bom(content)
             # infile is now *always* a list
             #
             # Set the newlines attribute (first line ending it finds)
             # and strip trailing '\n' or '\r' from lines
-            for line in infile:
-                if (not line) or (line[-1] not in ('\r', '\n', '\r\n')):
+            for line in content:
+                if (not line) or (line[-1] not in ('\r', '\n')):
                     continue
                 for end in ('\r\n', '\n', '\r'):
                     if line.endswith(end):
@@ -1313,9 +1298,10 @@
                         break
                 break
 
-            infile = [line.rstrip('\r\n') for line in infile]
+        assert all(isinstance(line, six.string_types) for line in content), 
repr(content)
+        content = [line.rstrip('\r\n') for line in content]
             
-        self._parse(infile)
+        self._parse(content)
         # if we had any errors, now is the time to raise them
         if self._errors:
             info = "at line %s." % self._errors[0].line_number
@@ -1404,6 +1390,7 @@
         ``infile`` must always be returned as a list of lines, but may be
         passed in as a single string.
         """
+
         if ((self.encoding is not None) and
             (self.encoding.lower() not in BOM_LIST)):
             # No need to check for a BOM
@@ -1415,6 +1402,13 @@
             line = infile[0]
         else:
             line = infile
+
+        if isinstance(line, six.text_type):
+            # it's already decoded and there's no need to do anything
+            # else, just use the _decode utility method to handle
+            # listifying appropriately
+            return self._decode(infile, self.encoding)
+
         if self.encoding is not None:
             # encoding explicitly supplied
             # And it could have an associated BOM
@@ -1423,7 +1417,7 @@
             enc = BOM_LIST[self.encoding.lower()]
             if enc == 'utf_16':
                 # For UTF16 we try big endian and little endian
-                for BOM, (encoding, final_encoding) in BOMS.items():
+                for BOM, (encoding, final_encoding) in list(BOMS.items()):
                     if not final_encoding:
                         # skip UTF8
                         continue
@@ -1453,8 +1447,9 @@
             return self._decode(infile, self.encoding)
         
         # No encoding specified - so we need to check for UTF8/UTF16
-        for BOM, (encoding, final_encoding) in BOMS.items():
-            if not line.startswith(BOM):
+        for BOM, (encoding, final_encoding) in list(BOMS.items()):
+            if not isinstance(line, six.binary_type) or not 
line.startswith(BOM):
+                # didn't specify a BOM, or it's not a bytestring
                 continue
             else:
                 # BOM discovered
@@ -1468,25 +1463,32 @@
                         infile[0] = newline
                     else:
                         infile = newline
-                    # UTF8 - don't decode
-                    if isinstance(infile, basestring):
+                    # UTF-8
+                    if isinstance(infile, six.text_type):
                         return infile.splitlines(True)
+                    elif isinstance(infile, six.binary_type):
+                        return infile.decode('utf-8').splitlines(True)
                     else:
-                        return infile
+                        return self._decode(infile, 'utf-8')
                 # UTF16 - have to decode
                 return self._decode(infile, encoding)
             
-        # No BOM discovered and no encoding specified, just return
-        if isinstance(infile, basestring):
-            # infile read from a file will be a single string
-            return infile.splitlines(True)
-        return infile
+
+        if six.PY2 and isinstance(line, str):
+            # don't actually do any decoding, since we're on python 2 and
+            # returning a bytestring is fine
+            return self._decode(infile, None)
+        # No BOM discovered and no encoding specified, default to UTF-8
+        if isinstance(infile, six.binary_type):
+            return infile.decode('utf-8').splitlines(True)
+        else:
+            return self._decode(infile, 'utf-8')
 
 
     def _a_to_u(self, aString):
         """Decode ASCII strings to unicode if a self.encoding is specified."""
-        if self.encoding:
-            return aString.decode('ascii')
+        if isinstance(aString, six.binary_type) and self.encoding:
+            return aString.decode(self.encoding)
         else:
             return aString
 
@@ -1497,34 +1499,42 @@
         
         if is a string, it also needs converting to a list.
         """
-        if isinstance(infile, basestring):
-            # can't be unicode
+        if isinstance(infile, six.string_types):
+            return infile.splitlines(True)
+        if isinstance(infile, six.binary_type):
             # NOTE: Could raise a ``UnicodeDecodeError``
-            return infile.decode(encoding).splitlines(True)
-        for i, line in enumerate(infile):
-            if not isinstance(line, unicode):
-                # NOTE: The isinstance test here handles mixed lists of 
unicode/string
-                # NOTE: But the decode will break on any non-string values
-                # NOTE: Or could raise a ``UnicodeDecodeError``
-                infile[i] = line.decode(encoding)
+            if encoding:
+                return infile.decode(encoding).splitlines(True)
+            else:
+                return infile.splitlines(True)
+
+        if encoding:
+            for i, line in enumerate(infile):
+                if isinstance(line, six.binary_type):
+                    # NOTE: The isinstance test here handles mixed lists of 
unicode/string
+                    # NOTE: But the decode will break on any non-string values
+                    # NOTE: Or could raise a ``UnicodeDecodeError``
+                    infile[i] = line.decode(encoding)
         return infile
 
 
     def _decode_element(self, line):
         """Decode element to unicode if necessary."""
-        if not self.encoding:
-            return line
-        if isinstance(line, str) and self.default_encoding:
+        if isinstance(line, six.binary_type) and self.default_encoding:
             return line.decode(self.default_encoding)
-        return line
+        else:
+            return line
 
 
+    # TODO: this may need to be modified
     def _str(self, value):
         """
         Used by ``stringify`` within validate, to turn non-string values
         into strings.
         """
-        if not isinstance(value, basestring):
+        if not isinstance(value, six.string_types):
+            # intentially 'str' because it's just whatever the "normal"
+            # string type is for the python version we're dealing with
             return str(value)
         else:
             return value
@@ -1615,10 +1625,8 @@
             # so it should be a valid ``key = value`` line
             mat = self._keyword.match(line)
             if mat is None:
-                # it neither matched as a keyword
-                # or a section marker
                 self._handle_error(
-                    'Invalid line at line "%s".',
+                    'Invalid line ({0!r}) (matched as neither section nor 
keyword) at line "%s".'.format(line),
                     ParseError, infile, cur_index)
             else:
                 # is a keyword value
@@ -1633,7 +1641,7 @@
                             value, infile, cur_index, maxline)
                     except SyntaxError:
                         self._handle_error(
-                            'Parse error in value at line %s.',
+                            'Parse error in multiline value at line %s.',
                             ParseError, infile, cur_index)
                         continue
                     else:
@@ -1641,11 +1649,11 @@
                             comment = ''
                             try:
                                 value = unrepr(value)
-                            except Exception, e:
+                            except Exception as e:
                                 if type(e) == UnknownType:
                                     msg = 'Unknown name or type in value at 
line %s.'
                                 else:
-                                    msg = 'Parse error in value at line %s.'
+                                    msg = 'Parse error from unrepr-ing 
multiline value at line %s.'
                                 self._handle_error(msg, UnreprError, infile,
                                     cur_index)
                                 continue
@@ -1654,11 +1662,11 @@
                         comment = ''
                         try:
                             value = unrepr(value)
-                        except Exception, e:
+                        except Exception as e:
                             if isinstance(e, UnknownType):
                                 msg = 'Unknown name or type in value at line 
%s.'
                             else:
-                                msg = 'Parse error in value at line %s.'
+                                msg = 'Parse error from unrepr-ing value at 
line %s.'
                             self._handle_error(msg, UnreprError, infile,
                                 cur_index)
                             continue
@@ -1777,8 +1785,10 @@
                 return self._quote(value[0], multiline=False) + ','
             return ', '.join([self._quote(val, multiline=False)
                 for val in value])
-        if not isinstance(value, basestring):
+        if not isinstance(value, six.string_types):
             if self.stringify:
+                # intentially 'str' because it's just whatever the "normal"
+                # string type is for the python version we're dealing with
                 value = str(value)
             else:
                 raise TypeError('Value "%s" is not a string.' % value)
@@ -1929,11 +1939,11 @@
                                        raise_errors=True,
                                        file_error=True,
                                        _inspec=True)
-            except ConfigObjError, e:
+            except ConfigObjError as e:
                 # FIXME: Should these errors have a reference
                 #        to the already parsed ConfigObj ?
                 raise ConfigspecError('Parsing configspec failed: %s' % e)
-            except IOError, e:
+            except IOError as e:
                 raise IOError('Reading configspec failed: %s' % e)
         
         self.configspec = configspec
@@ -2049,7 +2059,7 @@
             this_entry = section[entry]
             comment = self._handle_comment(section.inline_comments[entry])
             
-            if isinstance(this_entry, dict):
+            if isinstance(this_entry, Section):
                 # a section
                 out.append(self._write_marker(
                     indent_string,
@@ -2097,21 +2107,25 @@
             # Windows specific hack to avoid writing '\r\r\n'
             newline = '\n'
         output = self._a_to_u(newline).join(out)
-        if self.encoding:
-            output = output.encode(self.encoding)
-        if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)):
-            # Add the UTF8 BOM
-            output = BOM_UTF8 + output
-            
         if not output.endswith(newline):
             output += newline
-        if outfile is not None:
-            outfile.write(output)
+
+        if isinstance(output, six.binary_type):
+            output_bytes = output
         else:
-            h = open(self.filename, 'wb')
-            h.write(output)
-            h.close()
+            output_bytes = output.encode(self.encoding or
+                                         self.default_encoding or
+                                         'ascii')
+
+        if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)):
+            # Add the UTF8 BOM
+            output_bytes = BOM_UTF8 + output_bytes
 
+        if outfile is not None:
+            outfile.write(output_bytes)
+        else:
+            with open(self.filename, 'wb') as h:
+                h.write(output_bytes)
 
     def validate(self, validator, preserve_errors=False, copy=False,
                  section=None):
@@ -2189,7 +2203,7 @@
                                         val,
                                         missing=missing
                                         )
-            except validator.baseErrorClass, e:
+            except validator.baseErrorClass as e:
                 if not preserve_errors or isinstance(e, self._vdtMissingValue):
                     out[entry] = False
                 else:
@@ -2338,7 +2352,7 @@
         This method raises a ``ReloadError`` if the ConfigObj doesn't have
         a filename attribute pointing to a file.
         """
-        if not isinstance(self.filename, basestring):
+        if not isinstance(self.filename, six.string_types):
             raise ReloadError()
 
         filename = self.filename
@@ -2416,13 +2430,13 @@
         levels = []
         results = []
     if res == True:
-        return results
+        return sorted(results)
     if res == False or isinstance(res, Exception):
         results.append((levels[:], None, res))
         if levels:
             levels.pop()
-        return results
-    for (key, val) in res.items():
+        return sorted(results)
+    for (key, val) in list(res.items()):
         if val == True:
             continue
         if isinstance(cfg.get(key), dict):
@@ -2436,7 +2450,7 @@
     if levels:
         levels.pop()
     #
-    return results
+    return sorted(results)
 
 
 def get_extra_values(conf, _prepend=()):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/configobj-4.7.2/setup.py new/configobj-5.0.5/setup.py
--- old/configobj-4.7.2/setup.py        2010-03-02 00:18:36.000000000 +0100
+++ new/configobj-5.0.5/setup.py        2014-04-26 19:06:01.000000000 +0200
@@ -1,26 +1,35 @@
 # setup.py
 # Install script for ConfigObj
-# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         mark AT la-la DOT com
-#         nico AT tekNico DOT net
+# Copyright (C) 2005-2014:
+# (name) : (email)
+# Michael Foord: fuzzyman AT voidspace DOT org DOT uk
+# Mark Andrews: mark AT la-la DOT com
+# Nicola Larosa: nico AT tekNico DOT net
+# Rob Dennis: rdennis AT gmail DOT com
+# Eli Courtwright: eli AT courtwright DOT org
 
 # This software is licensed under the terms of the BSD license.
-# http://www.voidspace.org.uk/python/license.shtml
-
+# http://opensource.org/licenses/BSD-3-Clause
+import os
 import sys
 from distutils.core import setup
-from configobj import __version__ as VERSION
+# a simple import wouldn't work if we moved towards a package with __init__
+from _version import __version__
 
-NAME = 'configobj'
+if sys.version_info < (2, 6):
+    print('for python versions < 2.6 use configobj '
+          'version 4.7.2')
+    sys.exit(1)
 
-MODULES = 'configobj', 'validate'
+__here__ = os.path.abspath(os.path.dirname(__file__))
 
-DESCRIPTION = 'Config file reading, writing and validation.'
+VERSION = __version__
+NAME = 'configobj'
+MODULES = 'configobj', 'validate', '_version'
 
-URL = 'http://www.voidspace.org.uk/python/configobj.html'
+DESCRIPTION = 'Config file reading, writing and validation.'
 
-DOWNLOAD_URL = "http://www.voidspace.org.uk/downloads/configobj-%s.zip"; % 
VERSION
+URL = 'https://github.com/DiffSK/configobj'
 
 LONG_DESCRIPTION = """**ConfigObj** is a simple but powerful config file 
reader and writer: an *ini
 file round tripper*. Its main feature is that it is very easy to use, with a
@@ -42,6 +51,17 @@
 * The order of keys/sections is preserved
 * Powerful ``unrepr`` mode for storing/retrieving Python data-types
 
+| Release 5.0.5 corrects a unicode-bug that still existed in writing files
+| Release 5.0.4 corrects a unicode-bug that still existed in reading files 
after
+| fixing lists of string in 5.0.3
+| Release 5.0.3 corrects errors related to the incorrectly handling unicode
+| encoding and writing out files
+| Release 5.0.2 adds a specific error message when trying to install on
+| Python versions older than 2.5
+| Release 5.0.1 fixes a regression with unicode conversion not happening
+| in certain cases PY2
+| Release 5.0.0 updates the supported Python versions to 2.6, 2.7, 3.2, 3.3
+| and is otherwise unchanged
 | Release 4.7.2 fixes several bugs in 4.7.1
 | Release 4.7.1 fixes a bug with the deprecated options keyword in
 | 4.7.0.
@@ -53,27 +73,29 @@
     'Intended Audience :: Developers',
     'License :: OSI Approved :: BSD License',
     'Programming Language :: Python',
-    'Programming Language :: Python :: 2.3',
-    'Programming Language :: Python :: 2.4',
-    'Programming Language :: Python :: 2.5',
+    'Programming Language :: Python :: 2',
     'Programming Language :: Python :: 2.6',
+    'Programming Language :: Python :: 2.7',
+    'Programming Language :: Python :: 3',
+    'Programming Language :: Python :: 3.2',
+    'Programming Language :: Python :: 3.3',
     'Operating System :: OS Independent',
     'Topic :: Software Development :: Libraries',
     'Topic :: Software Development :: Libraries :: Python Modules',
 ]
 
-AUTHOR = 'Michael Foord & Nicola Larosa'
+AUTHOR = 'Rob Dennis, Eli Courtwright (Michael Foord & Nicola Larosa original 
maintainers)'
 
-AUTHOR_EMAIL = 'fuzzy...@voidspace.org.uk'
+AUTHOR_EMAIL = 'rdennis+config...@gmail.com, e...@courtwright.org, 
fuzzy...@voidspace.co.uk, n...@teknico.net'
 
 KEYWORDS = "config, ini, dictionary, application, admin, sysadmin, 
configuration, validation".split(', ')
 
 
 setup(name=NAME,
       version=VERSION,
+      install_requires=['six'],
       description=DESCRIPTION,
       long_description=LONG_DESCRIPTION,
-      download_url=DOWNLOAD_URL,
       author=AUTHOR,
       author_email=AUTHOR_EMAIL,
       url=URL,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/configobj-4.7.2/validate.py 
new/configobj-5.0.5/validate.py
--- old/configobj-4.7.2/validate.py     2010-03-02 00:04:02.000000000 +0100
+++ new/configobj-5.0.5/validate.py     2014-02-20 03:41:51.000000000 +0100
@@ -1,20 +1,18 @@
 # validate.py
 # A Validator object
-# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#         mark AT la-la DOT com
-#         nico AT tekNico DOT net
+# Copyright (C) 2005-2014:
+# (name) : (email)
+# Michael Foord: fuzzyman AT voidspace DOT org DOT uk
+# Mark Andrews: mark AT la-la DOT com
+# Nicola Larosa: nico AT tekNico DOT net
+# Rob Dennis: rdennis AT gmail DOT com
+# Eli Courtwright: eli AT courtwright DOT org
 
 # This software is licensed under the terms of the BSD license.
-# http://www.voidspace.org.uk/python/license.shtml
-# Basically you're free to copy, modify, distribute and relicense it,
-# So long as you keep a copy of the license with it.
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# For information about bugfixes, updates and support, please join the
-# ConfigObj mailing list:
-# http://lists.sourceforge.net/lists/listinfo/configobj-develop
-# Comments, suggestions and bug reports welcome.
+# http://opensource.org/licenses/BSD-3-Clause
+
+# ConfigObj 5 - main repository for documentation and issue tracking:
+# https://github.com/DiffSK/configobj
 
 """
     The Validator object is used to check that supplied values 
@@ -165,7 +163,24 @@
 
 
 import re
+import sys
+from pprint import pprint
 
+#TODO - #21 - six is part of the repo now, but we didn't switch over to it here
+# this could be replaced if six is used for compatibility, or there are no
+# more assertions about items being a string
+if sys.version_info < (3,):
+    string_type = basestring
+else:
+    string_type = str
+    # so tests that care about unicode on 2.x can specify unicode, and the same
+    # tests when run on 3.x won't complain about a undefined name "unicode"
+    # since all strings are unicode on 3.x we just want to pass it through
+    # unchanged
+    unicode = lambda x: x
+    # in python 3, all ints are equivalent to python 2 longs, and they'll
+    # never show "L" in the repr
+    long = int
 
 _list_arg = re.compile(r'''
     (?:
@@ -269,7 +284,7 @@
     >>> int(dottedQuadToNum('1.2.3.4'))
     16909060
     >>> dottedQuadToNum('255.255.255.255')
-    4294967295L
+    4294967295
     >>> dottedQuadToNum('255.255.255.256')
     Traceback (most recent call last):
     ValueError: Not a good dotted-quad IP: 255.255.255.256
@@ -282,41 +297,54 @@
         return struct.unpack('!L',
             socket.inet_aton(ip.strip()))[0]
     except socket.error:
-        # bug in inet_aton, corrected in Python 2.4
-        if ip.strip() == '255.255.255.255':
-            return 0xFFFFFFFFL
-        else:
-            raise ValueError('Not a good dotted-quad IP: %s' % ip)
+        raise ValueError('Not a good dotted-quad IP: %s' % ip)
     return
 
 
 def numToDottedQuad(num):
     """
-    Convert long int to dotted quad string
+    Convert int or long int to dotted quad string
     
-    >>> numToDottedQuad(-1L)
+    >>> numToDottedQuad(long(-1))
     Traceback (most recent call last):
     ValueError: Not a good numeric IP: -1
-    >>> numToDottedQuad(1L)
+    >>> numToDottedQuad(long(1))
     '0.0.0.1'
-    >>> numToDottedQuad(16777218L)
+    >>> numToDottedQuad(long(16777218))
     '1.0.0.2'
-    >>> numToDottedQuad(16908291L)
+    >>> numToDottedQuad(long(16908291))
     '1.2.0.3'
-    >>> numToDottedQuad(16909060L)
+    >>> numToDottedQuad(long(16909060))
     '1.2.3.4'
-    >>> numToDottedQuad(4294967295L)
+    >>> numToDottedQuad(long(4294967295))
     '255.255.255.255'
-    >>> numToDottedQuad(4294967296L)
+    >>> numToDottedQuad(long(4294967296))
     Traceback (most recent call last):
     ValueError: Not a good numeric IP: 4294967296
+    >>> numToDottedQuad(-1)
+    Traceback (most recent call last):
+    ValueError: Not a good numeric IP: -1
+    >>> numToDottedQuad(1)
+    '0.0.0.1'
+    >>> numToDottedQuad(16777218)
+    '1.0.0.2'
+    >>> numToDottedQuad(16908291)
+    '1.2.0.3'
+    >>> numToDottedQuad(16909060)
+    '1.2.3.4'
+    >>> numToDottedQuad(4294967295)
+    '255.255.255.255'
+    >>> numToDottedQuad(4294967296)
+    Traceback (most recent call last):
+    ValueError: Not a good numeric IP: 4294967296
+
     """
     
     # import here to avoid it when ip_addr values are not used
     import socket, struct
     
     # no need to intercept here, 4294967295L is fine
-    if num > 4294967295L or num < 0:
+    if num > long(4294967295) or num < 0:
         raise ValueError('Not a good numeric IP: %s' % num)
     try:
         return socket.inet_ntoa(
@@ -464,9 +492,9 @@
     ...     # check that value is of the correct type.
     ...     # possible valid inputs are integers or strings
     ...     # that represent integers
-    ...     if not isinstance(value, (int, long, basestring)):
+    ...     if not isinstance(value, (int, long, string_type)):
     ...         raise VdtTypeError(value)
-    ...     elif isinstance(value, basestring):
+    ...     elif isinstance(value, string_type):
     ...         # if we are given a string
     ...         # attempt to convert to an integer
     ...         try:
@@ -615,7 +643,7 @@
             fun_kwargs = dict(fun_kwargs)
         else:
             fun_name, fun_args, fun_kwargs, default = self._parse_check(check)
-            fun_kwargs = dict([(str(key), value) for (key, value) in 
fun_kwargs.items()])
+            fun_kwargs = dict([(str(key), value) for (key, value) in 
list(fun_kwargs.items())])
             self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), 
default
         return fun_name, fun_args, fun_kwargs, default
         
@@ -736,10 +764,10 @@
     for (name, val) in zip(names, values):
         if val is None:
             out_params.append(val)
-        elif isinstance(val, (int, long, float, basestring)):
+        elif isinstance(val, (int, long, float, string_type)):
             try:
                 out_params.append(fun(val))
-            except ValueError, e:
+            except ValueError as e:
                 raise VdtParamError(name, val)
         else:
             raise VdtParamError(name, val)
@@ -793,9 +821,9 @@
     0
     """
     (min_val, max_val) = _is_num_param(('min', 'max'), (min, max))
-    if not isinstance(value, (int, long, basestring)):
+    if not isinstance(value, (int, long, string_type)):
         raise VdtTypeError(value)
-    if isinstance(value, basestring):
+    if isinstance(value, string_type):
         # if it's a string - does it represent an integer ?
         try:
             value = int(value)
@@ -845,7 +873,7 @@
     """
     (min_val, max_val) = _is_num_param(
         ('min', 'max'), (min, max), to_float=True)
-    if not isinstance(value, (int, long, float, basestring)):
+    if not isinstance(value, (int, long, float, string_type)):
         raise VdtTypeError(value)
     if not isinstance(value, float):
         # if it's a string - does it represent a float ?
@@ -910,7 +938,7 @@
     VdtTypeError: the value "up" is of the wrong type.
     
     """
-    if isinstance(value, basestring):
+    if isinstance(value, string_type):
         try:
             return bool_dict[value.lower()]
         except KeyError:
@@ -953,7 +981,7 @@
     Traceback (most recent call last):
     VdtTypeError: the value "0" is of the wrong type.
     """
-    if not isinstance(value, basestring):
+    if not isinstance(value, string_type):
         raise VdtTypeError(value)
     value = value.strip()
     try:
@@ -995,7 +1023,7 @@
     VdtTypeError: the value "12" is of the wrong type.
     """
     (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
-    if isinstance(value, basestring):
+    if isinstance(value, string_type):
         raise VdtTypeError(value)
     try:
         num_members = len(value)
@@ -1064,7 +1092,7 @@
     Traceback (most recent call last):
     VdtValueTooLongError: the value "1234" is too long.
     """
-    if not isinstance(value, basestring):
+    if not isinstance(value, string_type):
         raise VdtTypeError(value)
     (min_len, max_len) = _is_num_param(('min', 'max'), (min, max))
     try:
@@ -1170,7 +1198,7 @@
     Traceback (most recent call last):
     VdtTypeError: the value "hello" is of the wrong type.
     """
-    if isinstance(value, basestring):
+    if isinstance(value, string_type):
         raise VdtTypeError(value)
     return [is_string(mem) for mem in is_list(value, min, max)]
 
@@ -1266,21 +1294,10 @@
     >>> vtor.check(mix_str, 0)
     Traceback (most recent call last):
     VdtTypeError: the value "0" is of the wrong type.
-    
-    This test requires an elaborate setup, because of a change in error string
-    output from the interpreter between Python 2.2 and 2.3 .
-    
-    >>> res_seq = (
-    ...     'passed an incorrect value "',
-    ...     'yoda',
-    ...     '" for parameter "mixed_list".',
-    ... )
-    >>> res_str = "'".join(res_seq)
-    >>> try:
-    ...     vtor.check('mixed_list("yoda")', ('a'))
-    ... except VdtParamError, err:
-    ...     str(err) == res_str
-    1
+
+    >>> vtor.check('mixed_list("yoda")', ('a'))
+    Traceback (most recent call last):
+    VdtParamError: passed an incorrect value "KeyError('yoda',)" for parameter 
"'mixed_list'"
     """
     try:
         length = len(value)
@@ -1292,7 +1309,7 @@
         raise VdtValueTooLongError(value)
     try:
         return [fun_dict[arg](val) for arg, val in zip(args, value)]
-    except KeyError, e:
+    except KeyError as e:
         raise VdtParamError('mixed_list', e)
 
 
@@ -1309,7 +1326,7 @@
     Traceback (most recent call last):
     VdtTypeError: the value "0" is of the wrong type.
     """
-    if not isinstance(value, basestring):
+    if not isinstance(value, string_type):
         raise VdtTypeError(value)
     if not value in options:
         raise VdtValueError(value)
@@ -1338,20 +1355,20 @@
     ...    ]
     >>> v = Validator({'test': _test})
     >>> for entry in checks:
-    ...     print v.check(('test(%s)' % entry), 3)
-    (3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'})
+    ...     pprint(v.check(('test(%s)' % entry), 3))
+    (3, ('3', '6'), {'max': '3', 'min': '1', 'test': ['a', 'b', 'c']})
     (3, ('3',), {})
     (3, ('3', '6'), {})
     (3, ('3',), {})
-    (3, (), {'test': 'a b c', 'min': '1'})
-    (3, (), {'test': 'a, b, c', 'min': '5'})
-    (3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'})
-    (3, (), {'test': '-99', 'min': '-100'})
+    (3, (), {'min': '1', 'test': 'a b c'})
+    (3, (), {'min': '5', 'test': 'a, b, c'})
+    (3, (), {'max': '3', 'min': '1', 'test': 'a, b, c'})
+    (3, (), {'min': '-100', 'test': '-99'})
     (3, (), {'max': '3', 'min': '1'})
     (3, ('3', '6'), {'test': '36'})
     (3, ('3', '6'), {'test': 'a, b, c'})
-    (3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'})
-    (3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'})
+    (3, ('3',), {'max': '3', 'test': ['a', 'b', 'c']})
+    (3, ('3',), {'max': '3', 'test': ["'a'", 'b', 'x=(c)']})
     (3, (), {'test': 'x=fish(3)'})
     
     >>> v = Validator()
@@ -1383,14 +1400,14 @@
     
     Bug test for unicode arguments
     >>> v = Validator()
-    >>> v.check(u'string(min=4)', u'test')
-    u'test'
+    >>> v.check(unicode('string(min=4)'), unicode('test')) == unicode('test')
+    True
     
     >>> v = Validator()
-    >>> v.get_default_value(u'string(min=4, default="1234")')
-    u'1234'
-    >>> v.check(u'string(min=4, default="1234")', u'test')
-    u'test'
+    >>> v.get_default_value(unicode('string(min=4, default="1234")')) == 
unicode('1234')
+    True
+    >>> v.check(unicode('string(min=4, default="1234")'), unicode('test')) == 
unicode('test')
+    True
     
     >>> v = Validator()
     >>> default = v.get_default_value('string(default=None)')
@@ -1416,7 +1433,8 @@
     ''
     >>> vtor.check('string(default="\n")', '', missing=True)
     '\n'
-    >>> print vtor.check('string(default="\n")', '', missing=True),
+    >>> print(vtor.check('string(default="\n")', '', missing=True))
+    <BLANKLINE>
     <BLANKLINE>
     >>> vtor.check('string()', '\n')
     '\n'
@@ -1447,4 +1465,8 @@
     globs.update({
         'vtor': Validator(),
     })
-    doctest.testmod(m, globs=globs)
+
+    failures, tests = doctest.testmod(
+        m, globs=globs,
+        optionflags=doctest.IGNORE_EXCEPTION_DETAIL | doctest.ELLIPSIS)
+    assert not failures, '{} failures out of {} tests'.format(failures, tests)

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to