Closes #20444: Merged fix from 3.4.
This commit is contained in:
commit
ab405d5575
|
@ -277,6 +277,30 @@ def valid_ident(s):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ConvertingMixin(object):
|
||||||
|
"""For ConvertingXXX's, this mixin class provides common functions"""
|
||||||
|
|
||||||
|
def convert_with_key(self, key, value, replace=True):
|
||||||
|
result = self.configurator.convert(value)
|
||||||
|
#If the converted value is different, save for next time
|
||||||
|
if value is not result:
|
||||||
|
if replace:
|
||||||
|
self[key] = result
|
||||||
|
if type(result) in (ConvertingDict, ConvertingList,
|
||||||
|
ConvertingTuple):
|
||||||
|
result.parent = self
|
||||||
|
result.key = key
|
||||||
|
return result
|
||||||
|
|
||||||
|
def convert(self, value):
|
||||||
|
result = self.configurator.convert(value)
|
||||||
|
if value is not result:
|
||||||
|
if type(result) in (ConvertingDict, ConvertingList,
|
||||||
|
ConvertingTuple):
|
||||||
|
result.parent = self
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
# The ConvertingXXX classes are wrappers around standard Python containers,
|
# The ConvertingXXX classes are wrappers around standard Python containers,
|
||||||
# and they serve to convert any suitable values in the container. The
|
# and they serve to convert any suitable values in the container. The
|
||||||
# conversion converts base dicts, lists and tuples to their wrapped
|
# conversion converts base dicts, lists and tuples to their wrapped
|
||||||
|
@ -286,77 +310,37 @@ def valid_ident(s):
|
||||||
# Each wrapper should have a configurator attribute holding the actual
|
# Each wrapper should have a configurator attribute holding the actual
|
||||||
# configurator to use for conversion.
|
# configurator to use for conversion.
|
||||||
|
|
||||||
class ConvertingDict(dict):
|
class ConvertingDict(dict, ConvertingMixin):
|
||||||
"""A converting dictionary wrapper."""
|
"""A converting dictionary wrapper."""
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
value = dict.__getitem__(self, key)
|
value = dict.__getitem__(self, key)
|
||||||
result = self.configurator.convert(value)
|
return self.convert_with_key(key, value)
|
||||||
#If the converted value is different, save for next time
|
|
||||||
if value is not result:
|
|
||||||
self[key] = result
|
|
||||||
if type(result) in (ConvertingDict, ConvertingList,
|
|
||||||
ConvertingTuple):
|
|
||||||
result.parent = self
|
|
||||||
result.key = key
|
|
||||||
return result
|
|
||||||
|
|
||||||
def get(self, key, default=None):
|
def get(self, key, default=None):
|
||||||
value = dict.get(self, key, default)
|
value = dict.get(self, key, default)
|
||||||
result = self.configurator.convert(value)
|
return self.convert_with_key(key, value)
|
||||||
#If the converted value is different, save for next time
|
|
||||||
if value is not result:
|
|
||||||
self[key] = result
|
|
||||||
if type(result) in (ConvertingDict, ConvertingList,
|
|
||||||
ConvertingTuple):
|
|
||||||
result.parent = self
|
|
||||||
result.key = key
|
|
||||||
return result
|
|
||||||
|
|
||||||
def pop(self, key, default=None):
|
def pop(self, key, default=None):
|
||||||
value = dict.pop(self, key, default)
|
value = dict.pop(self, key, default)
|
||||||
result = self.configurator.convert(value)
|
return self.convert_with_key(key, value, replace=False)
|
||||||
if value is not result:
|
|
||||||
if type(result) in (ConvertingDict, ConvertingList,
|
|
||||||
ConvertingTuple):
|
|
||||||
result.parent = self
|
|
||||||
result.key = key
|
|
||||||
return result
|
|
||||||
|
|
||||||
class ConvertingList(list):
|
class ConvertingList(list, ConvertingMixin):
|
||||||
"""A converting list wrapper."""
|
"""A converting list wrapper."""
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
value = list.__getitem__(self, key)
|
value = list.__getitem__(self, key)
|
||||||
result = self.configurator.convert(value)
|
return self.convert_with_key(key, value)
|
||||||
#If the converted value is different, save for next time
|
|
||||||
if value is not result:
|
|
||||||
self[key] = result
|
|
||||||
if type(result) in (ConvertingDict, ConvertingList,
|
|
||||||
ConvertingTuple):
|
|
||||||
result.parent = self
|
|
||||||
result.key = key
|
|
||||||
return result
|
|
||||||
|
|
||||||
def pop(self, idx=-1):
|
def pop(self, idx=-1):
|
||||||
value = list.pop(self, idx)
|
value = list.pop(self, idx)
|
||||||
result = self.configurator.convert(value)
|
return self.convert(value)
|
||||||
if value is not result:
|
|
||||||
if type(result) in (ConvertingDict, ConvertingList,
|
|
||||||
ConvertingTuple):
|
|
||||||
result.parent = self
|
|
||||||
return result
|
|
||||||
|
|
||||||
class ConvertingTuple(tuple):
|
class ConvertingTuple(tuple, ConvertingMixin):
|
||||||
"""A converting tuple wrapper."""
|
"""A converting tuple wrapper."""
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
value = tuple.__getitem__(self, key)
|
value = tuple.__getitem__(self, key)
|
||||||
result = self.configurator.convert(value)
|
# Can't replace a tuple entry.
|
||||||
if value is not result:
|
return self.convert_with_key(key, value, replace=False)
|
||||||
if type(result) in (ConvertingDict, ConvertingList,
|
|
||||||
ConvertingTuple):
|
|
||||||
result.parent = self
|
|
||||||
result.key = key
|
|
||||||
return result
|
|
||||||
|
|
||||||
class BaseConfigurator(object):
|
class BaseConfigurator(object):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue