Mercurial > paraspace
view paraspace/structpath.py @ 32:9bac21d401fe
Make get_parent() as a method of structpath.context
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 15 Jun 2011 02:03:38 +0800 |
parents | aed662c820d8 |
children | fe1ebf0c3d40 |
line wrap: on
line source
## # Implement a xpath liked query language. # class context(object): all_classes = None class_instances = None root = None objs = None def __init__(self, objs, ctx=None): if ctx: self.all_classes = ctx.all_classes self.class_instances = ctx.class_instances self.root = ctx.root pass self.objs = objs pass def get_parent(self, obj): raise NotImplementedError, 'get_parent() is not implemented' pass def _path_split(path): parts = [p.strip() for p in path.split('/')] return parts def _is_abs(path_parts): if len(path_parts) == 0: return False return path_parts[0] == '' def _rel_of_abs(path_parts): return path_parts[1:] def _is_class(part): return part.startswith('.') def _class_name(part): return part[1:] def _is_parent_name(part): return part == '..' def _obj_attr(obj, attrname): if isinstance(obj, list): idx = int(attrname) return obj[idx] elif isinstance(obj, dict): key = eval(attrname) return obj[key] return getattr(obj, attrname) def _handle_path_part_obj(ctx, part, obj): if _is_parent_name(part): new_objs = [ctx.get_parent(obj)] elif _is_class(part): class_name = _class_name(part) new_objs = ctx.class_instances[class_name] else: new_objs = [_obj_attr(obj, part)] pass return new_objs def _handle_path_part(ctx, part): from itertools import chain if not ctx.objs: ctx = ctx.__class__([ctx.root], ctx) pass objss = [_handle_path_part_obj(ctx, part, obj) for obj in ctx.objs] objs = [o for o in chain(*objss)] new_ctx = ctx.__class__(objs, ctx) return new_ctx def _handle_path_parts(ctx, path_parts): if _is_abs(path_parts): ctx = ctx.__class__([ctx.root], ctx) path_parts = _rel_of_abs(path_parts) pass if len(path_parts) == 1 and path_parts[0] == '': return ctx for path_part in path_parts: ctx = _handle_path_part(ctx, path_part) pass return ctx def find_objs_path(ctx, path): path_parts = _path_split(path) rctx = _handle_path_parts(ctx, path_parts) return rctx.objs