# Buggy code
def _eval_evalf(self, prec):
    # Lookup mpmath function based on name
    fname = self.func.__name__
    try:
        if not hasattr(mpmath, fname):
            from sympy.utilities.lambdify import MPMATH_TRANSLATIONS

            fname = MPMATH_TRANSLATIONS[fname]
        func = getattr(mpmath, fname)
    except (AttributeError, KeyError):
        try:
            return Float(self._imp_(*[i.evalf(prec) for i in self.args]), prec)
        except (AttributeError, TypeError, ValueError):
            return

    # Convert all args to mpf or mpc
    # Convert the arguments to *higher* precision than requested for the
    # final result.
    # XXX + 5 is a guess, it is similar to what is used in evalf.py. Should
    #     we be more intelligent about it?
    try:
        args = [arg._to_mpmath(prec + 5) for arg in self.args]

        def bad(m):
            from mpmath import mpf, mpc

            # the precision of an mpf value is the last element
            # if that is 1 (and m[1] is not 1 which would indicate a
            # power of 2), then the eval failed; so check that none of
            # the arguments failed to compute to a finite precision.
            # Note: An mpc value has two parts, the re and imag tuple;
            # check each of those parts, too. Anything else is allowed to
            # pass
            if isinstance(m, mpf):
                m = m._mpf_
                return m[1] != 1 and m[-1] == 1
            elif isinstance(m, mpc):
                m, n = m._mpc_
                return m[1] != 1 and m[-1] == 1 and n[1] != 1 and n[-1] == 1
            else:
                return False

        if any(bad(a) for a in args):
            raise ValueError  # one or more args failed to compute with significance
    except ValueError:
        return

    with mpmath.workprec(prec):
        v = func(*args)

    return Expr._from_mpmath(v, prec)


# Traceback (AttributeError)
If I run sympy.S("ceil(2.3)").evalf() with sympy 0.7.1 then I get 3.  However, if I run the same using sympy 0.7.2 then I get an AttributeError (see below).  I discovered that switching to use ceiling() instead of ceil() works, but I have no idea why ceil() disappeared in the first place.  Someone in IRC told me that the AttributeError was not the correct behaviour for 0.7.2 either.

In [32]: S("ceil(2.3)").evalf()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-32-82d9887af7f2> in <module>()
----> 1 S("ceil(2.3)").evalf()

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/sympify.pyc in sympify(a, locals, convert_xor, strict, rational)
176     try:
177         a = a.replace('\n', '')
--> 178         expr = parse_expr(a, locals or {}, rational, convert_xor)
179     except (TokenError, SyntaxError):
180         raise SympifyError('could not parse %r' % a)

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/parsing/sympy_parser.pyc in parse_expr(s, local_dict, rationalize, convert_xor)
160
161     code = _transform(s.strip(), local_dict, global_dict, rationalize, convert_xor)
--> 162     expr = eval(code, global_dict, local_dict) # take local objects in preference
163
164     if not hit:

<string> in <module>()

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/symbol.pyc in __call__(self, *args)
111     def __call__(self, *args):
112         from function import Function
--> 113         return Function(self.name)(*args)
114
115     def as_real_imag(self, deep=True, **hints):

/home/rob/tmp/sympy-install/lib/python2.7/site-packages/sympy/core/function.pyc in __new__(cls, *args, **options)
596         args = map(sympify, args)
597         result = super(AppliedUndef, cls).__new__(cls, *args, **options)
--> 598         result.nargs = len(args)
599         return result
600

AttributeError: 'Float' object has no attribute 'nargs'

# Fixed code
def _eval_evalf(self, prec):
    # Lookup mpmath function based on name
    try:
        if isinstance(self.func, UndefinedFunction):
            # Shouldn't lookup in mpmath but might have ._imp_
            raise AttributeError
        fname = self.func.__name__
        if not hasattr(mpmath, fname):
            from sympy.utilities.lambdify import MPMATH_TRANSLATIONS

            fname = MPMATH_TRANSLATIONS[fname]
        func = getattr(mpmath, fname)
    except (AttributeError, KeyError):
        try:
            return Float(self._imp_(*[i.evalf(prec) for i in self.args]), prec)
        except (AttributeError, TypeError, ValueError):
            return

    # Convert all args to mpf or mpc
    # Convert the arguments to *higher* precision than requested for the
    # final result.
    # XXX + 5 is a guess, it is similar to what is used in evalf.py. Should
    #     we be more intelligent about it?
    try:
        args = [arg._to_mpmath(prec + 5) for arg in self.args]

        def bad(m):
            from mpmath import mpf, mpc

            # the precision of an mpf value is the last element
            # if that is 1 (and m[1] is not 1 which would indicate a
            # power of 2), then the eval failed; so check that none of
            # the arguments failed to compute to a finite precision.
            # Note: An mpc value has two parts, the re and imag tuple;
            # check each of those parts, too. Anything else is allowed to
            # pass
            if isinstance(m, mpf):
                m = m._mpf_
                return m[1] != 1 and m[-1] == 1
            elif isinstance(m, mpc):
                m, n = m._mpc_
                return m[1] != 1 and m[-1] == 1 and n[1] != 1 and n[-1] == 1
            else:
                return False

        if any(bad(a) for a in args):
            raise ValueError  # one or more args failed to compute with significance
    except ValueError:
        return

    with mpmath.workprec(prec):
        v = func(*args)

    return Expr._from_mpmath(v, prec)