(rv, F, atoms=False, nonbasic=False)
return rv
Apply ``F`` to all expressions in an expression tree from the
    bottom up. If ``atoms`` is True, apply ``F`` even if there are no args;
    if ``nonbasic`` is True, try to apply ``F`` to non-Basic objects.
Apply ``F`` to all expressions in an expression tree from the
    bottom up. If ``atoms`` is True, apply ``F`` even if there are no args;
    if ``nonbasic`` is True, try to apply ``F`` to non-Basic objects.
Apply F to all expressions in an expression tree from the bottom up . If atoms is True apply F even if there are no args ; if nonbasic is True try to apply F to non - Basic objects .
def bottom_up(rv, F, atoms=False, nonbasic=False):
    """Apply ``F`` to all expressions in an expression tree from the
    bottom up. If ``atoms`` is True, apply ``F`` even if there are no args;
    if ``nonbasic`` is True, try to apply ``F`` to non-Basic objects.
    """
    try:
        if rv.args:
            args = tuple([bottom_up(a, F, atoms, nonbasic)
                for a in rv.args])
            if args != rv.args:
                rv = rv.func(*args)
            rv = F(rv)
        elif atoms:
            rv = F(rv)
    except AttributeError:
        if nonbasic:
            try:
                rv = F(rv)
            except TypeError:
                pass

    return rv
def bottom_up ( rv , F , atoms = False , nonbasic = False ) : try : if rv . args : args = tuple ( [ bottom_up ( a , F , atoms , nonbasic ) for a in rv . args ] ) if args != rv . args : rv = rv . func ( * args ) rv = F ( rv ) elif atoms : rv = F ( rv ) except AttributeError : if nonbasic : try : rv = F ( rv ) except TypeError : pass return rv