diff --git a/psycopg/psycopg.h b/psycopg/psycopg.h index 57a73d02..e87744c7 100644 --- a/psycopg/psycopg.h +++ b/psycopg/psycopg.h @@ -122,6 +122,7 @@ HIDDEN char *psycopg_escape_string(PyObject *conn, HIDDEN char *psycopg_strdup(const char *from, Py_ssize_t len); HIDDEN PyObject * psycopg_ensure_bytes(PyObject *obj); +HIDDEN PyObject * psycopg_ensure_text(PyObject *obj); /* Exceptions docstrings */ #define Error_doc \ diff --git a/psycopg/utils.c b/psycopg/utils.c index e5b221f9..16b92498 100644 --- a/psycopg/utils.c +++ b/psycopg/utils.c @@ -118,3 +118,27 @@ psycopg_ensure_bytes(PyObject *obj) return rv; } +/* Take a Python object and return text from it. + * + * On Py3 this means converting bytes to unicode. On Py2 bytes are fine. + * + * The function is ref neutral: steals a ref from obj and adds one to the + * return value. It is safe to call it on NULL. + */ +PyObject * +psycopg_ensure_text(PyObject *obj) +{ +#if PY_MAJOR_VERSION < 3 + return obj; +#else + if (obj) { + /* bytes to unicode in Py3 */ + PyObject *rv = PyUnicode_FromEncodedObject(obj, "utf8", "replace"); + Py_DECREF(obj); + return rv; + } + else { + return NULL; + } +#endif +}