@@ -96,7 +96,7 @@ Quick Reference
96
96
| | | __gt__, | | | | |
97
97
| | | __ge__ | | | | |
98
98
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
99
- | :c:member: `~PyTypeObject.tp_weaklistoffset ` | :c:type: `Py_ssize_t ` | | | X | | ? |
99
+ | ( :c:member: `~PyTypeObject.tp_weaklistoffset `) | :c:type: `Py_ssize_t ` | | | X | | ? |
100
100
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
101
101
| :c:member: `~PyTypeObject.tp_iter ` | :c:type: `getiterfunc ` | __iter__ | | | | X |
102
102
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
@@ -117,7 +117,7 @@ Quick Reference
117
117
| :c:member: `~PyTypeObject.tp_descr_set ` | :c:type: `descrsetfunc ` | __set__, | | | | X |
118
118
|
10000
| | __delete__ | | | | |
119
119
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
120
- | :c:member: `~PyTypeObject.tp_dictoffset ` | :c:type: `Py_ssize_t ` | | | X | | ? |
120
+ | ( :c:member: `~PyTypeObject.tp_dictoffset `) | :c:type: `Py_ssize_t ` | | | X | | ? |
121
121
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
122
122
| :c:member: `~PyTypeObject.tp_init ` | :c:type: `initproc ` | __init__ | X | X | | X |
123
123
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
@@ -1018,7 +1018,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
1018
1018
:const: `Py_TPFLAGS_HAVE_GC ` flag bit is clear in the subtype and the
1019
1019
:c:member: `~PyTypeObject.tp_traverse ` and :c:member: `~PyTypeObject.tp_clear ` fields in the subtype exist and have
1020
1020
``NULL `` values.
1021
-
1022
1021
.. XXX are most flag bits *really* inherited individually?
1023
1022
1024
1023
**Default: **
@@ -1135,6 +1134,33 @@ and :c:type:`PyType_Type` effectively act as defaults.)
1135
1134
:const: `Py_TPFLAGS_IMMUTABLETYPE ` flag set. For extension types, it is
1136
1135
inherited whenever :c:member: `~PyTypeObject.tp_descr_get ` is inherited.
1137
1136
1137
+ .. data :: Py_TPFLAGS_MANAGED_DICT
1138
+
1139
+ This bit indicates that instances of the class have a ``__dict___ ``
1140
+ attribute, and that the space for the dictionary is managed by the VM.
1141
+
1142
+ If this flag is set, :const: `Py_TPFLAGS_HAVE_GC ` should also be set.
1143
+
1144
+ .. versionadded :: 3.12
1145
+
1146
+ **Inheritance: **
1147
+
1148
+ This flag is inherited unless the
1149
+ :c:member: `~PyTypeObject.tp_dictoffset ` field is set in a superclass.
1150
+
1151
+
1152
+ .. data :: Py_TPFLAGS_MANAGED_WEAKREF
1153
+
1154
+ This bit indicates that instances of the class should
10000
be weakly
1155
+ referenceable.
1156
+
1157
+ .. versionadded :: 3.12
1158
+
1159
+ **Inheritance: **
1160
+
1161
+ This flag is inherited unless the
1162
+ :c:member: `~PyTypeObject.tp_weaklistoffset ` field is set in a superclass.
1163
+
1138
1164
1139
1165
.. XXX Document more flags here?
1140
1166
@@ -1487,6 +1513,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
1487
1513
1488
1514
.. c :member :: Py_ssize_t PyTypeObject.tp_weaklistoffset
1489
1515
1516
+ While this field is still supported, :const: `Py_TPFLAGS_MANAGED_WEAKREF `
1517
+ should be used instead, if at all possible.
1518
+
1490
1519
If the instances of this type are weakly referenceable, this field is greater
1491
1520
than zero and contains the offset in the instance structure of the weak
1492
1521
reference list head (ignoring the GC header, if present); this offset is used by
@@ -1497,26 +1526,22 @@ and :c:type:`PyType_Type` effectively act as defaults.)
1497
1526
Do not confuse this field with :c:member: `~PyTypeObject.tp_weaklist `; that is the list head for
1498
1527
weak references to the type object itself.
1499
1528
1529
+ It is an error to set both the :const: `Py_TPFLAGS_MANAGED_WEAKREF ` bit and
1530
+ :c:member: `~PyTypeObject.tp_weaklist `.
1531
+
1500
1532
**Inheritance: **
1501
1533
1502
1534
This field is inherited by subtypes, but see the rules listed below. A subtype
1503
1535
may override this offset; this means that the subtype uses a different weak
1504
1536
reference list head than the base type. Since the list head is always found via
1505
1537
:c:member: `~PyTypeObject.tp_weaklistoffset `, this should not be a problem.
1506
1538
1507
- When a type defined by a class statement has no :attr: `~object.__slots__ ` declaration,
1508
- and none of its base types are weakly referenceable, the type is made weakly
1509
- referenceable by adding a weak reference list head slot to the instance layout
1510
- and setting the :c:member: `~PyTypeObject.tp_weaklistoffset ` of that slot's offset.
1511
-
1512
- When a type's :attr: `__slots__ ` declaration contains a slot named
1513
- :attr: `__weakref__ `, that slot becomes the weak reference list head for
1514
- instances of the type, and the slot's offset is stored in the type's
1515
- :c:member: `~PyTypeObject.tp_weaklistoffset `.
1539
+ **Default: **
1516
1540
1517
- When a type's :attr: `__slots__ ` declaration does not contain a slot named
1518
- :attr: `__weakref__ `, the type inherits its :c:member: `~PyTypeObject.tp_weaklistoffset ` from its
1519
- base type.
1541
+ If the :const: `Py_TPFLAGS_MANAGED_WEAKREF ` bit is set in the
1542
+ :c:member: `~PyTypeObject.tp_dict ` field, then
1543
+ :c:member: `~PyTypeObject.tp_weaklistoffset ` will be set to a negative value,
1544
+ to indicate that it is unsafe to use this field.
1520
1545
1521
1546
1522
1547
.. c :member :: getiterfunc PyTypeObject.tp_iter
@@ -1695,6 +1720,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
1695
1720
1696
1721
.. c :member :: Py_ssize_t PyTypeObject.tp_dictoffset
1697
1722
1723
+ While this field is still supported, :const: `Py_TPFLAGS_MANAGED_DICT ` should be
1724
+ used instead, if at all possible.
1725
+
1698
1726
If the instances of this type have a dictionary containing instance variables,
1699
1727
this field is non-zero and contains the offset in the instances of the type of
1700
1728
the instance variable dictionary; this offset is used by
@@ -1703,48 +1731,34 @@ and :c:type:`PyType_Type` effectively act as defaults.)
1703
1731
Do not confuse this field with :c:member: `~PyTypeObject.tp_dict `; that is the dictionary for
1704
1732
attributes of the type object itself.
1705
1733
1706
- If the value of this field is greater than zero, it specifies the offset from
1707
- the start of the instance structure. If the value is less than zero, it
1708
- specifies the offset from the *end * of the instance structure. A negative
1709
- offset is more expensive to use, and should only be used when the instance
1710
- structure contains a variable-length part. This is used for example to add an
1711
- instance variable dictionary to subtypes of :class: `str ` or :class: `tuple `. Note
1712
- that the :c:member: `~PyTypeObject.tp_basicsize ` field should account for the dictionary added to
1713
- the end in that case, even though the dictionary is not included in the basic
1714
- object layout. On a system with a pointer size of 4 bytes,
1715
- :c:member: `~PyTypeObject.tp_dictoffset ` should be set to ``-4 `` to indicate that the dictionary is
1716
- at the very end of the structure.
1734
+ The value specifies the offset of the dictionary from the start of the instance structure.
1717
1735
1718
1736
The :c:member: `~PyTypeObject.tp_dictoffset ` should be regarded as write-only.
1719
1737
To get the pointer to the dictionary call :c:func: `PyObject_GenericGetDict `.
1720
1738
Calling :c:func: `PyObject_GenericGetDict ` may need to allocate memory for the
1721
1739
dictionary, so it is may be more efficient to call :c:func: `PyObject_GetAttr `
1722
1740
when accessing an attribute on the object.
1723
1741
1724
- **Inheritance: **
1725
-
1726
- This field is inherited by subtypes, but see the rules listed below. A subtype
1727
- may override this offset; this means that the subtype instances store the
1728
- dictionary at a difference offset than the base type. Since the dictionary is
1729
- always found via :c:member: `~PyTypeObject.tp_dictoffset `, this should not be a problem.
1742
+ It is an error to set both the :const: `Py_TPFLAGS_MANAGED_WEAKREF ` bit and
1743
+ :c:member: `~PyTypeObject.tp_dictoffset `.
1730
1744
1731
- When a type defined by a class statement has no :attr: `~object.__slots__ ` declaration,
1732
- and none of its base types has an instance variable dictionary, a dictionary
1733
- slot is added to the instance layout and the :c:member: `~PyTypeObject.tp_dictoffset ` is set to
1734
- that slot's offset.
1735
-
1736
- When a type defined by a class statement has a :attr: `__slots__ ` declaration,
1737
- the type inherits its :c:member: `~PyTypeObject.tp_dictoffset ` from its base type.
1745
+ **Inheritance: **
1738
1746
1739
- (Adding a slot named :attr: `~object.__dict__ ` to the :attr: `__slots__ ` declaration does
1740
- not have the expected effect, it just causes confusion. Maybe this should be
1741
- added as a feature just like :attr: `__weakref__ ` though.)
1747
+ This field is inherited by subtypes. A subtype should not override this offset;
1748
+ doing so could be unsafe, if C code tries to access the dictionary at the
1749
+ previous offset.
1750
+ To properly support inheritance, use :const: `Py_TPFLAGS_MANAGED_DICT `.
1742
1751
1743
1752
**Default: **
1744
1753
1745
1754
This slot has no default. For :ref: `static types <static-types >`, if the
1746
1755
field is ``NULL `` then no :attr: `__dict__ ` gets created for instances.
1747
1756
1757
+ If the :const: `Py_TPFLAGS_MANAGED_DICT ` bit is set in the
1758
+ :c:member: `~PyTypeObject.tp_dict ` field, then
1759
+ :c:member: `~PyTypeObject.tp_dictoffset ` will be set to ``-1 ``, to indicate
1760
+ that it is unsafe to use this field.
1761
+
1748
1762
1749
1763
.. c :member :: initproc PyTypeObject.tp_init
1750
1764
@@ -2663,18 +2677,16 @@ A type that supports weakrefs, instance dicts, and hashing::
2663
2677
typedef struct {
2664
2678
PyObject_HEAD
2665
2679
const char *data;
2666
- PyObject *inst_dict;
2667
- PyObject *weakreflist;
2668
2680
} MyObject;
2669
2681
2670
2682
static PyTypeObject MyObject_Type = {
2671
2683
PyVarObject_HEAD_INIT(NULL, 0)
2672
2684
.tp_name = "mymod.MyObject",
2673
2685
.tp_basicsize = sizeof(MyObject),
2674
2686
.tp_doc = PyDoc_STR("My objects"),
2675
- .tp_weaklistoffset = offsetof(MyObject, weakreflist),
2676
- .tp_dictoffset = offsetof(MyObject, inst_dict),
2677
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC ,
2687
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2688
+ Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT |
2689
+ Py_TPFLAGS_MANAGED_WEAKREF ,
2678
2690
.tp_new = myobj_new,
2679
2691
.tp_traverse = (traverseproc)myobj_traverse,
2680
2692
.tp_clear = (inquiry)myobj_clear,
0 commit comments