forked from pool/python-configobj
- Update to 5.0.9
* Drop support for Python 2 and <3.7 * Fix CVE-2023-26112, ReDoS attack - Drop CVE-2023-26112.patch, merged upstream - Drop remove_six.patch, fixed upstream OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-configobj?expand=0&rev=51
This commit is contained in:
commit
c8f298cf10
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
## Default LFS
|
||||||
|
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zst filter=lfs diff=lfs merge=lfs -text
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.osc
|
48
CVE-2023-26112.patch
Normal file
48
CVE-2023-26112.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From a82ea8fb0338f2bd46cf627c4b763094448e6bd7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: cdcadman <mythirty@gmail.com>
|
||||||
|
Date: Wed, 17 May 2023 03:57:08 -0700
|
||||||
|
Subject: [PATCH] Address CVE-2023-26112 ReDoS
|
||||||
|
|
||||||
|
---
|
||||||
|
src/configobj/validate.py | 2 +-
|
||||||
|
src/tests/test_validate_errors.py | 10 +++++++++-
|
||||||
|
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/configobj/validate.py b/src/configobj/validate.py
|
||||||
|
index 9267a3f..98d879f 100644
|
||||||
|
--- a/src/configobj/validate.py
|
||||||
|
+++ b/src/configobj/validate.py
|
||||||
|
@@ -541,7 +541,7 @@ class Validator(object):
|
||||||
|
"""
|
||||||
|
|
||||||
|
# this regex does the initial parsing of the checks
|
||||||
|
- _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL)
|
||||||
|
+ _func_re = re.compile(r'([^\(\)]+?)\((.*)\)', re.DOTALL)
|
||||||
|
|
||||||
|
# this regex takes apart keyword arguments
|
||||||
|
_key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$', re.DOTALL)
|
||||||
|
diff --git a/src/tests/test_validate_errors.py b/src/tests/test_validate_errors.py
|
||||||
|
index 399daa8..f7d6c27 100644
|
||||||
|
--- a/src/tests/test_validate_errors.py
|
||||||
|
+++ b/src/tests/test_validate_errors.py
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from configobj import ConfigObj, get_extra_values, ParseError, NestingError
|
||||||
|
-from configobj.validate import Validator
|
||||||
|
+from configobj.validate import Validator, VdtUnknownCheckError
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def thisdir():
|
||||||
|
@@ -77,3 +77,11 @@ def test_no_parent(tmpdir, specpath):
|
||||||
|
ini.write('[[haha]]')
|
||||||
|
with pytest.raises(NestingError):
|
||||||
|
conf = ConfigObj(str(ini), configspec=specpath, file_error=True)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def test_re_dos(val):
|
||||||
|
+ value = "aaa"
|
||||||
|
+ i = 165100
|
||||||
|
+ attack = '\x00'*i + ')' + '('*i
|
||||||
|
+ with pytest.raises(VdtUnknownCheckError):
|
||||||
|
+ val.check(attack, value)
|
BIN
configobj-5.0.8-gh.tar.gz
(Stored with Git LFS)
Normal file
BIN
configobj-5.0.8-gh.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
3
configobj-5.0.9-gh.tar.gz
Normal file
3
configobj-5.0.9-gh.tar.gz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:2bd70f9ce7912679c4ba9c80da289877906db0ca6bd02c3ab545d660e9b60d4f
|
||||||
|
size 98246
|
183
python-configobj.changes
Normal file
183
python-configobj.changes
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Feb 4 08:55:17 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
|
||||||
|
|
||||||
|
- Update to 5.0.9
|
||||||
|
* Drop support for Python 2 and <3.7
|
||||||
|
* Fix CVE-2023-26112, ReDoS attack
|
||||||
|
- Drop CVE-2023-26112.patch, merged upstream
|
||||||
|
- Drop remove_six.patch, fixed upstream
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Sep 11 12:08:59 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
|
||||||
|
|
||||||
|
- Refresh CVE-2023-26112.patch according to the last state of
|
||||||
|
gh#DiffSK/configobj!236.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 3 16:47:32 UTC 2024 - Ben Greiner <code@bnavigator.de>
|
||||||
|
|
||||||
|
- Remove six from the rpm requirements. Why would we have
|
||||||
|
remove_six.patch in the first place if we still require it?
|
||||||
|
- Enable unit tests
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 3 09:46:30 UTC 2024 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
- require setuptools
|
||||||
|
- remove python2 logic, this makes no sense after
|
||||||
|
"remove_six.patch"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jul 5 07:29:38 UTC 2023 - Matej Cepl <mcepl@suse.com>
|
||||||
|
|
||||||
|
- Add remove_six.patch (gh#DiffSK/configobj#239) removing the
|
||||||
|
need for six.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jul 4 10:51:42 UTC 2023 - Markéta Machová <mmachova@suse.com>
|
||||||
|
|
||||||
|
- Add CVE-2023-26112.patch (bsc#1210070)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu May 4 18:56:05 UTC 2023 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
- update to 5.0.8:
|
||||||
|
* 5.0.7 originally did this work, but 5.0.8 fixes a regression
|
||||||
|
* update testing to validate against python version 2.7 and
|
||||||
|
3.5-3.11
|
||||||
|
* update broken links / non-existent services and references
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Apr 21 12:23:30 UTC 2023 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
- add sle15_python_module_pythons (jsc#PED-68)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Apr 13 22:40:36 UTC 2023 - Matej Cepl <mcepl@suse.com>
|
||||||
|
|
||||||
|
- Make calling of %{sle15modernpython} optional.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Jan 16 21:16:58 UTC 2023 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
- require setuptools
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Dec 4 12:46:48 UTC 2018 - Matej Cepl <mcepl@suse.com>
|
||||||
|
|
||||||
|
- Remove superfluous devel dependency for noarch package
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed May 24 17:01:11 UTC 2017 - toddrme2178@gmail.com
|
||||||
|
|
||||||
|
- Implement single-spec version.
|
||||||
|
- Fix source URL.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Sep 11 10:37:46 UTC 2014 - toddrme2178@gmail.com
|
||||||
|
|
||||||
|
- Update to version 5.0.6
|
||||||
|
* Improves error messages in certain edge cases
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Jul 24 09:03:10 UTC 2014 - fcastelli@suse.com
|
||||||
|
|
||||||
|
- Added runtime depedency: python-six
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jul 23 13:04:31 UTC 2014 - fcastelli@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)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue May 29 08:26:59 UTC 2012 - cfarrell@suse.com
|
||||||
|
|
||||||
|
- license update: BSD-3-Clause
|
||||||
|
Refers only to the license available at
|
||||||
|
http://www.voidspace.org.uk/python/license.shtml (which is BSD-3-Clause)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri May 25 08:21:00 UTC 2012 - toddrme2178@gmail.com
|
||||||
|
|
||||||
|
- Spec file cleanups
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Sun Feb 5 19:40:33 UTC 2012 - dimstar@opensuse.org
|
||||||
|
|
||||||
|
- Really make the obsoletes sane: The package was called
|
||||||
|
python-configobj-docs before, so that's what we need to obsolete
|
||||||
|
(not -doc).
|
||||||
|
- The Obsoletes tag is for <= %{version}, as the package existed in
|
||||||
|
version 4.7.2, which is also when it was merged back. Obsoleting
|
||||||
|
only < 4.7.2 would cause conflicts when installing the newly
|
||||||
|
merged package.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jan 24 13:50:32 UTC 2012 - bwiedemann@suse.com
|
||||||
|
|
||||||
|
- fix Obsoletes
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Dec 9 12:39:05 UTC 2011 - saschpe@suse.de
|
||||||
|
|
||||||
|
- Spec file cleanup:
|
||||||
|
* Use upstream tarball
|
||||||
|
* Obsoleted empty doc package
|
||||||
|
* Fix SLE-11 build
|
||||||
|
* Use upstream description
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Dec 8 13:54:30 UTC 2011 - coolo@suse.com
|
||||||
|
|
||||||
|
- fix license to be in spdx.org format
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Sep 13 22:07:25 CEST 2010 - dimstar@opensuse.org
|
||||||
|
|
||||||
|
- Update to version 4.7.2:
|
||||||
|
+ BUGFIX: Restore Python 2.3 compatibility
|
||||||
|
+ BUGFIX: Members that were lists were being returned as copies
|
||||||
|
due to interpolation introduced in 4.7. Lists are now only
|
||||||
|
copies if interpolation changes a list member.
|
||||||
|
+ BUGFIX: pop now does interpolation in list values as well.
|
||||||
|
+ BUGFIX: where interpolation matches a section name rather
|
||||||
|
than a value it is ignored instead of raising an exception on
|
||||||
|
fetching the item.
|
||||||
|
+ BUGFIX: values that use interpolation to reference members
|
||||||
|
that don't exist can now be repr'd.
|
||||||
|
+ BUGFIX: Fix to avoid writing '\r\r\n' on Windows when given a
|
||||||
|
file opened in text write mode ('w').
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jul 20 20:24:28 UTC 2010 - pascal.bleser@opensuse.org
|
||||||
|
|
||||||
|
- update to 4.7.1
|
||||||
|
- split out -docs subpackage
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Sun May 27 18:22:00 CEST 2007 - peter+rpmspam@suntel.com.tr
|
||||||
|
|
||||||
|
- add "unzip" as a builddep so it builds on Factory - 4.4.0
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
Fri May 11 16:59:40 CEST 2007 - poeml@suse.de
|
||||||
|
|
||||||
|
- package created (copy from packman package) - 4.4.0
|
||||||
|
|
77
python-configobj.spec
Normal file
77
python-configobj.spec
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#
|
||||||
|
# spec file for package python-configobj
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025 SUSE LLC
|
||||||
|
#
|
||||||
|
# All modifications and additions to the file contributed by third parties
|
||||||
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
|
# upon. The license for this file, and modifications and additions to the
|
||||||
|
# file, is the same license as for the pristine package itself (unless the
|
||||||
|
# license for the pristine package is not an Open Source License, in which
|
||||||
|
# case the license is the MIT License). An "Open Source License" is a
|
||||||
|
# license that conforms to the Open Source Definition (Version 1.9)
|
||||||
|
# published by the Open Source Initiative.
|
||||||
|
|
||||||
|
# Please submit bugfixes or comments via https://bugs.opensuse.org/
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
%{?sle15_python_module_pythons}
|
||||||
|
Name: python-configobj
|
||||||
|
Version: 5.0.9
|
||||||
|
Release: 0
|
||||||
|
Summary: Config file reading, writing and validation
|
||||||
|
License: BSD-3-Clause
|
||||||
|
Group: Development/Languages/Python
|
||||||
|
URL: https://github.com/DiffSK/configobj
|
||||||
|
# No tests in PyPI sdist
|
||||||
|
Source: https://github.com/DiffSK/configobj/archive/refs/tags/v%{version}.tar.gz#/configobj-%{version}-gh.tar.gz
|
||||||
|
BuildRequires: %{python_module pip}
|
||||||
|
BuildRequires: %{python_module setuptools}
|
||||||
|
BuildRequires: %{python_module wheel}
|
||||||
|
BuildRequires: fdupes
|
||||||
|
BuildRequires: python-rpm-macros
|
||||||
|
BuildArch: noarch
|
||||||
|
# SECTION test
|
||||||
|
BuildRequires: %{python_module pytest}
|
||||||
|
# /SECTION
|
||||||
|
%python_subpackages
|
||||||
|
|
||||||
|
%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.
|
||||||
|
It has lots of other features though:
|
||||||
|
|
||||||
|
* Nested sections (subsections), to any level
|
||||||
|
* List values
|
||||||
|
* Multiple line values
|
||||||
|
* Full Unicode support
|
||||||
|
* String interpolation (substitution)
|
||||||
|
* Integrated with a powerful validation system
|
||||||
|
- 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
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup -p1 -n configobj-%{version}
|
||||||
|
|
||||||
|
%build
|
||||||
|
%pyproject_wheel
|
||||||
|
|
||||||
|
%install
|
||||||
|
%pyproject_install
|
||||||
|
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||||
|
|
||||||
|
%check
|
||||||
|
%pytest
|
||||||
|
|
||||||
|
%files %{python_files}
|
||||||
|
%{python_sitelib}/configobj
|
||||||
|
%{python_sitelib}/validate
|
||||||
|
%{python_sitelib}/configobj-%{version}.dist-info
|
||||||
|
|
||||||
|
%changelog
|
379
remove_six.patch
Normal file
379
remove_six.patch
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
https://github.com/DiffSK/configobj/issues/239
|
||||||
|
|
||||||
|
Index: configobj-5.0.8/setup.py
|
||||||
|
===================================================================
|
||||||
|
--- configobj-5.0.8.orig/setup.py
|
||||||
|
+++ configobj-5.0.8/setup.py
|
||||||
|
@@ -41,7 +41,6 @@ DESCRIPTION = 'Config file reading, writ
|
||||||
|
URL = 'https://github.com/DiffSK/configobj'
|
||||||
|
|
||||||
|
REQUIRES = """
|
||||||
|
- six
|
||||||
|
"""
|
||||||
|
|
||||||
|
VERSION = ''
|
||||||
|
Index: configobj-5.0.8/src/configobj/__init__.py
|
||||||
|
===================================================================
|
||||||
|
--- configobj-5.0.8.orig/src/configobj/__init__.py
|
||||||
|
+++ configobj-5.0.8/src/configobj/__init__.py
|
||||||
|
@@ -19,7 +19,6 @@ import sys
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -553,11 +552,11 @@ class Section(dict):
|
||||||
|
"""Fetch the item and do string interpolation."""
|
||||||
|
val = dict.__getitem__(self, key)
|
||||||
|
if self.main.interpolation:
|
||||||
|
- if isinstance(val, six.string_types):
|
||||||
|
+ if isinstance(val, str):
|
||||||
|
return self._interpolate(key, val)
|
||||||
|
if isinstance(val, list):
|
||||||
|
def _check(entry):
|
||||||
|
- if isinstance(entry, six.string_types):
|
||||||
|
+ if isinstance(entry, str):
|
||||||
|
return self._interpolate(key, entry)
|
||||||
|
return entry
|
||||||
|
new = [_check(entry) for entry in val]
|
||||||
|
@@ -580,7 +579,7 @@ class Section(dict):
|
||||||
|
``unrepr`` must be set when setting a value to a dictionary, without
|
||||||
|
creating a new sub-section.
|
||||||
|
"""
|
||||||
|
- if not isinstance(key, six.string_types):
|
||||||
|
+ if not isinstance(key, str):
|
||||||
|
raise ValueError('The key "%s" is not a string.' % key)
|
||||||
|
|
||||||
|
# add the comment
|
||||||
|
@@ -614,11 +613,11 @@ class Section(dict):
|
||||||
|
if key not in self:
|
||||||
|
self.scalars.append(key)
|
||||||
|
if not self.main.stringify:
|
||||||
|
- if isinstance(value, six.string_types):
|
||||||
|
+ if isinstance(value, str):
|
||||||
|
pass
|
||||||
|
elif isinstance(value, (list, tuple)):
|
||||||
|
for entry in value:
|
||||||
|
- if not isinstance(entry, six.string_types):
|
||||||
|
+ if not isinstance(entry, str):
|
||||||
|
raise TypeError('Value is not a string "%s".' % entry)
|
||||||
|
else:
|
||||||
|
raise TypeError('Value is not a string "%s".' % value)
|
||||||
|
@@ -959,7 +958,7 @@ class Section(dict):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
- if not isinstance(val, six.string_types):
|
||||||
|
+ if not isinstance(val, str):
|
||||||
|
# TODO: Why do we raise a KeyError here?
|
||||||
|
raise KeyError()
|
||||||
|
else:
|
||||||
|
@@ -1230,7 +1229,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
|
||||||
|
def _load(self, infile, configspec):
|
||||||
|
- if isinstance(infile, six.string_types):
|
||||||
|
+ if isinstance(infile, str):
|
||||||
|
self.filename = infile
|
||||||
|
if os.path.isfile(infile):
|
||||||
|
with open(infile, 'rb') as h:
|
||||||
|
@@ -1298,7 +1297,7 @@ class ConfigObj(Section):
|
||||||
|
break
|
||||||
|
break
|
||||||
|
|
||||||
|
- assert all(isinstance(line, six.string_types) for line in content), repr(content)
|
||||||
|
+ assert all(isinstance(line, str) for line in content), repr(content)
|
||||||
|
content = [line.rstrip('\r\n') for line in content]
|
||||||
|
|
||||||
|
self._parse(content)
|
||||||
|
@@ -1403,7 +1402,7 @@ class ConfigObj(Section):
|
||||||
|
else:
|
||||||
|
line = infile
|
||||||
|
|
||||||
|
- if isinstance(line, six.text_type):
|
||||||
|
+ if isinstance(line, str):
|
||||||
|
# it's already decoded and there's no need to do anything
|
||||||
|
# else, just use the _decode utility method to handle
|
||||||
|
# listifying appropriately
|
||||||
|
@@ -1448,7 +1447,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
# No encoding specified - so we need to check for UTF8/UTF16
|
||||||
|
for BOM, (encoding, final_encoding) in list(BOMS.items()):
|
||||||
|
- if not isinstance(line, six.binary_type) or not line.startswith(BOM):
|
||||||
|
+ if not isinstance(line, bytes) or not line.startswith(BOM):
|
||||||
|
# didn't specify a BOM, or it's not a bytestring
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
@@ -1464,9 +1463,9 @@ class ConfigObj(Section):
|
||||||
|
else:
|
||||||
|
infile = newline
|
||||||
|
# UTF-8
|
||||||
|
- if isinstance(infile, six.text_type):
|
||||||
|
+ if isinstance(infile, str):
|
||||||
|
return infile.splitlines(True)
|
||||||
|
- elif isinstance(infile, six.binary_type):
|
||||||
|
+ elif isinstance(infile, bytes):
|
||||||
|
return infile.decode('utf-8').splitlines(True)
|
||||||
|
else:
|
||||||
|
return self._decode(infile, 'utf-8')
|
||||||
|
@@ -1474,12 +1473,8 @@ class ConfigObj(Section):
|
||||||
|
return self._decode(infile, encoding)
|
||||||
|
|
||||||
|
|
||||||
|
- 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):
|
||||||
|
+ if isinstance(infile, bytes):
|
||||||
|
return infile.decode('utf-8').splitlines(True)
|
||||||
|
else:
|
||||||
|
return self._decode(infile, 'utf-8')
|
||||||
|
@@ -1487,7 +1482,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
def _a_to_u(self, aString):
|
||||||
|
"""Decode ASCII strings to unicode if a self.encoding is specified."""
|
||||||
|
- if isinstance(aString, six.binary_type) and self.encoding:
|
||||||
|
+ if isinstance(aString, bytes) and self.encoding:
|
||||||
|
return aString.decode(self.encoding)
|
||||||
|
else:
|
||||||
|
return aString
|
||||||
|
@@ -1499,9 +1494,9 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
if is a string, it also needs converting to a list.
|
||||||
|
"""
|
||||||
|
- if isinstance(infile, six.string_types):
|
||||||
|
+ if isinstance(infile, str):
|
||||||
|
return infile.splitlines(True)
|
||||||
|
- if isinstance(infile, six.binary_type):
|
||||||
|
+ if isinstance(infile, bytes):
|
||||||
|
# NOTE: Could raise a ``UnicodeDecodeError``
|
||||||
|
if encoding:
|
||||||
|
return infile.decode(encoding).splitlines(True)
|
||||||
|
@@ -1510,7 +1505,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
if encoding:
|
||||||
|
for i, line in enumerate(infile):
|
||||||
|
- if isinstance(line, six.binary_type):
|
||||||
|
+ if isinstance(line, bytes):
|
||||||
|
# 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``
|
||||||
|
@@ -1520,7 +1515,7 @@ class ConfigObj(Section):
|
||||||
|
|
||||||
|
def _decode_element(self, line):
|
||||||
|
"""Decode element to unicode if necessary."""
|
||||||
|
- if isinstance(line, six.binary_type) and self.default_encoding:
|
||||||
|
+ if isinstance(line, bytes) and self.default_encoding:
|
||||||
|
return line.decode(self.default_encoding)
|
||||||
|
else:
|
||||||
|
return line
|
||||||
|
@@ -1532,7 +1527,7 @@ class ConfigObj(Section):
|
||||||
|
Used by ``stringify`` within validate, to turn non-string values
|
||||||
|
into strings.
|
||||||
|
"""
|
||||||
|
- if not isinstance(value, six.string_types):
|
||||||
|
+ if not isinstance(value, str):
|
||||||
|
# intentially 'str' because it's just whatever the "normal"
|
||||||
|
# string type is for the python version we're dealing with
|
||||||
|
return str(value)
|
||||||
|
@@ -1786,7 +1781,7 @@ class ConfigObj(Section):
|
||||||
|
return self._quote(value[0], multiline=False) + ','
|
||||||
|
return ', '.join([self._quote(val, multiline=False)
|
||||||
|
for val in value])
|
||||||
|
- if not isinstance(value, six.string_types):
|
||||||
|
+ if not isinstance(value, str):
|
||||||
|
if self.stringify:
|
||||||
|
# intentially 'str' because it's just whatever the "normal"
|
||||||
|
# string type is for the python version we're dealing with
|
||||||
|
@@ -2111,7 +2106,7 @@ class ConfigObj(Section):
|
||||||
|
if not output.endswith(newline):
|
||||||
|
output += newline
|
||||||
|
|
||||||
|
- if isinstance(output, six.binary_type):
|
||||||
|
+ if isinstance(output, bytes):
|
||||||
|
output_bytes = output
|
||||||
|
else:
|
||||||
|
output_bytes = output.encode(self.encoding or
|
||||||
|
@@ -2353,7 +2348,7 @@ class ConfigObj(Section):
|
||||||
|
This method raises a ``ReloadError`` if the ConfigObj doesn't have
|
||||||
|
a filename attribute pointing to a file.
|
||||||
|
"""
|
||||||
|
- if not isinstance(self.filename, six.string_types):
|
||||||
|
+ if not isinstance(self.filename, str):
|
||||||
|
raise ReloadError()
|
||||||
|
|
||||||
|
filename = self.filename
|
||||||
|
Index: configobj-5.0.8/src/tests/test_configobj.py
|
||||||
|
===================================================================
|
||||||
|
--- configobj-5.0.8.orig/src/tests/test_configobj.py
|
||||||
|
+++ configobj-5.0.8/src/tests/test_configobj.py
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
+import io
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
@@ -8,7 +9,6 @@ from warnings import catch_warnings
|
||||||
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
-import six
|
||||||
|
|
||||||
|
import configobj as co
|
||||||
|
from configobj import ConfigObj, flatten_errors, ReloadError, DuplicateError, MissingInterpolationOption, InterpolationLoopError, ConfigObjError
|
||||||
|
@@ -36,13 +36,13 @@ def cfg_lines(config_string_representati
|
||||||
|
'{!r}'.format(config_string_representation))
|
||||||
|
|
||||||
|
first_content = lines[line_no_with_content]
|
||||||
|
- if isinstance(first_content, six.binary_type):
|
||||||
|
+ if isinstance(first_content, bytes):
|
||||||
|
first_content = first_content.decode('utf-8')
|
||||||
|
ws_chars = len(re.search('^(\s*)', first_content).group(1))
|
||||||
|
|
||||||
|
def yield_stringified_line():
|
||||||
|
for line in lines:
|
||||||
|
- if isinstance(line, six.binary_type):
|
||||||
|
+ if isinstance(line, bytes):
|
||||||
|
yield line.decode('utf-8')
|
||||||
|
else:
|
||||||
|
yield line
|
||||||
|
@@ -70,7 +70,7 @@ def cfg_contents(request):
|
||||||
|
|
||||||
|
with NamedTemporaryFile(delete=False, mode='wb') as cfg_file:
|
||||||
|
for line in lines:
|
||||||
|
- if isinstance(line, six.binary_type):
|
||||||
|
+ if isinstance(line, bytes):
|
||||||
|
cfg_file.write(line + os.linesep.encode('utf-8'))
|
||||||
|
else:
|
||||||
|
cfg_file.write((line + os.linesep).encode('utf-8'))
|
||||||
|
@@ -186,11 +186,7 @@ class TestEncoding(object):
|
||||||
|
|
||||||
|
c = ConfigObj(cfg, encoding='utf8')
|
||||||
|
|
||||||
|
- if six.PY2:
|
||||||
|
- assert not isinstance(c['test'], str)
|
||||||
|
- assert isinstance(c['test'], unicode)
|
||||||
|
- else:
|
||||||
|
- assert isinstance(c['test'], str)
|
||||||
|
+ assert isinstance(c['test'], str)
|
||||||
|
|
||||||
|
|
||||||
|
#issue #18
|
||||||
|
@@ -198,11 +194,7 @@ class TestEncoding(object):
|
||||||
|
cfg = cfg_contents(b"test = some string")
|
||||||
|
|
||||||
|
c = ConfigObj(cfg)
|
||||||
|
- if six.PY2:
|
||||||
|
- assert isinstance(c['test'], str)
|
||||||
|
- assert not isinstance(c['test'], unicode)
|
||||||
|
- else:
|
||||||
|
- assert isinstance(c['test'], str)
|
||||||
|
+ assert isinstance(c['test'], str)
|
||||||
|
|
||||||
|
#issue #44
|
||||||
|
def test_that_encoding_using_list_of_strings(self):
|
||||||
|
@@ -210,11 +202,7 @@ class TestEncoding(object):
|
||||||
|
|
||||||
|
c = ConfigObj(cfg, encoding='utf8')
|
||||||
|
|
||||||
|
- if six.PY2:
|
||||||
|
- assert isinstance(c['test'], unicode)
|
||||||
|
- assert not isinstance(c['test'], str)
|
||||||
|
- else:
|
||||||
|
- assert isinstance(c['test'], str)
|
||||||
|
+ assert isinstance(c['test'], str)
|
||||||
|
|
||||||
|
assert c['test'] == '\U0001f41c'
|
||||||
|
|
||||||
|
@@ -223,7 +211,7 @@ class TestEncoding(object):
|
||||||
|
c = cfg_contents(ant_cfg)
|
||||||
|
cfg = ConfigObj(c, encoding='utf-8')
|
||||||
|
|
||||||
|
- assert isinstance(cfg['tags']['bug']['translated'], six.text_type)
|
||||||
|
+ assert isinstance(cfg['tags']['bug']['translated'], str)
|
||||||
|
|
||||||
|
#issue #44 and #55
|
||||||
|
def test_encoding_in_config_files(self, request, ant_cfg):
|
||||||
|
@@ -233,7 +221,7 @@ class TestEncoding(object):
|
||||||
|
request.addfinalizer(lambda : os.unlink(cfg_file.name))
|
||||||
|
|
||||||
|
cfg = ConfigObj(cfg_file.name, encoding='utf-8')
|
||||||
|
- assert isinstance(cfg['tags']['bug']['translated'], six.text_type)
|
||||||
|
+ assert isinstance(cfg['tags']['bug']['translated'], str)
|
||||||
|
cfg.write()
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
@@ -500,7 +488,7 @@ def test_unicode_handling():
|
||||||
|
'section': {'test': 'test', 'test2': 'test2'}}
|
||||||
|
uc = ConfigObj(u, encoding='utf_8', default_encoding='latin-1')
|
||||||
|
assert uc.BOM
|
||||||
|
- assert isinstance(uc['test1'], six.text_type)
|
||||||
|
+ assert isinstance(uc['test1'], str)
|
||||||
|
assert uc.encoding == 'utf_8'
|
||||||
|
assert uc.newlines == '\n'
|
||||||
|
assert len(uc.write()) == 13
|
||||||
|
@@ -508,14 +496,14 @@ def test_unicode_handling():
|
||||||
|
a_list = uc.write()
|
||||||
|
assert 'latin1' in str(a_list)
|
||||||
|
assert len(a_list) == 14
|
||||||
|
- assert isinstance(a_list[0], six.binary_type)
|
||||||
|
+ assert isinstance(a_list[0], bytes)
|
||||||
|
assert a_list[0].startswith(BOM_UTF8)
|
||||||
|
|
||||||
|
u = u_base.replace('\n', '\r\n').encode('utf-8').splitlines(True)
|
||||||
|
uc = ConfigObj(u)
|
||||||
|
assert uc.newlines == '\r\n'
|
||||||
|
uc.newlines = '\r'
|
||||||
|
- file_like = six.BytesIO()
|
||||||
|
+ file_like = io.BytesIO()
|
||||||
|
uc.write(file_like)
|
||||||
|
file_like.seek(0)
|
||||||
|
uc2 = ConfigObj(file_like)
|
||||||
|
@@ -723,7 +711,7 @@ class TestSectionBehavior(object):
|
||||||
|
val = section[key]
|
||||||
|
newkey = key.replace('XXXX', 'CLIENT1')
|
||||||
|
section.rename(key, newkey)
|
||||||
|
- if isinstance(val, six.string_types):
|
||||||
|
+ if isinstance(val, str):
|
||||||
|
val = val.replace('XXXX', 'CLIENT1')
|
||||||
|
section[newkey] = val
|
||||||
|
|
||||||
|
@@ -811,7 +799,7 @@ class TestReloading(object):
|
||||||
|
return content
|
||||||
|
|
||||||
|
def test_handle_no_filename(self):
|
||||||
|
- for bad_args in ([six.BytesIO()], [], [[]]):
|
||||||
|
+ for bad_args in ([io.BytesIO()], [], [[]]):
|
||||||
|
cfg = ConfigObj(*bad_args)
|
||||||
|
with pytest.raises(ReloadError) as excinfo:
|
||||||
|
cfg.reload()
|
||||||
|
@@ -1264,21 +1252,21 @@ class TestEdgeCasesWhenWritingOut(object
|
||||||
|
def test_newline_terminated(self, empty_cfg):
|
||||||
|
empty_cfg.newlines = '\n'
|
||||||
|
empty_cfg['a'] = 'b'
|
||||||
|
- collector = six.BytesIO()
|
||||||
|
+ collector = io.BytesIO()
|
||||||
|
empty_cfg.write(collector)
|
||||||
|
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.BytesIO()
|
||||||
|
+ collector = io.BytesIO()
|
||||||
|
empty_cfg.write(collector)
|
||||||
|
assert collector.getvalue() == b'"#a" = "b # something"\n'
|
||||||
|
|
||||||
|
empty_cfg = ConfigObj()
|
||||||
|
empty_cfg.newlines = '\n'
|
||||||
|
empty_cfg['a'] = 'b # something', 'c # something'
|
||||||
|
- collector = six.BytesIO()
|
||||||
|
+ collector = io.BytesIO()
|
||||||
|
empty_cfg.write(collector)
|
||||||
|
assert collector.getvalue() == b'a = "b # something", "c # something"\n'
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user