Implicit conversions to bool + np.bool_ conversion (#925)

This adds support for implicit conversions to bool from Python types
with `__bool__` (Python 3) or `__nonzero__` (Python 2) attributes, and
adds direct (i.e. non-converting) support for numpy bools.
diff --git a/tests/test_builtin_casters.cpp b/tests/test_builtin_casters.cpp
index bf972e1..b73e96e 100644
--- a/tests/test_builtin_casters.cpp
+++ b/tests/test_builtin_casters.cpp
@@ -116,6 +116,10 @@
     m.def("load_nullptr_t", [](std::nullptr_t) {}); // not useful, but it should still compile
     m.def("cast_nullptr_t", []() { return std::nullptr_t{}; });
 
+    // test_bool_caster
+    m.def("bool_passthrough", [](bool arg) { return arg; });
+    m.def("bool_passthrough_noconvert", [](bool arg) { return arg; }, py::arg().noconvert());
+
     // test_reference_wrapper
     m.def("refwrap_builtin", [](std::reference_wrapper<int> p) { return 10 * p.get(); });
     m.def("refwrap_usertype", [](std::reference_wrapper<UserType> p) { return p.get().value(); });
diff --git a/tests/test_builtin_casters.py b/tests/test_builtin_casters.py
index d7d49b6..64d2f19 100644
--- a/tests/test_builtin_casters.py
+++ b/tests/test_builtin_casters.py
@@ -265,3 +265,58 @@
     """std::complex casts"""
     assert m.complex_cast(1) == "1.0"
     assert m.complex_cast(2j) == "(0.0, 2.0)"
+
+
+def test_bool_caster():
+    """Test bool caster implicit conversions."""
+    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
+
+    def require_implicit(v):
+        pytest.raises(TypeError, noconvert, v)
+
+    def cant_convert(v):
+        pytest.raises(TypeError, convert, v)
+
+    # straight up bool
+    assert convert(True) is True
+    assert convert(False) is False
+    assert noconvert(True) is True
+    assert noconvert(False) is False
+
+    # None requires implicit conversion
+    require_implicit(None)
+    assert convert(None) is False
+
+    class A(object):
+        def __init__(self, x):
+            self.x = x
+
+        def __nonzero__(self):
+            return self.x
+
+        def __bool__(self):
+            return self.x
+
+    class B(object):
+        pass
+
+    # Arbitrary objects are not accepted
+    cant_convert(object())
+    cant_convert(B())
+
+    # Objects with __nonzero__ / __bool__ defined can be converted
+    require_implicit(A(True))
+    assert convert(A(True)) is True
+    assert convert(A(False)) is False
+
+
+@pytest.requires_numpy
+def test_numpy_bool():
+    import numpy as np
+    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
+
+    # np.bool_ is not considered implicit
+    assert convert(np.bool_(True)) is True
+    assert convert(np.bool_(False)) is False
+    assert noconvert(np.bool_(True)) is True
+    assert noconvert(np.bool_(False)) is False