mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Patch #1371075: Make ConfigParser accept optional dict type
for ordering, sorting, etc.
This commit is contained in:
		
							parent
							
								
									046c4d13be
								
							
						
					
					
						commit
						a00bcac003
					
				
					 4 changed files with 68 additions and 11 deletions
				
			
		|  | @ -48,11 +48,20 @@ Default values can be specified by passing them into the | |||
| may be passed into the \method{get()} method which will override all | ||||
| others. | ||||
| 
 | ||||
| \begin{classdesc}{RawConfigParser}{\optional{defaults}} | ||||
| Sections are normally stored in a builtin dictionary. An alternative | ||||
| dictionary type can be passed to the \class{ConfigParser} constructor. | ||||
| For example, if a dictionary type is passed that sorts is keys, | ||||
| the sections will be sorted on write-back, as will be the keys within | ||||
| each section. | ||||
| 
 | ||||
| \begin{classdesc}{RawConfigParser}{\optional{defaults\optional{, dict_type}}} | ||||
| The basic configuration object.  When \var{defaults} is given, it is | ||||
| initialized into the dictionary of intrinsic defaults.  This class | ||||
| does not support the magical interpolation behavior. | ||||
| initialized into the dictionary of intrinsic defaults.  When \var{dict_type} | ||||
| is given, it will be used to create the dictionary objects for the list | ||||
| of sections, for the options within a section, and for the default values. | ||||
| This class does not support the magical interpolation behavior. | ||||
| \versionadded{2.3} | ||||
| \versionchanged{\var{dict_type} was added}[2.6] | ||||
| \end{classdesc} | ||||
| 
 | ||||
| \begin{classdesc}{ConfigParser}{\optional{defaults}} | ||||
|  |  | |||
|  | @ -199,11 +199,11 @@ def __init__(self, filename, lineno, line): | |||
|         self.line = line | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class RawConfigParser: | ||||
|     def __init__(self, defaults=None): | ||||
|         self._sections = {} | ||||
|         self._defaults = {} | ||||
|     def __init__(self, defaults=None, dict_type=dict): | ||||
|         self._dict = dict_type | ||||
|         self._sections = self._dict() | ||||
|         self._defaults = self._dict() | ||||
|         if defaults: | ||||
|             for key, value in defaults.items(): | ||||
|                 self._defaults[self.optionxform(key)] = value | ||||
|  | @ -224,7 +224,7 @@ def add_section(self, section): | |||
|         """ | ||||
|         if section in self._sections: | ||||
|             raise DuplicateSectionError(section) | ||||
|         self._sections[section] = {} | ||||
|         self._sections[section] = self._dict() | ||||
| 
 | ||||
|     def has_section(self, section): | ||||
|         """Indicate whether the named section is present in the configuration. | ||||
|  | @ -307,7 +307,7 @@ def items(self, section): | |||
|         except KeyError: | ||||
|             if section != DEFAULTSECT: | ||||
|                 raise NoSectionError(section) | ||||
|             d2 = {} | ||||
|             d2 = self._dict() | ||||
|         d = self._defaults.copy() | ||||
|         d.update(d2) | ||||
|         if "__name__" in d: | ||||
|  | @ -453,7 +453,8 @@ def _read(self, fp, fpname): | |||
|                     elif sectname == DEFAULTSECT: | ||||
|                         cursect = self._defaults | ||||
|                     else: | ||||
|                         cursect = {'__name__': sectname} | ||||
|                         cursect = self._dict() | ||||
|                         cursect['__name__'] = sectname | ||||
|                         self._sections[sectname] = cursect | ||||
|                     # So sections can't start with a continuation line | ||||
|                     optname = None | ||||
|  |  | |||
|  | @ -1,9 +1,29 @@ | |||
| import ConfigParser | ||||
| import StringIO | ||||
| import unittest | ||||
| import UserDict | ||||
| 
 | ||||
| from test import test_support | ||||
| 
 | ||||
| class SortedDict(UserDict.UserDict): | ||||
|     def items(self): | ||||
|         result = self.data.items() | ||||
|         result.sort() | ||||
|         return result | ||||
| 
 | ||||
|     def keys(self): | ||||
|         result = self.data.keys() | ||||
|         result.sort() | ||||
|         return result | ||||
|      | ||||
|     def values(self): | ||||
|         result = self.items() | ||||
|         return [i[1] for i in values] | ||||
| 
 | ||||
|     def iteritems(self): return iter(self.items()) | ||||
|     def iterkeys(self): return iter(self.keys()) | ||||
|     __iter__ = iterkeys | ||||
|     def itervalues(self): return iter(self.values()) | ||||
| 
 | ||||
| class TestCaseBase(unittest.TestCase): | ||||
|     def newconfig(self, defaults=None): | ||||
|  | @ -414,12 +434,36 @@ def test_set_nonstring_types(self): | |||
|         self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0) | ||||
|         self.assertRaises(TypeError, cf.set, "sect", "option2", object()) | ||||
| 
 | ||||
| class SortedTestCase(RawConfigParserTestCase): | ||||
|     def newconfig(self, defaults=None): | ||||
|         self.cf = self.config_class(defaults=defaults, dict_type=SortedDict) | ||||
|         return self.cf | ||||
| 
 | ||||
|     def test_sorted(self): | ||||
|         self.fromstring("[b]\n" | ||||
|                         "o4=1\n" | ||||
|                         "o3=2\n" | ||||
|                         "o2=3\n" | ||||
|                         "o1=4\n" | ||||
|                         "[a]\n" | ||||
|                         "k=v\n")         | ||||
|         output = StringIO.StringIO() | ||||
|         self.cf.write(output) | ||||
|         self.assertEquals(output.getvalue(), | ||||
|                           "[a]\n" | ||||
|                           "k = v\n\n"        | ||||
|                           "[b]\n" | ||||
|                           "o1 = 4\n" | ||||
|                           "o2 = 3\n" | ||||
|                           "o3 = 2\n" | ||||
|                           "o4 = 1\n\n") | ||||
| 
 | ||||
| def test_main(): | ||||
|     test_support.run_unittest( | ||||
|         ConfigParserTestCase, | ||||
|         RawConfigParserTestCase, | ||||
|         SafeConfigParserTestCase | ||||
|         SafeConfigParserTestCase, | ||||
|         SortedTestCase | ||||
|     ) | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|  |  | |||
|  | @ -101,6 +101,9 @@ Core and builtins | |||
| Library | ||||
| ------- | ||||
| 
 | ||||
| - Patch #1371075: Make ConfigParser accept optional dict type | ||||
|   for ordering, sorting, etc. | ||||
| 
 | ||||
| - Bug #1563807: _ctypes built on AIX fails with ld ffi error. | ||||
| 
 | ||||
| - Bug #1598620: A ctypes Structure cannot contain itself. | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Martin v. Löwis
						Martin v. Löwis