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
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])
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
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()
_Py_IDENTIFIER(__abstractmethods__);
_Py_IDENTIFIER(__class__);
_Py_IDENTIFIER(__delitem__);
-_Py_IDENTIFIER(__definition_order__);
_Py_IDENTIFIER(__dict__);
_Py_IDENTIFIER(__doc__);
_Py_IDENTIFIER(__getattribute__);
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)
{
{"__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},
goto error;
}
- /* Copy the definition namespace into a new dict. */
dict = PyDict_Copy(orig_dict);
if (dict == NULL)
goto error;
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__.
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 *.
*/
static PyObject *
type_prepare(PyObject *self, PyObject *args, PyObject *kwds)
{
- return PyODict_New();
+ return PyDict_New();
}
/*