Make string conversion stricter (#695)

* Make string conversion stricter

The string conversion logic added in PR #624 for all std::basic_strings
was derived from the old std::wstring logic, but that was underused and
turns out to have had a bug in accepting almost anything convertible to
unicode, while the previous std::string logic was much stricter.  This
restores the previous std::string logic by only allowing actual unicode
or string types.

Fixes #685.

* Added missing 'requires numpy' decorator

(I forgot that the change to a global decorator here is in the
not-yet-merged Eigen PR)
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 01abf3f..6cb02fd 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -657,6 +657,8 @@
             return false;
             // The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false
 #else
+            if (!PYBIND11_BYTES_CHECK(load_src.ptr()))
+                return false;
             temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr()));
             if (!temp) { PyErr_Clear(); return false; }
             load_src = temp;
diff --git a/tests/test_numpy_array.cpp b/tests/test_numpy_array.cpp
index 14c4c29..23da916 100644
--- a/tests/test_numpy_array.cpp
+++ b/tests/test_numpy_array.cpp
@@ -150,4 +150,9 @@
             "array_t<double>"_a=py::array_t<double>(o)
         );
     });
+
+    // Issue 685: ndarray shouldn't go to std::string overload
+    sm.def("issue685", [](std::string) { return "string"; });
+    sm.def("issue685", [](py::array) { return "array"; });
+    sm.def("issue685", [](py::object) { return "other"; });
 });
diff --git a/tests/test_numpy_array.py b/tests/test_numpy_array.py
index b96790c..25defe7 100644
--- a/tests/test_numpy_array.py
+++ b/tests/test_numpy_array.py
@@ -272,3 +272,12 @@
     assert results["array"].dtype == np.int_
     assert results["array_t<int32>"].dtype == np.int32
     assert results["array_t<double>"].dtype == np.float64
+
+
+@pytest.requires_numpy
+def test_greedy_string_overload():  # issue 685
+    from pybind11_tests.array import issue685
+
+    assert issue685("abc") == "string"
+    assert issue685(np.array([97, 98, 99], dtype='b')) == "array"
+    assert issue685(123) == "other"