cpython: 9aa5424fd1df (original) (raw)
Mercurial > cpython
changeset 103378:9aa5424fd1df
Issue #24254: Drop cls.__definition_order__. [#24254]
Eric Snow ericsnowcurrently@gmail.com | |
---|---|
date | Thu, 08 Sep 2016 15:11:11 -0700 |
parents | a06299a4b00c |
children | 4af9d196cd21 |
files | Doc/library/inspect.rst Doc/library/types.rst Doc/reference/compound_stmts.rst Doc/reference/datamodel.rst Include/object.h Include/odictobject.h Lib/test/test_builtin.py Lib/test/test_metaclass.py Lib/test/test_pydoc.py Lib/test/test_sys.py Lib/test/test_types.py Lib/types.py Lib/typing.py Objects/odictobject.c Objects/typeobject.c Python/bltinmodule.c |
diffstat | 16 files changed, 193 insertions(+), 533 deletions(-)[+] [-] 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 |
line wrap: on
line diff
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -34,190 +34,185 @@ provided as convenient choices for the s
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
-
.. function:: getmembers(object[, predicate])
--- 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[](#l2.9)
namespace.[](#l2.10)
-
.. 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-[](#l2.17)
preserving mapping is used when the metaclass does not have a[](#l2.18)
``__prepare__`` method,[](#l2.19)
tuple has changed. Now an insertion-order-preserving mapping is[](#l2.20)
used when the metaclass does not have a ``__prepare__`` method,[](#l2.21)
--- a/Doc/reference/compound_stmts.rst
+++ b/Doc/reference/compound_stmts.rst
@@ -634,15 +634,9 @@ dictionary. The class name is bound to
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 <metaclasses>
.
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -1752,13 +1752,6 @@ additional keyword arguments, if any, co
If the metaclass has no __prepare__
attribute, then the class namespace
is initialised as an empty ordered mapping.
-.. impl-detail::
-
.. seealso::
:pep:3115
- Metaclasses in Python 3000
--- a/Include/object.h +++ b/Include/object.h @@ -421,8 +421,6 @@ typedef struct _typeobject { destructor tp_finalize;
- #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ Py_ssize_t tp_allocs;
--- 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) [](#l6.13)
--- 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)[](#l7.10)
+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:[](#l7.20)
b = 1[](#l7.21)
c = 3[](#l7.22)
a = 2[](#l7.23)
d = 4[](#l7.24)
eggs = 2[](#l7.25)
e = 5[](#l7.26)
b = 42[](#l7.27)
self.assertEqual(Spam.__definition_order__,[](#l7.29)
('__module__', '__qualname__',[](#l7.30)
'b', 'c', 'a', 'd', 'eggs', 'e'))[](#l7.31)
self.assertEqual(Empty.__definition_order__,[](#l7.37)
('__module__', '__qualname__'))[](#l7.38)
- def test_type_definition_order_on_instance(self):
class Spam:[](#l7.41)
a = 2[](#l7.42)
b = 1[](#l7.43)
c = 3[](#l7.44)
with self.assertRaises(AttributeError):[](#l7.45)
Spam().__definition_order__[](#l7.46)
- def test_type_definition_order_set_to_None(self):
class Spam:[](#l7.49)
a = 2[](#l7.50)
b = 1[](#l7.51)
c = 3[](#l7.52)
Spam.__definition_order__ = None[](#l7.53)
self.assertEqual(Spam.__definition_order__, None)[](#l7.54)
- def test_type_definition_order_set_to_tuple(self):
class Spam:[](#l7.57)
a = 2[](#l7.58)
b = 1[](#l7.59)
c = 3[](#l7.60)
Spam.__definition_order__ = ('x', 'y', 'z')[](#l7.61)
self.assertEqual(Spam.__definition_order__, ('x', 'y', 'z'))[](#l7.62)
- def test_type_definition_order_deleted(self):
class Spam:[](#l7.65)
a = 2[](#l7.66)
b = 1[](#l7.67)
c = 3[](#l7.68)
del Spam.__definition_order__[](#l7.69)
self.assertEqual(Spam.__definition_order__, None)[](#l7.70)
- def test_type_definition_order_set_to_bad_type(self):
class Spam:[](#l7.73)
a = 2[](#l7.74)
b = 1[](#l7.75)
c = 3[](#l7.76)
Spam.__definition_order__ = 42[](#l7.77)
self.assertEqual(Spam.__definition_order__, 42)[](#l7.78)
- def test_type_definition_order_builtins(self):
self.assertEqual(object.__definition_order__, None)[](#l7.81)
self.assertEqual(type.__definition_order__, None)[](#l7.82)
self.assertEqual(dict.__definition_order__, None)[](#l7.83)
self.assertEqual(type(None).__definition_order__, None)[](#l7.84)
- def test_type_definition_order_dunder_names_included(self):
class Dunder:[](#l7.87)
VAR = 3[](#l7.88)
def __init__(self):[](#l7.89)
pass[](#l7.90)
self.assertEqual(Dunder.__definition_order__,[](#l7.92)
('__module__', '__qualname__',[](#l7.93)
'VAR', '__init__'))[](#l7.94)
- def test_type_definition_order_only_dunder_names(self):
class DunderOnly:[](#l7.97)
__xyz__ = None[](#l7.98)
def __init__(self):[](#l7.99)
pass[](#l7.100)
self.assertEqual(DunderOnly.__definition_order__,[](#l7.102)
('__module__', '__qualname__',[](#l7.103)
'__xyz__', '__init__'))[](#l7.104)
- def test_type_definition_order_underscore_names(self):
class HalfDunder:[](#l7.107)
__whether_to_be = True[](#l7.108)
or_not_to_be__ = False[](#l7.109)
self.assertEqual(HalfDunder.__definition_order__,[](#l7.111)
('__module__', '__qualname__',[](#l7.112)
'_HalfDunder__whether_to_be', 'or_not_to_be__'))[](#l7.113)
- def test_type_definition_order_with_slots(self):
class Slots:[](#l7.116)
__slots__ = ('x', 'y')[](#l7.117)
a = 1[](#l7.118)
b = 2[](#l7.119)
self.assertEqual(Slots.__definition_order__,[](#l7.121)
('__module__', '__qualname__',[](#l7.122)
'__slots__', 'a', 'b'))[](#l7.123)
- def test_type_definition_order_overwritten_None(self):
class OverwrittenNone:[](#l7.126)
__definition_order__ = None[](#l7.127)
a = 1[](#l7.128)
b = 2[](#l7.129)
c = 3[](#l7.130)
self.assertEqual(OverwrittenNone.__definition_order__, None)[](#l7.132)
- def test_type_definition_order_overwritten_tuple(self):
class OverwrittenTuple:[](#l7.135)
__definition_order__ = ('x', 'y', 'z')[](#l7.136)
a = 1[](#l7.137)
b = 2[](#l7.138)
c = 3[](#l7.139)
self.assertEqual(OverwrittenTuple.__definition_order__,[](#l7.141)
('x', 'y', 'z'))[](#l7.142)
- def test_type_definition_order_overwritten_bad_item(self):
with self.assertRaises(TypeError):[](#l7.145)
class PoorlyOverwritten:[](#l7.146)
__definition_order__ = ('a', 2, 'c')[](#l7.147)
a = 1[](#l7.148)
b = 2[](#l7.149)
c = 3[](#l7.150)
- def test_type_definition_order_overwritten_bad_type(self):
with self.assertRaises(TypeError):[](#l7.153)
class PoorlyOverwritten:[](#l7.154)
__definition_order__ = ['a', 2, 'c'][](#l7.155)
a = 1[](#l7.156)
b = 2[](#l7.157)
c = 3[](#l7.158)
def __init__(self, *args, **kwargs):[](#l7.164)
super().__init__(*args, **kwargs)[](#l7.165)
self.assertEqual(Meta.__definition_order__,[](#l7.167)
('__module__', '__qualname__',[](#l7.168)
'SPAM', '__init__'))[](#l7.169)
- def test_type_definition_order_OrderedDict(self):
class Meta(type):[](#l7.172)
def __prepare__(self, *args, **kwargs):[](#l7.173)
return OrderedDict()[](#l7.174)
class WithODict(metaclass=Meta):[](#l7.176)
x='y'[](#l7.177)
self.assertEqual(WithODict.__definition_order__,[](#l7.179)
('__module__', '__qualname__', 'x'))[](#l7.180)
class Meta(type):[](#l7.182)
def __prepare__(self, *args, **kwargs):[](#l7.183)
class ODictSub(OrderedDict):[](#l7.184)
pass[](#l7.185)
return ODictSub()[](#l7.186)
class WithODictSub(metaclass=Meta):[](#l7.188)
x='y'[](#l7.189)
self.assertEqual(WithODictSub.__definition_order__,[](#l7.191)
('__module__', '__qualname__', 'x'))[](#l7.192)
- @cpython_only
- def test_type_definition_order_cpython(self):
# some implementations will have an ordered-by-default dict.[](#l7.196)
class Meta(type):[](#l7.198)
def __prepare__(self, *args, **kwargs):[](#l7.199)
return {}[](#l7.200)
class NotOrdered(metaclass=Meta):[](#l7.202)
x='y'[](#l7.203)
self.assertEqual(NotOrdered.__definition_order__, None)[](#l7.205)
- def test_bad_args(self): with self.assertRaises(TypeError): type()
--- a/Lib/test/test_metaclass.py +++ b/Lib/test/test_metaclass.py @@ -180,7 +180,7 @@ Use a metaclass that doesn't derive from meta: C () ns: [('module', 'test.test_metaclass'), ('qualname', 'C'), ('a', 42), ('b', 24)] kw: []
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.
- {}
Make sure it works with subclassing. @@ -251,9 +248,7 @@ Test failures in looking up the __prepar """ -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():
--- 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[](#l9.7) self.assertEqual(result, expected_html)[](#l9.8)
@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[](#l9.15)
# cases.[](#l9.16) class A:[](#l9.17)
__definition_order__ = None[](#l9.18) __name__ = 42[](#l9.19) class B:[](#l9.20) pass[](#l9.21) adoc = pydoc.render_doc(A())[](#l9.22) bdoc = pydoc.render_doc(B())[](#l9.23)
self.maxDiff = None[](#l9.24)
expected = adoc.replace("A", "B")[](#l9.25)
self.assertEqual(bdoc, expected)[](#l9.26)
self.assertEqual(adoc.replace("A", "B"), bdoc)[](#l9.27)
def test_not_here(self): missing_module = "test.i_am_not_here"
--- 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'[](#l10.7)
fmt = 'P2n15Pl4Pn9Pn11PIP'[](#l10.8) if hasattr(sys, 'getcounts'):[](#l10.9) fmt += '3n2P'[](#l10.10) s = vsize(fmt)[](#l10.11)
--- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -825,28 +825,6 @@ class ClassCreationTests(unittest.TestCa self.assertEqual(C.y, 1) self.assertEqual(C.z, 2)
- def test_new_class_deforder(self):
C = types.new_class("C")[](#l11.8)
self.assertEqual(C.__definition_order__, tuple())[](#l11.9)
Meta = self.Meta[](#l11.11)
def func(ns):[](#l11.12)
ns["x"] = 0[](#l11.13)
D = types.new_class("D", (), {"metaclass": Meta, "z": 2}, func)[](#l11.14)
self.assertEqual(D.__definition_order__, ('y', 'z', 'x'))[](#l11.15)
def func(ns):[](#l11.17)
ns["__definition_order__"] = None[](#l11.18)
ns["x"] = 0[](#l11.19)
D = types.new_class("D", (), {"metaclass": Meta, "z": 2}, func)[](#l11.20)
self.assertEqual(D.__definition_order__, None)[](#l11.21)
def func(ns):[](#l11.23)
ns["__definition_order__"] = ('a', 'b', 'c')[](#l11.24)
ns["x"] = 0[](#l11.25)
D = types.new_class("D", (), {"metaclass": Meta, "z": 2}, func)[](#l11.26)
self.assertEqual(D.__definition_order__, ('a', 'b', 'c'))[](#l11.27)
- # Many of the following tests are derived from test_descr.py def test_prepare_class(self): # Basic test of metaclass derivation
--- 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=N if hasattr(meta, 'prepare'): ns = meta.prepare(name, bases, **kwds) else:
ns = _DefaultClassNamespaceType()[](#l12.19)
--- 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[](#l13.7) attr != '__dict__' and[](#l13.8) attr != '__args__' and[](#l13.9) attr != '__slots__' and[](#l13.10)
--- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1765,21 +1765,6 @@ PyODict_DelItem(PyObject *od, PyObject * 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;[](#l14.13)
- _odict_FOREACH((PyODictObject *)od, node) {
Py_INCREF(_odictnode_KEY(node));[](#l14.15)
PyTuple_SET_ITEM(keys, i, _odictnode_KEY(node));[](#l14.16)
i++;[](#l14.17)
- }
- return keys;
-} - /* -------------------------------------------
--- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -48,7 +48,6 @@ static size_t method_cache_collisions = _Py_IDENTIFIER(abstractmethods); _Py_IDENTIFIER(class); _Py_IDENTIFIER(delitem); -_Py_IDENTIFIER(definition_order); _Py_IDENTIFIER(dict); _Py_IDENTIFIER(doc); _Py_IDENTIFIER(getattribute); @@ -490,23 +489,6 @@ type_set_module(PyTypeObject *type, PyOb } static PyObject * -type_deforder(PyTypeObject *type, void *context) -{
- if (type->tp_deforder == NULL)
Py_RETURN_NONE;[](#l15.18)
- Py_INCREF(type->tp_deforder);
- return type->tp_deforder;
-} - -static int -type_set_deforder(PyTypeObject *type, PyObject *value, void *context) -{
-} - -static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { PyObject *mod = NULL; @@ -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,
{"abstractmethods", (getter)type_abstractmethods, (setter)type_set_abstractmethods, NULL}, {"dict", (getter)type_dict, NULL, NULL}, @@ -2371,7 +2351,6 @@ type_new(PyTypeObject *metatype, PyObjec goto error; }(setter)type_set_deforder, NULL},[](#l15.40)
- /* 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, PyObjec 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);[](#l15.59)
// Due to subclass lookup, __definition_order__ can't be in __dict__.[](#l15.61)
if (_PyDict_DelItemId(dict, &PyId___definition_order__) != 0) {[](#l15.62)
goto error;[](#l15.63)
}[](#l15.64)
if (type->tp_deforder != Py_None) {[](#l15.66)
Py_ssize_t numnames;[](#l15.67)
if (!PyTuple_Check(type->tp_deforder)) {[](#l15.69)
PyErr_SetString(PyExc_TypeError,[](#l15.70)
"__definition_order__ must be a tuple or None");[](#l15.71)
goto error;[](#l15.72)
}[](#l15.73)
// Make sure they are identifers.[](#l15.75)
numnames = PyTuple_Size(type->tp_deforder);[](#l15.76)
for (i = 0; i < numnames; i++) {[](#l15.77)
PyObject *name = PyTuple_GET_ITEM(type->tp_deforder, i);[](#l15.78)
if (name == NULL) {[](#l15.79)
goto error;[](#l15.80)
}[](#l15.81)
if (!PyUnicode_Check(name) || !PyUnicode_IsIdentifier(name)) {[](#l15.82)
PyErr_Format(PyExc_TypeError,[](#l15.83)
"__definition_order__ must "[](#l15.84)
"contain only identifiers, got '%s'",[](#l15.85)
name);[](#l15.86)
goto error;[](#l15.87)
}[](#l15.88)
}[](#l15.89)
}[](#l15.90)
- }
- else if (PyODict_Check(orig_dict)) {
type->tp_deforder = _PyODict_KeysAsTuple(orig_dict);[](#l15.93)
if (type->tp_deforder == NULL)[](#l15.94)
goto error;[](#l15.95)
- }
- /* 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
- return PyODict_New();
--- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -147,7 +147,7 @@ builtin___build_class__(PyObject *self, if (prep == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear();
ns = PyODict_New();[](#l16.7)
ns = PyDict_New();[](#l16.8) }[](#l16.9) else {[](#l16.10) Py_DECREF(meta);[](#l16.11)