diff --git a/Doc/library/constants.rst b/Doc/builtins/constants.rst similarity index 100% rename from Doc/library/constants.rst rename to Doc/builtins/constants.rst diff --git a/Doc/library/exceptions.rst b/Doc/builtins/exceptions.rst similarity index 100% rename from Doc/library/exceptions.rst rename to Doc/builtins/exceptions.rst diff --git a/Doc/library/functions.rst b/Doc/builtins/functions.rst similarity index 100% rename from Doc/library/functions.rst rename to Doc/builtins/functions.rst diff --git a/Doc/builtins/index.rst b/Doc/builtins/index.rst new file mode 100644 index 000000000000000..17aab32200d976e --- /dev/null +++ b/Doc/builtins/index.rst @@ -0,0 +1,35 @@ +.. _builtins-index: + +############################## + Python built-ins reference +############################## + +Python comes with a number of built-in functions and classes. + +The built-in classes include data types that would normally be considered part +of the "core" of a language, such as numbers and lists. For these types, the +Python language core defines the form of literals and places some constraints +on their semantics, but does not fully define the semantics. + +The built-ins also include functions and exceptions --- objects that can +be used by all Python code without the need of an :keyword:`import` statement. +Some of these are defined by the core language, but many are not essential for +the core semantics and are only described here. + +.. seealso:: + + In addition to the built-ins, Python provides an extensive importable + standard library, see :ref:`library-index`. + +.. We don't use :numbered: option for the TOC below as it enforces + numbered sections for the entire builtin docs. If desired, + :numbered: can be enabled on a per-page basis. +.. toctree:: + :maxdepth: 2 + + stdtypes.rst + constants.rst + functions.rst + exceptions.rst + threadsafety.rst + time-complexity.rst diff --git a/Doc/library/stdtypes.rst b/Doc/builtins/stdtypes.rst similarity index 100% rename from Doc/library/stdtypes.rst rename to Doc/builtins/stdtypes.rst diff --git a/Doc/library/threadsafety.rst b/Doc/builtins/threadsafety.rst similarity index 100% rename from Doc/library/threadsafety.rst rename to Doc/builtins/threadsafety.rst diff --git a/Doc/library/time-complexity.rst b/Doc/builtins/time-complexity.rst similarity index 100% rename from Doc/library/time-complexity.rst rename to Doc/builtins/time-complexity.rst diff --git a/Doc/conf.py b/Doc/conf.py index c768e6fd676a5a3..f803fb1ff44bef9 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -44,6 +44,7 @@ 'sphinx_linklint.ext', 'notfound.extension', 'sphinxext.opengraph', + 'sphinxext.rediraffe', 'sphinxcontrib.rsvgconverter', ) for optional_ext in _OPTIONAL_EXTENSIONS: @@ -359,7 +360,13 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ - ('c-api/index', 'c-api.tex', 'The Python/C API', _doc_authors, 'manual'), + ( + 'c-api/index', + 'c-api.tex', + 'The Python/C API', + _doc_authors, + 'manual', + ), ( 'extending/index', 'extending.tex', @@ -374,6 +381,13 @@ _doc_authors, 'manual', ), + ( + 'builtins/index', + 'builtins.tex', + 'Python Built-ins Reference', + _doc_authors, + 'manual', + ), ( 'library/index', 'library.tex', @@ -606,3 +620,16 @@ '', '', ) + +# Options for sphinxext-rediraffe +# ------------------------------- + +rediraffe_redirects = { + # Splitting builtins from library + "library/functions.rst": "builtins/functions.rst", + "library/stdtypes.rst": "builtins/stdtypes.rst", + "library/constants.rst": "builtins/constants.rst", + "library/exceptions.rst": "builtins/exceptions.rst", + "library/threadsafety.rst": "builtins/threadsafety.rst", + "library/time-complexity.rst": "builtins/time-complexity.rst", +} diff --git a/Doc/contents.rst b/Doc/contents.rst index b57f4b09a5dcb6a..852be4a6d5b6ba7 100644 --- a/Doc/contents.rst +++ b/Doc/contents.rst @@ -8,6 +8,7 @@ tutorial/index.rst using/index.rst reference/index.rst + builtins/index.rst library/index.rst extending/index.rst c-api/index.rst diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst index c0c494c3059d99c..0f0686ea40e75be 100644 --- a/Doc/extending/index.rst +++ b/Doc/extending/index.rst @@ -16,9 +16,10 @@ underlying operating system supports this feature. This document assumes basic knowledge about C and Python. For an informal introduction to Python, see :ref:`tutorial-index`. :ref:`reference-index` -gives a more formal definition of the language. :ref:`library-index` documents -the existing object types, functions and modules (both built-in and written in -Python) that give the language its wide application range. +gives a more formal definition of the language. :ref:`builtins-index` documents +the built-in functions and object types, and :ref:`library-index` documents the +modules (both built-in and written in Python) that give the language its wide +application range. For a detailed description of the whole Python/C API, see the separate :ref:`c-api-index`. diff --git a/Doc/library/index.rst b/Doc/library/index.rst index f28c03e2fae092f..79437d533512b1a 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -1,16 +1,18 @@ .. _library-index: ############################### - The Python Standard Library + The Python standard library ############################### -While :ref:`reference-index` describes the exact syntax and -semantics of the Python language, this library reference manual -describes the standard library that is distributed with Python. It also -describes some of the optional components that are commonly included -in Python distributions. +This library reference manual describes the standard library +distributed with Python. It also describes some of the optional +components that are commonly included in Python distributions. -Python's standard library is very extensive, offering a wide range of +Elsewhere, :ref:`reference-index` describes the exact syntax and +semantics of the Python language, and :ref:`builtins-index` describes +the built-in functions. + +Python's standard library is extensive, offering a wide range of facilities as indicated by the long table of contents listed below. The library contains built-in modules (written in C) that provide access to system functionality such as file I/O that would otherwise be @@ -39,12 +41,6 @@ the `Python Package Index `_. :maxdepth: 2 intro.rst - functions.rst - constants.rst - stdtypes.rst - exceptions.rst - threadsafety.rst - time-complexity.rst text.rst binary.rst diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index 8f76044be488cda..fcd2175dbccc01b 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -4,48 +4,34 @@ Introduction ************ -The "Python library" contains several different kinds of components. - -It contains data types that would normally be considered part of the "core" of a -language, such as numbers and lists. For these types, the Python language core -defines the form of literals and places some constraints on their semantics, but -does not fully define the semantics. (On the other hand, the language core does -define syntactic properties like the spelling and priorities of operators.) - -The library also contains built-in functions and exceptions --- objects that can -be used by all Python code without the need of an :keyword:`import` statement. -Some of these are defined by the core language, but many are not essential for -the core semantics and are only described here. - -The bulk of the library, however, consists of a collection of modules. There are -many ways to dissect this collection. Some modules are written in C and built -in to the Python interpreter; others are written in Python and imported in -source form. Some modules provide interfaces that are highly specific to +The Python standard library consists of a collection of modules. There are +many ways to dissect this collection. Most modules are written in Python, +but some are written in C. All can be imported into your program to add +functionality. Some modules provide interfaces that are highly specific to Python, like printing a stack trace; some provide interfaces that are specific to particular operating systems, such as access to specific hardware; others provide interfaces that are specific to a particular application domain, like -the World Wide Web. Some modules are available in all versions and ports of +web development. Some modules are available in all versions and ports of Python; others are only available when the underlying system supports or requires them; yet others are available only when a particular configuration option was chosen at the time when Python was compiled and installed. -This manual is organized "from the inside out:" it first describes the built-in -functions, data types and exceptions, and finally the modules, grouped in -chapters of related modules. - -This means that if you start reading this manual from the start, and skip to the +If you start reading this manual from the start, and skip to the next chapter when you get bored, you will get a reasonable overview of the available modules and application areas that are supported by the Python library. Of course, you don't *have* to read it like a novel --- you can also browse the table of contents (in front of the manual), or look for a specific function, module or term in the index (in the back). And finally, if you enjoy -learning about random subjects, you choose a random page number (see module -:mod:`random`) and read a section or two. Regardless of the order in which you -read the sections of this manual, it helps to start with chapter -:ref:`built-in-funcs`, as the remainder of the manual assumes familiarity with -this material. +learning about random subjects, you choose a random page +and read a section or two. Regardless of the order in which you +read the sections of this manual, it helps to first read +:ref:`built-in-funcs`, as the remainder of this section +assumes familiarity with this material. + +.. seealso:: -Let the show begin! + The built-in functions and classes (which can be used without an + :keyword:`import` statement) are described in :ref:`builtins-index`. .. _availability: diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index efc81f31e36a5be..3e1f7a7e12a94e7 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -187,6 +187,12 @@ module documentation. This section lists the differences between the API and The *standalone* argument behaves exactly as in :meth:`writexml`. + No indentation is added inside an element + which is marked with ``xml:space="preserve"``, + which is declared in the DTD as not having element content, + or, in absence of such declaration, which contains text, + because this would change its content. + .. versionchanged:: 3.8 The :meth:`toprettyxml` method now preserves the attribute order specified by the user. @@ -194,6 +200,10 @@ module documentation. This section lists the differences between the API and .. versionchanged:: 3.9 The *standalone* parameter was added. + .. versionchanged:: next + Whitespace is no longer added inside an element with mixed content + or marked with ``xml:space="preserve"``. + .. _dom-example: DOM Example @@ -274,6 +284,10 @@ rules apply: and produced an invalid document, but removing an absent attribute raised :exc:`~xml.dom.NotFoundErr`. + .. versionchanged:: next + Namespaces are now validated in the factory methods and when setting + :attr:`~xml.dom.Node.prefix` of an attribute. + The following interfaces have no implementation in :mod:`!xml.dom.minidom`: * :class:`DOMTimeStamp` diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index b916e5ad9bd782a..b1c9e27a55274b1 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -687,6 +687,10 @@ inherits properties from :class:`Node`. :meth:`~Node.insertBefore` or :meth:`~Node.appendChild`. Raise :exc:`InvalidCharacterErr` if the name is not a valid XML name. + Raise :exc:`NamespaceErr` if the qualified name is malformed, + if it has a prefix and the namespace URI is empty, + or if the prefix is ``'xml'`` + and the namespace URI is not the XML namespace. .. method:: Document.createTextNode(data) @@ -740,6 +744,11 @@ inherits properties from :class:`Node`. :class:`Element` object to use the newly created attribute instance. Raise :exc:`InvalidCharacterErr` if the name is not a valid XML name. + Raise :exc:`NamespaceErr` if the qualified name is malformed, + if it has a prefix and the namespace URI is empty, + if the prefix is ``'xml'`` and the namespace URI is not the XML namespace, + or if the name or the prefix is ``'xmlns'`` + and the namespace URI is not the XMLNS namespace, or vice versa. .. method:: Document.getElementById(id) @@ -905,6 +914,11 @@ of that class. Note that a qname is the whole attribute name. This is different than above. Raise :exc:`InvalidCharacterErr` if the name is not a valid XML name. + Raise :exc:`NamespaceErr` if the qualified name is malformed, + if it has a prefix and the namespace URI is empty, + if the prefix is ``'xml'`` and the namespace URI is not the XML namespace, + or if the name or the prefix is ``'xmlns'`` + and the namespace URI is not the XMLNS namespace, or vice versa. .. _dom-attr-objects: diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 7948b2ed78f4d0d..a61fb05bf99d873 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -160,8 +160,37 @@ some storage device. In such cases, blocking reads are unacceptable. Because it's so flexible, :class:`XMLPullParser` can be inconvenient to use for simpler use-cases. If you don't mind your application blocking on reading XML data but would still like to have incremental parsing capabilities, take a look -at :func:`iterparse`. It can be useful when you're reading a large XML document -and don't want to hold it wholly in memory. +at :func:`iterparse`. + +Note that both parsers build the tree incrementally: it is not freed +incrementally, so every parsed element is kept until the whole document is +read. To keep the memory usage low, get rid of the data which is not needed +any more. + +If the processed elements are large, it is enough to clear them. +This works wherever they are in the tree, +but the emptied elements are left in it:: + + for event, elem in ET.iterparse(source): + if elem.tag == 'record': + process(elem) + elem.clear() + +If an element has a large number of children, +remove the processed children from it:: + + for event, elem in ET.iterparse(source, events=('start', 'end')): + if event == 'start' and elem.tag == 'parent': + parent = elem + elif event == 'end' and elem.tag == 'child': + process(elem) + parent.remove(elem) + +These examples are not universal, +they only give an idea for two common cases. +If you do not need a tree at all, +parse with :class:`XMLParser` and a custom target instead; +it is not built then, and nothing has to be removed. Where *immediate* feedback through events is wanted, calling method :meth:`XMLPullParser.flush` can help reduce delay; @@ -602,8 +631,16 @@ Functions characters by default. For indenting partial subtrees inside of an already indented tree, pass the initial indentation level as *level*. + No whitespace is added inside an element + which is marked with ``xml:space="preserve"`` + or which contains text, because this would change its content. + .. versionadded:: 3.9 + .. versionchanged:: next + Whitespace is no longer added inside an element with mixed content + or marked with ``xml:space="preserve"``. + .. function:: iselement(element) @@ -611,10 +648,11 @@ Functions element instance. Return ``True`` if this is an element object. -.. function:: iterparse(source, events=None, parser=None) +.. function:: iterparse(source, events=None, parser=None, *, target=None) - Parses an XML section into an element tree incrementally, and reports what's - going on to the user. *source* is a filename or :term:`file object` + Parses an XML section incrementally, and reports what's going on to the + user. Unless a custom target is used, an element tree is built. + *source* is a filename or :term:`file object` containing XML data. *events* is a sequence of events to report back. The supported events are the strings ``"start"``, ``"end"``, ``"comment"``, ``"pi"``, ``"start-ns"`` and ``"end-ns"`` @@ -622,11 +660,18 @@ Functions information). If *events* is omitted, only ``"end"`` events are reported. *parser* is an optional parser instance. If not given, the standard :class:`XMLParser` parser is used. - *parser* must be an instance of :class:`XMLParser` or its subclass - and can only use the default :class:`TreeBuilder` as a target. - Returns an :term:`iterator` providing ``(event, elem)`` pairs; + *parser* must be an instance of :class:`XMLParser` or its subclass. + *target* is the target of the standard parser, + as for :class:`XMLPullParser`; + it cannot be used together with *parser*. + Returns an :term:`iterator` providing ``(event, obj)`` pairs, + as described for :meth:`XMLPullParser.read_events`; it has a ``root`` attribute that references the root element of the - resulting XML tree once *source* is fully read. + resulting XML tree, or the value returned by the ``close()`` method + of a custom target, once *source* is fully read. + If a custom target is used, it is set to the value returned + by the :meth:`!close` method of the target. + The iterator has the :meth:`!close` method that closes the internal file object if *source* is a filename. @@ -635,6 +680,10 @@ Functions for applications where blocking reads can't be made. For fully non-blocking parsing, see :class:`XMLPullParser`. + The tree is only built incrementally, it is not freed incrementally: + every parsed element is kept until the whole document is read. + See :ref:`elementtree-pull-parsing` for how to keep the memory usage low. + .. note:: :func:`iterparse` only guarantees that it has seen the ">" character of a @@ -658,6 +707,9 @@ Functions A :exc:`ResourceWarning` is now emitted if the iterator opened a file and is not explicitly closed. + .. versionchanged:: next + Added the *target* parameter. + .. function:: parse(source, parser=None) @@ -1491,7 +1543,7 @@ XMLParser Objects XMLPullParser Objects ^^^^^^^^^^^^^^^^^^^^^ -.. class:: XMLPullParser(events=None) +.. class:: XMLPullParser(events=None, *, target=None) A pull parser suitable for non-blocking applications. Its input-side API is similar to that of :class:`XMLParser`, but instead of pushing calls to a @@ -1502,6 +1554,20 @@ XMLPullParser Objects are used to get detailed namespace information). If *events* is omitted, only ``"end"`` events are reported. + *target* is the target object of the underlying :class:`XMLParser`. + If omitted, the standard :class:`TreeBuilder` is used, + and the reported objects are :class:`Element` instances. + With other targets the reported object is the value returned + by the corresponding method of the target, + so no tree is built if the target does not build one. + The target must implement the methods for all requested events, + except :meth:`!start_ns` and :meth:`!end_ns`: + if they are not implemented, a ``(prefix, uri)`` tuple and ``None`` + are reported for the ``"start-ns"`` and ``"end-ns"`` events. + + .. versionchanged:: next + Added the *target* parameter. + .. method:: feed(data) Feed the given data to the parser. *data* is a string @@ -1534,9 +1600,10 @@ XMLPullParser Objects Return an iterator over the events which have been encountered in the data fed to the - parser. The iterator yields ``(event, elem)`` pairs, where *event* is a - string representing the type of event (e.g. ``"end"``) and *elem* is the - encountered :class:`Element` object, or other context value as follows. + parser. The iterator yields ``(event, obj)`` pairs, where *event* is a + string representing the type of event (e.g. ``"end"``) and *obj* is the + object returned by the corresponding method of the target. + With the standard :class:`TreeBuilder` it is as follows. * ``start``, ``end``: the current Element. * ``comment``, ``pi``: the current comment / processing instruction diff --git a/Doc/pylock.toml b/Doc/pylock.toml index 94b7d9d48d646e5..3ad79b3cc6a8735 100644 --- a/Doc/pylock.toml +++ b/Doc/pylock.toml @@ -238,6 +238,12 @@ version = "0.13.0" sdist = { url = "https://files.pythonhosted.org/packages/f6/c0/eb6838e3bae624ce6c8b90b245d17e84252863150e95efdb88f92c8aa3fb/sphinxext_opengraph-0.13.0.tar.gz", upload-time = 2025-08-29T12:20:31Z, size = 1026875, hashes = { sha256 = "103335d08567ad8468faf1425f575e3b698e9621f9323949a6c8b96d9793e80b" } } wheels = [{ url = "https://files.pythonhosted.org/packages/bf/a4/66c1fd4f8fab88faf71cee04a945f9806ba0fef753f2cfc8be6353f64508/sphinxext_opengraph-0.13.0-py3-none-any.whl", upload-time = 2025-08-29T12:20:29Z, size = 1004152, hashes = { sha256 = "936c07828edc9ad9a7b07908b29596dc84ed0b3ceaa77acdf51282d232d4d80e" } }] +[[packages]] +name = "sphinxext-rediraffe" +version = "0.3.0" +sdist = { url = "https://files.pythonhosted.org/packages/e3/a9/ab13d156049eea633f992424f3e92cb40e3f1b606bb6d01d40a27457d38a/sphinxext_rediraffe-0.3.0.tar.gz", upload-time = 2025-09-28T15:31:53Z, size = 22114, hashes = { sha256 = "f319b3ccb7c3c3b6f63ffa6fd3eeb171b6d272df55075a9e84364394f391f507" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/87/55/ab40a0d1378ee5c859590a633052cf1d0a1f8435af87558a9f7cd576601a/sphinxext_rediraffe-0.3.0-py3-none-any.whl", upload-time = 2025-09-28T15:31:52Z, size = 7194, hashes = { sha256 = "f4220beafa99c99177488276b8e4fcf61fbeeec4253c1e4aae841a18c475330c" } }] + [[packages]] name = "urllib3" version = "2.7.0" diff --git a/Doc/reference/index.rst b/Doc/reference/index.rst index a66673b17246d7b..9a5b2e631204a55 100644 --- a/Doc/reference/index.rst +++ b/Doc/reference/index.rst @@ -4,10 +4,13 @@ The Python Language Reference ################################# -This reference manual describes the syntax and "core semantics" of the -language. It is terse, but attempts to be exact and complete. The semantics of -non-essential built-in object types and of the built-in functions and modules -are described in :ref:`library-index`. For an informal introduction to the +This reference manual describes the syntax and core semantics of the +language. It is terse, but attempts to be exact and complete. + +Elsewhere, the built-in object types and functions are described in +:ref:`builtins-index`. Standard library modules are described in :ref:`library-index`. + +For an informal introduction to the language, see :ref:`tutorial-index`. For C or C++ programmers, two additional manuals exist: :ref:`extending-index` describes the high-level picture of how to write a Python extension module, and the :ref:`c-api-index` describes the diff --git a/Doc/requirements.txt b/Doc/requirements.txt index b9072b4af542225..2fa952aa291f1fc 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -16,6 +16,7 @@ blurb sphinx-linklint sphinx-notfound-page~=1.0.0 sphinxext-opengraph~=0.13.0 +sphinxext-rediraffe # The theme used by the documentation is stored separately, so we need # to install that as well. diff --git a/Doc/tools/check-html-ids.py b/Doc/tools/check-html-ids.py index 3ea0a99d1dd4f68..12bda7666073d45 100644 --- a/Doc/tools/check-html-ids.py +++ b/Doc/tools/check-html-ids.py @@ -19,18 +19,33 @@ ) +class Redirect(Exception): # noqa: N818 Exception should be named with an Error suffix + def __init__(self, redirect_to): + self.redirect_to = redirect_to + + class IDGatherer(html.parser.HTMLParser): def __init__(self, ids): super().__init__() self.__ids = ids def handle_starttag(self, tag, attrs): + if tag == "meta": + # Redirects are done with a meta tag: + # + dattr = dict(attrs) + if dattr.get("http-equiv") == "refresh": + content = dattr.get("content", "") + if content.startswith("0; url="): + redirect_to = content[7:] + raise Redirect(redirect_to) for name, value in attrs: if name == 'id': if not IGNORED_ID_RE.fullmatch(value): self.__ids.add(value) +@functools.cache def get_ids_from_file(path): ids = set() gatherer = IDGatherer(ids) @@ -40,6 +55,18 @@ def get_ids_from_file(path): return ids +def get_ids_including_redirects(path): + # Only try 6 redirects, to avoid accidental endless loops + for _ in range(6): + try: + return get_ids_from_file(path) + except Redirect as r: + path = (path.parent / r.redirect_to).resolve() + continue + else: + raise RuntimeError("Apparent infinite redirects") + + def gather_ids(htmldir, *, verbose_print): if not htmldir.joinpath('objects.inv').exists(): raise ValueError(f'{htmldir!r} is not a Sphinx HTML output directory') @@ -55,7 +82,9 @@ def gather_ids(htmldir, *, verbose_print): continue if 'whatsnew' in relative_path.parts: continue - tasks[relative_path] = pool.submit(get_ids_from_file, path=path) + tasks[relative_path] = pool.submit( + get_ids_including_redirects, path=path + ) ids_by_page = {} for relative_path, future in tasks.items(): diff --git a/Doc/tools/templates/indexcontent.html b/Doc/tools/templates/indexcontent.html index 4366da69d1b2d09..59a693c00003c45 100644 --- a/Doc/tools/templates/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -56,16 +56,18 @@

{{ docstitle|e }}

{% trans whatsnew_index=pathto("whatsnew/index") %}Or all "What's new" documents since Python 2.0{% endtrans %} + + {% trans %}Standard library modules{% endtrans %} -