Move AnsibleBaseBaseYAMLObject's position_info into a property

pull/10596/merge
Toshio Kuratomi 10 years ago
parent 05f1bed12b
commit e697de6076

@ -92,7 +92,7 @@ class AnsibleError(Exception):
error_message = '' error_message = ''
try: try:
(src_file, line_number, col_number) = self._obj.get_position_info() (src_file, line_number, col_number) = self._obj.ansible_pos
error_message += YAML_POSITION_DETAILS % (src_file, line_number, col_number) error_message += YAML_POSITION_DETAILS % (src_file, line_number, col_number)
if src_file not in ('<string>', '<unicode>') and self._show_content: if src_file not in ('<string>', '<unicode>') and self._show_content:
(target_line, prev_line) = self._get_error_lines_from_file(src_file, line_number - 1) (target_line, prev_line) = self._get_error_lines_from_file(src_file, line_number - 1)

@ -146,7 +146,7 @@ class DataLoader():
err_obj = None err_obj = None
if hasattr(yaml_exc, 'problem_mark'): if hasattr(yaml_exc, 'problem_mark'):
err_obj = AnsibleBaseYAMLObject() err_obj = AnsibleBaseYAMLObject()
err_obj.set_position_info(file_name, yaml_exc.problem_mark.line + 1, yaml_exc.problem_mark.column + 1) err_obj.ansible_pos = (file_name, yaml_exc.problem_mark.line + 1, yaml_exc.problem_mark.column + 1)
raise AnsibleParserError(YAML_SYNTAX_ERROR, obj=err_obj, show_content=show_content) raise AnsibleParserError(YAML_SYNTAX_ERROR, obj=err_obj, show_content=show_content)

@ -33,23 +33,20 @@ class AnsibleConstructor(Constructor):
yield data yield data
value = self.construct_mapping(node) value = self.construct_mapping(node)
data.update(value) data.update(value)
data._line_number = value._line_number data.ansible_pos = value.ansible_pos
data._column_number = value._column_number
data._data_source = value._data_source
def construct_mapping(self, node, deep=False): def construct_mapping(self, node, deep=False):
ret = AnsibleMapping(super(Constructor, self).construct_mapping(node, deep)) ret = AnsibleMapping(super(Constructor, self).construct_mapping(node, deep))
ret._line_number = node.__line__
ret._column_number = node.__column__
# in some cases, we may have pre-read the data and then # in some cases, we may have pre-read the data and then
# passed it to the load() call for YAML, in which case we # passed it to the load() call for YAML, in which case we
# want to override the default datasource (which would be # want to override the default datasource (which would be
# '<string>') to the actual filename we read in # '<string>') to the actual filename we read in
if self._ansible_file_name: if self._ansible_file_name:
ret._data_source = self._ansible_file_name data_source = self._ansible_file_name
else: else:
ret._data_source = node.__datasource__ data_source = node.__datasource__
ret.ansible_pos = (data_source, node.__line__, node.__column__)
return ret return ret
@ -58,16 +55,15 @@ class AnsibleConstructor(Constructor):
# to always return unicode objects # to always return unicode objects
value = self.construct_scalar(node) value = self.construct_scalar(node)
value = to_unicode(value) value = to_unicode(value)
data = AnsibleUnicode(self.construct_scalar(node)) ret = AnsibleUnicode(self.construct_scalar(node))
data._line_number = node.__line__
data._column_number = node.__column__
if self._ansible_file_name: if self._ansible_file_name:
data._data_source = self._ansible_file_name data_source = self._ansible_file_name
else: else:
data._data_source = node.__datasource__ data_source = node.__datasource__
ret.ansible_pos = (data_source, node.__line__, node.__column__)
return data return ret
AnsibleConstructor.add_constructor( AnsibleConstructor.add_constructor(
u'tag:yaml.org,2002:map', u'tag:yaml.org,2002:map',

@ -29,22 +29,19 @@ class AnsibleBaseYAMLObject:
_line_number = 0 _line_number = 0
_column_number = 0 _column_number = 0
def get_position_info(self): def _get_ansible_position(self):
return (self._data_source, self._line_number, self._column_number) return (self._data_source, self._line_number, self._column_number)
def set_position_info(self, src, line, col): def _set_ansible_position(self, obj):
try:
(src, line, col) = obj
except (TypeError, ValueError):
raise AssertionError('ansible_pos can only be set with a tuple/list of three values: source, line number, column number')
self._data_source = src self._data_source = src
self._line_number = line self._line_number = line
self._column_number = col self._column_number = col
def copy_position_info(self, obj): ansible_pos = property(_get_ansible_position, _set_ansible_position)
''' copies the position info from another object '''
assert isinstance(obj, AnsibleBaseYAMLObject)
(src, line, col) = obj.get_position_info()
self._data_source = src
self._line_number = line
self._column_number = col
class AnsibleMapping(AnsibleBaseYAMLObject, dict): class AnsibleMapping(AnsibleBaseYAMLObject, dict):
''' sub class for dictionaries ''' ''' sub class for dictionaries '''

@ -74,7 +74,7 @@ def load_list_of_tasks(ds, block=None, role=None, task_include=None, use_handler
#if 'include' in task: #if 'include' in task:
# cur_basedir = None # cur_basedir = None
# if isinstance(task, AnsibleBaseYAMLObject) and loader: # if isinstance(task, AnsibleBaseYAMLObject) and loader:
# pos_info = task.get_position_info() # pos_info = task.ansible_pos
# new_basedir = os.path.dirname(pos_info[0]) # new_basedir = os.path.dirname(pos_info[0])
# cur_basedir = loader.get_basedir() # cur_basedir = loader.get_basedir()
# loader.set_basedir(new_basedir) # loader.set_basedir(new_basedir)

@ -80,7 +80,7 @@ class PlaybookInclude(Base):
# items reduced to a standard structure # items reduced to a standard structure
new_ds = AnsibleMapping() new_ds = AnsibleMapping()
if isinstance(ds, AnsibleBaseYAMLObject): if isinstance(ds, AnsibleBaseYAMLObject):
new_ds.copy_position_info(ds) new_ds.ansible_pos = ds.ansible_pos
for (k,v) in ds.iteritems(): for (k,v) in ds.iteritems():
if k == 'include': if k == 'include':

@ -66,7 +66,7 @@ class RoleDefinition(Base, Become, Conditional, Taggable):
# can preserve file:line:column information if it exists # can preserve file:line:column information if it exists
new_ds = AnsibleMapping() new_ds = AnsibleMapping()
if isinstance(ds, AnsibleBaseYAMLObject): if isinstance(ds, AnsibleBaseYAMLObject):
new_ds.copy_position_info(ds) new_ds.ansible_pos = ds.ansible_pos
# first we pull the role name out of the data structure, # first we pull the role name out of the data structure,
# and then use that to determine the role path (which may # and then use that to determine the role path (which may

@ -159,7 +159,7 @@ class Task(Base, Conditional, Taggable, Become):
# attributes of the task class # attributes of the task class
new_ds = AnsibleMapping() new_ds = AnsibleMapping()
if isinstance(ds, AnsibleBaseYAMLObject): if isinstance(ds, AnsibleBaseYAMLObject):
new_ds.copy_position_info(ds) new_ds.ansible_pos = ds.ansible_pos
# use the args parsing class to determine the action, args, # use the args parsing class to determine the action, args,
# and the delegate_to value from the various possible forms # and the delegate_to value from the various possible forms

@ -44,9 +44,7 @@ class TestErrors(unittest.TestCase):
@patch.object(AnsibleError, '_get_error_lines_from_file') @patch.object(AnsibleError, '_get_error_lines_from_file')
def test_error_with_object(self, mock_method): def test_error_with_object(self, mock_method):
self.obj._data_source = 'foo.yml' self.obj.ansible_pos = ('foo.yml', 1, 1)
self.obj._line_number = 1
self.obj._column_number = 1
mock_method.return_value = ('this is line 1\n', '') mock_method.return_value = ('this is line 1\n', '')
e = AnsibleError(self.message, self.obj) e = AnsibleError(self.message, self.obj)
@ -59,16 +57,12 @@ class TestErrors(unittest.TestCase):
with patch('{0}.open'.format(BUILTINS), m): with patch('{0}.open'.format(BUILTINS), m):
# this line will be found in the file # this line will be found in the file
self.obj._data_source = 'foo.yml' self.obj.ansible_pos = ('foo.yml', 1, 1)
self.obj._line_number = 1
self.obj._column_number = 1
e = AnsibleError(self.message, self.obj) e = AnsibleError(self.message, self.obj)
self.assertEqual(e.message, "ERROR! This is the error message\n\nThe error appears to have been in 'foo.yml': line 1, column 1, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\nthis is line 1\n^ here\n") self.assertEqual(e.message, "ERROR! This is the error message\n\nThe error appears to have been in 'foo.yml': line 1, column 1, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\nthis is line 1\n^ here\n")
# this line will not be found, as it is out of the index range # this line will not be found, as it is out of the index range
self.obj._data_source = 'foo.yml' self.obj.ansible_pos = ('foo.yml', 2, 1)
self.obj._line_number = 2
self.obj._column_number = 1
e = AnsibleError(self.message, self.obj) e = AnsibleError(self.message, self.obj)
self.assertEqual(e.message, "ERROR! This is the error message\n\nThe error appears to have been in 'foo.yml': line 2, column 1, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\n(specified line no longer in file, maybe it changed?)") self.assertEqual(e.message, "ERROR! This is the error message\n\nThe error appears to have been in 'foo.yml': line 2, column 1, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\n(specified line no longer in file, maybe it changed?)")

@ -54,9 +54,7 @@ class TestAnsibleLoaderBasic(unittest.TestCase):
self.assertEqual(data, u'Ansible') self.assertEqual(data, u'Ansible')
self.assertIsInstance(data, unicode) self.assertIsInstance(data, unicode)
self.assertEqual(data._line_number, 2) self.assertEqual(data.ansible_pos, ('myfile.yml', 2, 17))
self.assertEqual(data._column_number, 17)
self.assertEqual(data._data_source, 'myfile.yml')
def test_parse_utf8_string(self): def test_parse_utf8_string(self):
stream = StringIO(""" stream = StringIO("""
@ -67,9 +65,7 @@ class TestAnsibleLoaderBasic(unittest.TestCase):
self.assertEqual(data, u'Cafè Eñyei') self.assertEqual(data, u'Cafè Eñyei')
self.assertIsInstance(data, unicode) self.assertIsInstance(data, unicode)
self.assertEqual(data._line_number, 2) self.assertEqual(data.ansible_pos, ('myfile.yml', 2, 17))
self.assertEqual(data._column_number, 17)
self.assertEqual(data._data_source, 'myfile.yml')
def test_parse_dict(self): def test_parse_dict(self):
stream = StringIO(""" stream = StringIO("""
@ -84,17 +80,10 @@ class TestAnsibleLoaderBasic(unittest.TestCase):
self.assertIsInstance(data.values()[0], unicode) self.assertIsInstance(data.values()[0], unicode)
# Beginning of the first key # Beginning of the first key
self.assertEqual(data._line_number, 2) self.assertEqual(data.ansible_pos, ('myfile.yml', 2, 17))
self.assertEqual(data._column_number, 17)
self.assertEqual(data._data_source, 'myfile.yml')
self.assertEqual(data[u'webster']._line_number, 2) self.assertEqual(data[u'webster'].ansible_pos, ('myfile.yml', 2, 26))
self.assertEqual(data[u'webster']._column_number, 26) self.assertEqual(data[u'oed'].ansible_pos, ('myfile.yml', 3, 22))
self.assertEqual(data[u'webster']._data_source, 'myfile.yml')
self.assertEqual(data[u'oed']._line_number, 3)
self.assertEqual(data[u'oed']._column_number, 22)
self.assertEqual(data[u'oed']._data_source, 'myfile.yml')
def test_parse_list(self): def test_parse_list(self):
stream = StringIO(""" stream = StringIO("""
@ -191,109 +180,51 @@ class TestAnsibleLoaderPlay(unittest.TestCase):
def check_vars(self): def check_vars(self):
# Numbers don't have line/col information yet # Numbers don't have line/col information yet
#self.assertEqual(self.data[0][u'vars'][u'number']._line_number, 4) #self.assertEqual(self.data[0][u'vars'][u'number'].ansible_pos, (self.play_filename, 4, 21))
#self.assertEqual(self.data[0][u'vars'][u'number']._column_number, 21)
#self.assertEqual(self.data[0][u'vars'][u'number']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'vars'][u'string']._line_number, 5)
self.assertEqual(self.data[0][u'vars'][u'string']._column_number, 29)
self.assertEqual(self.data[0][u'vars'][u'string']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'vars'][u'utf8_string']._line_number, 6)
self.assertEqual(self.data[0][u'vars'][u'utf8_string']._column_number, 34)
self.assertEqual(self.data[0][u'vars'][u'utf8_string']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'vars'][u'dictionary']._line_number, 8)
self.assertEqual(self.data[0][u'vars'][u'dictionary']._column_number, 23)
self.assertEqual(self.data[0][u'vars'][u'dictionary']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'webster']._line_number, 8) self.assertEqual(self.data[0][u'vars'][u'string'].ansible_pos, (self.play_filename, 5, 29))
self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'webster']._column_number, 32) self.assertEqual(self.data[0][u'vars'][u'utf8_string'].ansible_pos, (self.play_filename, 6, 34))
self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'webster']._data_source, self.play_filename) self.assertEqual(self.data[0][u'vars'][u'dictionary'].ansible_pos, (self.play_filename, 8, 23))
self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'webster'].ansible_pos, (self.play_filename, 8, 32))
self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'oed']._line_number, 9) self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'oed'].ansible_pos, (self.play_filename, 9, 28))
self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'oed']._column_number, 28)
self.assertEqual(self.data[0][u'vars'][u'dictionary'][u'oed']._data_source, self.play_filename)
# Lists don't yet have line/col information # Lists don't yet have line/col information
#self.assertEqual(self.data[0][u'vars'][u'list']._line_number, 10) #self.assertEqual(self.data[0][u'vars'][u'list'].ansible_pos, (self.play_filename, 10, 21))
#self.assertEqual(self.data[0][u'vars'][u'list']._column_number, 21)
#self.assertEqual(self.data[0][u'vars'][u'list']._data_source, self.play_filename)
def check_tasks(self): def check_tasks(self):
# #
# First Task # First Task
# #
self.assertEqual(self.data[0][u'tasks'][0]._line_number, 16) self.assertEqual(self.data[0][u'tasks'][0].ansible_pos, (self.play_filename, 16, 23))
self.assertEqual(self.data[0][u'tasks'][0]._column_number, 23) self.assertEqual(self.data[0][u'tasks'][0][u'name'].ansible_pos, (self.play_filename, 16, 29))
self.assertEqual(self.data[0][u'tasks'][0]._data_source, self.play_filename) self.assertEqual(self.data[0][u'tasks'][0][u'ping'].ansible_pos, (self.play_filename, 18, 25))
self.assertEqual(self.data[0][u'tasks'][0][u'ping'][u'data'].ansible_pos, (self.play_filename, 18, 31))
self.assertEqual(self.data[0][u'tasks'][0][u'name']._line_number, 16)
self.assertEqual(self.data[0][u'tasks'][0][u'name']._column_number, 29)
self.assertEqual(self.data[0][u'tasks'][0][u'name']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'tasks'][0][u'ping']._line_number, 18)
self.assertEqual(self.data[0][u'tasks'][0][u'ping']._column_number, 25)
self.assertEqual(self.data[0][u'tasks'][0][u'ping']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'tasks'][0][u'ping'][u'data']._line_number, 18)
self.assertEqual(self.data[0][u'tasks'][0][u'ping'][u'data']._column_number, 31)
self.assertEqual(self.data[0][u'tasks'][0][u'ping'][u'data']._data_source, self.play_filename)
# #
# Second Task # Second Task
# #
self.assertEqual(self.data[0][u'tasks'][1]._line_number, 20) self.assertEqual(self.data[0][u'tasks'][1].ansible_pos, (self.play_filename, 20, 23))
self.assertEqual(self.data[0][u'tasks'][1]._column_number, 23) self.assertEqual(self.data[0][u'tasks'][1][u'name'].ansible_pos, (self.play_filename, 20, 29))
self.assertEqual(self.data[0][u'tasks'][1]._data_source, self.play_filename) self.assertEqual(self.data[0][u'tasks'][1][u'ping'].ansible_pos, (self.play_filename, 22, 25))
self.assertEqual(self.data[0][u'tasks'][1][u'ping'][u'data'].ansible_pos, (self.play_filename, 22, 31))
self.assertEqual(self.data[0][u'tasks'][1][u'name']._line_number, 20)
self.assertEqual(self.data[0][u'tasks'][1][u'name']._column_number, 29)
self.assertEqual(self.data[0][u'tasks'][1][u'name']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'tasks'][1][u'ping']._line_number, 22)
self.assertEqual(self.data[0][u'tasks'][1][u'ping']._column_number, 25)
self.assertEqual(self.data[0][u'tasks'][1][u'ping']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'tasks'][1][u'ping'][u'data']._line_number, 22)
self.assertEqual(self.data[0][u'tasks'][1][u'ping'][u'data']._column_number, 31)
self.assertEqual(self.data[0][u'tasks'][1][u'ping'][u'data']._data_source, self.play_filename)
# #
# Third Task # Third Task
# #
self.assertEqual(self.data[0][u'tasks'][2]._line_number, 24) self.assertEqual(self.data[0][u'tasks'][2].ansible_pos, (self.play_filename, 24, 23))
self.assertEqual(self.data[0][u'tasks'][2]._column_number, 23) self.assertEqual(self.data[0][u'tasks'][2][u'name'].ansible_pos, (self.play_filename, 24, 29))
self.assertEqual(self.data[0][u'tasks'][2]._data_source, self.play_filename) self.assertEqual(self.data[0][u'tasks'][2][u'command'].ansible_pos, (self.play_filename, 25, 32))
self.assertEqual(self.data[0][u'tasks'][2][u'name']._line_number, 24)
self.assertEqual(self.data[0][u'tasks'][2][u'name']._column_number, 29)
self.assertEqual(self.data[0][u'tasks'][2][u'name']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'tasks'][2][u'command']._line_number, 25)
self.assertEqual(self.data[0][u'tasks'][2][u'command']._column_number, 32)
self.assertEqual(self.data[0][u'tasks'][2][u'command']._data_source, self.play_filename)
def test_line_numbers(self): def test_line_numbers(self):
# Check the line/column numbers are correct # Check the line/column numbers are correct
# Note: Remember, currently dicts begin at the start of their first entry's value # Note: Remember, currently dicts begin at the start of their first entry
self.assertEqual(self.data[0]._line_number, 2) self.assertEqual(self.data[0].ansible_pos, (self.play_filename, 2, 19))
self.assertEqual(self.data[0]._column_number, 19) self.assertEqual(self.data[0][u'hosts'].ansible_pos, (self.play_filename, 2, 26))
self.assertEqual(self.data[0]._data_source, self.play_filename) self.assertEqual(self.data[0][u'vars'].ansible_pos, (self.play_filename, 4, 21))
self.assertEqual(self.data[0][u'hosts']._line_number, 2)
self.assertEqual(self.data[0][u'hosts']._column_number, 26)
self.assertEqual(self.data[0][u'hosts']._data_source, self.play_filename)
self.assertEqual(self.data[0][u'vars']._line_number, 4)
self.assertEqual(self.data[0][u'vars']._column_number, 21)
self.assertEqual(self.data[0][u'vars']._data_source, self.play_filename)
self.check_vars() self.check_vars()
# Lists don't yet have line/col info # Lists don't yet have line/col info
#self.assertEqual(self.data[0][u'tasks']._line_number, 17) #self.assertEqual(self.data[0][u'tasks'].ansible_pos, (self.play_filename, 17, 28))
#self.assertEqual(self.data[0][u'tasks']._column_number, 28)
#self.assertEqual(self.data[0][u'tasks']._data_source, self.play_filename)
self.check_tasks() self.check_tasks()

Loading…
Cancel
Save