# HG changeset patch # User Daniel Holth # Date 1373064755 14400 # Node ID c4d6f29a6ea35e4dd3b39a59a88bb852af8acf9d # Parent d5536c06a0824143adb620de2d64ccc54e65d38e add sys.get/setbyteswarningflag() methods diff -r d5536c06a082 -r c4d6f29a6ea3 Include/pystate.h --- a/Include/pystate.h Fri Jul 05 01:40:52 2013 +0200 +++ b/Include/pystate.h Fri Jul 05 18:52:35 2013 -0400 @@ -118,6 +118,8 @@ int trash_delete_nesting; PyObject *trash_delete_later; + int byteswarning; /* Should str(bytes) emit a warning? */ + /* XXX signal handlers should also be here */ } PyThreadState; @@ -151,6 +153,9 @@ PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); +PyAPI_FUNC(int) PyThreadState_GetBytesWarningFlag(); +PyAPI_FUNC(void) PyThreadState_SetBytesWarningFlag(int); + /* Variable and macro for in-line access to current thread state */ diff -r d5536c06a082 -r c4d6f29a6ea3 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Fri Jul 05 01:40:52 2013 +0200 +++ b/Objects/bytearrayobject.c Fri Jul 05 18:52:35 2013 -0400 @@ -937,7 +937,7 @@ static PyObject * bytearray_str(PyObject *op) { - if (Py_BytesWarningFlag) { + if (PyThreadState_GetBytesWarningFlag()) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytearray instance", 1)) return NULL; @@ -959,7 +959,7 @@ error, even if the comparison is for equality. */ if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) || PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) { - if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) { + if (PyThreadState_GetBytesWarningFlag() && (op == Py_EQ || op == Py_NE)) { if (PyErr_WarnEx(PyExc_BytesWarning, "Comparison between bytearray and string", 1)) return NULL; diff -r d5536c06a082 -r c4d6f29a6ea3 Objects/bytesobject.c --- a/Objects/bytesobject.c Fri Jul 05 01:40:52 2013 +0200 +++ b/Objects/bytesobject.c Fri Jul 05 18:52:35 2013 -0400 @@ -654,7 +654,7 @@ static PyObject * bytes_str(PyObject *op) { - if (Py_BytesWarningFlag) { + if (PyThreadState_GetBytesWarningFlag()) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytes instance", 1)) return NULL; @@ -812,7 +812,7 @@ /* Make sure both arguments are strings. */ if (!(PyBytes_Check(a) && PyBytes_Check(b))) { - if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE) && + if (PyThreadState_GetBytesWarningFlag() && (op == Py_EQ || op == Py_NE) && (PyObject_IsInstance((PyObject*)a, (PyObject*)&PyUnicode_Type) || PyObject_IsInstance((PyObject*)b, diff -r d5536c06a082 -r c4d6f29a6ea3 Python/_warnings.c --- a/Python/_warnings.c Fri Jul 05 01:40:52 2013 +0200 +++ b/Python/_warnings.c Fri Jul 05 18:52:35 2013 -0400 @@ -953,9 +953,9 @@ create_filter(PyExc_PendingDeprecationWarning, "ignore")); PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ImportWarning, "ignore")); - if (Py_BytesWarningFlag > 1) + if (PyThreadState_GetBytesWarningFlag() > 1) bytes_action = "error"; - else if (Py_BytesWarningFlag) + else if (PyThreadState_GetBytesWarningFlag()) bytes_action = "default"; else bytes_action = "ignore"; diff -r d5536c06a082 -r c4d6f29a6ea3 Python/pystate.c --- a/Python/pystate.c Fri Jul 05 01:40:52 2013 +0200 +++ b/Python/pystate.c Fri Jul 05 18:52:35 2013 -0400 @@ -209,6 +209,8 @@ tstate->trash_delete_nesting = 0; tstate->trash_delete_later = NULL; + tstate->byteswarning = Py_BytesWarningFlag; + if (init) _PyThreadState_Init(tstate); @@ -498,6 +500,21 @@ return tstate->dict; } +/* Adjust whether str(bytes) and str(bytearray) does nothing, warns or raises + * an exception at runtime + */ +int +PyThreadState_GetBytesWarningFlag() { + PyThreadState *tstate = PyThreadState_GET(); + return tstate->byteswarning; +} + +void +PyThreadState_SetBytesWarningFlag(int value) { + PyThreadState *tstate = PyThreadState_GET(); + tstate->byteswarning = value; +} + /* Asynchronously raise an exception in a thread. Requested by Just van Rossum and Alex Martelli. diff -r d5536c06a082 -r c4d6f29a6ea3 Python/sysmodule.c --- a/Python/sysmodule.c Fri Jul 05 01:40:52 2013 +0200 +++ b/Python/sysmodule.c Fri Jul 05 18:52:35 2013 -0400 @@ -611,6 +611,34 @@ return Py_None; } +PyDoc_STRVAR(setbyteswarningflag_doc, +"setbyteswarningflag(flag)\n\ +\n\ +Set the thread local bytes warning flag. It controls whether str(b'bytes')\n" +"is ignored, a warning, or an error.\n" +); +static PyObject * +sys_setbyteswarningflag(PyObject *self, PyObject *o) +{ + long byteswarningflag = PyLong_AsLong(o); + PyThreadState_SetBytesWarningFlag(byteswarningflag); + return Py_None; +} + +PyDoc_STRVAR(getbyteswarningflag_doc, +"getbyteswarningflag()\n\ +\n\ +Get the thread local bytes warning flag. It controls whether str(b'bytes')\n" +"is ignored, a warning, or an error.\n" +); + +static PyObject * +sys_getbyteswarningflag(PyObject *self) +{ + int byteswarningflag = PyThreadState_GetBytesWarningFlag(); + return PyLong_FromLong(byteswarningflag); +} + static PyTypeObject Hash_InfoType; PyDoc_STRVAR(hash_info_doc, @@ -1131,6 +1159,8 @@ {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, {"_debugmallocstats", sys_debugmallocstats, METH_VARARGS, debugmallocstats_doc}, + {"getbyteswarningflag", sys_getbyteswarningflag, METH_NOARGS, getbyteswarningflag_doc}, + {"setbyteswarningflag", sys_setbyteswarningflag, METH_O, setbyteswarningflag_doc}, {NULL, NULL} /* sentinel */ };