Ajustar todas las llamadas a métodos posibles de una clase en un bloque try / except

Estoy tratando de incluir todos los métodos de una Clase existente (no de mi creación) en una suite try / except. Podría ser cualquier clase, pero usaré elpandas.DataFrame clase aquí como un ejemplo práctico.

Entonces, si el método invocado tiene éxito, simplemente seguimos adelante. Pero si debe generar una excepción, se agrega a una lista para su posterior inspección / descubrimiento (aunque el siguiente ejemplo solo emite una declaración impresa por simplicidad).

(Tenga en cuenta que los tipos de excepciones relacionadas con los datos que pueden ocurrir cuando se invoca un método en la instancia, aún no se conocen; y esa es la razón de este ejercicio: descubrimiento).

Estaenviar fue bastante útil (particularmente la respuesta de @martineau Python-3), pero tengo problemas para adaptarlo. A continuación, esperaba la segunda llamada al (envuelto)info () método para emitir salida de impresión pero, lamentablemente, no lo hace.

#!/usr/bin/env python3

import functools, types, pandas

def method_wrapper(method):
    @functools.wraps(method)
    def wrapper(*args, **kwargs): #Note: args[0] points to 'self'.
        try:
            print('Calling: {}.{}()... '.format(args[0].__class__.__name__,
                                      ,          method.__name__))
            return method(*args, **kwargs)
        except Exception:
            print('Exception: %r' % sys.exc_info()) # Something trivial.
            #<Actual code would append that exception info to a list>.
    return wrapper


class MetaClass(type):
    def __new__(mcs, class_name, base_classes, classDict):
        newClassDict = {}
        for attributeName, attribute in classDict.items():
            if type(attribute) == types.FunctionType: # Replace it with a
                attribute = method_wrapper(attribute) # decorated version.
            newClassDict[attributeName] = attribute
        return type.__new__(mcs, class_name, base_classes, newClassDict)

class WrappedDataFrame2(MetaClass('WrappedDataFrame',
                                  (pandas.DataFrame, object,), {}),
                                  metaclass=type):
    pass

print('Unwrapped pandas.DataFrame().info():')
pandas.DataFrame().info()

print('\n\nWrapped pandas.DataFrame().info():')
WrappedDataFrame2().info()
print()

Esto produce:

Unwrapped pandas.DataFrame().info():
<class 'pandas.core.frame.DataFrame'>
Index: 0 entries
Empty DataFrame

Wrapped pandas.DataFrame().info():   <-- Missing print statement after this line.
<class '__main__.WrappedDataFrame2'>
Index: 0 entries
Empty WrappedDataFrame2

En resumen,...

>>> unwrapped_object.someMethod(...)
# Should be mirrored by ...

>>> wrapping_object.someMethod(...)
# Including signature, docstring, etc. (i.e. all attributes); except that it
# executes inside a try/except suite (so I can catch exceptions generically).

Respuestas a la pregunta(2)

Su respuesta a la pregunta