From 4f29e75289592991efcc65a96a2a4a995417b76e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 8 Sep 2016 15:11:11 -0700 Subject: [PATCH] Issue #24254: Drop cls.__definition_order__. --- Doc/library/inspect.rst | 367 +++++++++++++++---------------- Doc/library/types.rst | 10 +- Doc/reference/compound_stmts.rst | 12 +- Doc/reference/datamodel.rst | 7 - Include/object.h | 2 - Include/odictobject.h | 4 - Lib/test/test_builtin.py | 192 +--------------- Lib/test/test_metaclass.py | 11 +- Lib/test/test_pydoc.py | 8 +- Lib/test/test_sys.py | 2 +- Lib/test/test_types.py | 22 -- Lib/types.py | 5 +- Lib/typing.py | 1 - Objects/odictobject.c | 15 -- Objects/typeobject.c | 66 +----- Python/bltinmodule.c | 2 +- 16 files changed, 193 insertions(+), 533 deletions(-) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 1977d88a2b5..5cb7c22adbe 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -34,190 +34,185 @@ provided as convenient choices for the second argument to :func:`getmembers`. They also help you determine when you can expect to find the following special attributes: -+-----------+----------------------+---------------------------+ -| Type | Attribute | Description | -+===========+======================+===========================+ -| module | __doc__ | documentation string | -+-----------+----------------------+---------------------------+ -| | __file__ | filename (missing for | -| | | built-in modules) | -+-----------+----------------------+---------------------------+ -| class | __doc__ | documentation string | -+-----------+----------------------+---------------------------+ -| | __name__ | name with which this | -| | | class was defined | -+-----------+----------------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+----------------------+---------------------------+ -| | __module__ | name of module in which | -| | | this class was defined | -+-----------+----------------------+---------------------------+ -| | __definition_order__ | the names of the class's | -| | | attributes, in the order | -| | | in which they were | -| | | defined (if known) | -+-----------+----------------------+---------------------------+ -| method | __doc__ | documentation string | -+-----------+----------------------+---------------------------+ -| | __name__ | name with which this | -| | | method was defined | -+-----------+----------------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+----------------------+---------------------------+ -| | __func__ | function object | -| | | containing implementation | -| | | of method | -+-----------+----------------------+---------------------------+ -| | __self__ | instance to which this | -| | | method is bound, or | -| | | ``None`` | -+-----------+----------------------+---------------------------+ -| function | __doc__ | documentation string | -+-----------+----------------------+---------------------------+ -| | __name__ | name with which this | -| | | function was defined | -+-----------+----------------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+----------------------+---------------------------+ -| | __code__ | code object containing | -| | | compiled function | -| | | :term:`bytecode` | -+-----------+----------------------+---------------------------+ -| | __defaults__ | tuple of any default | -| | | values for positional or | -| | | keyword parameters | -+-----------+----------------------+---------------------------+ -| | __kwdefaults__ | mapping of any default | -| | | values for keyword-only | -| | | parameters | -+-----------+----------------------+---------------------------+ -| | __globals__ | global namespace in which | -| | | this function was defined | -+-----------+----------------------+---------------------------+ -| | __annotations__ | mapping of parameters | -| | | names to annotations; | -| | | ``"return"`` key is | -| | | reserved for return | -| | | annotations. | -+-----------+----------------------+---------------------------+ -| traceback | tb_frame | frame object at this | -| | | level | -+-----------+----------------------+---------------------------+ -| | tb_lasti | index of last attempted | -| | | instruction in bytecode | -+-----------+----------------------+---------------------------+ -| | tb_lineno | current line number in | -| | | Python source code | -+-----------+----------------------+---------------------------+ -| | tb_next | next inner traceback | -| | | object (called by this | -| | | level) | -+-----------+----------------------+---------------------------+ -| frame | f_back | next outer frame object | -| | | (this frame's caller) | -+-----------+----------------------+---------------------------+ -| | f_builtins | builtins namespace seen | -| | | by this frame | -+-----------+----------------------+---------------------------+ -| | f_code | code object being | -| | | executed in this frame | -+-----------+----------------------+---------------------------+ -| | f_globals | global namespace seen by | -| | | this frame | -+-----------+----------------------+---------------------------+ -| | f_lasti | index of last attempted | -| | | instruction in bytecode | -+-----------+----------------------+---------------------------+ -| | f_lineno | current line number in | -| | | Python source code | -+-----------+----------------------+---------------------------+ -| | f_locals | local namespace seen by | -| | | this frame | -+-----------+----------------------+---------------------------+ -| | f_restricted | 0 or 1 if frame is in | -| | | restricted execution mode | -+-----------+----------------------+---------------------------+ -| | f_trace | tracing function for this | -| | | frame, or ``None`` | -+-----------+----------------------+---------------------------+ -| code | co_argcount | number of arguments (not | -| | | including \* or \*\* | -| | | args) | -+-----------+----------------------+---------------------------+ -| | co_code | string of raw compiled | -| | | bytecode | -+-----------+----------------------+---------------------------+ -| | co_consts | tuple of constants used | -| | | in the bytecode | -+-----------+----------------------+---------------------------+ -| | co_filename | name of file in which | -| | | this code object was | -| | | created | -+-----------+----------------------+---------------------------+ -| | co_firstlineno | number of first line in | -| | | Python source code | -+-----------+----------------------+---------------------------+ -| | co_flags | bitmap: 1=optimized ``|`` | -| | | 2=newlocals ``|`` 4=\*arg | -| | | ``|`` 8=\*\*arg | -+-----------+----------------------+---------------------------+ -| | co_lnotab | encoded mapping of line | -| | | numbers to bytecode | -| | | indices | -+-----------+----------------------+---------------------------+ -| | co_name | name with which this code | -| | | object was defined | -+-----------+----------------------+---------------------------+ -| | co_names | tuple of names of local | -| | | variables | -+-----------+----------------------+---------------------------+ -| | co_nlocals | number of local variables | -+-----------+----------------------+---------------------------+ -| | co_stacksize | virtual machine stack | -| | | space required | -+-----------+----------------------+---------------------------+ -| | co_varnames | tuple of names of | -| | | arguments and local | -| | | variables | -+-----------+----------------------+---------------------------+ -| generator | __name__ | name | -+-----------+----------------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+----------------------+---------------------------+ -| | gi_frame | frame | -+-----------+----------------------+---------------------------+ -| | gi_running | is the generator running? | -+-----------+----------------------+---------------------------+ -| | gi_code | code | -+-----------+----------------------+---------------------------+ -| | gi_yieldfrom | object being iterated by | -| | | ``yield from``, or | -| | | ``None`` | -+-----------+----------------------+---------------------------+ -| coroutine | __name__ | name | -+-----------+----------------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+----------------------+---------------------------+ -| | cr_await | object being awaited on, | -| | | or ``None`` | -+-----------+----------------------+---------------------------+ -| | cr_frame | frame | -+-----------+----------------------+---------------------------+ -| | cr_running | is the coroutine running? | -+-----------+----------------------+---------------------------+ -| | cr_code | code | -+-----------+----------------------+---------------------------+ -| builtin | __doc__ | documentation string | -+-----------+----------------------+---------------------------+ -| | __name__ | original name of this | -| | | function or method | -+-----------+----------------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+----------------------+---------------------------+ -| | __self__ | instance to which a | -| | | method is bound, or | -| | | ``None`` | -+-----------+----------------------+---------------------------+ ++-----------+-----------------+---------------------------+ +| Type | Attribute | Description | ++===========+=================+===========================+ +| module | __doc__ | documentation string | ++-----------+-----------------+---------------------------+ +| | __file__ | filename (missing for | +| | | built-in modules) | ++-----------+-----------------+---------------------------+ +| class | __doc__ | documentation string | ++-----------+-----------------+---------------------------+ +| | __name__ | name with which this | +| | | class was defined | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | __module__ | name of module in which | +| | | this class was defined | ++-----------+-----------------+---------------------------+ +| method | __doc__ | documentation string | ++-----------+-----------------+---------------------------+ +| | __name__ | name with which this | +| | | method was defined | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | __func__ | function object | +| | | containing implementation | +| | | of method | ++-----------+-----------------+---------------------------+ +| | __self__ | instance to which this | +| | | method is bound, or | +| | | ``None`` | ++-----------+-----------------+---------------------------+ +| function | __doc__ | documentation string | ++-----------+-----------------+---------------------------+ +| | __name__ | name with which this | +| | | function was defined | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | __code__ | code object containing | +| | | compiled function | +| | | :term:`bytecode` | ++-----------+-----------------+---------------------------+ +| | __defaults__ | tuple of any default | +| | | values for positional or | +| | | keyword parameters | ++-----------+-----------------+---------------------------+ +| | __kwdefaults__ | mapping of any default | +| | | values for keyword-only | +| | | parameters | ++-----------+-----------------+---------------------------+ +| | __globals__ | global namespace in which | +| | | this function was defined | ++-----------+-----------------+---------------------------+ +| | __annotations__ | mapping of parameters | +| | | names to annotations; | +| | | ``"return"`` key is | +| | | reserved for return | +| | | annotations. | ++-----------+-----------------+---------------------------+ +| traceback | tb_frame | frame object at this | +| | | level | ++-----------+-----------------+---------------------------+ +| | tb_lasti | index of last attempted | +| | | instruction in bytecode | ++-----------+-----------------+---------------------------+ +| | tb_lineno | current line number in | +| | | Python source code | ++-----------+-----------------+---------------------------+ +| | tb_next | next inner traceback | +| | | object (called by this | +| | | level) | ++-----------+-----------------+---------------------------+ +| frame | f_back | next outer frame object | +| | | (this frame's caller) | ++-----------+-----------------+---------------------------+ +| | f_builtins | builtins namespace seen | +| | | by this frame | ++-----------+-----------------+---------------------------+ +| | f_code | code object being | +| | | executed in this frame | ++-----------+-----------------+---------------------------+ +| | f_globals | global namespace seen by | +| | | this frame | ++-----------+-----------------+---------------------------+ +| | f_lasti | index of last attempted | +| | | instruction in bytecode | ++-----------+-----------------+---------------------------+ +| | f_lineno | current line number in | +| | | Python source code | ++-----------+-----------------+---------------------------+ +| | f_locals | local namespace seen by | +| | | this frame | ++-----------+-----------------+---------------------------+ +| | f_restricted | 0 or 1 if frame is in | +| | | restricted execution mode | ++-----------+-----------------+---------------------------+ +| | f_trace | tracing function for this | +| | | frame, or ``None`` | ++-----------+-----------------+---------------------------+ +| code | co_argcount | number of arguments (not | +| | | including \* or \*\* | +| | | args) | ++-----------+-----------------+---------------------------+ +| | co_code | string of raw compiled | +| | | bytecode | ++-----------+-----------------+---------------------------+ +| | co_consts | tuple of constants used | +| | | in the bytecode | ++-----------+-----------------+---------------------------+ +| | co_filename | name of file in which | +| | | this code object was | +| | | created | ++-----------+-----------------+---------------------------+ +| | co_firstlineno | number of first line in | +| | | Python source code | ++-----------+-----------------+---------------------------+ +| | co_flags | bitmap: 1=optimized ``|`` | +| | | 2=newlocals ``|`` 4=\*arg | +| | | ``|`` 8=\*\*arg | ++-----------+-----------------+---------------------------+ +| | co_lnotab | encoded mapping of line | +| | | numbers to bytecode | +| | | indices | ++-----------+-----------------+---------------------------+ +| | co_name | name with which this code | +| | | object was defined | ++-----------+-----------------+---------------------------+ +| | co_names | tuple of names of local | +| | | variables | ++-----------+-----------------+---------------------------+ +| | co_nlocals | number of local variables | ++-----------+-----------------+---------------------------+ +| | co_stacksize | virtual machine stack | +| | | space required | ++-----------+-----------------+---------------------------+ +| | co_varnames | tuple of names of | +| | | arguments and local | +| | | variables | ++-----------+-----------------+---------------------------+ +| generator | __name__ | name | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | gi_frame | frame | ++-----------+-----------------+---------------------------+ +| | gi_running | is the generator running? | ++-----------+-----------------+---------------------------+ +| | gi_code | code | ++-----------+-----------------+---------------------------+ +| | gi_yieldfrom | object being iterated by | +| | | ``yield from``, or | +| | | ``None`` | ++-----------+-----------------+---------------------------+ +| coroutine | __name__ | name | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | cr_await | object being awaited on, | +| | | or ``None`` | ++-----------+-----------------+---------------------------+ +| | cr_frame | frame | ++-----------+-----------------+---------------------------+ +| | cr_running | is the coroutine running? | ++-----------+-----------------+---------------------------+ +| | cr_code | code | ++-----------+-----------------+---------------------------+ +| builtin | __doc__ | documentation string | ++-----------+-----------------+---------------------------+ +| | __name__ | original name of this | +| | | function or method | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | __self__ | instance to which a | +| | | method is bound, or | +| | | ``None`` | ++-----------+-----------------+---------------------------+ .. versionchanged:: 3.5 @@ -226,10 +221,6 @@ attributes: The ``__name__`` attribute of generators is now set from the function name, instead of the code name, and it can now be modified. -.. versionchanged:: 3.6 - - Add ``__definition_order__`` to classes. - .. function:: getmembers(object[, predicate]) diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 5eb84c1886c..898b95a940c 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -53,19 +53,13 @@ Dynamic Type Creation in *kwds* argument with any ``'metaclass'`` entry removed. If no *kwds* argument is passed in, this will be an empty dict. - .. impl-detail:: - - CPython uses :class:`collections.OrderedDict` for the default - namespace. - .. versionadded:: 3.3 .. versionchanged:: 3.6 The default value for the ``namespace`` element of the returned - tuple has changed from :func:`dict`. Now an insertion-order- - preserving mapping is used when the metaclass does not have a - ``__prepare__`` method, + tuple has changed. Now an insertion-order-preserving mapping is + used when the metaclass does not have a ``__prepare__`` method, .. seealso:: diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index ffdeae04e56..4fc6af02f12 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -634,15 +634,9 @@ dictionary. The class name is bound to this class object in the original local namespace. The order in which attributes are defined in the class body is preserved -in the ``__definition_order__`` attribute on the new class. If that order -is not known then the attribute is set to :const:`None`. The class body -may include a ``__definition_order__`` attribute. In that case it is used -directly. The value must be a tuple of identifiers or ``None``, otherwise -:exc:`TypeError` will be raised when the class statement is executed. - -.. versionchanged:: 3.6 - - Add ``__definition_order__`` to classes. +in the new class's ``__dict__``. Note that this is reliable only right +after the class is created and only for classes that were defined using +the definition syntax. Class creation can be customized heavily using :ref:`metaclasses `. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 00785ed39c6..a0755039f7d 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1752,13 +1752,6 @@ 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 ordered mapping. -.. impl-detail:: - - In CPython the default is :class:`collections.OrderedDict`. - -.. versionchanged:: 3.6 - Defaults to :class:`collections.OrderedDict` instead of :func:`dict`. - .. seealso:: :pep:`3115` - Metaclasses in Python 3000 diff --git a/Include/object.h b/Include/object.h index 9e1ffd3fcfa..5b4ef98c947 100644 --- a/Include/object.h +++ b/Include/object.h @@ -421,8 +421,6 @@ typedef struct _typeobject { destructor tp_finalize; - PyObject *tp_deforder; - #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ Py_ssize_t tp_allocs; diff --git a/Include/odictobject.h b/Include/odictobject.h index ca865c73562..c1d9592a1db 100644 --- a/Include/odictobject.h +++ b/Include/odictobject.h @@ -28,10 +28,6 @@ PyAPI_FUNC(PyObject *) PyODict_New(void); PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyODict_KeysAsTuple(PyObject *od); -#endif - /* wrappers around PyDict* functions */ #define PyODict_GetItem(od, key) PyDict_GetItem((PyObject *)od, key) #define PyODict_GetItemWithError(od, key) \ diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index c0343eff689..e0cffe1d9c4 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -16,10 +16,8 @@ import traceback import types import unittest import warnings -from collections import OrderedDict from operator import neg -from test.support import (TESTFN, unlink, run_unittest, check_warnings, - cpython_only) +from test.support import TESTFN, unlink, run_unittest, check_warnings from test.support.script_helper import assert_python_ok try: import pty, signal @@ -1780,194 +1778,6 @@ class TestType(unittest.TestCase): A.__doc__ = doc self.assertEqual(A.__doc__, doc) - def test_type_definition_order_nonempty(self): - class Spam: - b = 1 - c = 3 - a = 2 - d = 4 - eggs = 2 - e = 5 - b = 42 - - self.assertEqual(Spam.__definition_order__, - ('__module__', '__qualname__', - 'b', 'c', 'a', 'd', 'eggs', 'e')) - - def test_type_definition_order_empty(self): - class Empty: - pass - - self.assertEqual(Empty.__definition_order__, - ('__module__', '__qualname__')) - - def test_type_definition_order_on_instance(self): - class Spam: - a = 2 - b = 1 - c = 3 - with self.assertRaises(AttributeError): - Spam().__definition_order__ - - def test_type_definition_order_set_to_None(self): - class Spam: - a = 2 - b = 1 - c = 3 - Spam.__definition_order__ = None - self.assertEqual(Spam.__definition_order__, None) - - def test_type_definition_order_set_to_tuple(self): - class Spam: - a = 2 - b = 1 - c = 3 - Spam.__definition_order__ = ('x', 'y', 'z') - self.assertEqual(Spam.__definition_order__, ('x', 'y', 'z')) - - def test_type_definition_order_deleted(self): - class Spam: - a = 2 - b = 1 - c = 3 - del Spam.__definition_order__ - self.assertEqual(Spam.__definition_order__, None) - - def test_type_definition_order_set_to_bad_type(self): - class Spam: - a = 2 - b = 1 - c = 3 - Spam.__definition_order__ = 42 - self.assertEqual(Spam.__definition_order__, 42) - - def test_type_definition_order_builtins(self): - self.assertEqual(object.__definition_order__, None) - self.assertEqual(type.__definition_order__, None) - self.assertEqual(dict.__definition_order__, None) - self.assertEqual(type(None).__definition_order__, None) - - def test_type_definition_order_dunder_names_included(self): - class Dunder: - VAR = 3 - def __init__(self): - pass - - self.assertEqual(Dunder.__definition_order__, - ('__module__', '__qualname__', - 'VAR', '__init__')) - - def test_type_definition_order_only_dunder_names(self): - class DunderOnly: - __xyz__ = None - def __init__(self): - pass - - self.assertEqual(DunderOnly.__definition_order__, - ('__module__', '__qualname__', - '__xyz__', '__init__')) - - def test_type_definition_order_underscore_names(self): - class HalfDunder: - __whether_to_be = True - or_not_to_be__ = False - - self.assertEqual(HalfDunder.__definition_order__, - ('__module__', '__qualname__', - '_HalfDunder__whether_to_be', 'or_not_to_be__')) - - def test_type_definition_order_with_slots(self): - class Slots: - __slots__ = ('x', 'y') - a = 1 - b = 2 - - self.assertEqual(Slots.__definition_order__, - ('__module__', '__qualname__', - '__slots__', 'a', 'b')) - - def test_type_definition_order_overwritten_None(self): - class OverwrittenNone: - __definition_order__ = None - a = 1 - b = 2 - c = 3 - - self.assertEqual(OverwrittenNone.__definition_order__, None) - - def test_type_definition_order_overwritten_tuple(self): - class OverwrittenTuple: - __definition_order__ = ('x', 'y', 'z') - a = 1 - b = 2 - c = 3 - - self.assertEqual(OverwrittenTuple.__definition_order__, - ('x', 'y', 'z')) - - def test_type_definition_order_overwritten_bad_item(self): - with self.assertRaises(TypeError): - class PoorlyOverwritten: - __definition_order__ = ('a', 2, 'c') - a = 1 - b = 2 - c = 3 - - def test_type_definition_order_overwritten_bad_type(self): - with self.assertRaises(TypeError): - class PoorlyOverwritten: - __definition_order__ = ['a', 2, 'c'] - a = 1 - b = 2 - c = 3 - - def test_type_definition_order_metaclass(self): - class Meta(type): - SPAM = 42 - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.assertEqual(Meta.__definition_order__, - ('__module__', '__qualname__', - 'SPAM', '__init__')) - - def test_type_definition_order_OrderedDict(self): - class Meta(type): - def __prepare__(self, *args, **kwargs): - return OrderedDict() - - class WithODict(metaclass=Meta): - x='y' - - self.assertEqual(WithODict.__definition_order__, - ('__module__', '__qualname__', 'x')) - - class Meta(type): - def __prepare__(self, *args, **kwargs): - class ODictSub(OrderedDict): - pass - return ODictSub() - - class WithODictSub(metaclass=Meta): - x='y' - - self.assertEqual(WithODictSub.__definition_order__, - ('__module__', '__qualname__', 'x')) - - @cpython_only - def test_type_definition_order_cpython(self): - # some implementations will have an ordered-by-default dict. - - class Meta(type): - def __prepare__(self, *args, **kwargs): - return {} - - class NotOrdered(metaclass=Meta): - x='y' - - self.assertEqual(NotOrdered.__definition_order__, None) - def test_bad_args(self): with self.assertRaises(TypeError): type() diff --git a/Lib/test/test_metaclass.py b/Lib/test/test_metaclass.py index 4db792ecef4..e6fe20a107c 100644 --- a/Lib/test/test_metaclass.py +++ b/Lib/test/test_metaclass.py @@ -180,7 +180,7 @@ Use a metaclass that doesn't derive from type. meta: C () ns: [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)] kw: [] - >>> type(C) is types._DefaultClassNamespaceType + >>> type(C) is dict True >>> print(sorted(C.items())) [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)] @@ -211,11 +211,8 @@ And again, with a __prepare__ attribute. The default metaclass must define a __prepare__() method. - >>> ns = type.__prepare__() - >>> type(ns) is types._DefaultClassNamespaceType - True - >>> list(ns) == [] - True + >>> type.__prepare__() + {} >>> Make sure it works with subclassing. @@ -251,9 +248,7 @@ Test failures in looking up the __prepare__ method work. """ -from collections import OrderedDict import sys -import types # Trace function introduces __locals__ which causes various tests to fail. if hasattr(sys, 'gettrace') and sys.gettrace(): diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 229fff47c9d..17a82c269a3 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -427,7 +427,6 @@ class PydocDocTest(unittest.TestCase): expected_html = expected_html_pattern % ( (mod_url, mod_file, doc_loc) + expected_html_data_docstrings) - self.maxDiff = None self.assertEqual(result, expected_html) @unittest.skipIf(sys.flags.optimize >= 2, @@ -474,18 +473,13 @@ class PydocDocTest(unittest.TestCase): def test_non_str_name(self): # issue14638 # Treat illegal (non-str) name like no name - # Definition order is set to None so it looks the same in both - # cases. class A: - __definition_order__ = None __name__ = 42 class B: pass adoc = pydoc.render_doc(A()) bdoc = pydoc.render_doc(B()) - self.maxDiff = None - expected = adoc.replace("A", "B") - self.assertEqual(bdoc, expected) + self.assertEqual(adoc.replace("A", "B"), bdoc) def test_not_here(self): missing_module = "test.i_am_not_here" diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index aa895069664..a6cd95ed498 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1085,7 +1085,7 @@ class SizeofTest(unittest.TestCase): check((1,2,3), vsize('') + 3*self.P) # type # static type: PyTypeObject - fmt = 'P2n15Pl4Pn9Pn11PIPP' + fmt = 'P2n15Pl4Pn9Pn11PIP' if hasattr(sys, 'getcounts'): fmt += '3n2P' s = vsize(fmt) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index e5e110f9c2f..a202196bd2f 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -825,28 +825,6 @@ class ClassCreationTests(unittest.TestCase): self.assertEqual(C.y, 1) self.assertEqual(C.z, 2) - def test_new_class_deforder(self): - C = types.new_class("C") - self.assertEqual(C.__definition_order__, tuple()) - - Meta = self.Meta - def func(ns): - ns["x"] = 0 - D = types.new_class("D", (), {"metaclass": Meta, "z": 2}, func) - self.assertEqual(D.__definition_order__, ('y', 'z', 'x')) - - def func(ns): - ns["__definition_order__"] = None - ns["x"] = 0 - D = types.new_class("D", (), {"metaclass": Meta, "z": 2}, func) - self.assertEqual(D.__definition_order__, None) - - def func(ns): - ns["__definition_order__"] = ('a', 'b', 'c') - ns["x"] = 0 - D = types.new_class("D", (), {"metaclass": Meta, "z": 2}, func) - self.assertEqual(D.__definition_order__, ('a', 'b', 'c')) - # Many of the following tests are derived from test_descr.py def test_prepare_class(self): # Basic test of metaclass derivation diff --git a/Lib/types.py b/Lib/types.py index cc093cb403d..48891cd3f60 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -25,11 +25,8 @@ CoroutineType = type(_c) _c.close() # Prevent ResourceWarning class _C: - _nsType = type(locals()) def _m(self): pass MethodType = type(_C()._m) -# In CPython, this should end up as OrderedDict. -_DefaultClassNamespaceType = _C._nsType BuiltinFunctionType = type(len) BuiltinMethodType = type([].append) # Same as BuiltinFunctionType @@ -88,7 +85,7 @@ def prepare_class(name, bases=(), kwds=None): if hasattr(meta, '__prepare__'): ns = meta.__prepare__(name, bases, **kwds) else: - ns = _DefaultClassNamespaceType() + ns = {} return meta, ns, kwds def _calculate_meta(meta, bases): diff --git a/Lib/typing.py b/Lib/typing.py index 5f451b0ca18..5573a1fbf93 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1301,7 +1301,6 @@ class _ProtocolMeta(GenericMeta): if (not attr.startswith('_abc_') and attr != '__abstractmethods__' and attr != '_is_protocol' and - attr != '__definition_order__' and attr != '__dict__' and attr != '__args__' and attr != '__slots__' and diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 4a4cd1e0480..5968e3f5d5a 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1765,21 +1765,6 @@ PyODict_DelItem(PyObject *od, PyObject *key) return _PyDict_DelItem_KnownHash(od, key, hash); } -PyObject * -_PyODict_KeysAsTuple(PyObject *od) { - Py_ssize_t i = 0; - _ODictNode *node; - PyObject *keys = PyTuple_New(PyODict_Size(od)); - if (keys == NULL) - return NULL; - _odict_FOREACH((PyODictObject *)od, node) { - Py_INCREF(_odictnode_KEY(node)); - PyTuple_SET_ITEM(keys, i, _odictnode_KEY(node)); - i++; - } - return keys; -} - /* ------------------------------------------- * The OrderedDict views (keys/values/items) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ae593636e6c..42054d42af3 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -48,7 +48,6 @@ static size_t method_cache_collisions = 0; _Py_IDENTIFIER(__abstractmethods__); _Py_IDENTIFIER(__class__); _Py_IDENTIFIER(__delitem__); -_Py_IDENTIFIER(__definition_order__); _Py_IDENTIFIER(__dict__); _Py_IDENTIFIER(__doc__); _Py_IDENTIFIER(__getattribute__); @@ -489,23 +488,6 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context) return _PyDict_SetItemId(type->tp_dict, &PyId___module__, value); } -static PyObject * -type_deforder(PyTypeObject *type, void *context) -{ - if (type->tp_deforder == NULL) - Py_RETURN_NONE; - Py_INCREF(type->tp_deforder); - return type->tp_deforder; -} - -static int -type_set_deforder(PyTypeObject *type, PyObject *value, void *context) -{ - Py_XINCREF(value); - Py_XSETREF(type->tp_deforder, value); - return 0; -} - static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { @@ -852,8 +834,6 @@ static PyGetSetDef type_getsets[] = { {"__qualname__", (getter)type_qualname, (setter)type_set_qualname, NULL}, {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL}, - {"__definition_order__", (getter)type_deforder, - (setter)type_set_deforder, NULL}, {"__abstractmethods__", (getter)type_abstractmethods, (setter)type_set_abstractmethods, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, @@ -2371,7 +2351,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) goto error; } - /* Copy the definition namespace into a new dict. */ dict = PyDict_Copy(orig_dict); if (dict == NULL) goto error; @@ -2580,48 +2559,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) if (qualname != NULL && PyDict_DelItem(dict, PyId___qualname__.object) < 0) goto error; - /* Set tp_deforder to the extracted definition order, if any. */ - type->tp_deforder = _PyDict_GetItemId(dict, &PyId___definition_order__); - if (type->tp_deforder != NULL) { - Py_INCREF(type->tp_deforder); - - // Due to subclass lookup, __definition_order__ can't be in __dict__. - if (_PyDict_DelItemId(dict, &PyId___definition_order__) != 0) { - goto error; - } - - if (type->tp_deforder != Py_None) { - Py_ssize_t numnames; - - if (!PyTuple_Check(type->tp_deforder)) { - PyErr_SetString(PyExc_TypeError, - "__definition_order__ must be a tuple or None"); - goto error; - } - - // Make sure they are identifers. - numnames = PyTuple_Size(type->tp_deforder); - for (i = 0; i < numnames; i++) { - PyObject *name = PyTuple_GET_ITEM(type->tp_deforder, i); - if (name == NULL) { - goto error; - } - if (!PyUnicode_Check(name) || !PyUnicode_IsIdentifier(name)) { - PyErr_Format(PyExc_TypeError, - "__definition_order__ must " - "contain only identifiers, got '%s'", - name); - goto error; - } - } - } - } - else if (PyODict_Check(orig_dict)) { - type->tp_deforder = _PyODict_KeysAsTuple(orig_dict); - if (type->tp_deforder == NULL) - goto error; - } - /* Set tp_doc to a copy of dict['__doc__'], if the latter is there and is a string. The __doc__ accessor will first look for tp_doc; if that fails, it will still look into __dict__. @@ -3136,7 +3073,6 @@ type_dealloc(PyTypeObject *type) Py_XDECREF(type->tp_mro); Py_XDECREF(type->tp_cache); Py_XDECREF(type->tp_subclasses); - Py_XDECREF(type->tp_deforder); /* A type's tp_doc is heap allocated, unlike the tp_doc slots * of most other objects. It's okay to cast it to char *. */ @@ -3179,7 +3115,7 @@ type_subclasses(PyTypeObject *type, PyObject *args_ignored) static PyObject * type_prepare(PyObject *self, PyObject *args, PyObject *kwds) { - return PyODict_New(); + return PyDict_New(); } /* diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 252c0a7b894..da9ad55ce8b 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -147,7 +147,7 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) if (prep == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); - ns = PyODict_New(); + ns = PyDict_New(); } else { Py_DECREF(meta);