diff -r 6f0f77333da5 Include/unicodeobject.h --- a/Include/unicodeobject.h Wed Nov 16 10:19:57 2016 +0200 +++ b/Include/unicodeobject.h Wed Nov 16 19:27:48 2016 +0800 @@ -2037,7 +2037,11 @@ ); #ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyUnicode_CompareWithId( +/* Test whether a unicode is equal to ASCII identifier. Return 1 if true, + 0 otherwise. Return 0 if any argument contains non-ASCII characters. + Any error occurs inside will be cleared before return. */ + +PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId( PyObject *left, /* Left string */ _Py_Identifier *right /* Right identifier */ ); diff -r 6f0f77333da5 Objects/typeobject.c --- a/Objects/typeobject.c Wed Nov 16 10:19:57 2016 +0200 +++ b/Objects/typeobject.c Wed Nov 16 19:27:48 2016 +0800 @@ -863,7 +863,7 @@ return NULL; } - if (mod != NULL && _PyUnicode_CompareWithId(mod, &PyId_builtins)) + if (mod != NULL && !_PyUnicode_EqualToASCIIId(mod, &PyId_builtins)) rtn = PyUnicode_FromFormat("", mod, name); else rtn = PyUnicode_FromFormat("", type->tp_name); @@ -2403,7 +2403,7 @@ if (!valid_identifier(tmp)) goto error; assert(PyUnicode_Check(tmp)); - if (_PyUnicode_CompareWithId(tmp, &PyId___dict__) == 0) { + if (_PyUnicode_EqualToASCIIId(tmp, &PyId___dict__)) { if (!may_add_dict || add_dict) { PyErr_SetString(PyExc_TypeError, "__dict__ slot disallowed: " @@ -2434,7 +2434,7 @@ for (i = j = 0; i < nslots; i++) { tmp = PyTuple_GET_ITEM(slots, i); if ((add_dict && - _PyUnicode_CompareWithId(tmp, &PyId___dict__) == 0) || + _PyUnicode_EqualToASCIIId(tmp, &PyId___dict__)) || (add_weak && _PyUnicode_EqualToASCIIString(tmp, "__weakref__"))) continue; @@ -3538,7 +3538,7 @@ Py_XDECREF(mod); return NULL; } - if (mod != NULL && _PyUnicode_CompareWithId(mod, &PyId_builtins)) + if (mod != NULL && !_PyUnicode_EqualToASCIIId(mod, &PyId_builtins)) rtn = PyUnicode_FromFormat("<%U.%U object at %p>", mod, name, self); else rtn = PyUnicode_FromFormat("<%s object at %p>", @@ -7238,7 +7238,7 @@ (i.e. super, or a subclass), not the class of su->obj. */ if (PyUnicode_Check(name) && PyUnicode_GET_LENGTH(name) == 9 && - _PyUnicode_CompareWithId(name, &PyId___class__) == 0) + _PyUnicode_EqualToASCIIId(name, &PyId___class__)) goto skip; mro = starttype->tp_mro; @@ -7450,7 +7450,7 @@ for (i = 0; i < n; i++) { PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); assert(PyUnicode_Check(name)); - if (!_PyUnicode_CompareWithId(name, &PyId___class__)) { + if (_PyUnicode_EqualToASCIIId(name, &PyId___class__)) { Py_ssize_t index = co->co_nlocals + PyTuple_GET_SIZE(co->co_cellvars) + i; PyObject *cell = f->f_localsplus[index]; diff -r 6f0f77333da5 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Wed Nov 16 10:19:57 2016 +0200 +++ b/Objects/unicodeobject.c Wed Nov 16 19:27:48 2016 +0800 @@ -10993,15 +10993,6 @@ } int -_PyUnicode_CompareWithId(PyObject *left, _Py_Identifier *right) -{ - PyObject *right_str = _PyUnicode_FromId(right); /* borrowed */ - if (right_str == NULL) - return -1; - return PyUnicode_Compare(left, right_str); -} - -int PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) { Py_ssize_t i; @@ -11083,6 +11074,48 @@ memcmp(PyUnicode_1BYTE_DATA(unicode), str, len) == 0; } +int +_PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right) +{ + PyObject *right_uni; + Py_hash_t hash; + size_t len; + + assert(_PyUnicode_CHECK(left)); + assert(right->string); + + if (PyUnicode_READY(left) == -1) { + /* memory error or bad data */ + PyErr_Clear(); + return non_ready_unicode_equal_to_ascii_string(left, right->string); + } + + if (!PyUnicode_IS_ASCII(left)) + return 0; + len = (size_t)PyUnicode_GET_LENGTH(left); + + right_uni = _PyUnicode_FromId(right); /* borrowed */ + if (right_uni == NULL) { + /* memory error or bad data */ + PyErr_Clear(); + return strlen(right->string) == len && + memcmp(PyUnicode_1BYTE_DATA(left), right->string, len) == 0; + } + + if (left == right_uni) { + return 1; + } + else if (PyUnicode_CHECK_INTERNED(left)) { + return 0; + } + + assert(_PyUnicode_HASH(right_uni) != 1); + hash = _PyUnicode_HASH(left); + if ((hash != -1) && hash != _PyUnicode_HASH(right_uni)) + return 0; + + return unicode_compare_eq(left, right_uni); +} #define TEST_COND(cond) \ ((cond) ? Py_True : Py_False) diff -r 6f0f77333da5 Python/errors.c --- a/Python/errors.c Wed Nov 16 10:19:57 2016 +0200 +++ b/Python/errors.c Wed Nov 16 19:27:48 2016 +0800 @@ -984,7 +984,7 @@ goto done; } else { - if (_PyUnicode_CompareWithId(moduleName, &PyId_builtins) != 0) { + if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { if (PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) < 0) goto done; if (PyFile_WriteString(".", f) < 0) diff -r 6f0f77333da5 Python/pythonrun.c --- a/Python/pythonrun.c Wed Nov 16 10:19:57 2016 +0200 +++ b/Python/pythonrun.c Wed Nov 16 19:27:48 2016 +0800 @@ -751,7 +751,7 @@ err = PyFile_WriteString("", f); } else { - if (_PyUnicode_CompareWithId(moduleName, &PyId_builtins) != 0) + if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); err += PyFile_WriteString(".", f);