Issue #18594: Fix the fast path for collections.Counter().
The path wasn't being taken due to an over-restrictive type check.
This commit is contained in:
parent
21b2933456
commit
2ff2190b62
|
@ -482,6 +482,7 @@ PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *,
|
||||||
PyObject *, PyObject *);
|
PyObject *, PyObject *);
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
|
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
|
||||||
|
PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *);
|
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *);
|
||||||
PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
|
PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,6 +74,9 @@ Library
|
||||||
- Issue #12641: Avoid passing "-mno-cygwin" to the mingw32 compiler, except
|
- Issue #12641: Avoid passing "-mno-cygwin" to the mingw32 compiler, except
|
||||||
when necessary. Patch by Oscar Benjamin.
|
when necessary. Patch by Oscar Benjamin.
|
||||||
|
|
||||||
|
- Issue #18594: The fast path for collections.Counter() was never taken
|
||||||
|
due to an over-restrictive type check.
|
||||||
|
|
||||||
- Properly initialize all fields of a SSL object after allocation.
|
- Properly initialize all fields of a SSL object after allocation.
|
||||||
|
|
||||||
- Issue #4366: Fix building extensions on all platforms when --enable-shared
|
- Issue #4366: Fix building extensions on all platforms when --enable-shared
|
||||||
|
|
|
@ -1689,10 +1689,16 @@ Count elements in the iterable, updating the mappping");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_count_elements(PyObject *self, PyObject *args)
|
_count_elements(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(__getitem__);
|
||||||
|
_Py_IDENTIFIER(__setitem__);
|
||||||
PyObject *it, *iterable, *mapping, *oldval;
|
PyObject *it, *iterable, *mapping, *oldval;
|
||||||
PyObject *newval = NULL;
|
PyObject *newval = NULL;
|
||||||
PyObject *key = NULL;
|
PyObject *key = NULL;
|
||||||
PyObject *one = NULL;
|
PyObject *one = NULL;
|
||||||
|
PyObject *mapping_getitem;
|
||||||
|
PyObject *mapping_setitem;
|
||||||
|
PyObject *dict_getitem;
|
||||||
|
PyObject *dict_setitem;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "_count_elements", 2, 2, &mapping, &iterable))
|
if (!PyArg_UnpackTuple(args, "_count_elements", 2, 2, &mapping, &iterable))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1707,7 +1713,15 @@ _count_elements(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyDict_CheckExact(mapping)) {
|
mapping_getitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___getitem__);
|
||||||
|
dict_getitem = _PyType_LookupId(&PyDict_Type, &PyId___getitem__);
|
||||||
|
mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__);
|
||||||
|
dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__);
|
||||||
|
|
||||||
|
if (mapping_getitem != NULL &&
|
||||||
|
mapping_getitem == dict_getitem &&
|
||||||
|
mapping_setitem != NULL &&
|
||||||
|
mapping_setitem == dict_setitem) {
|
||||||
while (1) {
|
while (1) {
|
||||||
key = PyIter_Next(it);
|
key = PyIter_Next(it);
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
|
|
|
@ -49,9 +49,6 @@ _Py_IDENTIFIER(__module__);
|
||||||
_Py_IDENTIFIER(__name__);
|
_Py_IDENTIFIER(__name__);
|
||||||
_Py_IDENTIFIER(__new__);
|
_Py_IDENTIFIER(__new__);
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
_PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name);
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
||||||
|
|
||||||
|
@ -2589,7 +2586,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
PyObject *
|
||||||
_PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name)
|
_PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name)
|
||||||
{
|
{
|
||||||
PyObject *oname;
|
PyObject *oname;
|
||||||
|
|
Loading…
Reference in New Issue