This patch adds a new Python C API called PyString_AsStringAndSize()

which implements the automatic conversion from Unicode to a string
object using the default encoding.

The new API is then put to use to have eval() and exec accept
Unicode objects as code parameter. This closes bugs #110924
and #113890.

As side-effect, the traditional C APIs PyString_Size() and
PyString_AsString() will also accept Unicode objects as
parameters.
This commit is contained in:
Marc-André Lemburg 2000-09-19 21:04:18 +00:00
parent f8d071332a
commit d1ba443206
8 changed files with 127 additions and 20 deletions

View file

@ -239,26 +239,82 @@ string_dealloc(PyObject *op)
PyObject_DEL(op);
}
static int
string_getsize(register PyObject *op)
{
char *s;
int len;
if (PyString_AsStringAndSize(op, &s, &len))
return -1;
return len;
}
static /*const*/ char *
string_getbuffer(register PyObject *op)
{
char *s;
int len;
if (PyString_AsStringAndSize(op, &s, &len))
return NULL;
return s;
}
int
PyString_Size(register PyObject *op)
{
if (!PyString_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
if (!PyString_Check(op))
return string_getsize(op);
return ((PyStringObject *)op) -> ob_size;
}
/*const*/ char *
PyString_AsString(register PyObject *op)
{
if (!PyString_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
if (!PyString_Check(op))
return string_getbuffer(op);
return ((PyStringObject *)op) -> ob_sval;
}
/* Internal API needed by PyString_AsStringAndSize(): */
extern
PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
const char *errors);
int
PyString_AsStringAndSize(register PyObject *obj,
register char **s,
register int *len)
{
if (s == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (!PyString_Check(obj)) {
if (PyUnicode_Check(obj)) {
obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);
if (obj == NULL)
return -1;
}
else {
PyErr_Format(PyExc_TypeError,
"expected string or Unicode object, "
"%.200s found", obj->ob_type->tp_name);
return -1;
}
}
*s = PyString_AS_STRING(obj);
if (len != NULL)
*len = PyString_GET_SIZE(obj);
else if ((int)strlen(*s) != PyString_GET_SIZE(obj)) {
PyErr_SetString(PyExc_TypeError,
"expected string without null bytes");
return -1;
}
return 0;
}
/* Methods */
static int