# HG changeset patch # User Eric Snow # Date 1463064725 21600 # Thu May 12 08:52:05 2016 -0600 # Node ID b734ecfbcf2e11bb9b824a27237584e004ca636d # Parent fceaa0dc715e0eb833f62a12223fd83df41e5fb5 Issue #24254: Default to OrderedDict for the class definition namespace. diff --git a/Doc/library/types.rst b/Doc/library/types.rst --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -55,6 +55,11 @@ .. versionadded:: 3.3 + .. versionchanged:: 3.6 + When the metaclass does not have a ``__prepare__`` attribute, + ``prepare_class`` defaults to returning a new + :class:`collections.OrderedDict` instance instead of :func:`dict`. + .. seealso:: :ref:`metaclasses` diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1692,7 +1692,10 @@ additional keyword arguments, if any, come from the class definition). If the metaclass has no ``__prepare__`` attribute, then the class namespace -is initialised as an empty :func:`dict` instance. +is initialised as an empty :class:`collections.OrderedDict` instance. + +.. versionchanged:: 3.6 + Defaults to :class:`collections.OrderedDict` instead of :func:`dict`. .. seealso:: diff --git a/Lib/test/test_metaclass.py b/Lib/test/test_metaclass.py --- a/Lib/test/test_metaclass.py +++ b/Lib/test/test_metaclass.py @@ -180,7 +180,7 @@ meta: C () ns: [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)] kw: [] - >>> type(C) is dict + >>> type(C) is OrderedDict True >>> print(sorted(C.items())) [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)] @@ -212,7 +212,7 @@ The default metaclass must define a __prepare__() method. >>> type.__prepare__() - {} + OrderedDict() >>> Make sure it works with subclassing. @@ -248,6 +248,7 @@ """ +from collections import OrderedDict import sys # Trace function introduces __locals__ which causes various tests to fail. diff --git a/Lib/types.py b/Lib/types.py --- a/Lib/types.py +++ b/Lib/types.py @@ -85,7 +85,13 @@ if hasattr(meta, '__prepare__'): ns = meta.__prepare__(name, bases, **kwds) else: - ns = {} + # We follow the pattern in this module of extracting types from + # builtins, rather than using collections.OrderedDict directly. + nstype = None + class _: + nonlocal nstype + nstype = type(locals()) + ns = nstype() return meta, ns, kwds def _calculate_meta(meta, bases): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -61,6 +61,9 @@ - Issue #21099: Switch applicable importlib tests to use PEP 451 API. +- Issue #24254: Default to using OrderedDict in the class *definition* + namespace. + - Issue #26563: Debug hooks on Python memory allocators now raise a fatal error if functions of the :c:func:`PyMem_Malloc` family are called without holding the GIL. diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2340,6 +2340,7 @@ goto error; } + /* Copy the definition namespace into a new dict. */ dict = PyDict_Copy(orig_dict); if (dict == NULL) goto error; @@ -3082,7 +3083,7 @@ static PyObject * type_prepare(PyObject *self, PyObject *args, PyObject *kwds) { - return PyDict_New(); + return PyODict_New(); } /* diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -145,7 +145,7 @@ if (prep == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); - ns = PyDict_New(); + ns = PyODict_New(); } else { Py_DECREF(meta);