Commit 39cf34975d9c289c2ef4535c912e974716ac24b4

Authored by selurvedu
1 parent e8c49e49

Rewrite set_to_object()

The new version supports nested objects (i.e. dictionaries
in dictionaries and lists in dictionaries) just like the old one.
Unlike the old version, the new one supports recursion
(lists in dictionaries in lists of dictionaries in dictionaries in
lists of dictionaries ...).
Two-dimensional lists (lists of lists) are not yet supported.
... ... @@ -379,29 +379,70 @@ def get_from_object(obj, path):
379 379 raise AttributeError('Attribute not found: {0}'.format(path))
380 380
381 381
382   -def set_to_object(obj, attribute, value):
383   - # Search the list index in path to value
384   - list_index = re.search('\d+', attribute)
385   - if list_index and attribute != 'stage2TenderID':
386   - list_index = list_index.group(0)
387   - parent, child = attribute.split('[' + list_index + '].')[:2]
388   - # Split attribute to path to lits (parent) and path to value in list element (child)
389   - try:
390   - # Get list from parent
391   - listing = get_from_object(obj, parent)
392   - # Create object with list_index if he don`t exist
393   - if len(listing) < int(list_index) + 1:
394   - listing.append({})
395   - except AttributeError:
396   - # Create list if he don`t exist
397   - listing = [{}]
398   - # Update list in parent
399   - xpathnew(obj, parent, listing, separator='.')
400   - # Set value in obj
401   - xpathnew(obj, '.'.join([parent, list_index, child]), value, separator='.')
402   - else:
403   - xpathnew(obj, attribute, value, separator='.')
404   - return munchify(obj)
  382 +def set_to_object(obj, path, value):
  383 + def recur(obj, path, value):
  384 + if not isinstance(obj, dict):
  385 + raise TypeError('expected %s, got %s' %
  386 + (dict.__name__, type(obj)))
  387 +
  388 + # Search the list index in path to value
  389 + groups = re.search(r'^(?P<key>[0-9a-zA-Z_]+)(?:\[(?P<index>-?\d+)\])?'
  390 + '(?:\.(?P<suffix>.+))?$', path)
  391 +
  392 + err = RuntimeError('could not parse the path: ' + path)
  393 + if not groups:
  394 + raise err
  395 +
  396 + gd = {k: v for k, v in groups.groupdict().items() if v is not None}
  397 + is_list = False
  398 + suffix = None
  399 +
  400 + if 'key' not in gd:
  401 + raise err
  402 + key = gd['key']
  403 +
  404 + if 'index' in gd:
  405 + is_list = True
  406 + index = int(gd['index'])
  407 +
  408 + if 'suffix' in gd:
  409 + suffix = gd['suffix']
  410 +
  411 + if is_list:
  412 + if key not in obj:
  413 + obj[key] = []
  414 + elif not isinstance(obj[key], list):
  415 + raise TypeError('expected %s, got %s' %
  416 + (list.__name__, type(obj[key])))
  417 +
  418 + plusone = 1 if index >= 0 else 0
  419 + if len(obj[key]) < abs(index) + plusone:
  420 + while not len(obj[key]) == abs(index) + plusone:
  421 + extension = [None for _ in
  422 + range(abs(index) + plusone - len(obj[key]))]
  423 + if index < 0:
  424 + obj[key] = extension + obj[key]
  425 + else:
  426 + obj[key].extend(extension)
  427 + if suffix:
  428 + obj[key][index] = {}
  429 + if suffix:
  430 + obj[key][index] = recur(obj[key][index], suffix, value)
  431 + else:
  432 + obj[key][index] = value
  433 + else:
  434 + if key not in obj:
  435 + obj[key] = {}
  436 + if suffix:
  437 + obj[key] = recur(obj[key], suffix, value)
  438 + else:
  439 + obj[key] = value
  440 +
  441 + return obj
  442 +
  443 + if not isinstance(path, STR_TYPES):
  444 + raise TypeError('Path must be one of %s' % str(STR_TYPES))
  445 + return munchify(recur(obj, path, value))
405 446
406 447
407 448 def wait_to_date(date_stamp):
... ...
Please register or login to post a comment