Implements issue #9951: Adds a hex() method to bytes, bytearray, & memoryview.

Also updates a few internal implementations of the same thing to use the
new built-in code.

Contributed by Arnon Yaari.
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index d981e0e..d2b52c7 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -5,6 +5,7 @@
 #include "Python.h"
 
 #include "bytes_methods.h"
+#include "pystrhex.h"
 #include <stddef.h>
 
 /*[clinic input]
@@ -3036,6 +3037,20 @@
     return NULL;
 }
 
+PyDoc_STRVAR(hex__doc__,
+"B.hex() -> string\n\
+\n\
+Create a string of hexadecimal numbers from a bytes object.\n\
+Example: b'\\xb9\\x01\\xef'.hex() -> 'b901ef'.");
+
+static PyObject *
+bytes_hex(PyBytesObject *self)
+{
+    char* argbuf = PyBytes_AS_STRING(self);
+    Py_ssize_t arglen = PyBytes_GET_SIZE(self);
+    return _Py_strhex(argbuf, arglen);
+}
+
 static PyObject *
 bytes_getnewargs(PyBytesObject *v)
 {
@@ -3057,6 +3072,7 @@
      expandtabs__doc__},
     {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__},
     BYTES_FROMHEX_METHODDEF
+    {"hex", (PyCFunction)bytes_hex, METH_NOARGS, hex__doc__},
     {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__},
     {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
      _Py_isalnum__doc__},