def replacement_traverse(obj, opts, replace):
 cloned = {}
 stop_on = set([id(x) for x in opts.get('stop_on', [])])
 def clone(elem, **kw):
  if ((id(elem) in stop_on) or ('no_replacement_traverse' in elem._annotations)):
   return elem
  else:
   newelem = replace(elem)
   if (newelem is not None):
    stop_on.add(id(newelem))
    return newelem
   else:
    if (elem not in cloned):
     cloned[elem] = newelem = elem._clone()
     newelem._copy_internals(clone=clone, **kw)
    return cloned[elem]
 if (obj is not None):
  obj = clone(obj, **opts)
 return obj

def replacement_traverse ( obj , opts , replace ) : cloned = { } stop_on = set ( [ id ( x ) for x in opts . get ( 'stop_on' , [ ] ) ] ) def clone ( elem , ** kw ) : if ( ( id ( elem ) in stop_on ) or ( 'no_replacement_traverse' in elem . _annotations ) ) : return elem else : newelem = replace ( elem ) if ( newelem is not None ) : stop_on . add ( id ( newelem ) ) return newelem else : if ( elem not in cloned ) : cloned [ elem ] = newelem = elem . _clone ( ) newelem . _copy_internals ( clone = clone , ** kw ) return cloned [ elem ] if ( obj is not None ) : obj = clone ( obj , ** opts ) return obj
clone the given expression structure .