text:
PEP: 324 Title: subprocess - New process module Version: $Revision$
Last-Modified: $Date$ Author: Peter Astrand<EMAIL_ADDRESS>Status: Final Type: Standards Track Content-Type: text/x-rst Created:
19-Nov-2003 Python-Version: 2.4 Post-History:

Abstract

This PEP describes a new module for starting and communicating with
processes.

Motivation

Starting new processes is a common task in any programming language, and
very common in a high-level language like Python. Good support for this
task is needed, because:

-   Inappropriate functions for starting processes could mean a security
    risk: If the program is started through the shell, and the arguments
    contain shell meta characters, the result can be disastrous.[1]
-   It makes Python an even better replacement language for
    over-complicated shell scripts.

Currently, Python has a large number of different functions for process
creation. This makes it hard for developers to choose.

The subprocess module provides the following enhancements over previous
functions:

-   One "unified" module provides all functionality from previous
    functions.
-   Cross-process exceptions: Exceptions happening in the child before
    the new process has started to execute are re-raised in the parent.
    This means that it's easy to handle exec() failures, for example.
    With popen2, for example, it's impossible to detect if the execution
    failed.
-   A hook for executing custom code between fork and exec. This can be
    used for, for example, changing uid.
-   No implicit call of /bin/sh. This means that there is no need for
    escaping dangerous shell meta characters.
-   All combinations of file descriptor redirection is possible. For
    example, the "python-dialog"[2] needs to spawn a process and
    redirect stderr, but not stdout. This is not possible with current
    functions, without using temporary files.
-   With the subprocess module, it's possible to control if all open
    file descriptors should be closed before the new program is
    executed.
-   Support for connecting several subprocesses (shell "pipe").
-   Universal newline support.
-   A communicate() method, which makes it easy to send stdin data and
    read stdout and stderr data, without risking deadlocks. Most people
    are aware of the flow control issues involved with child process
    communication, but not all have the patience or skills to write a
    fully correct and deadlock-free select loop. This means that many
    Python applications contain race conditions. A communicate() method
    in the standard library solves this problem.

Rationale

The following points summarizes the design:

-   subprocess was based on popen2, which is tried-and-tested.

-   The factory functions in popen2 have been removed, because I
    consider the class constructor equally easy to work with.

-   popen2 contains several factory functions and classes for different
    combinations of redirection. subprocess, however, contains one
    single class. Since the subprocess module supports 12 different
    combinations of redirection, providing a class or function for each
    of them would be cumbersome and not very intuitive. Even with
    popen2, this is a readability problem. For example, many people
    cannot tell the difference between popen2.popen2 and popen2.popen4
    without using the documentation.

-   One small utility function is provided: subprocess.call(). It aims
    to be an enhancement over os.system(), while still very easy to use:

    -   It does not use the Standard C function system(), which has
        limitations.
    -   It does not call the shell implicitly.
    -   No need for quoting; using an argument list.
    -   The return value is easier to work with.

    The call() utility function accepts an 'args' argument, just like
    the Popen class constructor. It waits for the command to complete,
    then returns the returncode attribute. The implementation is very
    simple:

        def call(*args, **kwargs):
            return Popen(*args, **kwargs).wait()

    The motivation behind the call() function is simple: Starting a
    process and wait for it to finish is a common task.

    While Popen supports a wide range of options, many users have simple
    needs. Many people are using os.system() today, mainly because it
    provides a simple interface. Consider this example:

        os.system("stty sane -F " + device)

    With subprocess.call(), this would look like:

        subprocess.call(["stty", "sane", "-F", device])

    or, if executing through the shell:

        subprocess.call("stty sane -F " + device, shell=True)

-   The "preexec" functionality makes it possible to run arbitrary code
    between fork and exec. One might ask why there are special arguments
    for setting the environment and current directory, but not for, for
    example, setting the uid. The answer is:

    -   Changing environment and working directory is considered fairly
        common.
    -   Old functions like spawn() has support for an "env"-argument.
    -   env and cwd are considered quite cross-platform: They make sense
        even on Windows.

-   On POSIX platforms, no extension module is required: the module uses
    os.fork(), os.execvp() etc.

-   On Windows platforms, the module requires either Mark Hammond's
    Windows extensions[3], or a small extension module called
    _subprocess.

Specification

This module defines one class called Popen:

    class Popen(args, bufsize=0, executable=None,
                stdin=None, stdout=None, stderr=None,
                preexec_fn=None, close_fds=False, shell=False,
                cwd=None, env=None, universal_newlines=False,
                startupinfo=None, creationflags=0):

Arguments are:

-   args should be a string, or a sequence of program arguments. The
    program to execute is normally the first item in the args sequence
    or string, but can be explicitly set by using the executable
    argument.

    On UNIX, with shell=False (default): In this case, the Popen class
    uses os.execvp() to execute the child program. args should normally
    be a sequence. A string will be treated as a sequence with the
    string as the only item (the program to execute).

    On UNIX, with shell=True: If args is a string, it specifies the
    command string to execute through the shell. If args is a sequence,
    the first item specifies the command string, and any additional
    items will be treated as additional shell arguments.

    On Windows: the Popen class uses CreateProcess() to execute the
    child program, which operates on strings. If args is a sequence, it
    will be converted to a string using the list2cmdline method. Please
    note that not all MS Windows applications interpret the command line
    the same way: The list2cmdline is designed for applications using
    the same rules as the MS C runtime.

-   bufsize, if given, has the same meaning as the corresponding
    argument to the built-in open() function: 0 means unbuffered, 1
    means line buffered, any other positive value means use a buffer of
    (approximately) that size. A negative bufsize means to use the
    system default, which usually means fully buffered. The default
    value for bufsize is 0 (unbuffered).

-   stdin, stdout and stderr specify the executed programs' standard
    input, standard output and standard error file handles,
    respectively. Valid values are PIPE, an existing file descriptor (a
    positive integer), an existing file object, and None. PIPE indicates
    that a new pipe to the child should be created. With None, no
    redirection will occur; the child's file handles will be inherited
    from the parent. Additionally, stderr can be STDOUT, which indicates
    that the stderr data from the applications should be captured into
    the same file handle as for stdout.

-   If preexec_fn is set to a callable object, this object will be
    called in the child process just before the child is executed.

-   If close_fds is true, all file descriptors except 0, 1 and 2 will be
    closed before the child process is executed.

-   If shell is true, the specified command will be executed through the
    shell.

-   If cwd is not None, the current directory will be changed to cwd
    before the child is executed.

-   If env is not None, it defines the environment variables for the new
    process.

-   If universal_newlines is true, the file objects stdout and stderr
    are opened as a text file, but lines may be terminated by any of \n,
    the Unix end-of-line convention, \r, the Macintosh convention or
    \r\n, the Windows convention. All of these external representations
    are seen as \n by the Python program. Note: This feature is only
    available if Python is built with universal newline support (the
    default). Also, the newlines attribute of the file objects stdout,
    stdin and stderr are not updated by the communicate() method.

-   The startupinfo and creationflags, if given, will be passed to the
    underlying CreateProcess() function. They can specify things such as
    appearance of the main window and priority for the new process.
    (Windows only)

This module also defines two shortcut functions:

-

    call(*args, **kwargs):

        Run command with arguments. Wait for command to complete, then
        return the returncode attribute.

        The arguments are the same as for the Popen constructor.
        Example:

            retcode = call(["ls", "-l"])

Exceptions

Exceptions raised in the child process, before the new program has
started to execute, will be re-raised in the parent. Additionally, the
exception object will have one extra attribute called 'child_traceback',
which is a string containing traceback information from the child's
point of view.

The most common exception raised is OSError. This occurs, for example,
when trying to execute a non-existent file. Applications should prepare
for OSErrors.

A ValueError will be raised if Popen is called with invalid arguments.

Security

Unlike some other popen functions, this implementation will never call
/bin/sh implicitly. This means that all characters, including shell
meta-characters, can safely be passed to child processes.

Popen objects

Instances of the Popen class have the following methods:

poll()

    Check if child process has terminated. Returns returncode attribute.

wait()

    Wait for child process to terminate. Returns returncode attribute.

communicate(input=None)

    Interact with process: Send data to stdin. Read data from stdout and
    stderr, until end-of-file is reached. Wait for process to terminate.
    The optional stdin argument should be a string to be sent to the
    child process, or None, if no data should be sent to the child.

    communicate() returns a tuple (stdout, stderr).

    Note: The data read is buffered in memory, so do not use this method
    if the data size is large or unlimited.

The following attributes are also available:

stdin

    If the stdin argument is PIPE, this attribute is a file object that
    provides input to the child process. Otherwise, it is None.

stdout

    If the stdout argument is PIPE, this attribute is a file object that
    provides output from the child process. Otherwise, it is None.

stderr

    If the stderr argument is PIPE, this attribute is file object that
    provides error output from the child process. Otherwise, it is None.

pid

    The process ID of the child process.

returncode

    The child return code. A None value indicates that the process
    hasn't terminated yet. A negative value -N indicates that the child
    was terminated by signal N (UNIX only).

Replacing older functions with the subprocess module

In this section, "a ==> b" means that b can be used as a replacement for
a.

Note: All functions in this section fail (more or less) silently if the
executed program cannot be found; this module raises an OSError
exception.

In the following examples, we assume that the subprocess module is
imported with from subprocess import *.

Replacing /bin/sh shell backquote

    output=`mycmd myarg`
    ==>
    output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]

Replacing shell pipe line

    output=`dmesg | grep hda`
    ==>
    p1 = Popen(["dmesg"], stdout=PIPE)
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
    output = p2.communicate()[0]

Replacing os.system()

    sts = os.system("mycmd" + " myarg")
    ==>
    p = Popen("mycmd" + " myarg", shell=True)
    sts = os.waitpid(p.pid, 0)

Note:

-   Calling the program through the shell is usually not required.
-   It's easier to look at the returncode attribute than the exit
    status.

A more real-world example would look like this:

    try:
        retcode = call("mycmd" + " myarg", shell=True)
        if retcode < 0:
            print >>sys.stderr, "Child was terminated by signal", -retcode
        else:
            print >>sys.stderr, "Child returned", retcode
    except OSError, e:
        print >>sys.stderr, "Execution failed:", e

Replacing os.spawn*

P_NOWAIT example:

    pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
    ==>
    pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT example:

    retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
    ==>
    retcode = call(["/bin/mycmd", "myarg"])

Vector example:

    os.spawnvp(os.P_NOWAIT, path, args)
    ==>
    Popen([path] + args[1:])

Environment example:

    os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
    ==>
    Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

Replacing os.popen*

    pipe = os.popen(cmd, mode='r', bufsize)
    ==>
    pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout

    pipe = os.popen(cmd, mode='w', bufsize)
    ==>
    pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin

    (child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
    ==>
    p = Popen(cmd, shell=True, bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, close_fds=True)
    (child_stdin, child_stdout) = (p.stdin, p.stdout)

    (child_stdin,
     child_stdout,
     child_stderr) = os.popen3(cmd, mode, bufsize)
    ==>
    p = Popen(cmd, shell=True, bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
    (child_stdin,
     child_stdout,
     child_stderr) = (p.stdin, p.stdout, p.stderr)

    (child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
    ==>
    p = Popen(cmd, shell=True, bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
    (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

Replacing popen2.*

Note: If the cmd argument to popen2 functions is a string, the command
is executed through /bin/sh. If it is a list, the command is directly
executed.

    (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
    ==>
    p = Popen(["somestring"], shell=True, bufsize=bufsize
              stdin=PIPE, stdout=PIPE, close_fds=True)
    (child_stdout, child_stdin) = (p.stdout, p.stdin)

    (child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
    ==>
    p = Popen(["mycmd", "myarg"], bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, close_fds=True)
    (child_stdout, child_stdin) = (p.stdout, p.stdin)

The popen2.Popen3 and popen3.Popen4 basically works as subprocess.Popen,
except that:

-   subprocess.Popen raises an exception if the execution fails
-   the capturestderr argument is replaced with the stderr argument.
-   stdin=PIPE and stdout=PIPE must be specified.
-   popen2 closes all file descriptors by default, but you have to
    specify close_fds=True with subprocess.Popen.

Open Issues

Some features have been requested but is not yet implemented. This
includes:

-   Support for managing a whole flock of subprocesses
-   Support for managing "daemon" processes
-   Built-in method for killing subprocesses

While these are useful features, it's expected that these can be added
later without problems.

-   expect-like functionality, including pty support.

pty support is highly platform-dependent, which is a problem. Also,
there are already other modules that provide this kind of
functionality[4].

Backwards Compatibility

Since this is a new module, no major backward compatible issues are
expected. The module name "subprocess" might collide with other,
previous modules[5] with the same name, but the name "subprocess" seems
to be the best suggested name so far. The first name of this module was
"popen5", but this name was considered too unintuitive. For a while, the
module was called "process", but this name is already used by Trent
Mick's module[6].

The functions and modules that this new module is trying to replace
(os.system, os.spawn*, os.popen*, popen2.*, commands.*) are expected to
be available in future Python versions for a long time, to preserve
backwards compatibility.

Reference Implementation

A reference implementation is available from
http://www.lysator.liu.se/~astrand/popen5/.

References

Copyright

This document has been placed in the public domain.

[1] Secure Programming for Linux and Unix HOWTO, section 8.3.
http://www.dwheeler.com/secure-programs/

[2] Python Dialog http://pythondialog.sourceforge.net/

[3] http://starship.python.net/crew/mhammond/win32/

[4] http://www.lysator.liu.se/~ceder/pcl-expect/

[5] http://www.iol.ie/~padraiga/libs/subProcess.py

[6] http://starship.python.net/crew/tmick/


text:
PEP: 379 Title: Adding an Assignment Expression Version: $Revision$
Last-Modified: $Date$ Author: Jervis Whitley<EMAIL_ADDRESS>Status: Withdrawn Type: Standards Track Content-Type: text/x-rst
Created: 14-Mar-2009 Python-Version: 2.7, 3.2 Post-History:

Abstract

This PEP adds a new assignment expression to the Python language to make
it possible to assign the result of an expression in almost any place.
The new expression will allow the assignment of the result of an
expression at first use (in a comparison for example).

Motivation and Summary

Issue1714448 "if something as x:"[1] describes a feature to allow
assignment of the result of an expression in an if statement to a name.
It supposed that the as syntax could be borrowed for this purpose. Many
times it is not the expression itself that is interesting, rather one of
the terms that make up the expression. To be clear, something like this:

    if (f_result() == [1, 2, 3]) as res:

seems awfully limited, when this:

    if (f_result() as res) == [1, 2, 3]:

is probably the desired result.

Use Cases

See the Examples section near the end.

Specification

A new expression is proposed with the (nominal) syntax:

    EXPR -> VAR

This single expression does the following:

-   Evaluate the value of EXPR, an arbitrary expression;
-   Assign the result to VAR, a single assignment target; and
-   Leave the result of EXPR on the Top of Stack (TOS)

Here -> or (RARROW) has been used to illustrate the concept that the
result of EXPR is assigned to VAR.

The translation of the proposed syntax is:

    VAR = (EXPR)
    (EXPR)

The assignment target can be either an attribute, a subscript or name:

    f() -> name[0]      # where 'name' exists previously.

    f() -> name.attr    # again 'name' exists prior to this expression.

    f() -> name

This expression should be available anywhere that an expression is
currently accepted.

All exceptions that are currently raised during invalid assignments will
continue to be raised when using the assignment expression. For example,
a NameError will be raised when in example 1 and 2 above if name is not
previously defined, or an IndexError if index 0 was out of range.

Examples from the Standard Library

The following two examples were chosen after a brief search through the
standard library, specifically both are from ast.py which happened to be
open at the time of the search.

Original:

    def walk(node):
        from collections import deque
        todo = deque([node])
        while todo:
            node = todo.popleft()
            todo.extend(iter_child_nodes(node))
            yield node

Using assignment expression:

    def walk(node):
        from collections import deque
        todo = deque([node])
        while todo:
            todo.extend(iter_child_nodes(todo.popleft() -> node))
            yield node

Original:

    def get_docstring(node, clean=True):
        if not isinstance(node, (FunctionDef, ClassDef, Module)):
            raise TypeError("%r can't have docstrings"
                                % node.__class__.__name__)
        if node.body and isinstance(node.body[0], Expr) and \
        isinstance(node.body[0].value, Str):
            if clean:
                import inspect
                return inspect.cleandoc(node.body[0].value.s)
            return node.body[0].value.s

Using assignment expression:

    def get_docstring(node, clean=True):
        if not isinstance(node, (FunctionDef, ClassDef, Module)):
            raise TypeError("%r can't have docstrings"
                                % node.__class__.__name__)
        if node.body -> body and isinstance(body[0] -> elem, Expr) and \
        isinstance(elem.value -> value, Str):
            if clean:
                import inspect
                return inspect.cleandoc(value.s)
            return value.s

Examples

The examples shown below highlight some of the desirable features of the
assignment expression, and some of the possible corner cases.

1.  Assignment in an if statement for use later:

        def expensive():
            import time; time.sleep(1)
            return 'spam'

        if expensive() -> res in ('spam', 'eggs'):
            dosomething(res)

2.  Assignment in a while loop clause:

        while len(expensive() -> res) == 4:
            dosomething(res)

3.  Keep the iterator object from the for loop:

        for ch in expensive() -> res:
            sell_on_internet(res)

4.  Corner case:

        for ch -> please_dont in expensive():
            pass
        # who would want to do this? Not I.

References

Copyright

This document has been placed in the public domain.

[1] Issue1714448 "if something as x:", k0wax
http://bugs.python.org/issue1714448

license: Public Domain


text:
PEP: 12 Title: Sample reStructuredText PEP Template Author: David
Goodger<EMAIL_ADDRESS>Barry Warsaw<EMAIL_ADDRESS>Brett
Cannon<EMAIL_ADDRESS>Status: Active Type: Process Created:
05-Aug-2002 Post-History: 30-Aug-2002

Note

For those who have written a PEP before, there is a template (which is
included as a file in the PEPs repository).

Abstract

This PEP provides a boilerplate or sample template for creating your own
reStructuredText PEPs. In conjunction with the content guidelines in PEP
1, this should make it easy for you to conform your own PEPs to the
format outlined below.

Note: if you are reading this PEP via the web, you should first grab the
text (reStructuredText) source of this PEP in order to complete the
steps below. DO NOT USE THE HTML FILE AS YOUR TEMPLATE!

The source for this (or any) PEP can be found in the PEPs repository, as
well as via a link at the bottom of each PEP.

Rationale

If you intend to submit a PEP, you MUST use this template, in
conjunction with the format guidelines below, to ensure that your PEP
submission won't get automatically rejected because of form.

ReStructuredText provides PEP authors with useful functionality and
expressivity, while maintaining easy readability in the source text. The
processed HTML form makes the functionality accessible to readers: live
hyperlinks, styled text, tables, images, and automatic tables of
contents, among other advantages.

How to Use This Template

To use this template you must first decide whether your PEP is going to
be an Informational or Standards Track PEP. Most PEPs are Standards
Track because they propose a new feature for the Python language or
standard library. When in doubt, read PEP 1 for details, or open a
tracker issue on the PEPs repo to ask for assistance.

Once you've decided which type of PEP yours is going to be, follow the
directions below.

-   Make a copy of this file (the .rst file, not the HTML!) and perform
    the following edits. Name the new file pep-{NNNN}.rst, using the
    next available number (not used by a published or in-PR PEP).

-   Replace the "PEP: 12" header with "PEP: NNNN", matching the file
    name. Note that the file name should be padded with zeros (eg
    pep-0012.rst), but the header should not (PEP: 12).

-   Change the Title header to the title of your PEP.

-   Change the Author header to include your name, and optionally your
    email address. Be sure to follow the format carefully: your name
    must appear first, and it must not be contained in parentheses. Your
    email address may appear second (or it can be omitted) and if it
    appears, it must appear in angle brackets. It is okay to obfuscate
    your email address.

-   If none of the authors are Python core developers, include a Sponsor
    header with the name of the core developer sponsoring your PEP.

-   Add the direct URL of the PEP's canonical discussion thread (on e.g.
    Python-Dev, Discourse, etc) under the Discussions-To header. If the
    thread will be created after the PEP is submitted as an official
    draft, it is okay to just list the venue name initially, but
    remember to update the PEP with the URL as soon as the PEP is
    successfully merged to the PEPs repository and you create the
    corresponding discussion thread. See PEP 1 <1#discussing-a-pep> for
    more details.

-   Change the Status header to "Draft".

-   For Standards Track PEPs, change the Type header to "Standards
    Track".

-   For Informational PEPs, change the Type header to "Informational".

-   For Standards Track PEPs, if your feature depends on the acceptance
    of some other currently in-development PEP, add a Requires header
    right after the Type header. The value should be the PEP number of
    the PEP yours depends on. Don't add this header if your dependent
    feature is described in a Final PEP.

-   Change the Created header to today's date. Be sure to follow the
    format carefully: it must be in dd-mmm-yyyy format, where the mmm is
    the 3 English letter month abbreviation, i.e. one of Jan, Feb, Mar,
    Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec.

-   For Standards Track PEPs, after the Created header, add a
    Python-Version header and set the value to the next planned version
    of Python, i.e. the one your new feature will hopefully make its
    first appearance in. Do not use an alpha or beta release designation
    here. Thus, if the last version of Python was 2.2 alpha 1 and you're
    hoping to get your new feature into Python 2.2, set the header to:

        Python-Version: 2.2

-   Add a Topic header if the PEP belongs under one shown at the
    topic-index. Most PEPs don't.

-   Leave Post-History alone for now; you'll add dates and corresponding
    links to this header each time you post your PEP to the designated
    discussion forum (and update the Discussions-To header with said
    link, as above). For each thread, use the date (in the dd-mmm-yyy
    format) as the linked text, and insert the URLs inline as anonymous
    reST hyperlinks, with commas in between each posting.

    If you posted threads for your PEP on August 14, 2001 and September
    3, 2001, the Post-History header would look like, e.g.:

        Post-History: `14-Aug-2001 <https://www.example.com/thread_1>`__,
                      `03-Sept-2001 <https://www.example.com/thread_2>`__

    You should add the new dates/links here as soon as you post a new
    discussion thread.

-   Add a Replaces header if your PEP obsoletes an earlier PEP. The
    value of this header is the number of the PEP that your new PEP is
    replacing. Only add this header if the older PEP is in "final" form,
    i.e. is either Accepted, Final, or Rejected. You aren't replacing an
    older open PEP if you're submitting a competing idea.

-   Now write your Abstract, Rationale, and other content for your PEP,
    replacing all this gobbledygook with your own text. Be sure to
    adhere to the format guidelines below, specifically on the
    prohibition of tab characters and the indentation requirements. See
    "Suggested Sections" below for a template of sections to include.

-   Update your Footnotes section, listing any footnotes and non-inline
    link targets referenced by the text.

-   Run ./build.py to ensure the PEP is rendered without errors, and
    check that the output in build/pep-{NNNN}.html looks as you intend.

-   Create a pull request against the PEPs repository.

For reference, here are all of the possible header fields (everything in
brackets should either be replaced or have the field removed if it has a
leading * marking it as optional and it does not apply to your PEP):

    PEP: [NNN]
    Title: [...]
    Author: [Full Name <email at example.com>]
    Sponsor: *[Full Name <email at example.com>]
    PEP-Delegate:
    Discussions-To: [URL]
    Status: Draft
    Type: [Standards Track | Informational | Process]
    Topic: *[Governance | Packaging | Release | Typing]
    Requires: *[NNN]
    Created: [DD-MMM-YYYY]
    Python-Version: *[M.N]
    Post-History: [`DD-MMM-YYYY <URL>`__]
    Replaces: *[NNN]
    Superseded-By: *[NNN]
    Resolution:

ReStructuredText PEP Formatting Requirements

The following is a PEP-specific summary of reStructuredText syntax. For
the sake of simplicity and brevity, much detail is omitted. For more
detail, see Resources below. Literal blocks (in which no markup
processing is done) are used for examples throughout, to illustrate the
plaintext markup.

General

Lines should usually not extend past column 79, excepting URLs and
similar circumstances. Tab characters must never appear in the document
at all.

Section Headings

PEP headings must begin in column zero and the initial letter of each
word must be capitalized as in book titles. Acronyms should be in all
capitals. Section titles must be adorned with an underline, a single
repeated punctuation character, which begins in column zero and must
extend at least as far as the right edge of the title text (4 characters
minimum). First-level section titles are underlined with "=" (equals
signs), second-level section titles with "-" (hyphens), and third-level
section titles with "'" (single quotes or apostrophes). For example:

    First-Level Title
    =================

    Second-Level Title
    ------------------

    Third-Level Title
    '''''''''''''''''

If there are more than three levels of sections in your PEP, you may
insert overline/underline-adorned titles for the first and second levels
as follows:

    ============================
    First-Level Title (optional)
    ============================

    -----------------------------
    Second-Level Title (optional)
    -----------------------------

    Third-Level Title
    =================

    Fourth-Level Title
    ------------------

    Fifth-Level Title
    '''''''''''''''''

You shouldn't have more than five levels of sections in your PEP. If you
do, you should consider rewriting it.

You must use two blank lines between the last line of a section's body
and the next section heading. If a subsection heading immediately
follows a section heading, a single blank line in-between is sufficient.

The body of each section is not normally indented, although some
constructs do use indentation, as described below. Blank lines are used
to separate constructs.

Paragraphs

Paragraphs are left-aligned text blocks separated by blank lines.
Paragraphs are not indented unless they are part of an indented
construct (such as a block quote or a list item).

Inline Markup

Portions of text within paragraphs and other text blocks may be styled.
For example:

    Text may be marked as *emphasized* (single asterisk markup,
    typically shown in italics) or **strongly emphasized** (double
    asterisks, typically boldface).  ``Inline literals`` (using double
    backquotes) are typically rendered in a monospaced typeface.  No
    further markup recognition is done within the double backquotes,
    so they're safe for any kind of code snippets.

Block Quotes

Block quotes consist of indented body elements. For example:

    This is a paragraph.

        This is a block quote.

        A block quote may contain many paragraphs.

Block quotes are used to quote extended passages from other sources.
Block quotes may be nested inside other body elements. Use 4 spaces per
indent level.

Literal Blocks

Literal blocks are used for code samples and other preformatted text. To
indicate a literal block, preface the indented text block with "::" (two
colons), or use the .. code-block:: directive. Indent the text block by
4 spaces; the literal block continues until the end of the indentation.
For example:

    This is a typical paragraph.  A literal block follows.

    ::

        for a in [5, 4, 3, 2, 1]:  # this is program code, shown as-is
            print(a)
        print("it's...")

"::" is also recognized at the end of any paragraph; if not immediately
preceded by whitespace, one colon will remain visible in the final
output:

    This is an example::

        Literal block

By default, literal blocks will be syntax-highlighted as Python code.
For specific blocks that contain code or data in other
languages/formats, use the .. code-block:: language directive,
substituting the "short name" of the appropriate Pygments lexer (or text
to disable highlighting) for language. For example:

    .. code-block:: rst

        An example of the ``rst`` lexer (i.e. *reStructuredText*).

For PEPs that predominantly contain literal blocks of a specific
language, use the .. highlight:: language directive with the appropriate
language at the top of the PEP body (below the headers and above the
Abstract). All literal blocks will then be treated as that language,
unless specified otherwise in the specific .. code-block. For example:

    .. highlight:: c

    Abstract
    ========

    Here's some C code::

        printf("Hello, World!\n");

Lists

Bullet list items begin with one of "-", "*", or "+" (hyphen, asterisk,
or plus sign), followed by whitespace and the list item body. List item
bodies must be left-aligned and indented relative to the bullet; the
text immediately after the bullet determines the indentation. For
example:

    This paragraph is followed by a list.

    * This is the first bullet list item.  The blank line above the
      first list item is required; blank lines between list items
      (such as below this paragraph) are optional.

    * This is the first paragraph in the second item in the list.

      This is the second paragraph in the second item in the list.
      The blank line above this paragraph is required.  The left edge
      of this paragraph lines up with the paragraph above, both
      indented relative to the bullet.

      - This is a sublist.  The bullet lines up with the left edge of
        the text blocks above.  A sublist is a new list so requires a
        blank line above and below.

    * This is the third item of the main list.

    This paragraph is not part of the list.

Enumerated (numbered) list items are similar, but use an enumerator
instead of a bullet. Enumerators are numbers (1, 2, 3, ...), letters (A,
B, C, ...; uppercase or lowercase), or Roman numerals (i, ii, iii, iv,
...; uppercase or lowercase), formatted with a period suffix ("1.",
"2."), parentheses ("(1)", "(2)"), or a right-parenthesis suffix ("1)",
"2)"). For example:

    1. As with bullet list items, the left edge of paragraphs must
       align.

    2. Each list item may contain multiple paragraphs, sublists, etc.

       This is the second paragraph of the second list item.

       a) Enumerated lists may be nested.
       b) Blank lines may be omitted between list items.

Definition lists are written like this:

    what
        Definition lists associate a term with a definition.

    how
        The term is a one-line phrase, and the definition is one
        or more paragraphs or body elements, indented relative to
        the term.

Tables

Simple tables are easy and compact:

    =====  =====  =======
      A      B    A and B
    =====  =====  =======
    False  False  False
    True   False  False
    False  True   False
    True   True   True
    =====  =====  =======

There must be at least two columns in a table (to differentiate from
section titles). Column spans use underlines of hyphens ("Inputs" spans
the first two columns):

    =====  =====  ======
       Inputs     Output
    ------------  ------
      A      B    A or B
    =====  =====  ======
    False  False  False
    True   False  True
    False  True   True
    True   True   True
    =====  =====  ======

Text in a first-column cell starts a new row. No text in the first
column indicates a continuation line; the rest of the cells may consist
of multiple lines. For example:

    =====  =========================
    col 1  col 2
    =====  =========================
    1      Second column of row 1.
    2      Second column of row 2.
           Second line of paragraph.
    3      - Second column of row 3.

           - Second item in bullet
             list (row 3, column 2).
    =====  =========================

Hyperlinks

When referencing an external web page in the body of a PEP, you should
include the title of the page or a suitable description in the text,
with either an inline hyperlink or a separate explicit target with the
URL. Do not include bare URLs in the body text of the PEP, and use HTTPS
links wherever available.

Hyperlink references use backquotes and a trailing underscore to mark up
the reference text; backquotes are optional if the reference text is a
single word. For example, to reference a hyperlink target named
Python website, you would write:

    In this paragraph, we refer to the `Python website`_.

If you intend to only reference a link once, and want to define it
inline with the text, insert the link into angle brackets (<>) after the
text you want to link, but before the closing backtick, with a space
between the text and the opening backtick. You should also use a
double-underscore after the closing backtick instead of a single one,
which makes it an anonymous reference to avoid conflicting with other
target names. For example:

    Visit the `website <https://www.python.org/>`__ for more.

If you want to use one link multiple places with different linked text,
or want to ensure you don't have to update your link target names when
changing the linked text, include the target name within angle brackets
following the text to link, with an underscore after the target name but
before the closing angle bracket (or the link will not work). For
example:

    For further examples, see the `documentation <pydocs_>`_.

An explicit target provides the URL. Put targets in the Footnotes
section at the end of the PEP, or immediately after the paragraph with
the reference. Hyperlink targets begin with two periods and a space (the
"explicit markup start"), followed by a leading underscore, the
reference text, a colon, and the URL.

    .. _Python web site: https://www.python.org/
    .. _pydocs: https://docs.python.org/

The reference text and the target text must match (although the match is
case-insensitive and ignores differences in whitespace). Note that the
underscore trails the reference text but precedes the target text. If
you think of the underscore as a right-pointing arrow, it points away
from the reference and toward the target.

Internal and PEP/RFC Links

The same mechanism as hyperlinks can be used for internal references.
Every unique section title implicitly defines an internal hyperlink
target. We can make a link to the Abstract section like this:

    Here is a hyperlink reference to the `Abstract`_ section.  The
    backquotes are optional since the reference text is a single word;
    we can also just write: Abstract_.

To refer to PEPs or RFCs, always use the :pep: and :rfc: roles, never
hardcoded URLs. For example:

    See PEP 1 for more information on how to write a PEP,
    and :pep:`the Hyperlink section of PEP 12 <12#hyperlinks>` for how to link.

This renders as:

  See PEP 1 for more information on how to write a PEP, and
  the Hyperlink section of PEP 12 <12#hyperlinks> for how to link.

PEP numbers in the text are never padded, and there is a space (not a
dash) between "PEP" or "RFC" and the number; the above roles will take
care of that for you.

Footnotes

Footnote references consist of a left square bracket, a label, a right
square bracket, and a trailing underscore. Instead of a number, use a
label of the form "#word", where "word" is a mnemonic consisting of
alphanumerics plus internal hyphens, underscores, and periods (no
whitespace or other characters are allowed). For example:

    Refer to The TeXbook [#TeXbook]_ for more information.

which renders as

  Refer to The TeXbook for more information.

Whitespace must precede the footnote reference. Leave a space between
the footnote reference and the preceding word.

Use footnotes for additional notes, explanations and caveats, as well as
for references to books and other sources not readily available online.
Native reST hyperlink targets or inline hyperlinks in the text should be
used in preference to footnotes for including URLs to online resources.

Footnotes begin with ".. " (the explicit markup start), followed by the
footnote marker (no underscores), followed by the footnote body. For
example:

    .. [#TeXbook] Donald Knuth's *The TeXbook*, pages 195 and 196.

which renders as

Footnotes and footnote references will be numbered automatically, and
the numbers will always match.

Images

If your PEP contains a diagram or other graphic, you may include it in
the processed output using the image directive:

    .. image:: diagram.png

Any browser-friendly graphics format is possible; PNG should be
preferred for graphics, JPEG for photos and GIF for animations.
Currently, SVG must be avoided due to compatibility issues with the PEP
build system.

For accessibility and readers of the source text, you should include a
description of the image and any key information contained within using
the :alt: option to the image directive:

    .. image:: dataflow.png
       :alt: Data flows from the input module, through the "black box"
             module, and finally into (and through) the output module.

Comments

A comment is an indented block of arbitrary text immediately following
an explicit markup start: two periods and whitespace. Leave the ".." on
a line by itself to ensure that the comment is not misinterpreted as
another explicit markup construct. Comments are not visible in the
processed document. For example:

    ..
       This section should be updated in the final PEP.
       Ensure the date is accurate.

Escaping Mechanism

reStructuredText uses backslashes ("\") to override the special meaning
given to markup characters and get the literal characters themselves. To
get a literal backslash, use an escaped backslash ("\\"). There are two
contexts in which backslashes have no special meaning: literal blocks
and inline literals (see Inline Markup above). In these contexts, no
markup recognition is done, and a single backslash represents a literal
backslash, without having to double up.

If you find that you need to use a backslash in your text, consider
using inline literals or a literal block instead.

Intersphinx

You can use Intersphinx references to other Sphinx sites, such as the
Python documentation packaging.python.org, and typing.readthedocs.io, to
easily cross-reference pages, sections and Python/C objects.

For example, to create a link pointing to a section of the typing docs,
you would write the following:

    :ref:`type expression <typing:type-expression>`

Canonical Documentation

As PEP 1 describes <1#pep-maintenance>, PEPs are considered historical
documents once marked Final, and their canonical
documentation/specification should be moved elsewhere. To indicate this,
use the canonical-doc directive or an appropriate subclass:

-   canonical-pypa-spec for packaging standards
-   canonical-typing-spec for typing standards

Add the directive between the headers and the first section of the PEP
(typically the Abstract) and pass as an argument an Intersphinx
reference of the canonical doc/spec (or if the target is not on a Sphinx
site, a reST hyperlink).

For example, to create a banner pointing to the python:sqlite3 docs, you
would write the following:

    .. canonical-doc:: :mod:`python:sqlite3`

which would generate the banner:

  python:sqlite3

Or for a PyPA spec, such as the packaging:core-metadata, you would use:

    .. canonical-pypa-spec:: :ref:`packaging:core-metadata`

which renders as:

  packaging:core-metadata

For a typing PEP that introduces no new runtime objects, you might use
something like the first one of these; for a typing PEP that introduces
a new object to the typing module at runtime, you might use the second:

    .. canonical-typing-spec:: :ref:`typing:packaging-typed-libraries`
    .. canonical-typing-spec:: :ref:`typing:literal-types` and
                               :py:data:`typing.Literal`

The two render as:

  typing:packaging-typed-libraries

  typing:literal-types and typing.Literal

The argument accepts arbitrary reST, so you can include multiple linked
docs/specs and name them whatever you like, and you can also include
directive content that will be inserted into the text. The following
advanced example:

    .. canonical-doc:: the :ref:`python:sqlite3-connection-objects` and :exc:`python:~sqlite3.DataError` docs

        Also, see the :ref:`Data Persistence docs <persistence>` for other examples.

would render as:

  the python:sqlite3-connection-objects and python:sqlite3.DataError
  docs

  Also, see the Data Persistence docs <persistence> for other examples.

Habits to Avoid

Many programmers who are familiar with TeX often write quotation marks
like this:

    `single-quoted' or ``double-quoted''

Backquotes are significant in reStructuredText, so this practice should
be avoided. For ordinary text, use ordinary 'single-quotes' or
"double-quotes". For inline literal text (see Inline Markup above), use
double-backquotes:

    ``literal text: in here, anything goes!``

Suggested Sections

Various sections are found to be common across PEPs and are outlined in
PEP 1. Those sections are provided here for convenience.

Resources

Many other constructs and variations are possible, both those supported
by basic Docutils and the extensions added by Sphinx.

A number of resources are available to learn more about them:

-   Sphinx ReStructuredText Primer, a gentle but fairly detailed
    introduction.
-   reStructuredText Markup Specification, the authoritative,
    comprehensive documentation of the basic reST syntax, directives,
    roles and more.
-   Sphinx Roles and Sphinx Directives, the extended constructs added by
    the Sphinx documentation system used to render the PEPs to HTML.

If you have questions or require assistance with writing a PEP that the
above resources don't address, ping @python/pep-editors on GitHub, open
an issue on the PEPs repository or reach out to a PEP editor directly.

Copyright

This document is placed in the public domain or under the
CC0-1.0-Universal license, whichever is more permissive.


text:
PEP: 420 Title: Implicit Namespace Packages Version: $Revision$
Last-Modified: $Date$ Author: Eric V. Smith<EMAIL_ADDRESS>Status:
Final Type: Standards Track Content-Type: text/x-rst Created:
19-Apr-2012 Python-Version: 3.3 Post-History: Resolution:
https://mail.python.org/pipermail/python-dev/2012-May/119651.html

Abstract

Namespace packages are a mechanism for splitting a single Python package
across multiple directories on disk. In current Python versions, an
algorithm to compute the packages __path__ must be formulated. With the
enhancement proposed here, the import machinery itself will construct
the list of directories that make up the package. This PEP builds upon
previous work, documented in PEP 382 and PEP 402. Those PEPs have since
been rejected in favor of this one. An implementation of this PEP is
at[1].

Terminology

Within this PEP:

-   "package" refers to Python packages as defined by Python's import
    statement.
-   "distribution" refers to separately installable sets of Python
    modules as stored in the Python package index, and installed by
    distutils or setuptools.
-   "vendor package" refers to groups of files installed by an operating
    system's packaging mechanism (e.g. Debian or Redhat packages install
    on Linux systems).
-   "regular package" refers to packages as they are implemented in
    Python 3.2 and earlier.
-   "portion" refers to a set of files in a single directory (possibly
    stored in a zip file) that contribute to a namespace package.
-   "legacy portion" refers to a portion that uses __path__ manipulation
    in order to implement namespace packages.

This PEP defines a new type of package, the "namespace package".

Namespace packages today

Python currently provides pkgutil.extend_path to denote a package as a
namespace package. The recommended way of using it is to put:

    from pkgutil import extend_path
    __path__ = extend_path(__path__, __name__)

in the package's __init__.py. Every distribution needs to provide the
same contents in its __init__.py, so that extend_path is invoked
independent of which portion of the package gets imported first. As a
consequence, the package's __init__.py cannot practically define any
names as it depends on the order of the package fragments on sys.path to
determine which portion is imported first. As a special feature,
extend_path reads files named <packagename>.pkg which allows declaration
of additional portions.

setuptools provides a similar function named
pkg_resources.declare_namespace that is used in the form:

    import pkg_resources
    pkg_resources.declare_namespace(__name__)

In the portion's __init__.py, no assignment to __path__ is necessary, as
declare_namespace modifies the package __path__ through sys.modules. As
a special feature, declare_namespace also supports zip files, and
registers the package name internally so that future additions to
sys.path by setuptools can properly add additional portions to each
package.

setuptools allows declaring namespace packages in a distribution's
setup.py, so that distribution developers don't need to put the magic
__path__ modification into __init__.py themselves.

See PEP 402's "The Problem" <402#the-problem> section for additional
motivations for namespace packages. Note that PEP 402 has been rejected,
but the motivating use cases are still valid.

Rationale

The current imperative approach to namespace packages has led to
multiple slightly-incompatible mechanisms for providing namespace
packages. For example, pkgutil supports *.pkg files; setuptools doesn't.
Likewise, setuptools supports inspecting zip files, and supports adding
portions to its _namespace_packages variable, whereas pkgutil doesn't.

Namespace packages are designed to support being split across multiple
directories (and hence found via multiple sys.path entries). In this
configuration, it doesn't matter if multiple portions all provide an
__init__.py file, so long as each portion correctly initializes the
namespace package. However, Linux distribution vendors (amongst others)
prefer to combine the separate portions and install them all into the
same file system directory. This creates a potential for conflict, as
the portions are now attempting to provide the same file on the target
system - something that is not allowed by many package managers.
Allowing implicit namespace packages means that the requirement to
provide an __init__.py file can be dropped completely, and affected
portions can be installed into a common directory or split across
multiple directories as distributions see fit.

A namespace package will not be constrained by a fixed __path__,
computed from the parent path at namespace package creation time.
Consider the standard library encodings package:

1.  Suppose that encodings becomes a namespace package.
2.  It sometimes gets imported during interpreter startup to initialize
    the standard io streams.
3.  An application modifies sys.path after startup and wants to
    contribute additional encodings from new path entries.
4.  An attempt is made to import an encoding from an encodings portion
    that is found on a path entry added in step 3.

If the import system was restricted to only finding portions along the
value of sys.path that existed at the time the encodings namespace
package was created, the additional paths added in step 3 would never be
searched for the additional portions imported in step 4. In addition, if
step 2 were sometimes skipped (due to some runtime flag or other
condition), then the path items added in step 3 would indeed be used the
first time a portion was imported. Thus this PEP requires that the list
of path entries be dynamically computed when each portion is loaded. It
is expected that the import machinery will do this efficiently by
caching __path__ values and only refreshing them when it detects that
the parent path has changed. In the case of a top-level package like
encodings, this parent path would be sys.path.

Specification

Regular packages will continue to have an __init__.py and will reside in
a single directory.

Namespace packages cannot contain an __init__.py. As a consequence,
pkgutil.extend_path and pkg_resources.declare_namespace become obsolete
for purposes of namespace package creation. There will be no marker file
or directory for specifying a namespace package.

During import processing, the import machinery will continue to iterate
over each directory in the parent path as it does in Python 3.2. While
looking for a module or package named "foo", for each directory in the
parent path:

-   If <directory>/foo/__init__.py is found, a regular package is
    imported and returned.
-   If not, but <directory>/foo.{py,pyc,so,pyd} is found, a module is
    imported and returned. The exact list of extension varies by
    platform and whether the -O flag is specified. The list here is
    representative.
-   If not, but <directory>/foo is found and is a directory, it is
    recorded and the scan continues with the next directory in the
    parent path.
-   Otherwise the scan continues with the next directory in the parent
    path.

If the scan completes without returning a module or package, and at
least one directory was recorded, then a namespace package is created.
The new namespace package:

-   Has a __path__ attribute set to an iterable of the path strings that
    were found and recorded during the scan.
-   Does not have a __file__ attribute.

Note that if "import foo" is executed and "foo" is found as a namespace
package (using the above rules), then "foo" is immediately created as a
package. The creation of the namespace package is not deferred until a
sub-level import occurs.

A namespace package is not fundamentally different from a regular
package. It is just a different way of creating packages. Once a
namespace package is created, there is no functional difference between
it and a regular package.

Dynamic path computation

The import machinery will behave as if a namespace package's __path__ is
recomputed before each portion is loaded.

For performance reasons, it is expected that this will be achieved by
detecting that the parent path has changed. If no change has taken
place, then no __path__ recomputation is required. The implementation
must ensure that changes to the contents of the parent path are
detected, as well as detecting the replacement of the parent path with a
new path entry list object.

Impact on import finders and loaders

PEP 302 defines "finders" that are called to search path elements. These
finders' find_module methods return either a "loader" object or None.

For a finder to contribute to namespace packages, it must implement a
new find_loader(fullname) method. fullname has the same meaning as for
find_module. find_loader always returns a 2-tuple of
(loader, <iterable-of-path-entries>). loader may be None, in which case
<iterable-of-path-entries> (which may be empty) is added to the list of
recorded path entries and path searching continues. If loader is not
None, it is immediately used to load a module or regular package.

Even if loader is returned and is not None, <iterable-of-path-entries>
must still contain the path entries for the package. This allows code
such as pkgutil.extend_path() to compute path entries for packages that
it does not load.

Note that multiple path entries per finder are allowed. This is to
support the case where a finder discovers multiple namespace portions
for a given fullname. Many finders will support only a single namespace
package portion per find_loader call, in which case this iterable will
contain only a single string.

The import machinery will call find_loader if it exists, else fall back
to find_module. Legacy finders which implement find_module but not
find_loader will be unable to contribute portions to a namespace
package.

The specification expands PEP 302 loaders to include an optional method
called module_repr() which if present, is used to generate module object
reprs. See the section below for further details.

Differences between namespace packages and regular packages

Namespace packages and regular packages are very similar. The
differences are:

-   Portions of namespace packages need not all come from the same
    directory structure, or even from the same loader. Regular packages
    are self-contained: all parts live in the same directory hierarchy.
-   Namespace packages have no __file__ attribute.
-   Namespace packages' __path__ attribute is a read-only iterable of
    strings, which is automatically updated when the parent path is
    modified.
-   Namespace packages have no __init__.py module.
-   Namespace packages have a different type of object for their
    __loader__ attribute.

Namespace packages in the standard library

It is possible, and this PEP explicitly allows, that parts of the
standard library be implemented as namespace packages. When and if any
standard library packages become namespace packages is outside the scope
of this PEP.

Migrating from legacy namespace packages

As described above, prior to this PEP pkgutil.extend_path() was used by
legacy portions to create namespace packages. Because it is likely not
practical for all existing portions of a namespace package to be
migrated to this PEP at once, extend_path() will be modified to also
recognize PEP 420 namespace packages. This will allow some portions of a
namespace to be legacy portions while others are migrated to PEP 420.
These hybrid namespace packages will not have the dynamic path
computation that normal namespace packages have, since extend_path()
never provided this functionality in the past.

Packaging Implications

Multiple portions of a namespace package can be installed into the same
directory, or into separate directories. For this section, suppose there
are two portions which define "foo.bar" and "foo.baz". "foo" itself is a
namespace package.

If these are installed in the same location, a single directory "foo"
would be in a directory that is on sys.path. Inside "foo" would be two
directories, "bar" and "baz". If "foo.bar" is removed (perhaps by an OS
package manager), care must be taken not to remove the "foo/baz" or
"foo" directories. Note that in this case "foo" will be a namespace
package (because it lacks an __init__.py), even though all of its
portions are in the same directory.

Note that "foo.bar" and "foo.baz" can be installed into the same "foo"
directory because they will not have any files in common.

If the portions are installed in different locations, two different
"foo" directories would be in directories that are on sys.path.
"foo/bar" would be in one of these sys.path entries, and "foo/baz" would
be in the other. Upon removal of "foo.bar", the "foo/bar" and
corresponding "foo" directories can be completely removed. But "foo/baz"
and its corresponding "foo" directory cannot be removed.

It is also possible to have the "foo.bar" portion installed in a
directory on sys.path, and have the "foo.baz" portion provided in a zip
file, also on sys.path.

Examples

Nested namespace packages

This example uses the following directory structure:

    Lib/test/namespace_pkgs
        project1
            parent
                child
                    one.py
        project2
            parent
                child
                    two.py

Here, both parent and child are namespace packages: Portions of them
exist in different directories, and they do not have __init__.py files.

Here we add the parent directories to sys.path, and show that the
portions are correctly found:

    >>> import sys
    >>> sys.path += ['Lib/test/namespace_pkgs/project1', 'Lib/test/namespace_pkgs/project2']
    >>> import parent.child.one
    >>> parent.__path__
    _NamespacePath(['Lib/test/namespace_pkgs/project1/parent', 'Lib/test/namespace_pkgs/project2/parent'])
    >>> parent.child.__path__
    _NamespacePath(['Lib/test/namespace_pkgs/project1/parent/child', 'Lib/test/namespace_pkgs/project2/parent/child'])
    >>> import parent.child.two
    >>>

Dynamic path computation

This example uses a similar directory structure, but adds a third
portion:

    Lib/test/namespace_pkgs
        project1
            parent
                child
                    one.py
        project2
            parent
                child
                    two.py
        project3
            parent
                child
                    three.py

We add project1 and project2 to sys.path, then import parent.child.one
and parent.child.two. Then we add the project3 to sys.path and when
parent.child.three is imported, project3/parent is automatically added
to parent.__path__:

    # add the first two parent paths to sys.path
    >>> import sys
    >>> sys.path += ['Lib/test/namespace_pkgs/project1', 'Lib/test/namespace_pkgs/project2']

    # parent.child.one can be imported, because project1 was added to sys.path:
    >>> import parent.child.one
    >>> parent.__path__
    _NamespacePath(['Lib/test/namespace_pkgs/project1/parent', 'Lib/test/namespace_pkgs/project2/parent'])

    # parent.child.__path__ contains project1/parent/child and project2/parent/child, but not project3/parent/child:
    >>> parent.child.__path__
    _NamespacePath(['Lib/test/namespace_pkgs/project1/parent/child', 'Lib/test/namespace_pkgs/project2/parent/child'])

    # parent.child.two can be imported, because project2 was added to sys.path:
    >>> import parent.child.two

    # we cannot import parent.child.three, because project3 is not in the path:
    >>> import parent.child.three
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<frozen importlib._bootstrap>", line 1286, in _find_and_load
      File "<frozen importlib._bootstrap>", line 1250, in _find_and_load_unlocked
    ImportError: No module named 'parent.child.three'

    # now add project3 to sys.path:
    >>> sys.path.append('Lib/test/namespace_pkgs/project3')

    # and now parent.child.three can be imported:
    >>> import parent.child.three

    # project3/parent has been added to parent.__path__:
    >>> parent.__path__
    _NamespacePath(['Lib/test/namespace_pkgs/project1/parent', 'Lib/test/namespace_pkgs/project2/parent', 'Lib/test/namespace_pkgs/project3/parent'])

    # and project3/parent/child has been added to parent.child.__path__
    >>> parent.child.__path__
    _NamespacePath(['Lib/test/namespace_pkgs/project1/parent/child', 'Lib/test/namespace_pkgs/project2/parent/child', 'Lib/test/namespace_pkgs/project3/parent/child'])
    >>>

Discussion

At PyCon 2012, we had a discussion about namespace packages at which PEP
382 and PEP 402 were rejected, to be replaced by this PEP[2].

There is no intention to remove support of regular packages. If a
developer knows that her package will never be a portion of a namespace
package, then there is a performance advantage to it being a regular
package (with an __init__.py). Creation and loading of a regular package
can take place immediately when it is located along the path. With
namespace packages, all entries in the path must be scanned before the
package is created.

Note that an ImportWarning will no longer be raised for a directory
lacking an __init__.py file. Such a directory will now be imported as a
namespace package, whereas in prior Python versions an ImportWarning
would be raised.

Alyssa (Nick) Coghlan presented a list of her objections to this
proposal[3]. They are:

1.  Implicit package directories go against the Zen of Python.
2.  Implicit package directories pose awkward backwards compatibility
    challenges.
3.  Implicit package directories introduce ambiguity into file system
    layouts.
4.  Implicit package directories will permanently entrench current
    newbie-hostile behavior in __main__.

Alyssa later gave a detailed response to her own objections[4], which is
summarized here:

1.  The practicality of this PEP wins over other proposals and the
    status quo.
2.  Minor backward compatibility issues are okay, as long as they are
    properly documented.
3.  This will be addressed in PEP 395.
4.  This will also be addressed in PEP 395.

The inclusion of namespace packages in the standard library was
motivated by Martin v. Löwis, who wanted the encodings package to become
a namespace package[5]. While this PEP allows for standard library
packages to become namespaces, it defers a decision on encodings.

find_module versus find_loader

An early draft of this PEP specified a change to the find_module method
in order to support namespace packages. It would be modified to return a
string in the case where a namespace package portion was discovered.

However, this caused a problem with existing code outside of the
standard library which calls find_module. Because this code would not be
upgraded in concert with changes required by this PEP, it would fail
when it would receive unexpected return values from find_module. Because
of this incompatibility, this PEP now specifies that finders that want
to provide namespace portions must implement the find_loader method,
described above.

The use case for supporting multiple portions per find_loader call is
given in[6].

Dynamic path computation

Guido raised a concern that automatic dynamic path computation was an
unnecessary feature[7]. Later in that thread, PJ Eby and Alyssa Coghlan
presented arguments as to why dynamic computation would minimize
surprise to Python users. The conclusion of that discussion has been
included in this PEP's Rationale section.

An earlier version of this PEP required that dynamic path computation
could only take affect if the parent path object were modified in-place.
That is, this would work:

    sys.path.append('new-dir')

But this would not:

    sys.path = sys.path + ['new-dir']

In the same thread[8], it was pointed out that this restriction is not
required. If the parent path is looked up by name instead of by holding
a reference to it, then there is no restriction on how the parent path
is modified or replaced. For a top-level namespace package, the lookup
would be the module named "sys" then its attribute "path". For a
namespace package nested inside a package foo, the lookup would be for
the module named "foo" then its attribute "__path__".

Module reprs

Previously, module reprs were hard coded based on assumptions about a
module's __file__ attribute. If this attribute existed and was a string,
it was assumed to be a file system path, and the module object's repr
would include this in its value. The only exception was that PEP 302
reserved missing __file__ attributes to built-in modules, and in
CPython, this assumption was baked into the module object's
implementation. Because of this restriction, some modules contained
contrived __file__ values that did not reflect file system paths, and
which could cause unexpected problems later (e.g. os.path.join() on a
non-path __file__ would return gibberish).

This PEP relaxes this constraint, and leaves the setting of __file__ to
the purview of the loader producing the module. Loaders may opt to leave
__file__ unset if no file system path is appropriate. Loaders may also
set additional reserved attributes on the module if useful. This means
that the definitive way to determine the origin of a module is to check
its __loader__ attribute.

For example, namespace packages as described in this PEP will have no
__file__ attribute because no corresponding file exists. In order to
provide flexibility and descriptiveness in the reprs of such modules, a
new optional protocol is added to PEP 302 loaders. Loaders can implement
a module_repr() method which takes a single argument, the module object.
This method should return the string to be used verbatim as the repr of
the module. The rules for producing a module repr are now standardized
as:

-   If the module has an __loader__ and that loader has a module_repr()
    method, call it with a single argument, which is the module object.
    The value returned is used as the module's repr.
-   If an exception occurs in module_repr(), the exception is caught and
    discarded, and the calculation of the module's repr continues as if
    module_repr() did not exist.
-   If the module has an __file__ attribute, this is used as part of the
    module's repr.
-   If the module has no __file__ but does have an __loader__, then the
    loader's repr is used as part of the module's repr.
-   Otherwise, just use the module's __name__ in the repr.

Here is a snippet showing how namespace module reprs are calculated from
its loader:

    class NamespaceLoader:
        @classmethod
        def module_repr(cls, module):
            return "<module '{}' (namespace)>".format(module.__name__)

Built-in module reprs would no longer need to be hard-coded, but instead
would come from their loader as well:

    class BuiltinImporter:
        @classmethod
        def module_repr(cls, module):
            return "<module '{}' (built-in)>".format(module.__name__)

Here are some example reprs of different types of modules with different
sets of the related attributes:

    >>> import email
    >>> email
    <module 'email' from '/home/barry/projects/python/pep-420/Lib/email/__init__.py'>
    >>> m = type(email)('foo')
    >>> m
    <module 'foo'>
    >>> m.__file__ = 'zippy:/de/do/dah'
    >>> m
    <module 'foo' from 'zippy:/de/do/dah'>
    >>> class Loader: pass
    ...
    >>> m.__loader__ = Loader
    >>> del m.__file__
    >>> m
    <module 'foo' (<class '__main__.Loader'>)>
    >>> class NewLoader:
    ...   @classmethod
    ...   def module_repr(cls, module):
    ...      return '<mystery module!>'
    ...
    >>> m.__loader__ = NewLoader
    >>> m
    <mystery module!>
    >>>

References

Copyright

This document has been placed in the public domain.

  Local Variables: mode: indented-text indent-tabs-mode: nil
  sentence-end-double-space: t fill-column: 70 coding: utf-8 End:

[1] PEP 420 branch (http://hg.python.org/features/pep-420)

[2] PyCon 2012 Namespace Package discussion outcome
(https://mail.python.org/pipermail/import-sig/2012-March/000421.html)

[3] Alyssa Coghlan's objection to the lack of marker files or
directories
(https://mail.python.org/pipermail/import-sig/2012-March/000423.html)

[4] Alyssa Coghlan's response to her initial objections
(https://mail.python.org/pipermail/import-sig/2012-April/000464.html)

[5] Martin v. Löwis's suggestion to make encodings a namespace package
(https://mail.python.org/pipermail/import-sig/2012-May/000540.html)

[6] Use case for multiple portions per find_loader call
(https://mail.python.org/pipermail/import-sig/2012-May/000585.html)

[7] Discussion about dynamic path computation
(https://mail.python.org/pipermail/python-dev/2012-May/119560.html)

[8] Discussion about dynamic path computation
(https://mail.python.org/pipermail/python-dev/2012-May/119560.html)


text:
PEP: 284 Title: Integer for-loops Author: David Eppstein
<EMAIL_ADDRESS>Gregory Ewing<EMAIL_ADDRESS>Status: Rejected Type: Standards Track Content-Type: text/x-rst Created:
01-Mar-2002 Python-Version: 2.3 Post-History:

Abstract

This PEP proposes to simplify iteration over intervals of integers, by
extending the range of expressions allowed after a "for" keyword to
allow three-way comparisons such as :

    for lower <= var < upper:

in place of the current :

    for item in list:

syntax. The resulting loop or list iteration will loop over all values
of var that make the comparison true, starting from the left endpoint of
the given interval.

Pronouncement

This PEP is rejected. There were a number of fixable issues with the
proposal (see the fixups listed in Raymond Hettinger's python-dev post
on 18 June 2005[1]). However, even with the fixups the proposal did not
garner support. Specifically, Guido did not buy the premise that the
range() format needed fixing, "The whole point (15 years ago) of range()
was to avoid needing syntax to specify a loop over numbers. I think it's
worked out well and there's nothing that needs to be fixed (except
range() needs to become an iterator, which it will in Python 3.0)."

Rationale

One of the most common uses of for-loops in Python is to iterate over an
interval of integers. Python provides functions range() and xrange() to
generate lists and iterators for such intervals, which work best for the
most frequent case: half-open intervals increasing from zero. However,
the range() syntax is more awkward for open or closed intervals, and
lacks symmetry when reversing the order of iteration. In addition, the
call to an unfamiliar function makes it difficult for newcomers to
Python to understand code that uses range() or xrange().

The perceived lack of a natural, intuitive integer iteration syntax has
led to heated debate on python-list, and spawned at least four PEPs
before this one. PEP 204 (rejected) proposed to re-use Python's slice
syntax for integer ranges, leading to a terser syntax but not solving
the readability problem of multi-argument range(). PEP 212 (deferred)
proposed several syntaxes for directly converting a list to a sequence
of integer indices, in place of the current idiom :

    range(len(list))

for such conversion, and PEP 281 proposes to simplify the same idiom by
allowing it to be written as :

    range(list).

PEP 276 proposes to allow automatic conversion of integers to iterators,
simplifying the most common half-open case but not addressing the
complexities of other types of interval. Additional alternatives have
been discussed on python-list.

The solution described here is to allow a three-way comparison after a
"for" keyword, both in the context of a for-loop and of a list
comprehension:

    for lower <= var < upper:

This would cause iteration over an interval of consecutive integers,
beginning at the left bound in the comparison and ending at the right
bound. The exact comparison operations used would determine whether the
interval is open or closed at either end and whether the integers are
considered in ascending or descending order.

This syntax closely matches standard mathematical notation, so is likely
to be more familiar to Python novices than the current range() syntax.
Open and closed interval endpoints are equally easy to express, and the
reversal of an integer interval can be formed simply by swapping the two
endpoints and reversing the comparisons. In addition, the semantics of
such a loop would closely resemble one way of interpreting the existing
Python for-loops:

    for item in list

iterates over exactly those values of item that cause the expression :

    item in list

to be true. Similarly, the new format :

    for lower <= var < upper:

would iterate over exactly those integer values of var that cause the
expression :

    lower <= var < upper

to be true.

Specification

We propose to extend the syntax of a for statement, currently :

    for_stmt: "for" target_list "in" expression_list ":" suite
          ["else" ":" suite]

as described below:

    for_stmt: "for" for_test ":" suite ["else" ":" suite]
    for_test: target_list "in" expression_list |
            or_expr less_comp or_expr less_comp or_expr |
            or_expr greater_comp or_expr greater_comp or_expr
    less_comp: "<" | "<="
    greater_comp: ">" | ">="

Similarly, we propose to extend the syntax of list comprehensions,
currently :

    list_for: "for" expression_list "in" testlist [list_iter]

by replacing it with:

    list_for: "for" for_test [list_iter]

In all cases the expression formed by for_test would be subject to the
same precedence rules as comparisons in expressions. The two
comp_operators in a for_test must be required to be both of similar
types, unlike chained comparisons in expressions which do not have such
a restriction.

We refer to the two or_expr's occurring on the left and right sides of
the for-loop syntax as the bounds of the loop, and the middle or_expr as
the variable of the loop. When a for-loop using the new syntax is
executed, the expressions for both bounds will be evaluated, and an
iterator object created that iterates through all integers between the
two bounds according to the comparison operations used. The iterator
will begin with an integer equal or near to the left bound, and then
step through the remaining integers with a step size of +1 or -1 if the
comparison operation is in the set described by less_comp or
greater_comp respectively. The execution will then proceed as if the
expression had been :

    for variable in iterator

where "variable" refers to the variable of the loop and "iterator"
refers to the iterator created for the given integer interval.

The values taken by the loop variable in an integer for-loop may be
either plain integers or long integers, according to the magnitude of
the bounds. Both bounds of an integer for-loop must evaluate to a real
numeric type (integer, long, or float). Any other value will cause the
for-loop statement to raise a TypeError exception.

Issues

The following issues were raised in discussion of this and related
proposals on the Python list.

-   Should the right bound be evaluated once, or every time through the
    loop? Clearly, it only makes sense to evaluate the left bound once.
    For reasons of consistency and efficiency, we have chosen the same
    convention for the right bound.

-   Although the new syntax considerably simplifies integer for-loops,
    list comprehensions using the new syntax are not as simple. We feel
    that this is appropriate since for-loops are more frequent than
    comprehensions.

-   The proposal does not allow access to integer iterator objects such
    as would be created by xrange. True, but we see this as a
    shortcoming in the general list-comprehension syntax, beyond the
    scope of this proposal. In addition, xrange() will still be
    available.

-   The proposal does not allow increments other than 1 and -1. More
    general arithmetic progressions would need to be created by range()
    or xrange(), or by a list comprehension syntax such as :

        [2*x for 0 <= x <= 100]

-   The position of the loop variable in the middle of a three-way
    comparison is not as apparent as the variable in the present :

        for item in list

    syntax, leading to a possible loss of readability. We feel that this
    loss is outweighed by the increase in readability from a natural
    integer iteration syntax.

-   To some extent, this PEP addresses the same issues as PEP 276. We
    feel that the two PEPs are not in conflict since PEP 276 is
    primarily concerned with half-open ranges starting in 0 (the easy
    case of range()) while this PEP is primarily concerned with
    simplifying all other cases. However, if this PEP is approved, its
    new simpler syntax for integer loops could to some extent reduce the
    motivation for PEP 276.

-   It is not clear whether it makes sense to allow floating point
    bounds for an integer loop: if a float represents an inexact value,
    how can it be used to determine an exact sequence of integers? On
    the other hand, disallowing float bounds would make it difficult to
    use floor() and ceiling() in integer for-loops, as it is difficult
    to use them now with range(). We have erred on the side of
    flexibility, but this may lead to some implementation difficulties
    in determining the smallest and largest integer values that would
    cause a given comparison to be true.

-   Should types other than int, long, and float be allowed as bounds?
    Another choice would be to convert all bounds to integers by int(),
    and allow as bounds anything that can be so converted instead of
    just floats. However, this would change the semantics: 0.3 <= x is
    not the same as int(0.3) <= x, and it would be confusing for a loop
    with 0.3 as lower bound to start at zero. Also, in general int(f)
    can be very far from f.

Implementation

An implementation is not available at this time. Implementation is not
expected to pose any great difficulties: the new syntax could, if
necessary, be recognized by parsing a general expression after each
"for" keyword and testing whether the top level operation of the
expression is "in" or a three-way comparison. The Python compiler would
convert any instance of the new syntax into a loop over the items in a
special iterator object.

References

Copyright

This document has been placed in the public domain.

[1] Raymond Hettinger, Propose updating PEP 284 -- Integer for-loops
https://mail.python.org/pipermail/python-dev/2005-June/054316.html


text:
PEP: 7 Title: Style Guide for C Code Author: Guido van Rossum
<EMAIL_ADDRESS>Barry Warsaw<EMAIL_ADDRESS>Status: Active Type:
Process Created: 05-Jul-2001 Post-History:

Introduction

This document gives coding conventions for the C code comprising the C
implementation of Python. Please see the companion informational PEP
describing style guidelines for Python code <8>.

Note, rules are there to be broken. Two good reasons to break a
particular rule:

1.  When applying the rule would make the code less readable, even for
    someone who is used to reading code that follows the rules.
2.  To be consistent with surrounding code that also breaks it (maybe
    for historic reasons) -- although this is also an opportunity to
    clean up someone else's mess (in true XP style).

C dialect

-   Python 3.11 and newer versions use C11 without optional features.
    The public C API should be compatible with C++.
-   Python 3.6 to 3.10 use C89 with several select C99 features:
    -   Standard integer types in <stdint.h> and <inttypes.h>. We
        require the fixed width integer types.
    -   static inline functions
    -   designated initializers (especially nice for type declarations)
    -   intermingled declarations
    -   booleans
    -   C++-style line comments
-   Python versions before 3.6 used ANSI/ISO standard C (the 1989
    version of the standard). This meant (amongst many other things)
    that all declarations must be at the top of a block (not necessarily
    at the top of function).
-   Don't use compiler-specific extensions, such as those of GCC or MSVC
    (e.g. don't write multi-line strings without trailing backslashes).
-   All function declarations and definitions must use full prototypes
    (i.e. specify the types of all arguments).
-   No compiler warnings with major compilers (gcc, VC++, a few others).
-   static inline functions should be preferred over macros in new code.

Code lay-out

-   Use 4-space indents and no tabs at all.

-   No line should be longer than 79 characters. If this and the
    previous rule together don't give you enough room to code, your code
    is too complicated -- consider using subroutines.

-   No line should end in whitespace. If you think you need significant
    trailing whitespace, think again -- somebody's editor might delete
    it as a matter of routine.

-   Function definition style: function name in column 1, outermost
    curly braces in column 1, blank line after local variable
    declarations.

        static int
        extra_ivars(PyTypeObject *type, PyTypeObject *base)
        {
            int t_size = PyType_BASICSIZE(type);
            int b_size = PyType_BASICSIZE(base);

            assert(t_size >= b_size); /* type smaller than base! */
            ...
            return 1;
        }

-   Code structure: one space between keywords like if, for and the
    following left paren; no spaces inside the paren; braces are
    required everywhere, even where C permits them to be omitted, but do
    not add them to code you are not otherwise modifying. All new C code
    requires braces. Braces should be formatted as shown:

        if (mro != NULL) {
            ...
        }
        else {
            ...
        }

-   The return statement should not get redundant parentheses:

        return(albatross); /* incorrect */

    Instead:

        return albatross; /* correct */

-   Function and macro call style: foo(a, b, c) -- no space before the
    open paren, no spaces inside the parens, no spaces before commas,
    one space after each comma.

-   Always put spaces around assignment, Boolean and comparison
    operators. In expressions using a lot of operators, add spaces
    around the outermost (lowest-priority) operators.

-   Breaking long lines: if you can, break after commas in the outermost
    argument list. Always indent continuation lines appropriately, e.g.:

        PyErr_Format(PyExc_TypeError,
                     "cannot create '%.100s' instances",
                     type->tp_name);

-   When you break a long expression at a binary operator, braces should
    be formatted as shown:

        if (type->tp_dictoffset != 0
            && base->tp_dictoffset == 0
            && type->tp_dictoffset == b_size
            && (size_t)t_size == b_size + sizeof(PyObject *))
        {
            return 0; /* "Forgive" adding a __dict__ only */
        }

    It's OK to put operators at ends of lines, especially to be
    consistent with surrounding code. (See
    PEP 8 <pep8-operator-linebreak> for a longer discussion.)

-   Vertically align line continuation characters in multi-line macros.

-   Macros intended to be used as a statement should use the
    do { ... } while (0) macro idiom, without a final semicolon.
    Example:

        #define ADD_INT_MACRO(MOD, INT)                                   \
            do {                                                          \
                if (PyModule_AddIntConstant((MOD), (#INT), (INT)) < 0) {  \
                    goto error;                                           \
                }                                                         \
            } while (0)

        // To be used like a statement with a semicolon:
        ADD_INT_MACRO(m, SOME_CONSTANT);

-   #undef file local macros after use.

-   Put blank lines around functions, structure definitions, and major
    sections inside functions.

-   Comments go before the code they describe.

-   All functions and global variables should be declared static unless
    they are to be part of a published interface.

-   For external functions and variables, we always have a declaration
    in an appropriate header file in the "Include" directory, which uses
    the PyAPI_FUNC() macro and PyAPI_DATA() macro, like this:

        PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);

        PyAPI_DATA(PyTypeObject) PySuper_Type;

Naming conventions

-   Use a Py prefix for public functions; never for static functions.
    The Py_ prefix is reserved for global service routines like
    Py_FatalError; specific groups of routines (e.g. specific object
    type APIs) use a longer prefix, e.g. PyString_ for string functions.
-   Public functions and variables use MixedCase with underscores, like
    this: PyObject_GetAttr, Py_BuildValue, PyExc_TypeError.
-   Occasionally an "internal" function has to be visible to the loader;
    we use the _Py prefix for this, e.g.: _PyObject_Dump.
-   Macros should have a MixedCase prefix and then use upper case, for
    example: PyString_AS_STRING, Py_PRINT_RAW.
-   Macro parameters should use ALL_CAPS style, so they are easily
    distinguishable from C variables and struct members.

Documentation Strings

-   Use the PyDoc_STR() or PyDoc_STRVAR() macro for docstrings to
    support building Python without docstrings
    (./configure --without-doc-strings).

-   The first line of each function docstring should be a "signature
    line" that gives a brief synopsis of the arguments and return value.
    For example:

        PyDoc_STRVAR(myfunction__doc__,
        "myfunction(name, value) -> bool\n\n\
        Determine whether name and value make a valid pair.");

    Always include a blank line between the signature line and the text
    of the description.

    If the return value for the function is always None (because there
    is no meaningful return value), do not include the indication of the
    return type.

-   When writing multi-line docstrings, be sure to always use backslash
    continuations, as in the example above, or string literal
    concatenation:

        PyDoc_STRVAR(myfunction__doc__,
        "myfunction(name, value) -> bool\n\n"
        "Determine whether name and value make a valid pair.");

    Though some C compilers accept string literals without either:

        /* BAD -- don't do this! */
        PyDoc_STRVAR(myfunction__doc__,
        "myfunction(name, value) -> bool\n\n
        Determine whether name and value make a valid pair.");

    not all do; the MSVC compiler is known to complain about this.

Copyright

This document has been placed in the public domain.

authors:
Barry Warsaw
Guido van Rossum