[Python-checkins] [3.12] Improve references in the tutorial (GH-108069) (#108203)

Yhg1s webhook-mailer at python.org
Mon Aug 21 07:20:25 EDT 2023


https://github.com/python/cpython/commit/f798a6360b038a3fc47509101eb77bcc1c9b6662
commit: f798a6360b038a3fc47509101eb77bcc1c9b6662
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Yhg1s <thomas at python.org>
date: 2023-08-21T13:20:21+02:00
summary:

[3.12] Improve references in the tutorial (GH-108069) (#108203)

Improve references in the tutorial (GH-108069)

* Use full qualified names for references (even if they do not work now,
  they will work in future).
* Silence references to examples.
(cherry picked from commit 622ddc41674c2566062af82f7b079aa01d2aae8c)

Co-authored-by: Serhiy Storchaka <storchaka at gmail.com>

files:
M Doc/tools/.nitignore
M Doc/tutorial/classes.rst
M Doc/tutorial/controlflow.rst
M Doc/tutorial/datastructures.rst
M Doc/tutorial/inputoutput.rst
M Doc/tutorial/modules.rst

diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index b1894c4d3df37..ada46064e358e 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -180,9 +180,7 @@ Doc/tutorial/appendix.rst
 Doc/tutorial/classes.rst
 Doc/tutorial/controlflow.rst
 Doc/tutorial/datastructures.rst
-Doc/tutorial/inputoutput.rst
 Doc/tutorial/introduction.rst
-Doc/tutorial/modules.rst
 Doc/using/cmdline.rst
 Doc/using/configure.rst
 Doc/using/windows.rst
diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst
index 06445e000c1ef..91a3b73d2b55a 100644
--- a/Doc/tutorial/classes.rst
+++ b/Doc/tutorial/classes.rst
@@ -91,7 +91,7 @@ Attributes may be read-only or writable.  In the latter case, assignment to
 attributes is possible.  Module attributes are writable: you can write
 ``modname.the_answer = 42``.  Writable attributes may also be deleted with the
 :keyword:`del` statement.  For example, ``del modname.the_answer`` will remove
-the attribute :attr:`the_answer` from the object named by ``modname``.
+the attribute :attr:`!the_answer` from the object named by ``modname``.
 
 Namespaces are created at different moments and have different lifetimes.  The
 namespace containing the built-in names is created when the Python interpreter
@@ -249,7 +249,7 @@ created.  This is basically a wrapper around the contents of the namespace
 created by the class definition; we'll learn more about class objects in the
 next section.  The original local scope (the one in effect just before the class
 definition was entered) is reinstated, and the class object is bound here to the
-class name given in the class definition header (:class:`ClassName` in the
+class name given in the class definition header (:class:`!ClassName` in the
 example).
 
 
@@ -291,20 +291,20 @@ variable ``x``.
 The instantiation operation ("calling" a class object) creates an empty object.
 Many classes like to create objects with instances customized to a specific
 initial state. Therefore a class may define a special method named
-:meth:`__init__`, like this::
+:meth:`~object.__init__`, like this::
 
    def __init__(self):
        self.data = []
 
-When a class defines an :meth:`__init__` method, class instantiation
-automatically invokes :meth:`__init__` for the newly created class instance.  So
+When a class defines an :meth:`~object.__init__` method, class instantiation
+automatically invokes :meth:`!__init__` for the newly created class instance.  So
 in this example, a new, initialized instance can be obtained by::
 
    x = MyClass()
 
-Of course, the :meth:`__init__` method may have arguments for greater
+Of course, the :meth:`~object.__init__` method may have arguments for greater
 flexibility.  In that case, arguments given to the class instantiation operator
-are passed on to :meth:`__init__`.  For example, ::
+are passed on to :meth:`!__init__`.  For example, ::
 
    >>> class Complex:
    ...     def __init__(self, realpart, imagpart):
@@ -328,7 +328,7 @@ attribute names: data attributes and methods.
 *data attributes* correspond to "instance variables" in Smalltalk, and to "data
 members" in C++.  Data attributes need not be declared; like local variables,
 they spring into existence when they are first assigned to.  For example, if
-``x`` is the instance of :class:`MyClass` created above, the following piece of
+``x`` is the instance of :class:`!MyClass` created above, the following piece of
 code will print the value ``16``, without leaving a trace::
 
    x.counter = 1
@@ -363,7 +363,7 @@ Usually, a method is called right after it is bound::
 
    x.f()
 
-In the :class:`MyClass` example, this will return the string ``'hello world'``.
+In the :class:`!MyClass` example, this will return the string ``'hello world'``.
 However, it is not necessary to call a method right away: ``x.f`` is a method
 object, and can be stored away and called at a later time.  For example::
 
@@ -375,7 +375,7 @@ will continue to print ``hello world`` until the end of time.
 
 What exactly happens when a method is called?  You may have noticed that
 ``x.f()`` was called without an argument above, even though the function
-definition for :meth:`f` specified an argument.  What happened to the argument?
+definition for :meth:`!f` specified an argument.  What happened to the argument?
 Surely Python raises an exception when a function that requires an argument is
 called without any --- even if the argument isn't actually used...
 
@@ -532,9 +532,9 @@ variable in the class is also ok.  For example::
 
        h = g
 
-Now ``f``, ``g`` and ``h`` are all attributes of class :class:`C` that refer to
+Now ``f``, ``g`` and ``h`` are all attributes of class :class:`!C` that refer to
 function objects, and consequently they are all methods of instances of
-:class:`C` --- ``h`` being exactly equivalent to ``g``.  Note that this practice
+:class:`!C` --- ``h`` being exactly equivalent to ``g``.  Note that this practice
 usually only serves to confuse the reader of a program.
 
 Methods may call other methods by using method attributes of the ``self``
@@ -581,7 +581,7 @@ this::
        .
        <statement-N>
 
-The name :class:`BaseClassName` must be defined in a
+The name :class:`!BaseClassName` must be defined in a
 namespace accessible from the scope containing the
 derived class definition.  In place of a base class name, other arbitrary
 expressions are also allowed.  This can be useful, for example, when the base
@@ -645,9 +645,9 @@ multiple base classes looks like this::
 For most purposes, in the simplest cases, you can think of the search for
 attributes inherited from a parent class as depth-first, left-to-right, not
 searching twice in the same class where there is an overlap in the hierarchy.
-Thus, if an attribute is not found in :class:`DerivedClassName`, it is searched
-for in :class:`Base1`, then (recursively) in the base classes of :class:`Base1`,
-and if it was not found there, it was searched for in :class:`Base2`, and so on.
+Thus, if an attribute is not found in :class:`!DerivedClassName`, it is searched
+for in :class:`!Base1`, then (recursively) in the base classes of :class:`!Base1`,
+and if it was not found there, it was searched for in :class:`!Base2`, and so on.
 
 In fact, it is slightly more complex than that; the method resolution order
 changes dynamically to support cooperative calls to :func:`super`.  This
@@ -760,7 +760,8 @@ is to use :mod:`dataclasses` for this purpose::
 A piece of Python code that expects a particular abstract data type can often be
 passed a class that emulates the methods of that data type instead.  For
 instance, if you have a function that formats some data from a file object, you
-can define a class with methods :meth:`read` and :meth:`!readline` that get the
+can define a class with methods :meth:`~io.TextIOBase.read` and
+:meth:`~io.TextIOBase.readline` that get the
 data from a string buffer instead, and pass it as an argument.
 
 .. (Unfortunately, this technique has its limitations: a class can't define
@@ -769,7 +770,7 @@ data from a string buffer instead, and pass it as an argument.
    not cause the interpreter to read further input from it.)
 
 Instance method objects have attributes, too: ``m.__self__`` is the instance
-object with the method :meth:`m`, and ``m.__func__`` is the function object
+object with the method :meth:`!m`, and ``m.__func__`` is the function object
 corresponding to the method.
 
 
@@ -818,9 +819,9 @@ using the :func:`next` built-in function; this example shows how it all works::
    StopIteration
 
 Having seen the mechanics behind the iterator protocol, it is easy to add
-iterator behavior to your classes.  Define an :meth:`__iter__` method which
+iterator behavior to your classes.  Define an :meth:`~container.__iter__` method which
 returns an object with a :meth:`~iterator.__next__` method.  If the class
-defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``::
+defines :meth:`!__next__`, then :meth:`!__iter__` can just return ``self``::
 
    class Reverse:
        """Iterator for looping over a sequence backwards."""
@@ -879,7 +880,7 @@ easy to create::
 
 Anything that can be done with generators can also be done with class-based
 iterators as described in the previous section.  What makes generators so
-compact is that the :meth:`__iter__` and :meth:`~generator.__next__` methods
+compact is that the :meth:`~iterator.__iter__` and :meth:`~generator.__next__` methods
 are created automatically.
 
 Another key feature is that the local variables and execution state are
diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst
index 138d87f892e89..4bcc3768111cc 100644
--- a/Doc/tutorial/controlflow.rst
+++ b/Doc/tutorial/controlflow.rst
@@ -534,7 +534,7 @@ This example, as usual, demonstrates some new Python features:
   Different types define different methods.  Methods of different types may have
   the same name without causing ambiguity.  (It is possible to define your own
   object types and methods, using *classes*, see :ref:`tut-classes`)
-  The method :meth:`append` shown in the example is defined for list objects; it
+  The method :meth:`~list.append` shown in the example is defined for list objects; it
   adds a new element at the end of the list.  In this example it is equivalent to
   ``result = result + [a]``, but more efficient.
 
diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst
index c8e89d9b79bdd..87614d082a1d4 100644
--- a/Doc/tutorial/datastructures.rst
+++ b/Doc/tutorial/datastructures.rst
@@ -143,8 +143,8 @@ Using Lists as Stacks
 
 The list methods make it very easy to use a list as a stack, where the last
 element added is the first element retrieved ("last-in, first-out").  To add an
-item to the top of the stack, use :meth:`append`.  To retrieve an item from the
-top of the stack, use :meth:`pop` without an explicit index.  For example::
+item to the top of the stack, use :meth:`~list.append`.  To retrieve an item from the
+top of the stack, use :meth:`~list.pop` without an explicit index.  For example::
 
    >>> stack = [3, 4, 5]
    >>> stack.append(6)
@@ -341,7 +341,7 @@ The :keyword:`!del` statement
 =============================
 
 There is a way to remove an item from a list given its index instead of its
-value: the :keyword:`del` statement.  This differs from the :meth:`pop` method
+value: the :keyword:`del` statement.  This differs from the :meth:`~list.pop` method
 which returns a value.  The :keyword:`!del` statement can also be used to remove
 slices from a list or clear the entire list (which we did earlier by assignment
 of an empty list to the slice).  For example::
@@ -501,8 +501,8 @@ any immutable type; strings and numbers can always be keys.  Tuples can be used
 as keys if they contain only strings, numbers, or tuples; if a tuple contains
 any mutable object either directly or indirectly, it cannot be used as a key.
 You can't use lists as keys, since lists can be modified in place using index
-assignments, slice assignments, or methods like :meth:`append` and
-:meth:`extend`.
+assignments, slice assignments, or methods like :meth:`~list.append` and
+:meth:`~list.extend`.
 
 It is best to think of a dictionary as a set of *key: value* pairs,
 with the requirement that the keys are unique (within one dictionary). A pair of
@@ -567,7 +567,7 @@ Looping Techniques
 ==================
 
 When looping through dictionaries, the key and corresponding value can be
-retrieved at the same time using the :meth:`items` method. ::
+retrieved at the same time using the :meth:`~dict.items` method. ::
 
    >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
    >>> for k, v in knights.items():
diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst
index f5cdd84cbadef..fe9ca9ccb9c7e 100644
--- a/Doc/tutorial/inputoutput.rst
+++ b/Doc/tutorial/inputoutput.rst
@@ -15,7 +15,7 @@ Fancier Output Formatting
 =========================
 
 So far we've encountered two ways of writing values: *expression statements* and
-the :func:`print` function.  (A third way is using the :meth:`write` method
+the :func:`print` function.  (A third way is using the :meth:`~io.TextIOBase.write` method
 of file objects; the standard output file can be referenced as ``sys.stdout``.
 See the Library Reference for more information on this.)
 
@@ -456,8 +456,8 @@ to the very file end with ``seek(0, 2)``) and the only valid *offset* values are
 those returned from the ``f.tell()``, or zero. Any other *offset* value produces
 undefined behaviour.
 
-File objects have some additional methods, such as :meth:`~file.isatty` and
-:meth:`~file.truncate` which are less frequently used; consult the Library
+File objects have some additional methods, such as :meth:`~io.IOBase.isatty` and
+:meth:`~io.IOBase.truncate` which are less frequently used; consult the Library
 Reference for a complete guide to file objects.
 
 
@@ -469,7 +469,7 @@ Saving structured data with :mod:`json`
 .. index:: pair: module; json
 
 Strings can easily be written to and read from a file.  Numbers take a bit more
-effort, since the :meth:`read` method only returns strings, which will have to
+effort, since the :meth:`~io.TextIOBase.read` method only returns strings, which will have to
 be passed to a function like :func:`int`, which takes a string like ``'123'``
 and returns its numeric value 123.  When you want to save more complex data
 types like nested lists and dictionaries, parsing and serializing by hand
diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst
index 734dd1cfe6871..bf9e8e0b7b806 100644
--- a/Doc/tutorial/modules.rst
+++ b/Doc/tutorial/modules.rst
@@ -183,7 +183,7 @@ The Module Search Path
 
 .. index:: triple: module; search; path
 
-When a module named :mod:`spam` is imported, the interpreter first searches for
+When a module named :mod:`!spam` is imported, the interpreter first searches for
 a built-in module with that name. These module names are listed in
 :data:`sys.builtin_module_names`. If not found, it then searches for a file
 named :file:`spam.py` in a list of directories given by the variable
@@ -389,7 +389,7 @@ Packages
 ========
 
 Packages are a way of structuring Python's module namespace by using "dotted
-module names".  For example, the module name :mod:`A.B` designates a submodule
+module names".  For example, the module name :mod:`!A.B` designates a submodule
 named ``B`` in a package named ``A``.  Just like the use of modules saves the
 authors of different modules from having to worry about each other's global
 variable names, the use of dotted module names saves the authors of multi-module
@@ -448,7 +448,7 @@ example::
 
    import sound.effects.echo
 
-This loads the submodule :mod:`sound.effects.echo`.  It must be referenced with
+This loads the submodule :mod:`!sound.effects.echo`.  It must be referenced with
 its full name. ::
 
    sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
@@ -457,7 +457,7 @@ An alternative way of importing the submodule is::
 
    from sound.effects import echo
 
-This also loads the submodule :mod:`echo`, and makes it available without its
+This also loads the submodule :mod:`!echo`, and makes it available without its
 package prefix, so it can be used as follows::
 
    echo.echofilter(input, output, delay=0.7, atten=4)
@@ -466,8 +466,8 @@ Yet another variation is to import the desired function or variable directly::
 
    from sound.effects.echo import echofilter
 
-Again, this loads the submodule :mod:`echo`, but this makes its function
-:func:`echofilter` directly available::
+Again, this loads the submodule :mod:`!echo`, but this makes its function
+:func:`!echofilter` directly available::
 
    echofilter(input, output, delay=0.7, atten=4)
 
@@ -510,7 +510,7 @@ code::
    __all__ = ["echo", "surround", "reverse"]
 
 This would mean that ``from sound.effects import *`` would import the three
-named submodules of the :mod:`sound.effects` package.
+named submodules of the :mod:`!sound.effects` package.
 
 Be aware that submodules might become shadowed by locally defined names. For
 example, if you added a ``reverse`` function to the
@@ -529,8 +529,8 @@ would only import the two submodules ``echo`` and ``surround``, but *not* the
         return msg[::-1]    #     in the case of a 'from sound.effects import *'
 
 If ``__all__`` is not defined, the statement ``from sound.effects import *``
-does *not* import all submodules from the package :mod:`sound.effects` into the
-current namespace; it only ensures that the package :mod:`sound.effects` has
+does *not* import all submodules from the package :mod:`!sound.effects` into the
+current namespace; it only ensures that the package :mod:`!sound.effects` has
 been imported (possibly running any initialization code in :file:`__init__.py`)
 and then imports whatever names are defined in the package.  This includes any
 names defined (and submodules explicitly loaded) by :file:`__init__.py`.  It
@@ -541,8 +541,8 @@ previous :keyword:`import` statements.  Consider this code::
    import sound.effects.surround
    from sound.effects import *
 
-In this example, the :mod:`echo` and :mod:`surround` modules are imported in the
-current namespace because they are defined in the :mod:`sound.effects` package
+In this example, the :mod:`!echo` and :mod:`!surround` modules are imported in the
+current namespace because they are defined in the :mod:`!sound.effects` package
 when the ``from...import`` statement is executed.  (This also works when
 ``__all__`` is defined.)
 
@@ -561,15 +561,15 @@ packages.
 Intra-package References
 ------------------------
 
-When packages are structured into subpackages (as with the :mod:`sound` package
+When packages are structured into subpackages (as with the :mod:`!sound` package
 in the example), you can use absolute imports to refer to submodules of siblings
-packages.  For example, if the module :mod:`sound.filters.vocoder` needs to use
-the :mod:`echo` module in the :mod:`sound.effects` package, it can use ``from
+packages.  For example, if the module :mod:`!sound.filters.vocoder` needs to use
+the :mod:`!echo` module in the :mod:`!sound.effects` package, it can use ``from
 sound.effects import echo``.
 
 You can also write relative imports, with the ``from module import name`` form
 of import statement.  These imports use leading dots to indicate the current and
-parent packages involved in the relative import.  From the :mod:`surround`
+parent packages involved in the relative import.  From the :mod:`!surround`
 module for example, you might use::
 
    from . import echo



More information about the Python-checkins mailing list