Make attr and item accessors throw on error instead of returning nullptr

This also adds the `hasattr` and `getattr` functions which are needed
with the new attribute behavior. The new functions behave exactly like
their Python counterparts.

Similarly `object` gets a `contains` method which calls `__contains__`,
i.e. it's the same as the `in` keyword in Python.
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 1d9740d..7fa0348 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -39,7 +39,10 @@
         return *internals_ptr;
     handle builtins(PyEval_GetBuiltins());
     const char *id = PYBIND11_INTERNALS_ID;
-    capsule caps(builtins[id]);
+    capsule caps;
+    if (builtins.contains(id)) {
+        caps = builtins[id];
+    }
     if (caps.check()) {
         internals_ptr = caps;
     } else {
@@ -1221,7 +1224,7 @@
     }
 
     void process(list &/*args_list*/, arg_v a) {
-        if (m_kwargs[a.name]) {
+        if (m_kwargs.contains(a.name)) {
 #if defined(NDEBUG)
             multiple_values_error();
 #else
@@ -1240,7 +1243,7 @@
 
     void process(list &/*args_list*/, detail::kwargs_proxy kp) {
         for (const auto &k : dict(kp, true)) {
-            if (m_kwargs[k.first]) {
+            if (m_kwargs.contains(k.first)) {
 #if defined(NDEBUG)
                 multiple_values_error();
 #else
diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h
index a3e6672..fb8d3c6 100644
--- a/include/pybind11/numpy.h
+++ b/include/pybind11/numpy.h
@@ -125,11 +125,11 @@
 
     static npy_api lookup() {
         module m = module::import("numpy.core.multiarray");
-        object c = (object) m.attr("_ARRAY_API");
+        auto c = m.attr("_ARRAY_API").cast<object>();
 #if PY_MAJOR_VERSION >= 3
-        void **api_ptr = (void **) (c ? PyCapsule_GetPointer(c.ptr(), NULL) : nullptr);
+        void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL);
 #else
-        void **api_ptr = (void **) (c ? PyCObject_AsVoidPtr(c.ptr()) : nullptr);
+        void **api_ptr = (void **) PyCObject_AsVoidPtr(c.ptr());
 #endif
         npy_api api;
 #define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];
diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h
index 4a6fa8d..a0e2e72 100644
--- a/include/pybind11/pybind11.h
+++ b/include/pybind11/pybind11.h
@@ -278,9 +278,11 @@
 
             object scope_module;
             if (rec->scope) {
-                scope_module = (object) rec->scope.attr("__module__");
-                if (!scope_module)
-                    scope_module = (object) rec->scope.attr("__name__");
+                if (hasattr(rec->scope, "__module__")) {
+                    scope_module = rec->scope.attr("__module__");
+                } else if (hasattr(rec->scope, "__name__")) {
+                    scope_module = rec->scope.attr("__name__");
+                }
             }
 
             m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr());
@@ -544,8 +546,8 @@
 
     template <typename Func, typename... Extra>
     module &def(const char *name_, Func &&f, const Extra& ... extra) {
-        cpp_function func(std::forward<Func>(f), name(name_),
-                          sibling((handle) attr(name_)), scope(*this), extra...);
+        cpp_function func(std::forward<Func>(f), name(name_), scope(*this),
+                          sibling(getattr(*this, name_, none())), extra...);
         /* PyModule_AddObject steals a reference to 'func' */
         PyModule_AddObject(ptr(), name_, func.inc_ref().ptr());
         return *this;
@@ -588,16 +590,18 @@
         object name(PYBIND11_FROM_STRING(rec->name), false);
         object scope_module;
         if (rec->scope) {
-            scope_module = (object) rec->scope.attr("__module__");
-            if (!scope_module)
-                scope_module = (object) rec->scope.attr("__name__");
+            if (hasattr(rec->scope, "__module__")) {
+                scope_module = rec->scope.attr("__module__");
+            } else if (hasattr(rec->scope, "__name__")) {
+                scope_module = rec->scope.attr("__name__");
+            }
         }
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
         /* Qualified names for Python >= 3.3 */
         object scope_qualname;
-        if (rec->scope)
-            scope_qualname = (object) rec->scope.attr("__qualname__");
+        if (rec->scope && hasattr(rec->scope, "__qualname__"))
+            scope_qualname = rec->scope.attr("__qualname__");
         object ht_qualname;
         if (scope_qualname) {
             ht_qualname = object(PyUnicode_FromFormat(
@@ -894,17 +898,16 @@
 
     template <typename Func, typename... Extra>
     class_ &def(const char *name_, Func&& f, const Extra&... extra) {
-        cpp_function cf(std::forward<Func>(f), name(name_),
-                        sibling(attr(name_)), is_method(*this),
-                        extra...);
+        cpp_function cf(std::forward<Func>(f), name(name_), is_method(*this),
+                        sibling(getattr(*this, name_, none())), extra...);
         attr(cf.name()) = cf;
         return *this;
     }
 
     template <typename Func, typename... Extra> class_ &
     def_static(const char *name_, Func f, const Extra&... extra) {
-        cpp_function cf(std::forward<Func>(f), name(name_),
-                        sibling(attr(name_)), scope(*this), extra...);
+        cpp_function cf(std::forward<Func>(f), name(name_), scope(*this),
+                        sibling(getattr(*this, name_, none())), extra...);
         attr(cf.name()) = cf;
         return *this;
     }
@@ -1338,16 +1341,16 @@
     for (size_t i = 0; i < args.size(); ++i) {
         strings[i] = args[i].cast<object>().str();
     }
-    auto sep = kwargs["sep"] ? kwargs["sep"] : cast(" ");
+    auto sep = kwargs.contains("sep") ? kwargs["sep"] : cast(" ");
     auto line = sep.attr("join").cast<object>()(strings);
 
-    auto file = kwargs["file"] ? kwargs["file"].cast<object>()
-                               : module::import("sys").attr("stdout");
+    auto file = kwargs.contains("file") ? kwargs["file"].cast<object>()
+                                        : module::import("sys").attr("stdout");
     auto write = file.attr("write").cast<object>();
     write(line);
-    write(kwargs["end"] ? kwargs["end"] : cast("\n"));
+    write(kwargs.contains("end") ? kwargs["end"] : cast("\n"));
 
-    if (kwargs["flush"] && kwargs["flush"].cast<bool>()) {
+    if (kwargs.contains("flush") && kwargs["flush"].cast<bool>()) {
         file.attr("flush").cast<object>()();
     }
 }
@@ -1500,7 +1503,7 @@
     if (cache.find(key) != cache.end())
         return function();
 
-    function overload = (function) py_object.attr(name);
+    function overload = getattr(py_object, name, function());
     if (overload.is_cpp_function()) {
         cache.insert(key);
         return function();
diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h
index 872c90c..180bcdd 100644
--- a/include/pybind11/pytypes.h
+++ b/include/pybind11/pytypes.h
@@ -41,6 +41,7 @@
     accessor attr(handle key) const;
     accessor attr(const char *key) const;
     args_proxy operator*() const;
+    template <typename T> bool contains(T &&key) const;
 
     template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
     object operator()(Args &&...args) const;
@@ -117,6 +118,52 @@
     template <typename T> T cast() &&;
 };
 
+inline bool hasattr(handle obj, handle name) {
+    return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1;
+}
+
+inline bool hasattr(handle obj, const char *name) {
+    return PyObject_HasAttrString(obj.ptr(), name) == 1;
+}
+
+inline object getattr(handle obj, handle name) {
+    PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr());
+    if (!result) { throw error_already_set(); }
+    return {result, false};
+}
+
+inline object getattr(handle obj, const char *name) {
+    PyObject *result = PyObject_GetAttrString(obj.ptr(), name);
+    if (!result) { throw error_already_set(); }
+    return {result, false};
+}
+
+inline object getattr(handle obj, handle name, handle default_) {
+    if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) {
+        return {result, false};
+    } else {
+        PyErr_Clear();
+        return {default_, true};
+    }
+}
+
+inline object getattr(handle obj, const char *name, handle default_) {
+    if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) {
+        return {result, false};
+    } else {
+        PyErr_Clear();
+        return {default_, true};
+    }
+}
+
+inline void setattr(handle obj, handle name, handle value) {
+    if (PyObject_SetAttr(obj.ptr(), name.ptr(), value.ptr()) != 0) { throw error_already_set(); }
+}
+
+inline void setattr(handle obj, const char *name, handle value) {
+    if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) { throw error_already_set(); }
+}
+
 NAMESPACE_BEGIN(detail)
 inline handle get_function(handle value) {
     if (value) {
@@ -151,24 +198,14 @@
     }
 
     operator object() const {
-        object result(attr ? PyObject_GetAttr(obj.ptr(), key.ptr())
-                           : PyObject_GetItem(obj.ptr(), key.ptr()), false);
-        if (!result) {PyErr_Clear(); }
-        return result;
+        PyObject *result = attr ? PyObject_GetAttr(obj.ptr(), key.ptr())
+                                : PyObject_GetItem(obj.ptr(), key.ptr());
+        if (!result) { throw error_already_set(); }
+        return {result, false};
     }
 
     template <typename T> T cast() const { return operator object().cast<T>(); }
 
-    operator bool() const {
-        if (attr) {
-            return (bool) PyObject_HasAttr(obj.ptr(), key.ptr());
-        } else {
-            object result(PyObject_GetItem(obj.ptr(), key.ptr()), false);
-            if (!result) PyErr_Clear();
-            return (bool) result;
-        }
-    };
-
 private:
     handle obj;
     object key;
@@ -598,6 +635,8 @@
     detail::dict_iterator begin() const { return (++detail::dict_iterator(*this, 0)); }
     detail::dict_iterator end() const { return detail::dict_iterator(); }
     void clear() const { PyDict_Clear(ptr()); }
+    bool contains(handle key) const { return PyDict_Contains(ptr(), key.ptr()) == 1; }
+    bool contains(const char *key) const { return PyDict_Contains(ptr(), pybind11::str(key).ptr()) == 1; }
 };
 
 class list : public object {
@@ -695,6 +734,9 @@
 template <typename D> accessor object_api<D>::attr(handle key) const { return {derived(), key, true}; }
 template <typename D> accessor object_api<D>::attr(const char *key) const { return {derived(), key, true}; }
 template <typename D> args_proxy object_api<D>::operator*() const { return {derived().ptr()}; }
+template <typename D> template <typename T> bool object_api<D>::contains(T &&key) const {
+    return attr("__contains__").template cast<object>()(std::forward<T>(key)).template cast<bool>();
+}
 
 template <typename D>
 pybind11::str object_api<D>::str() const {
diff --git a/tests/pybind11_tests.cpp b/tests/pybind11_tests.cpp
index f3f557a..35981a0 100644
--- a/tests/pybind11_tests.cpp
+++ b/tests/pybind11_tests.cpp
@@ -39,7 +39,7 @@
     for (const auto &initializer : initializers())
         initializer(m);
 
-    if (!m.attr("have_eigen")) m.attr("have_eigen") = py::cast(false);
+    if (!py::hasattr(m, "have_eigen")) m.attr("have_eigen") = py::cast(false);
 
     return m.ptr();
 }