summaryrefslogtreecommitdiff
path: root/lib/ansible/playbook/base.py
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2017-11-22 14:35:58 -0600
committerMatt Clay <matt@mystile.com>2017-11-22 12:35:58 -0800
commitd8ae4dfbf212000e238dbdd2ed9a99dd829bdc01 (patch)
tree5fb660d8ba5bd1bc34c801e7d92759de3537d1fd /lib/ansible/playbook/base.py
parent23f8833e8745f01b490a6e12dd0f3e946d89654f (diff)
downloadansible-d8ae4dfbf212000e238dbdd2ed9a99dd829bdc01.tar.gz
Adding aliases for field attributes and renaming async attribute (#33141)
* Adding aliases for field attributes and renaming async attribute As of Python 3.7, the use of async raises an error, whereas before the use of the reserved word was ignored. This adds an alias field for field attrs so that both async and async_val (interally) work. This allows us to be backwards-compatible with 3rd party plugins that may still reference Task.async, but for the core engine to work on Py3.7+. * Remove files fixed for 'async' usage from the python 3.7 skip list
Diffstat (limited to 'lib/ansible/playbook/base.py')
-rw-r--r--lib/ansible/playbook/base.py20
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/ansible/playbook/base.py b/lib/ansible/playbook/base.py
index 4a27eaea6d..4beb56f55c 100644
--- a/lib/ansible/playbook/base.py
+++ b/lib/ansible/playbook/base.py
@@ -109,6 +109,11 @@ class BaseMeta(type):
dst_dict['_valid_attrs'][attr_name] = value
dst_dict['_attributes'][attr_name] = value.default
+ if value.alias is not None:
+ dst_dict[value.alias] = property(getter, setter, deleter)
+ dst_dict['_valid_attrs'][value.alias] = value
+ dst_dict['_alias_attrs'][value.alias] = attr_name
+
def _process_parents(parents, dst_dict):
'''
Helper method which creates attributes from all parent objects
@@ -124,6 +129,7 @@ class BaseMeta(type):
# create some additional class attributes
dct['_attributes'] = dict()
dct['_valid_attrs'] = dict()
+ dct['_alias_attrs'] = dict()
# now create the attributes based on the FieldAttributes
# available, including from parent (and grandparent) objects
@@ -235,12 +241,15 @@ class Base(with_metaclass(BaseMeta, object)):
# so that certain fields can be loaded before others, if they are dependent.
for name, attr in sorted(iteritems(self._valid_attrs), key=operator.itemgetter(1)):
# copy the value over unless a _load_field method is defined
+ target_name = name
+ if name in self._alias_attrs:
+ target_name = self._alias_attrs[name]
if name in ds:
method = getattr(self, '_load_%s' % name, None)
if method:
- self._attributes[name] = method(name, ds[name])
+ self._attributes[target_name] = method(name, ds[name])
else:
- self._attributes[name] = ds[name]
+ self._attributes[target_name] = ds[name]
# run early, non-critical validation
self.validate()
@@ -279,13 +288,16 @@ class Base(with_metaclass(BaseMeta, object)):
# walk all fields in the object
for (name, attribute) in iteritems(self._valid_attrs):
+ if name in self._alias_attrs:
+ name = self._alias_attrs[name]
+
# run validator only if present
method = getattr(self, '_validate_%s' % name, None)
if method:
method(attribute, name, getattr(self, name))
else:
# and make sure the attribute is of the type it should be
- value = getattr(self, name)
+ value = self._attributes[name]
if value is not None:
if attribute.isa == 'string' and isinstance(value, (list, dict)):
raise AnsibleParserError(
@@ -314,6 +326,8 @@ class Base(with_metaclass(BaseMeta, object)):
new_me = self.__class__()
for name in self._valid_attrs.keys():
+ if name in self._alias_attrs:
+ continue
new_me._attributes[name] = shallowcopy(self._attributes[name])
new_me._loader = self._loader