diff options
author | Rob Dennis <rdennis@gmail.com> | 2014-04-26 13:04:46 -0400 |
---|---|---|
committer | Rob Dennis <rdennis@gmail.com> | 2014-04-26 13:04:46 -0400 |
commit | bef6b97b7087053b46a0cf17ce76e93d25f1c070 (patch) | |
tree | cd837cd2c56eca99430482266c01c3501516f58a | |
parent | 81079e281e2b26096f53c291226de1ebd3bc4791 (diff) | |
parent | 9a64fa175b8020ac367d12bf63fdf74ba2d79ecd (diff) | |
download | configobj-git-bef6b97b7087053b46a0cf17ce76e93d25f1c070.tar.gz |
Merge pull request #56 from robdennis/master
fixes #55 - can write out non-ascii characters to disk
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | _version.py | 2 | ||||
-rw-r--r-- | configobj.py | 24 | ||||
-rw-r--r-- | docs/conf.py | 2 | ||||
-rw-r--r-- | docs/configobj.rst | 8 | ||||
-rw-r--r-- | setup.py | 1 | ||||
-rw-r--r-- | tests/test_configobj.py | 22 |
7 files changed, 35 insertions, 26 deletions
@@ -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 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/). 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 @@ -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'): |