Skip to content

Commit aac54ef

Browse files
miss-islingtonrhettinger
authored andcommitted
bpo-45198: __set_name__ documentation not clear about its usage with non-descriptor classes (GH-28439)
(cherry picked from commit 94b4626) Co-authored-by: Raymond Hettinger <[email protected]>
1 parent 0a74d33 commit aac54ef

File tree

2 files changed

+36
-30
lines changed

2 files changed

+36
-30
lines changed

Doc/reference/datamodel.rst

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,28 +1740,6 @@ class' :attr:`~object.__dict__`.
17401740
Called to delete the attribute on an instance *instance* of the owner class.
17411741

17421742

1743-
.. method:: object.__set_name__(self, owner, name)
1744-
1745-
Called at the time the owning class *owner* is created. The
1746-
descriptor has been assigned to *name*.
1747-
1748-
.. note::
1749-
1750-
:meth:`__set_name__` is only called implicitly as part of the
1751-
:class:`type` constructor, so it will need to be called explicitly with
1752-
the appropriate parameters when a descriptor is added to a class after
1753-
initial creation::
1754-
1755-
class A:
1756-
pass
1757-
descr = custom_descriptor()
1758-
A.attr = descr
1759-
descr.__set_name__(A, 'attr')
1760-
1761-
See :ref:`class-object-creation` for more details.
1762-
1763-
.. versionadded:: 3.6
1764-
17651743
The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module
17661744
as specifying the class where this object was defined (setting this
17671745
appropriately can assist in runtime introspection of dynamic class attributes).
@@ -1950,6 +1928,33 @@ class defining the method.
19501928
.. versionadded:: 3.6
19511929

19521930

1931+
When a class is created, :meth:`type.__new__` scans the class variables
1932+
and makes callbacks to those with a :meth:`__set_name__` hook.
1933+
1934+
.. method:: object.__set_name__(self, owner, name)
1935+
1936+
Automatically called at the time the owning class *owner* is
1937+
created. The object has been assigned to *name* in that class::
1938+
1939+
class A:
1940+
x = C() # Automatically calls: x.__set_name__(A, 'x')
1941+
1942+
If the class variable is assigned after the class is created,
1943+
:meth:`__set_name__` will not be called automatically.
1944+
If needed, :meth:`__set_name__` can be called directly::
1945+
1946+
class A:
1947+
pass
1948+
1949+
c = C()
1950+
A.x = c # The hook is not called
1951+
c.__set_name__(A, 'x') # Manually invoke the hook
1952+
1953+
See :ref:`class-object-creation` for more details.
1954+
1955+
.. versionadded:: 3.6
1956+
1957+
19531958
.. _metaclasses:
19541959

19551960
Metaclasses
@@ -2099,15 +2104,15 @@ current call is identified based on the first argument passed to the method.
20992104
Failing to do so will result in a :exc:`RuntimeError` in Python 3.8.
21002105

21012106
When using the default metaclass :class:`type`, or any metaclass that ultimately
2102-
calls ``type.__new__``, the following additional customisation steps are
2107+
calls ``type.__new__``, the following additional customization steps are
21032108
invoked after creating the class object:
21042109

2105-
* first, ``type.__new__`` collects all of the descriptors in the class
2106-
namespace that define a :meth:`~object.__set_name__` method;
2107-
* second, all of these ``__set_name__`` methods are called with the class
2108-
being defined and the assigned name of that particular descriptor;
2109-
* finally, the :meth:`~object.__init_subclass__` hook is called on the
2110-
immediate parent of the new class in its method resolution order.
2110+
1) The ``type.__new__`` method collects all of the attributes in the class
2111+
namespace that define a :meth:`~object.__set_name__` method;
2112+
2) Those ``__set_name__`` methods are called with the class
2113+
being defined and the assigned name of that particular attribute;
2114+
3) The :meth:`~object.__init_subclass__` hook is called on the
2115+
immediate parent of the new class in its method resolution order.
21112116

21122117
After the class object is created, it is passed to the class decorators
21132118
included in the class definition (if any) and the resulting object is bound

Objects/typeobject.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8420,7 +8420,8 @@ update_all_slots(PyTypeObject* type)
84208420
}
84218421

84228422

8423-
/* Call __set_name__ on all descriptors in a newly generated type */
8423+
/* Call __set_name__ on all attributes (including descriptors)
8424+
in a newly generated type */
84248425
static int
84258426
type_new_set_names(PyTypeObject *type)
84268427
{

0 commit comments

Comments
 (0)