From 5ae81b512e3e00ed291471565ea8aed4d16bd09d Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 8 Nov 2021 22:22:38 +0000 Subject: [PATCH 1/6] Improve docs on 'subscriptions' --- Doc/reference/expressions.rst | 68 +++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 6108c462362172..8f0fcac5955657 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -817,47 +817,63 @@ Subscriptions object: dictionary pair: sequence; item -Subscription of a sequence (string, tuple or list) or mapping (dictionary) -object usually selects an item from the collection: +The subscription of an object in Python can have one of two effects. If the +object is a :term:`sequence` (such as a :class:`string`, +:class:`tuple` or :class:`list`) or a :term:`mapping` (such as a +:class:`dictionary`), subscripting the object will select an object from +the collection. Subscripting certain *classes or types*, meanwhile, will +return a :ref:`generic alias ` object representing a +*parameterized generic class*. The latter form of subscription is primarily +useful for :term:`type hinting`. + +**HERE I SHALL PUT A REFERENCE TO THE NEW SECTION ON ``__GETITEM__`` VERSUS +``__CLASS_GETITEM__``, WHEN THAT PR IS MERGED.** .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription (lists or -dictionaries for example). User-defined objects can support subscription by -defining a :meth:`__getitem__` method. +The primary must evaluate to an object that supports subscription, such as a +:class:`list` or a :class:`dictionary`. User-defined objects can support +subscription by defining one or both of :meth:`~object.__getitem__` and +:meth:`~object.__class_getitem__`. -For built-in objects, there are two types of objects that support subscription: +Subscriptions calling *__getitem__* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If the primary is a mapping, the expression list must evaluate to an object -whose value is one of the keys of the mapping, and the subscription selects the -value in the mapping that corresponds to that key. (The expression list is a -tuple except if it has exactly one item.) +For built-in objects, there are two types of objects that support subscription +via :meth:`~object.__getitem__`: -If the primary is a sequence, the expression list must evaluate to an integer -or a slice (as discussed in the following section). +* If the primary is a :term:`mapping`, the expression list must evaluate to an + object whose value is one of the keys of the mapping, and the subscription + selects the value in the mapping that corresponds to that key. (The + expression list is a :class:`tuple` except if it has exactly one item.) +* If the primary is a :term:`sequence`, the expression list must evaluate to an + :class:`int` or a :class:`slice` (as discussed in the following section). The formal syntax makes no special provision for negative indices in -sequences; however, built-in sequences all provide a :meth:`__getitem__` -method that interprets negative indices by adding the length of the sequence -to the index (so that ``x[-1]`` selects the last item of ``x``). The -resulting value must be a nonnegative integer less than the number of items in -the sequence, and the subscription selects the item whose index is that value -(counting from zero). Since the support for negative indices and slicing -occurs in the object's :meth:`__getitem__` method, subclasses overriding -this method will need to explicitly add that support. +:term:`sequences`. However, built-in sequences all provide a +:meth:`~object.__getitem__` method that interprets negative indices by adding +the length of the sequence to the index so that, for example, ``x[-1]`` selects +the last item of ``x``. The resulting value must be a nonnegative integer less +than the number of items in the sequence, and the subscription selects the item +whose index is that value (counting from zero). Since the support for negative +indices and slicing occurs in the object's :meth:`__getitem__` method, +subclasses overriding this method will need to explicitly add that support. .. index:: single: character pair: string; item -A string's items are characters. A character is not a separate data type but a -string of exactly one character. +A :class:`string` is a special kind of sequence whose items are +*characters*. A character is not a separate data type but a string of exactly +one character. -Subscription of certain :term:`classes ` or :term:`types ` -creates a :ref:`generic alias `. -In this case, user-defined classes can support subscription by providing a -:meth:`__class_getitem__` classmethod. +Subscriptions calling *__class_getitem__* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A large number of types in the standard library support subscription via +:meth:`~object.__class_getitem__`. See :ref:`types-genericalias` for more +information on the objects returned by such subscriptions. .. _slicings: From f3d66fc278179d77cc4c5abc5a19785779e8cf82 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 19 Nov 2021 00:26:12 +0000 Subject: [PATCH 2/6] Make this mergeable --- Doc/reference/expressions.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 70f315f8dc793e..99fdb596f0be25 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -824,9 +824,6 @@ return a :ref:`generic alias ` object representing a *parameterized generic class*. The latter form of subscription is primarily useful for :term:`type hinting`. -**HERE I SHALL PUT A REFERENCE TO THE NEW SECTION ON ``__GETITEM__`` VERSUS -``__CLASS_GETITEM__``, WHEN THAT PR IS MERGED.** - .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" @@ -835,6 +832,12 @@ The primary must evaluate to an object that supports subscription, such as a subscription by defining one or both of :meth:`~object.__getitem__` and :meth:`~object.__class_getitem__`. +.. seealso:: + :ref:`classgetitem-versus-getitem` + Documentation explaining when a subscription will lead to + :meth:`~object.__class_getitem__` being called over + :meth:`~object.__getitem__` + Subscriptions calling *__getitem__* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 46f96c0914fd656538156af5c449ab6acc3b8c3d Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sat, 4 Dec 2021 16:57:52 +0000 Subject: [PATCH 3/6] Reduce diff --- Doc/reference/expressions.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 99fdb596f0be25..9348e576b1d900 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -852,14 +852,14 @@ via :meth:`~object.__getitem__`: :class:`int` or a :class:`slice` (as discussed in the following section). The formal syntax makes no special provision for negative indices in -:term:`sequences`. However, built-in sequences all provide a -:meth:`~object.__getitem__` method that interprets negative indices by adding -the length of the sequence to the index so that, for example, ``x[-1]`` selects -the last item of ``x``. The resulting value must be a nonnegative integer less -than the number of items in the sequence, and the subscription selects the item -whose index is that value (counting from zero). Since the support for negative -indices and slicing occurs in the object's :meth:`__getitem__` method, -subclasses overriding this method will need to explicitly add that support. +:term:`sequences`. However, built-in sequences all provide a :meth:`~object.__getitem__` +method that interprets negative indices by adding the length of the sequence +to the index so that, for example, ``x[-1]`` selects the last item of ``x``. The +resulting value must be a nonnegative integer less than the number of items in +the sequence, and the subscription selects the item whose index is that value +(counting from zero). Since the support for negative indices and slicing +occurs in the object's :meth:`__getitem__` method, subclasses overriding +this method will need to explicitly add that support. .. index:: single: character From dc77393a7207a18cfecd88cf621c98f34caa0a68 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 6 Dec 2021 14:59:09 +0000 Subject: [PATCH 4/6] Improve markup readability --- Doc/reference/expressions.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 9348e576b1d900..f21c9fb17a1708 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -816,19 +816,19 @@ Subscriptions pair: sequence; item The subscription of an object in Python can have one of two effects. If the -object is a :term:`sequence` (such as a :class:`string`, +object is a :term:`sequence` (such as a :class:`string `, :class:`tuple` or :class:`list`) or a :term:`mapping` (such as a -:class:`dictionary`), subscripting the object will select an object from +:class:`dictionary `), subscripting the object will select an object from the collection. Subscripting certain *classes or types*, meanwhile, will return a :ref:`generic alias ` object representing a *parameterized generic class*. The latter form of subscription is primarily -useful for :term:`type hinting`. +useful for :term:`type hinting `. .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" The primary must evaluate to an object that supports subscription, such as a -:class:`list` or a :class:`dictionary`. User-defined objects can support +:class:`list` or a :class:`dictionary `. User-defined objects can support subscription by defining one or both of :meth:`~object.__getitem__` and :meth:`~object.__class_getitem__`. @@ -852,7 +852,7 @@ via :meth:`~object.__getitem__`: :class:`int` or a :class:`slice` (as discussed in the following section). The formal syntax makes no special provision for negative indices in -:term:`sequences`. However, built-in sequences all provide a :meth:`~object.__getitem__` +:term:`sequences `. However, built-in sequences all provide a :meth:`~object.__getitem__` method that interprets negative indices by adding the length of the sequence to the index so that, for example, ``x[-1]`` selects the last item of ``x``. The resulting value must be a nonnegative integer less than the number of items in @@ -865,7 +865,7 @@ this method will need to explicitly add that support. single: character pair: string; item -A :class:`string` is a special kind of sequence whose items are +A :class:`string ` is a special kind of sequence whose items are *characters*. A character is not a separate data type but a string of exactly one character. From 53930086469ae601817a25dcb8710b228b9159a0 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sat, 5 Mar 2022 23:02:52 +0000 Subject: [PATCH 5/6] Make more concise, improve technical accuracy --- Doc/reference/expressions.rst | 59 +++++++++++++++-------------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 0ae4b068b0d86c..d79f02516b64d6 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -815,41 +815,39 @@ Subscriptions object: dictionary pair: sequence; item -The subscription of an object in Python can have one of two effects. If the -object is a :term:`sequence` (such as a :class:`string `, -:class:`tuple` or :class:`list`) or a :term:`mapping` (such as a -:class:`dictionary `), subscripting the object will select an object from -the collection. Subscripting certain *classes or types*, meanwhile, will -return a :ref:`generic alias ` object representing a -*parameterized generic class*. The latter form of subscription is primarily -useful for :term:`type hinting `. +The subscription of an instance of a :ref:`container class ` +will generally select an element from the container. The subscription of a +:term:`generic class ` will generally return a +:ref:`GenericAlias ` object. .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription, such as a -:class:`list` or a :class:`dictionary `. User-defined objects can support -subscription by defining one or both of :meth:`~object.__getitem__` and -:meth:`~object.__class_getitem__`. +When an object is subscripted, the interpreter will evaluate the primary and +the expression list. -.. seealso:: - :ref:`classgetitem-versus-getitem` - Documentation explaining when a subscription will lead to - :meth:`~object.__class_getitem__` being called over - :meth:`~object.__getitem__` +The primary must evaluate to an object that supports subscription. An object +may support subscription through defining one or both of +:meth:`~object.__getitem__` and :meth:`~object.__class_getitem__`. When the +primary is subscripted, the evaluated result of the expression list will be +passed to one of these methods. For more details on when ``__class_getitem__`` +is called instead of ``__getitem__``, see :ref:`classgetitem-versus-getitem`. -Subscriptions calling *__getitem__* -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +If the expression list contains at least one comma, it will evaluate to a +:class:`tuple` containing the items of the expression list. Otherwise, the +expression list will evaluate to the value of the list's sole member. For built-in objects, there are two types of objects that support subscription via :meth:`~object.__getitem__`: -* If the primary is a :term:`mapping`, the expression list must evaluate to an - object whose value is one of the keys of the mapping, and the subscription - selects the value in the mapping that corresponds to that key. (The - expression list is a :class:`tuple` except if it has exactly one item.) -* If the primary is a :term:`sequence`, the expression list must evaluate to an - :class:`int` or a :class:`slice` (as discussed in the following section). +1. Mappings. If the primary is a :term:`mapping`, the expression list must evaluate to an object + whose value is one of the keys of the mapping, and the subscription selects the + value in the mapping that corresponds to that key. An example of a mapping is + the :class:`dict` class. +2. Sequences. If the primary is a :term:`sequence`, the expression list must evaluate to an + :class:`int` or a :class:`slice` (as discussed in the following section). + Examples of builtin sequences include the :class:`str`, :class:`list` and + :class:`tuple` classes. The formal syntax makes no special provision for negative indices in :term:`sequences `. However, built-in sequences all provide a :meth:`~object.__getitem__` @@ -866,15 +864,8 @@ this method will need to explicitly add that support. pair: string; item A :class:`string ` is a special kind of sequence whose items are -*characters*. A character is not a separate data type but a string of exactly -one character. - -Subscriptions calling *__class_getitem__* -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -A large number of types in the standard library support subscription via -:meth:`~object.__class_getitem__`. See :ref:`types-genericalias` for more -information on the objects returned by such subscriptions. +*characters*. A character is not a separate data type but a +string of exactly one character. .. _slicings: From 19edeef062c1f898e816ea14e59be70176805ab2 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sat, 5 Mar 2022 23:20:18 +0000 Subject: [PATCH 6/6] tweaks --- Doc/reference/expressions.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index d79f02516b64d6..bb6d1dc1cdd04f 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -840,14 +840,14 @@ expression list will evaluate to the value of the list's sole member. For built-in objects, there are two types of objects that support subscription via :meth:`~object.__getitem__`: -1. Mappings. If the primary is a :term:`mapping`, the expression list must evaluate to an object - whose value is one of the keys of the mapping, and the subscription selects the - value in the mapping that corresponds to that key. An example of a mapping is - the :class:`dict` class. -2. Sequences. If the primary is a :term:`sequence`, the expression list must evaluate to an - :class:`int` or a :class:`slice` (as discussed in the following section). - Examples of builtin sequences include the :class:`str`, :class:`list` and - :class:`tuple` classes. +1. Mappings. If the primary is a :term:`mapping`, the expression list must + evaluate to an object whose value is one of the keys of the mapping, and the + subscription selects the value in the mapping that corresponds to that key. + An example of a builtin mapping class is the :class:`dict` class. +2. Sequences. If the primary is a :term:`sequence`, the expression list must + evaluate to an :class:`int` or a :class:`slice` (as discussed in the + following section). Examples of builtin sequence classes include the + :class:`str`, :class:`list` and :class:`tuple` classes. The formal syntax makes no special provision for negative indices in :term:`sequences `. However, built-in sequences all provide a :meth:`~object.__getitem__`