PyObject*  PropertyContainerPy::getPropertyByName(PyObject *args)
{
    char *pstr;
    if (!PyArg_ParseTuple(args, "s", &pstr))     // convert args: Python->C
        return NULL;                             // NULL triggers exception
    App::Property* prop = getPropertyContainerPtr()->getPropertyByName(pstr);
    if (prop) {
        return prop->getPyObject();
    }
    else {
        PyErr_Format(PyExc_AttributeError, "Property container has no property '%s'", pstr);
        return NULL;
    }
}
Py::Object DocumentObjectProtectorPy::getattr(const char * attr)
{
    if (!_dp) {
        std::string s;
        std::ostringstream s_out;
        s_out << "Cannot access attribute '" << attr << "' of deleted object";
        throw Py::RuntimeError(s_out.str());
    }
    else {
        App::DocumentObject* obj = _dp->getObject();
        App::Property* prop = obj->getPropertyByName(attr);
        if (!prop) {
            return Py::PythonExtension<DocumentObjectProtectorPy>::getattr(attr);
            //std::string s;
            //std::ostringstream s_out;
            //s_out << "No such attribute '" << attr << "'";
            //throw Py::AttributeError(s_out.str());
        }

        return Py::asObject(prop->getPyObject());
    }
}