<s> from collections import deque <EOL> import re <EOL> from atom . api import Atom , Unicode , Value , List , Event <EOL> def flag_generator ( ) : <EOL> """<STR_LIT>""" <EOL> flag = <NUM_LIT:1> <EOL> while True : <EOL> yield flag <EOL> flag <<= <NUM_LIT:1> <EOL> flag_generator = flag_generator ( ) <EOL> DESTROYED_FLAG = flag_generator . next ( ) <EOL> def flag_property ( flag ) : <EOL> """<STR_LIT>""" <EOL> def getter ( self ) : <EOL> return ( self . _flags & flag ) != <NUM_LIT:0> <EOL> def setter ( self , value ) : <EOL> if value : <EOL> self . _flags |= flag <EOL> else : <EOL> self . _flags &= ~ flag <EOL> return property ( getter , setter ) <EOL> class Object ( Atom ) : <EOL> """<STR_LIT>""" <EOL> name = Unicode ( ) <EOL> parent = property ( lambda self : self . _parent ) <EOL> children = property ( lambda self : self . _children ) <EOL> is_destroyed = flag_property ( DESTROYED_FLAG ) <EOL> destroyed = Event ( ) <EOL> _parent = Value ( ) <EOL> _children = List ( ) <EOL> _flags = Value ( <NUM_LIT:0> ) <EOL> def __init__ ( self , parent = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> super ( Object , self ) . __init__ ( ** kwargs ) <EOL> if parent is not None : <EOL> self . set_parent ( parent ) <EOL> def destroy ( self ) : <EOL> """<STR_LIT>""" <EOL> self . is_destroyed = True <EOL> self . destroyed ( ) <EOL> self . unobserve ( ) <EOL> for child in self . _children : <EOL> child . destroy ( ) <EOL> del self . _children <EOL> parent = self . _parent <EOL> if parent is not None : <EOL> if parent . is_destroyed : <EOL> self . _parent = None <EOL> else : <EOL> self . set_parent ( None ) <EOL> def set_parent ( self , parent ) : <EOL> """<STR_LIT>""" <EOL> old_parent = self . _parent <EOL> if parent is old_parent : <EOL> return <EOL> if parent is self : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if parent is not None and not isinstance ( parent , Object ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> self . _parent = parent <EOL> self . parent_changed ( old_parent , parent ) <EOL> if old_parent is not None : <EOL> old_parent . _children . remove ( self ) <EOL> old_parent . child_removed ( self ) <EOL> if parent is not None : <EOL> parent . _children . append ( self ) <EOL> parent . child_added ( self ) <EOL> def insert_children ( self , before , insert ) : <EOL> """<STR_LIT>""" <EOL> insert_list = list ( insert ) <EOL> insert_set = set ( insert_list ) <EOL> if self in insert_set : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if len ( insert_list ) != len ( insert_set ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if not all ( isinstance ( child , Object ) for child in insert_list ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> if isinstance ( before , int ) : <EOL> try : <EOL> before = self . _children [ before ] <EOL> except IndexError : <EOL> before = None <EOL> new = [ ] <EOL> added = False <EOL> for child in self . _children : <EOL> if child in insert_set : <EOL> insert_set . remove ( child ) <EOL> continue <EOL> if child is before : <EOL> new . extend ( insert_list ) <EOL> added = True <EOL> new . append ( child ) <EOL> if not added : <EOL> new . extend ( insert_list ) <EOL> for child in insert_list : <EOL> old_parent = child . _parent <EOL> if old_parent is not self : <EOL> child . _parent = self <EOL> child . parent_changed ( old_parent , self ) <EOL> if old_parent is not None : <EOL> old_parent . child_removed ( child ) <EOL> self . _children = new <EOL> child_added = self . child_added <EOL> child_moved = self . child_moved <EOL> for child in insert_list : <EOL> if child in insert_set : <EOL> child_added ( child ) <EOL> else : <EOL> child_moved ( child ) <EOL> def parent_changed ( self , old , new ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def child_added ( self , child ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def child_moved ( self , child ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def child_removed ( self , child ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def root_object ( self ) : <EOL> """<STR_LIT>""" <EOL> obj = self <EOL> while obj . _parent is not None : <EOL> obj = obj . _parent <EOL> return obj <EOL> def traverse ( self , depth_first = False ) : <EOL> """<STR_LIT>""" <EOL> if depth_first : <EOL> stack = [ self ] <EOL> stack_pop = stack . pop <EOL> stack_extend = stack . extend <EOL> else : <EOL> stack = deque ( [ self ] ) <EOL> stack_pop = stack . popleft <EOL> stack_extend = stack . extend <EOL> while stack : <EOL> obj = stack_pop ( ) <EOL> yield obj <EOL> stack_extend ( obj . _children ) <EOL> def traverse_ancestors ( self , root = None ) : <EOL> """<STR_LIT>""" <EOL> parent = self . _parent <EOL> while parent is not root and parent is not None : <EOL> yield parent <EOL> parent = parent . _parent <EOL> def find ( self , name , regex = False ) : <EOL> """<STR_LIT>""" <EOL> if regex : <EOL> rgx = re . compile ( name ) <EOL> match = lambda n : bool ( rgx . match ( n ) ) <EOL> else : <EOL> match = lambda n : n == name <EOL> for obj in self . traverse ( ) : <EOL> if match ( obj . name ) : <EOL> return obj <EOL> def find_all ( self , name , regex = False ) : <EOL> """<STR_LIT>""" <EOL> if regex : <EOL> rgx = re . compile ( name ) <EOL> match = lambda n : bool ( rgx . match ( n ) ) <EOL> else : <EOL> match = lambda n : n == name <EOL> res = [ ] <EOL> push = res . append <EOL> for obj in self . traverse ( ) : <EOL> if match ( obj . name ) : <EOL> push ( obj ) <EOL> return res </s>
