summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Dennis <rdennis@gmail.com>2014-04-28 07:14:44 -0400
committerRob Dennis <rdennis@gmail.com>2014-04-28 07:14:44 -0400
commit16d4f32268056ef5dacb87070e720d98d12e60d0 (patch)
tree9f5540d4af8fd5448e163ab973240a7cfbb135a1
parent6ae299fdabcf177e7f6176af34f43dbb067ddf1a (diff)
parentdf25945025f5ec799c99292a578d626d1cca66bf (diff)
downloadconfigobj-git-16d4f32268056ef5dacb87070e720d98d12e60d0.tar.gz
Merge pull request #57 from DiffSK/masterv5.0.5
release 5.0.5
-rw-r--r--README.md4
-rw-r--r--_version.py2
-rw-r--r--configobj.py24
-rw-r--r--docs/conf.py2
-rw-r--r--docs/configobj.rst8
-rw-r--r--setup.py1
-rw-r--r--tests/test_configobj.py22
7 files changed, 36 insertions, 27 deletions
diff --git a/README.md b/README.md
index 84d87fa..186a309 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-configobj [![Build Status](https://travis-ci.org/DiffSK/configobj.png?branch=master)](https://travis-ci.org/DiffSK/configobj)[![Downloads](https://pypip.in/d/configobj/badge.png)](https://crate.io/packages/configobj)[![PyPI version](https://badge.fury.io/py/configobj.png)](http://badge.fury.io/py/configobj)[![Coverage Status](https://coveralls.io/repos/DiffSK/configobj/badge.png?branch=master)](https://coveralls.io/r/DiffSK/configobj?branch=master)
+configobj [![Build Status](https://travis-ci.org/DiffSK/configobj.svg?branch=master)](https://travis-ci.org/DiffSK/configobj)[![Downloads](https://pypip.in/d/configobj/badge.png)](https://crate.io/packages/configobj)[![PyPI version](https://badge.fury.io/py/configobj.png)](http://badge.fury.io/py/configobj)[![Coverage Status](https://coveralls.io/repos/DiffSK/configobj/badge.png?branch=master)](https://coveralls.io/r/DiffSK/configobj?branch=master)
=========
Python 3+ compatible port of the [configobj](https://pypi.python.org/pypi/configobj/) library.
@@ -9,7 +9,7 @@ Found at [readthedocs](http://configobj.readthedocs.org/)
Status
=========
-This project has is now maintained by [Eli Courtwright](https://github.com/EliAndrewC) and [Rob Dennis](https://github.com/robdennis) with the blessing of original creator [Michael Foord](http://www.voidspace.org.uk/) and the most recent release is version *5.0.4* (view [changelog](http://configobj.readthedocs.org/en/latest/configobj.html#version-5-0-4)).
+This project is now maintained by [Eli Courtwright](https://github.com/EliAndrewC) and [Rob Dennis](https://github.com/robdennis) with the blessing of original creator [Michael Foord](http://www.voidspace.org.uk/).
For long time ConfigObj users, the biggest change is in the officially supported python versions:
- 2.6
diff --git a/_version.py b/_version.py
index 742c20e..04a5874 100644
--- a/_version.py
+++ b/_version.py
@@ -1 +1 @@
-__version__ = '5.0.4' \ No newline at end of file
+__version__ = '5.0.5' \ No newline at end of file
diff --git a/configobj.py b/configobj.py
index d730a13..2139e7f 100644
--- a/configobj.py
+++ b/configobj.py
@@ -2107,21 +2107,25 @@ class ConfigObj(Section):
# 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 isinstance(output, six.binary_type):
+ output_bytes = output
+ else:
+ 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)
+ outfile.write(output_bytes)
else:
with open(self.filename, 'wb') as h:
- h.write(output.encode(self.encoding or
- self.default_encoding or
- 'ascii'))
+ h.write(output_bytes)
def validate(self, validator, preserve_errors=False, copy=False,
section=None):
diff --git a/docs/conf.py b/docs/conf.py
index 1e4f78c..c988a3a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -50,7 +50,7 @@ copyright = u'2014, Michael Foord, Nicola Larosa, Rob Dennis, Eli Courtwright'
# built documents.
#
# The full version, including alpha/beta/rc tags.
-release = '5.0.4'
+release = '5.0.5'
# The short X.Y version.
version = '.'.join(release.split('.')[:2])
diff --git a/docs/configobj.rst b/docs/configobj.rst
index 445d694..30eac11 100644
--- a/docs/configobj.rst
+++ b/docs/configobj.rst
@@ -8,7 +8,7 @@
----------------------------------------
:Authors: Michael Foord, Nicola Larosa, Rob Dennis, Eli Courtwright
-:Version: ConfigObj 5.0.4
+:Version: ConfigObj 5.0.5
:Date: 2014/02/08
:PyPI Entry: `ConfigObj on PyPI <http://pypi.python.org/pypi/configobj/>`_
:Homepage: `Github Page`_
@@ -64,7 +64,7 @@ For support and bug reports please use the ConfigObj `Github Page`_.
Downloading
===========
-The current version is **5.0.4**, dated 11th April 2014. ConfigObj 5 is
+The current version is **5.0.5**, dated 25th April 2014. ConfigObj 5 is
stable and mature. We still expect to pick up a few bugs along the way though, particularly with respect to Python 3 compatibility [#]_.
We recommend downloading and installing using pip:
@@ -2385,6 +2385,10 @@ From version 4 it lists all releases and changes.
2014/04/11 - Version 5.0.4
--------------------------
+* BUGFIX: error in writing out config files to disk with non-ascii characters
+
+2014/04/11 - Version 5.0.4
+--------------------------
* BUGFIX: correcting that the code path fixed in 5.0.3 didn't cover reading in
config files
diff --git a/setup.py b/setup.py
index ec6d7a3..1489879 100644
--- a/setup.py
+++ b/setup.py
@@ -51,6 +51,7 @@ It has lots of other features though :
* 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
diff --git a/tests/test_configobj.py b/tests/test_configobj.py
index c37bd73..473992b 100644
--- a/tests/test_configobj.py
+++ b/tests/test_configobj.py
@@ -216,8 +216,7 @@ class TestEncoding(object):
else:
assert isinstance(c['test'], str)
- #TODO: this can be made more explicit if we switch to unicode_literals
- assert c['test'] == b'\xf0\x9f\x90\x9c'.decode('utf8')
+ assert c['test'] == '\U0001f41c'
#issue #44
def test_encoding_in_subsections(self, ant_cfg, cfg_contents):
@@ -226,7 +225,7 @@ class TestEncoding(object):
assert isinstance(cfg['tags']['bug']['translated'], six.text_type)
- #issue #44
+ #issue #44 and #55
def test_encoding_in_config_files(self, request, ant_cfg):
# the cfg_contents fixture is doing this too, but be explicit
with NamedTemporaryFile(delete=False, mode='wb') as cfg_file:
@@ -235,6 +234,7 @@ class TestEncoding(object):
cfg = ConfigObj(cfg_file.name, encoding='utf-8')
assert isinstance(cfg['tags']['bug']['translated'], six.text_type)
+ cfg.write()
@pytest.fixture
def testconfig1():
@@ -515,7 +515,7 @@ def test_unicode_handling():
uc = ConfigObj(u)
assert uc.newlines == '\r\n'
uc.newlines = '\r'
- file_like = six.StringIO()
+ file_like = six.BytesIO()
uc.write(file_like)
file_like.seek(0)
uc2 = ConfigObj(file_like)
@@ -811,7 +811,7 @@ class TestReloading(object):
return content
def test_handle_no_filename(self):
- for bad_args in ([six.StringIO()], [], [[]]):
+ for bad_args in ([six.BytesIO()], [], [[]]):
cfg = ConfigObj(*bad_args)
with pytest.raises(ReloadError) as excinfo:
cfg.reload()
@@ -1264,23 +1264,23 @@ class TestEdgeCasesWhenWritingOut(object):
def test_newline_terminated(self, empty_cfg):
empty_cfg.newlines = '\n'
empty_cfg['a'] = 'b'
- collector = six.StringIO()
+ collector = six.BytesIO()
empty_cfg.write(collector)
- assert collector.getvalue() == 'a = b\n'
+ assert collector.getvalue() == b'a = b\n'
def test_hash_escaping(self, empty_cfg):
empty_cfg.newlines = '\n'
empty_cfg['#a'] = 'b # something'
- collector = six.StringIO()
+ collector = six.BytesIO()
empty_cfg.write(collector)
- assert collector.getvalue() == '"#a" = "b # something"\n'
+ assert collector.getvalue() == b'"#a" = "b # something"\n'
empty_cfg = ConfigObj()
empty_cfg.newlines = '\n'
empty_cfg['a'] = 'b # something', 'c # something'
- collector = six.StringIO()
+ collector = six.BytesIO()
empty_cfg.write(collector)
- assert collector.getvalue() == 'a = "b # something", "c # something"\n'
+ assert collector.getvalue() == b'a = "b # something", "c # something"\n'
def test_detecting_line_endings_from_existing_files(self):
for expected_line_ending in ('\r\n', '\n'):