diff --git a/.bzrignore b/.bzrignore
new file mode 100644
index 00000000..e86ba36f
--- /dev/null
+++ b/.bzrignore
@@ -0,0 +1,40 @@
+.purify
+autom4te.cache
+config.log
+config.cache
+config.status
+config.status.lineno
+db_home
+Makefile
+buildno
+python
+build
+Makefile.pre
+platform
+pybuilddir.txt
+pyconfig.h
+libpython*.a
+libpython*.so*
+python.exe
+python-gdb.py
+reflog.txt
+tags
+TAGS
+.gdb_history
+Doc/tools/sphinx
+Doc/tools/jinja
+Doc/tools/jinja2
+Doc/tools/pygments
+Doc/tools/docutils
+Misc/python.pc
+Modules/Setup
+Modules/Setup.config
+Modules/Setup.local
+Modules/config.c
+Parser/pgen
+Lib/test/data/*
+Lib/lib2to3/Grammar*.pickle
+Lib/lib2to3/PatternGrammar*.pickle
+.coverage
+coverage/*
+htmlcov/*
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..d38d0cf7
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,42 @@
+# Binary data types
+*.aif binary
+*.aifc binary
+*.aiff binary
+*.au binary
+*.bmp binary
+*.db binary
+*.exe binary
+*.icns binary
+*.gif binary
+*.ico binary
+*.jpg binary
+*.pck binary
+*.png binary
+*.tar binary
+*.wav binary
+*.whl binary
+*.zip binary
+
+# Specific binary files
+Lib/test/sndhdrdata/sndhdr.* binary
+
+# Text files that should not be subject to eol conversion
+Lib/test/cjkencodings/* -text
+Lib/test/decimaltestdata/*.decTest -text
+Lib/email/test/data/*.txt -text
+Lib/test/xmltestdata/* -text
+
+# Special files in third party code
+Modules/zlib/zlib.map -text
+
+# CRLF files
+*.bat text eol=crlf
+*.ps1 text eol=crlf
+*.sln text eol=crlf
+*.vcxproj* text eol=crlf
+*.vcproj text eol=crlf
+*.vsprops text eol=crlf
+*.props text eol=crlf
+*.proj text eol=crlf
+PCbuild/readme.txt text eol=crlf
+PC/readme.txt text eol=crlf
diff --git a/.github/appveyor.yml b/.github/appveyor.yml
new file mode 100644
index 00000000..3830666e
--- /dev/null
+++ b/.github/appveyor.yml
@@ -0,0 +1,36 @@
+version: 2.7build{build}
+clone_depth: 5
+branches:
+ only:
+ - master
+ - /\d\.\d/
+ - buildbot-custom
+cache:
+ - externals -> PCbuild\*
+before_build:
+ - ps: |+
+ if ($env:APPVEYOR_RE_BUILD) {
+ echo 'Doing full build due to re-build request.'
+ } elseif (!$env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT) {
+ echo 'Not a PR, doing full build.'
+ } else {
+ git fetch -q origin +refs/heads/$env:APPVEYOR_REPO_BRANCH
+ $mergebase = git merge-base HEAD FETCH_HEAD
+ $changes = git diff --name-only HEAD $mergebase | grep -vE '(\.rst$)|(^Doc)|(^Misc)'
+ If (!$changes) {
+ echo 'Only docs were updated, stopping build process.'
+ Exit-AppveyorBuild
+ } else {
+ echo 'Doing full build due to non-doc changes in these files:'
+ echo $changes
+ }
+ }
+
+
+build_script:
+ - cmd: PCbuild\build.bat -e
+ - cmd: PCbuild\python.exe -m test.pythoninfo
+test_script:
+ - cmd: PCbuild\rt.bat -q -uall -u-cpu -u-largefile -rwW --slowest -j2
+environment:
+ HOST_PYTHON: C:\Python36\python.exe
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..8f3a2d13
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,89 @@
+# Two-trick pony for OSX and other case insensitive file systems:
+# Ignore ./python binary on Unix but still look into ./Python/ directory.
+/python
+!/Python/
+*.cover
+*.o
+*.orig
+*.pyc
+*.pyd
+*.pyo
+*.rej
+*.swp
+*~
+*.gc??
+*.profclang?
+*.profraw
+*.dyn
+Doc/build/
+Doc/venv/
+Doc/.venv/
+Doc/env/
+Doc/.env/
+Lib/lib2to3/*.pickle
+Lib/test/data/*
+Makefile
+Makefile.pre
+Misc/python.pc
+Modules/Setup
+Modules/Setup.config
+Modules/Setup.local
+Modules/config.c
+Modules/ld_so_aix
+PC/python_nt*.h
+PC/pythonnt_rc*.h
+PC/*/*.exe
+PC/*/*.exp
+PC/*/*.lib
+PC/*/*.bsc
+PC/*/*.dll
+PC/*/*.pdb
+PC/*/*.user
+PC/*/*.ncb
+PC/*/*.suo
+PC/*/Win32-temp-*
+PC/*/x64-temp-*
+PC/*/amd64
+PCbuild/*.ilk
+PCbuild/*.user
+PCbuild/*.suo
+PCbuild/*.*sdf
+PCbuild/*.bsc
+PCbuild/*.dll
+PCbuild/*.exe
+PCbuild/*.exp
+PCbuild/*.lib
+PCbuild/*.ncb
+PCbuild/*.o
+PCbuild/*.pdb
+PCbuild/Win32-temp-*
+PCbuild/*.VC.db
+PCbuild/*.VC.opendb
+PCbuild/amd64/
+PCbuild/obj/
+PCbuild/win32/
+Parser/pgen
+Parser/pgen.stamp
+autom4te.cache
+build/
+config.cache
+config.log
+config.status
+libpython*.a
+libpython*.so*
+libpython*.dylib
+libpython*.dll
+platform
+pybuilddir.txt
+pyconfig.h
+python$
+python.bat
+python.exe
+python*-gdb.py
+tags
+TAGS
+.coverage
+coverage/
+externals/
+htmlcov/
+gmon.out
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..4150f0b1
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,110 @@
+language: c
+dist: xenial
+
+# To cache doc-building dependencies and C compiler output.
+cache:
+ - pip
+ - ccache
+
+env:
+ global:
+ # Use -O3 because we don't use debugger on Travis-CI
+ - CFLAGS="-O3"
+
+branches:
+ only:
+ - master
+ - /^\d\.\d$/
+ - buildbot-custom
+
+matrix:
+ fast_finish: true
+ allow_failures:
+ - env: OPTIONAL=true
+ include:
+ - os: linux
+ language: c
+ compiler: clang
+ # gcc also works, but to keep the # of concurrent builds down, we use one C
+ # compiler here and the other to run the coverage build. Clang is preferred
+ # in this instance for its better error messages.
+ env: TESTING=cpython
+ addons:
+ apt:
+ packages:
+ - xvfb
+ - os: linux
+ language: python
+ # Build the docs against a stable version of Python so code bugs don't hold up doc-related PRs.
+ python: 3.6
+ env: TESTING=docs
+ before_script:
+ - cd Doc
+ # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures.
+ # (Updating the version is fine as long as no warnings are raised by doing so.)
+ - python3 -m pip install sphinx~=2.0.1
+ script:
+ - make check suspicious html SPHINXOPTS="-q -W -j4"
+
+
+before_install:
+ - set -e
+ - |
+ # Check short-circuit conditions
+ if [ "${TESTING}" != "docs" ]
+ then
+ if [ "$TRAVIS_PULL_REQUEST" = "false" ]
+ then
+ echo "Not a PR, doing full build."
+ else
+ # Pull requests are slightly complicated because $TRAVIS_COMMIT_RANGE
+ # may include more changes than desired if the history is convoluted.
+ # Instead, explicitly fetch the base branch and compare against the
+ # merge-base commit.
+ git fetch -q origin +refs/heads/$TRAVIS_BRANCH
+ changes=$(git diff --name-only HEAD $(git merge-base HEAD FETCH_HEAD))
+ echo "Files changed:"
+ echo "$changes"
+ if ! echo "$changes" | grep -qvE '(\.rst$)|(^Doc)|(^Misc)'
+ then
+ echo "Only docs were updated, stopping build process."
+ exit
+ fi
+ fi
+ fi
+
+
+# Travis provides only 2 cores, so don't overdo the parallelism and waste memory.
+before_script:
+ - ./configure --with-pydebug
+ - make -j4 regen-all
+ - changes=`git status --porcelain`
+ - |
+ # Check for changes in regenerated files
+ if ! test -z "$changes"
+ then
+ echo "Generated files not up to date"
+ echo "$changes"
+ exit 1
+ fi
+ - make -j4
+ - make pythoninfo
+
+script:
+ # Check that all symbols exported by libpython start with "Py" or "_Py"
+ - make smelly
+ # `-r -w` implicitly provided through `make buildbottest`.
+ - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then XVFB_RUN=xvfb-run; fi; $XVFB_RUN make buildbottest TESTOPTS="-j4 -uall,-cpu"
+
+notifications:
+ email: false
+ irc:
+ channels:
+ # This is set to a secure variable to prevent forks from notifying the
+ # IRC channel whenever they fail a build. This can be removed when travis
+ # implements https://github.com/travis-ci/travis-ci/issues/1094.
+ # The actual value here is: irc.freenode.net#python-dev
+ - secure: "s7kAkpcom2yUJ8XqyjFI0obJmhAGrn1xmoivdaPdgBIA++X47TBp1x4pgDsbEsoalef7bEwa4l07KdT4qa+DOd/c4QxaWom7fbN3BuLVsZuVfODnl79+gYq/TAbGfyH+yDs18DXrUfPgwD7C5aW32ugsqAOd4iWzfGJQ5OrOZzqzGjYdYQUEkJFXgxDEIb4aHvxNDWGO3Po9uKISrhb5saQ0l776yLo1Ur7M4oxl8RTbCdgX0vf5TzPg52BgvZpOgt3DHOUYPeiJLKNjAE6ibg0U95sEvMfHX77nz4aFY4/3UI6FFaRla34rZ+mYKrn0TdxOhera1QOgPmM6HzdO4K44FpfK1DS0Xxk9U9/uApq+cG0bU3W+cVUHDBe5+90lpRBAXHeHCgT7TI8gec614aiT8lEr3+yH8OBRYGzkjNK8E2LJZ/SxnVxDe7aLF6AWcoWLfS6/ziAIBFQ5Nc4U72CT8fGVSkl8ywPiRlvixKdvTODMSZo0jMqlfZSNaAPTsNRx4wu5Uis4qekwe32Fz4aB6KGpsuuVjBi+H6v0RKxNJNGY3JKDiEH2TK0UE2auJ5GvLW48aUVFcQMB7euCWYXlSWVRHh3WLU8QXF29Dw4JduRZqUpOdRgMHU79UHRq+mkE0jAS/nBcS6CvsmxCpTSrfVYuMOu32yt18QQoTyU="
+ on_success: change
+ on_failure: always
+ skip_join: true
diff --git a/Demo/metaclasses/index.html b/Demo/metaclasses/index.html
index eee473a8..1675c630 100644
--- a/Demo/metaclasses/index.html
+++ b/Demo/metaclasses/index.html
@@ -222,7 +222,7 @@
Writing Metaclasses in Python
means calling the metainstance, and this will return a real instance.
And what class is that an instance of? Conceptually, it is of course
an instance of our metainstance; but in most cases the Python runtime
-system will see it as an instance of a a helper class used by the
+system will see it as an instance of a helper class used by the
metaclass to implement its (non-meta) instances...
Hopefully an example will make things clearer. Let's presume we
diff --git a/Demo/scripts/newslist.doc b/Demo/scripts/newslist.doc
deleted file mode 100644
index 87fd9ba2..00000000
--- a/Demo/scripts/newslist.doc
+++ /dev/null
@@ -1,59 +0,0 @@
- NEWSLIST
- ========
- A program to assist HTTP browsing of newsgroups
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-WWW browsers such as NCSA Mosaic allow the user to read newsgroup
-articles by specifying the group name in a URL eg 'news:comp.answers'.
-
-To browse through many groups, though, (and there are several thousand
-of them) you really need a page or pages containing links to all the
-groups. There are some good ones out there, for example,
-
- http://info.cern.ch/hypertext/DataSources/News/Groups/Overview.html
-
-is the standard one at CERN, but it only shows the groups available there,
-which may be rather different from those available on your machine.
-
-Newslist is a program which creates a hierarchy of pages for you based
-on the groups available from YOUR server. It is written in python - a
-splendid interpreted object-oriented language which I suggest you get
-right now from the directory /pub/python at ftp.cwi.nl, if you haven't
-already got it.
-
-You should be able to see some sample output by looking at:
- http://pelican.cl.cam.ac.uk/newspage/root.html
-
-Descriptions of newsgroups can be added from a file with one group
-per line. eg:
-
- alt.foo Articles about foo
- comp.bar Programming in 'bar' and related languages
-
-A suitable list detailing most groups can be found at ftp.uu.net in
-/uunet-info/newsgroups.gz.
-
-Make sure you read the information at the beginning of the program source and
-configure the variables before running.
-
-In addition to python, you need:
-
- An NNTP-based news feed.
- A directory in which to put the pages.
-
-The programming is not very beautiful, but it works! It comes with no
-warranty, express or implied, but with the hope that some others may
-find it useful.
-
-Comments, improvements & suggestions welcomed.
-Quentin Stafford-Fraser
-
- ----------------------------------------------------------------------
- Quentin Stafford-Fraser
- http://pelican.cl.cam.ac.uk/people/qs101/me.html
-
- Cambridge University Computer Lab Rank Xerox Cambridge EuroPARC
- qs101@cl.cam.ac.uk fraser@europarc.xerox.com
- Tel: +44 223 334411 Tel: +44 223 341521
- Fax: +44 223 334679 Fax: +44 223 341510
- ----------------------------------------------------------------------
diff --git a/Demo/scripts/newslist.py b/Demo/scripts/newslist.py
deleted file mode 100644
index a91e901c..00000000
--- a/Demo/scripts/newslist.py
+++ /dev/null
@@ -1,362 +0,0 @@
-#! /usr/bin/env python
-#######################################################################
-# Newslist $Revision$
-#
-# Syntax:
-# newslist [ -a ]
-#
-# This is a program to create a directory full of HTML pages
-# which between them contain links to all the newsgroups available
-# on your server.
-#
-# The -a option causes a complete list of all groups to be read from
-# the server rather than just the ones which have appeared since last
-# execution. This recreates the local list from scratch. Use this on
-# the first invocation of the program, and from time to time thereafter.
-# When new groups are first created they may appear on your server as
-# empty groups. By default, empty groups are ignored by the -a option.
-# However, these new groups will not be created again, and so will not
-# appear in the server's list of 'new groups' at a later date. Hence it
-# won't appear until you do a '-a' after some articles have appeared.
-#
-# I should really keep a list of ignored empty groups and re-check them
-# for articles on every run, but I haven't got around to it yet.
-#
-# This assumes an NNTP news feed.
-#
-# Feel free to copy, distribute and modify this code for
-# non-commercial use. If you make any useful modifications, let me
-# know!
-#
-# (c) Quentin Stafford-Fraser 1994
-# fraser@europarc.xerox.com qs101@cl.cam.ac.uk
-# #
-#######################################################################
-import sys, nntplib, marshal, time, os
-
-#######################################################################
-# Check these variables before running! #
-
-# Top directory.
-# Filenames which don't start with / are taken as being relative to this.
-topdir = os.path.expanduser('~/newspage')
-
-# The name of your NNTP host
-# eg.
-# newshost = 'nntp-serv.cl.cam.ac.uk'
-# or use following to get the name from the NNTPSERVER environment
-# variable:
-# newshost = os.environ['NNTPSERVER']
-newshost = 'news.example.com'
-
-# The filename for a local cache of the newsgroup list
-treefile = 'grouptree'
-
-# The filename for descriptions of newsgroups
-# I found a suitable one at ftp.uu.net in /uunet-info/newgroups.gz
-# You can set this to '' if you don't wish to use one.
-descfile = 'newsgroups'
-
-# The directory in which HTML pages should be created
-# eg.
-# pagedir = '/usr/local/lib/html/newspage'
-# pagedir = 'pages'
-pagedir = topdir
-
-# The html prefix which will refer to this directory
-# eg.
-# httppref = '/newspage/',
-# or leave blank for relative links between pages: (Recommended)
-# httppref = ''
-httppref = ''
-
-# The name of the 'root' news page in this directory.
-# A .html suffix will be added.
-rootpage = 'root'
-
-# Set skipempty to 0 if you wish to see links to empty groups as well.
-# Only affects the -a option.
-skipempty = 1
-
-# pagelinkicon can contain html to put an icon after links to
-# further pages. This helps to make important links stand out.
-# Set to '' if not wanted, or '...' is quite a good one.
-pagelinkicon = '...
'
-
-# ---------------------------------------------------------------------
-# Less important personal preferences:
-
-# Sublistsize controls the maximum number of items the will appear as
-# an indented sub-list before the whole thing is moved onto a different
-# page. The smaller this is, the more pages you will have, but the
-# shorter each will be.
-sublistsize = 4
-
-# That should be all. #
-#######################################################################
-
-for dir in os.curdir, os.environ['HOME']:
- rcfile = os.path.join(dir, '.newslistrc.py')
- if os.path.exists(rcfile):
- print rcfile
- execfile(rcfile)
- break
-
-from nntplib import NNTP
-from stat import *
-
-rcsrev = '$Revision$'
-rcsrev = ' '.join(filter(lambda s: '$' not in s, rcsrev.split()))
-desc = {}
-
-# Make (possibly) relative filenames into absolute ones
-treefile = os.path.join(topdir,treefile)
-descfile = os.path.join(topdir,descfile)
-page = os.path.join(topdir,pagedir)
-
-# First the bits for creating trees ---------------------------
-
-# Addtotree creates/augments a tree from a list of group names
-def addtotree(tree, groups):
- print 'Updating tree...'
- for i in groups:
- parts = i.split('.')
- makeleaf(tree, parts)
-
-# Makeleaf makes a leaf and the branch leading to it if necessary
-def makeleaf(tree,path):
- j = path[0]
- l = len(path)
-
- if j not in tree:
- tree[j] = {}
- if l == 1:
- tree[j]['.'] = '.'
- if l > 1:
- makeleaf(tree[j],path[1:])
-
-# Then the bits for outputting trees as pages ----------------
-
-# Createpage creates an HTML file named .html containing links
-# to those groups beginning with .
-
-def createpage(root, tree, p):
- filename = os.path.join(pagedir, root+'.html')
- if root == rootpage:
- detail = ''
- else:
- detail = ' under ' + root
- with open(filename, 'w') as f:
- # f.write('Content-Type: text/html\n')
- f.write('\n\n')
- f.write('Newsgroups available%s\n' % detail)
- f.write('\n\n')
- f.write('Newsgroups available%s
\n' % detail)
- f.write('Back to top level\n' %
- (httppref, rootpage))
- printtree(f, tree, 0, p)
- f.write('\n
')
- f.write("This page automatically created by 'newslist' v. %s." %
- rcsrev)
- f.write(time.ctime(time.time()) + '\n')
- f.write('\n\n')
-
-# Printtree prints the groups as a bulleted list. Groups with
-# more than subgroups will be put on a separate page.
-# Other sets of subgroups are just indented.
-
-def printtree(f, tree, indent, p):
- l = len(tree)
-
- if l > sublistsize and indent > 0:
- # Create a new page and a link to it
- f.write('' % (httppref, p[1:]))
- f.write(p[1:] + '.*')
- f.write('%s\n' % pagelinkicon)
- createpage(p[1:], tree, p)
- return
-
- kl = tree.keys()
-
- if l > 1:
- kl.sort()
- if indent > 0:
- # Create a sub-list
- f.write('%s\n' % p[1:])
- else:
- # Create a main list
- f.write('')
- indent = indent + 1
-
- for i in kl:
- if i == '.':
- # Output a newsgroup
- f.write('- %s ' % (p[1:], p[1:]))
- if p[1:] in desc:
- f.write(' %s\n' % desc[p[1:]])
- else:
- f.write('\n')
- else:
- # Output a hierarchy
- printtree(f, tree[i], indent, p+'.'+i)
-
- if l > 1:
- f.write('\n
')
-
-# Reading descriptions file ---------------------------------------
-
-# This returns a dict mapping group name to its description
-
-def readdesc(descfile):
- global desc
- desc = {}
-
- if descfile == '':
- return
-
- try:
- with open(descfile, 'r') as d:
- print 'Reading descriptions...'
- for l in d:
- bits = l.split()
- try:
- grp = bits[0]
- dsc = ' '.join(bits[1:])
- if len(dsc) > 1:
- desc[grp] = dsc
- except IndexError:
- pass
- except IOError:
- print 'Failed to open description file ' + descfile
- return
-
-# Check that ouput directory exists, ------------------------------
-# and offer to create it if not
-
-def checkopdir(pagedir):
- if not os.path.isdir(pagedir):
- print 'Directory %s does not exist.' % pagedir
- print 'Shall I create it for you? (y/n)'
- if sys.stdin.readline()[0] == 'y':
- try:
- os.mkdir(pagedir, 0777)
- except:
- print 'Sorry - failed!'
- sys.exit(1)
- else:
- print 'OK. Exiting.'
- sys.exit(1)
-
-# Read and write current local tree ----------------------------------
-
-def readlocallist(treefile):
- print 'Reading current local group list...'
- tree = {}
- try:
- treetime = time.localtime(os.stat(treefile)[ST_MTIME])
- except:
- print '\n*** Failed to open local group cache '+treefile
- print 'If this is the first time you have run newslist, then'
- print 'use the -a option to create it.'
- sys.exit(1)
- treedate = '%02d%02d%02d' % (treetime[0] % 100, treetime[1], treetime[2])
- try:
- with open(treefile, 'rb') as dump:
- tree = marshal.load(dump)
- except IOError:
- print 'Cannot open local group list ' + treefile
- return (tree, treedate)
-
-def writelocallist(treefile, tree):
- try:
- with open(treefile, 'wb') as dump:
- groups = marshal.dump(tree, dump)
- print 'Saved list to %s\n' % treefile
- except:
- print 'Sorry - failed to write to local group cache', treefile
- print 'Does it (or its directory) have the correct permissions?'
- sys.exit(1)
-
-# Return list of all groups on server -----------------------------
-
-def getallgroups(server):
- print 'Getting list of all groups...'
- treedate = '010101'
- info = server.list()[1]
- groups = []
- print 'Processing...'
- if skipempty:
- print '\nIgnoring following empty groups:'
- for i in info:
- grpname = i[0].split()[0]
- if skipempty and int(i[1]) < int(i[2]):
- print grpname + ' ',
- else:
- groups.append(grpname)
- print '\n'
- if skipempty:
- print '(End of empty groups)'
- return groups
-
-# Return list of new groups on server -----------------------------
-
-def getnewgroups(server, treedate):
- print 'Getting list of new groups since start of %s...' % treedate,
- info = server.newgroups(treedate, '000001')[1]
- print 'got %d.' % len(info)
- print 'Processing...',
- groups = []
- for i in info:
- grpname = i.split()[0]
- groups.append(grpname)
- print 'Done'
- return groups
-
-# Now the main program --------------------------------------------
-
-def main():
- tree = {}
-
- # Check that the output directory exists
- checkopdir(pagedir)
-
- try:
- print 'Connecting to %s...' % newshost
- if sys.version[0] == '0':
- s = NNTP.init(newshost)
- else:
- s = NNTP(newshost)
- connected = True
- except (nntplib.error_temp, nntplib.error_perm), x:
- print 'Error connecting to host:', x
- print 'I\'ll try to use just the local list.'
- connected = False
-
- # If -a is specified, read the full list of groups from server
- if connected and len(sys.argv) > 1 and sys.argv[1] == '-a':
- groups = getallgroups(s)
-
- # Otherwise just read the local file and then add
- # groups created since local file last modified.
- else:
-
- (tree, treedate) = readlocallist(treefile)
- if connected:
- groups = getnewgroups(s, treedate)
-
- if connected:
- addtotree(tree, groups)
- writelocallist(treefile,tree)
-
- # Read group descriptions
- readdesc(descfile)
-
- print 'Creating pages...'
- createpage(rootpage, tree, '')
- print 'Done'
-
-if __name__ == "__main__":
- main()
-
-# That's all folks
-######################################################################
diff --git a/Demo/tix/INSTALL.txt b/Demo/tix/INSTALL.txt
index ac70b68c..c598e40a 100644
--- a/Demo/tix/INSTALL.txt
+++ b/Demo/tix/INSTALL.txt
@@ -4,7 +4,7 @@ Installing Tix.py
----------------
0) To use Tix.py, you need Tcl/Tk (V8.3.3), Tix (V8.1.1) and Python (V2.1.1).
- Tix.py has been written and tested on a Intel Pentium running RH Linux 5.2
+ Tix.py has been written and tested on an Intel Pentium running RH Linux 5.2
and Mandrake Linux 7.0 and Windows with the above mentioned packages.
Older versions, e.g. Tix 4.1 and Tk 8.0, might also work.
diff --git a/Demo/tix/samples/Balloon.py b/Demo/tix/samples/Balloon.py
index 22959057..0cd57c0c 100644
--- a/Demo/tix/samples/Balloon.py
+++ b/Demo/tix/samples/Balloon.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
@@ -11,7 +11,7 @@
# program.
# This file demonstrates the use of the tixBalloon widget, which provides
-# a interesting way to give help tips about elements in your user interface.
+# an interesting way to give help tips about elements in your user interface.
# Your can display the help message in a "balloon" and a status bar widget.
#
diff --git a/Demo/tix/samples/BtnBox.py b/Demo/tix/samples/BtnBox.py
index af2a2a87..d5e2e29d 100644
--- a/Demo/tix/samples/BtnBox.py
+++ b/Demo/tix/samples/BtnBox.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/CmpImg.py b/Demo/tix/samples/CmpImg.py
index 4720a10c..2fc513bb 100644
--- a/Demo/tix/samples/CmpImg.py
+++ b/Demo/tix/samples/CmpImg.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
@@ -155,7 +155,7 @@ def RunSample(w):
net = Tix.Button(w, padx=4, pady=1, width=120)
# Create the first image: we create a line, then put a string,
- # a space and a image into this line, from left to right.
+ # a space and an image into this line, from left to right.
# The result: we have a one-line image that consists of three
# individual items
#
diff --git a/Demo/tix/samples/ComboBox.py b/Demo/tix/samples/ComboBox.py
index 91409871..8abcf698 100644
--- a/Demo/tix/samples/ComboBox.py
+++ b/Demo/tix/samples/ComboBox.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/Control.py b/Demo/tix/samples/Control.py
index 3a344c1e..b486592b 100644
--- a/Demo/tix/samples/Control.py
+++ b/Demo/tix/samples/Control.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/DirList.py b/Demo/tix/samples/DirList.py
index 5fd8c0de..054d1f87 100644
--- a/Demo/tix/samples/DirList.py
+++ b/Demo/tix/samples/DirList.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/DirTree.py b/Demo/tix/samples/DirTree.py
index 2e4fe0b9..dfeadfbe 100644
--- a/Demo/tix/samples/DirTree.py
+++ b/Demo/tix/samples/DirTree.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/NoteBook.py b/Demo/tix/samples/NoteBook.py
index 1e0da3e7..96c0b0ff 100644
--- a/Demo/tix/samples/NoteBook.py
+++ b/Demo/tix/samples/NoteBook.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/OptMenu.py b/Demo/tix/samples/OptMenu.py
index 1d39420c..8e51a9d1 100644
--- a/Demo/tix/samples/OptMenu.py
+++ b/Demo/tix/samples/OptMenu.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/PanedWin.py b/Demo/tix/samples/PanedWin.py
index 3efc7317..13aeb5a9 100644
--- a/Demo/tix/samples/PanedWin.py
+++ b/Demo/tix/samples/PanedWin.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/PopMenu.py b/Demo/tix/samples/PopMenu.py
index 32f32292..7028f69b 100644
--- a/Demo/tix/samples/PopMenu.py
+++ b/Demo/tix/samples/PopMenu.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/SHList1.py b/Demo/tix/samples/SHList1.py
index 7ca7b3e7..51d005ad 100644
--- a/Demo/tix/samples/SHList1.py
+++ b/Demo/tix/samples/SHList1.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tix/samples/SHList2.py b/Demo/tix/samples/SHList2.py
index 17fd5519..5dd51ff5 100644
--- a/Demo/tix/samples/SHList2.py
+++ b/Demo/tix/samples/SHList2.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidget": it must have a
diff --git a/Demo/tix/samples/Tree.py b/Demo/tix/samples/Tree.py
index 9a7e4810..af5e421e 100644
--- a/Demo/tix/samples/Tree.py
+++ b/Demo/tix/samples/Tree.py
@@ -2,7 +2,7 @@
#
# $Id$
#
-# Tix Demostration Program
+# Tix Demonstration Program
#
# This sample program is structured in such a way so that it can be
# executed from the Tix demo program "tixwidgets.py": it must have a
diff --git a/Demo/tkinter/guido/canvasevents.py b/Demo/tkinter/guido/canvasevents.py
index 74ed76f6..1982a508 100644
--- a/Demo/tkinter/guido/canvasevents.py
+++ b/Demo/tkinter/guido/canvasevents.py
@@ -24,7 +24,7 @@ class Object:
depends on the object; for simple objects, it may be their center.
Objects have mouse sensitivity. They can be clicked, dragged and
- double-clicked. The behavior may actually determined by the pile
+ double-clicked. The behavior may actually be determined by the pile
they are in.
All instance attributes are public since the derived class may
diff --git a/Demo/tkinter/matt/canvas-with-scrollbars.py b/Demo/tkinter/matt/canvas-with-scrollbars.py
index 81ef25a8..8f81cadc 100644
--- a/Demo/tkinter/matt/canvas-with-scrollbars.py
+++ b/Demo/tkinter/matt/canvas-with-scrollbars.py
@@ -1,7 +1,7 @@
from Tkinter import *
-# This example program creates a scroling canvas, and demonstrates
-# how to tie scrollbars and canvses together. The mechanism
+# This example program creates a scrolling canvas, and demonstrates
+# how to tie scrollbars and canvases together. The mechanism
# is analogus for listboxes and other widgets with
# "xscroll" and "yscroll" configuration options.
diff --git a/Demo/tkinter/ttk/ttkcalendar.py b/Demo/tkinter/ttk/ttkcalendar.py
index faa45c5b..f163170b 100644
--- a/Demo/tkinter/ttk/ttkcalendar.py
+++ b/Demo/tkinter/ttk/ttkcalendar.py
@@ -191,7 +191,7 @@ def _prev_month(self):
self._date = self._date - self.timedelta(days=1)
self._date = self.datetime(self._date.year, self._date.month, 1)
- self._build_calendar() # reconstuct calendar
+ self._build_calendar() # reconstruct calendar
def _next_month(self):
"""Update calendar to show the next month."""
diff --git a/Demo/turtle/demohelp.txt b/Demo/turtle/demohelp.txt
index d565691f..a49720b0 100644
--- a/Demo/turtle/demohelp.txt
+++ b/Demo/turtle/demohelp.txt
@@ -2,7 +2,7 @@
----------------------------------------------
- xturtleDemo - Help
+ turtleDemo - Help
----------------------------------------------
@@ -15,7 +15,7 @@
(1) How to use the demo viewer.
Select a demoscript from the example menu.
- The (syntax coloured) source code appears in the left
+ The (syntax colored) source code appears in the left
source code window. IT CANNOT BE EDITED, but ONLY VIEWED!
- Press START button to start the demo.
@@ -52,24 +52,33 @@
(2) How to add your own demos to the demo repository
+ IMPORTANT! When imported, the demo should not modify the system
+ by calling functions in other modules, such as sys, tkinter, or
+ turtle. Global variables should be initialized in main().
- - scriptname: must begin with tdemo_ ,
+ - The script name must begin with tdemo_ ,
so it must have the form tdemo_.py
- - place: same directory as xturtleDemo.py or some
- subdirectory, the name of which must also begin with
- tdemo_.....
-
- - requirements on source code:
- code must contain a main() function which will
- be executed by the viewer (see provided example scripts)
- main() may return a string which will be displayed
- in the Label below the source code window (when execution
- has finished.)
-
- !! For programs, which are EVENT DRIVEN, main must return
- !! the string "EVENTLOOP". This informs the viewer, that the
- !! script is still running and must be stopped by the user!
-
-
-
+ - The code must contain a main() function which will
+ be executed by the viewer (see provided example scripts).
+ It may return a string which will be displayed in the Label below
+ the source code window (when execution has finished.)
+
+ - In order to run mydemo.py by itself, such as during development,
+ add the following at the end of the file:
+
+ if __name__ == '__main__':
+ main()
+ mainloop() # keep window
+
+ python -m turtledemo.mydemo # will then run it
+
+ - If the demo is EVENT DRIVEN, main must return the string
+ "EVENTLOOP". This informs the demo viewer that the script is
+ still running and must be stopped by the user!
+
+ If an "EVENTLOOP" demo runs by itself, as with clock, which uses
+ ontimer, or minimal_hanoi, which loops by recursion, then the
+ code should catch the turtle.Terminator exception that will be
+ raised when the user presses the STOP button. (Paint is not such
+ a demo; it only acts in response to mouse clicks and movements.)
diff --git a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py b/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
index c9e6e652..3851f557 100644
--- a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
+++ b/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
@@ -3,7 +3,7 @@
tdemo-I_dont_like_tiltdemo.py
-Demostrates
+Demonstrates
(a) use of a tilted ellipse as
turtle shape
(b) stamping that shape
diff --git a/Demo/turtle/tdemo_chaos.py b/Demo/turtle/tdemo_chaos.py
index d4656f89..6a45d0d8 100644
--- a/Demo/turtle/tdemo_chaos.py
+++ b/Demo/turtle/tdemo_chaos.py
@@ -29,8 +29,8 @@ def coosys():
line(-1, 0, N+1, 0)
line(0, -0.1, 0, 1.1)
-def plot(fun, start, colour):
- pencolor(colour)
+def plot(fun, start, color):
+ pencolor(color)
x = start
jumpto(0, x)
pendown()
diff --git a/Demo/turtle/tdemo_clock.py b/Demo/turtle/tdemo_clock.py
index b6280bb9..1d6eb80a 100644
--- a/Demo/turtle/tdemo_clock.py
+++ b/Demo/turtle/tdemo_clock.py
@@ -13,8 +13,6 @@
from turtle import *
from datetime import datetime
-mode("logo")
-
def jump(distanz, winkel=0):
penup()
right(winkel)
@@ -42,7 +40,6 @@ def make_hand_shape(name, laenge, spitze):
hand_form = get_poly()
register_shape(name, hand_form)
-
def clockface(radius):
reset()
pensize(7)
@@ -83,7 +80,6 @@ def setup():
writer.pu()
writer.bk(85)
-
def wochentag(t):
wochentag = ["Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"]
@@ -102,22 +98,25 @@ def tick():
sekunde = t.second + t.microsecond*0.000001
minute = t.minute + sekunde/60.0
stunde = t.hour + minute/60.0
- tracer(False)
- writer.clear()
- writer.home()
- writer.forward(65)
- writer.write(wochentag(t),
- align="center", font=("Courier", 14, "bold"))
- writer.back(150)
- writer.write(datum(t),
- align="center", font=("Courier", 14, "bold"))
- writer.forward(85)
- tracer(True)
- second_hand.setheading(6*sekunde)
- minute_hand.setheading(6*minute)
- hour_hand.setheading(30*stunde)
- tracer(True)
- ontimer(tick, 100)
+ try:
+ tracer(False) # Terminator can occur here
+ writer.clear()
+ writer.home()
+ writer.forward(65)
+ writer.write(wochentag(t),
+ align="center", font=("Courier", 14, "bold"))
+ writer.back(150)
+ writer.write(datum(t),
+ align="center", font=("Courier", 14, "bold"))
+ writer.forward(85)
+ tracer(True)
+ second_hand.setheading(6*sekunde) # or here
+ minute_hand.setheading(6*minute)
+ hour_hand.setheading(30*stunde)
+ tracer(True)
+ ontimer(tick, 100)
+ except Terminator:
+ pass # turtledemo user pressed STOP
def main():
tracer(False)
@@ -127,6 +126,7 @@ def main():
return "EVENTLOOP"
if __name__ == "__main__":
+ mode("logo")
msg = main()
print msg
- mainloop()
+ mainloop() # keep window open
diff --git a/Demo/turtle/tdemo_minimal_hanoi.py b/Demo/turtle/tdemo_minimal_hanoi.py
index 8a1caa85..86001b61 100644
--- a/Demo/turtle/tdemo_minimal_hanoi.py
+++ b/Demo/turtle/tdemo_minimal_hanoi.py
@@ -50,9 +50,12 @@ def hanoi(n, from_, with_, to_):
def play():
onkey(None,"space")
clear()
- hanoi(6, t1, t2, t3)
- write("press STOP button to exit",
- align="center", font=("Courier", 16, "bold"))
+ try:
+ hanoi(6, t1, t2, t3)
+ write("press STOP button to exit",
+ align="center", font=("Courier", 16, "bold"))
+ except Terminator:
+ pass # turtledemo user pressed STOP
def main():
global t1, t2, t3
diff --git a/Demo/turtle/tdemo_nim.py b/Demo/turtle/tdemo_nim.py
index 8e66d7e8..d7394572 100644
--- a/Demo/turtle/tdemo_nim.py
+++ b/Demo/turtle/tdemo_nim.py
@@ -1,7 +1,7 @@
""" turtle-example-suite:
tdemo_nim.py
-
+
Play nim against the computer. The player
who takes the last stick is the winner.
@@ -41,7 +41,7 @@ def computerzug(state):
return move
def randommove(state):
- m = max(state)
+ m = max(state)
while True:
z = random.randint(0,2)
if state[z] > (m > 1):
@@ -62,7 +62,7 @@ def setup(self):
self.winner = None
self.game.view.setup()
self.game.state = Nim.RUNNING
-
+
def move(self, row, col):
maxspalte = self.sticks[row]
self.sticks[row] = col
@@ -76,7 +76,7 @@ def move(self, row, col):
row, col = computerzug(self.sticks)
self.move(row, col)
self.player = 0
-
+
def game_over(self):
return self.sticks == [0, 0, 0]
@@ -100,13 +100,13 @@ def __init__(self, row, col, game):
self.goto(x,y)
self.color("white")
self.showturtle()
-
+
def coords(self, row, col):
packet, remainder = divmod(col, 5)
x = (3 + 11 * packet + 2 * remainder) * WUNIT
y = (2 + 3 * row) * HUNIT
return x - SCREENWIDTH // 2 + WUNIT // 2, SCREENHEIGHT // 2 - y - HUNIT // 2
-
+
def makemove(self, x, y):
if self.game.state != Nim.RUNNING:
return
@@ -142,7 +142,7 @@ def display(self, msg1, msg2=None):
self.writer.pencolor("black")
self.writer.write(msg1, align="center", font=("Courier",14,"bold"))
self.screen.tracer(True)
-
+
def setup(self):
self.screen.tracer(False)
@@ -181,6 +181,7 @@ def clear(self):
if self.game.state == Nim.OVER:
self.screen.clear()
+
class NimController(object):
def __init__(self, game):
@@ -200,28 +201,26 @@ def notify_move(self, row, col):
self.BUSY = True
self.game.model.notify_move(row, col)
self.BUSY = False
-
+
class Nim(object):
CREATED = 0
RUNNING = 1
OVER = 2
def __init__(self, screen):
- self.state = Nim.CREATED
+ self.state = Nim.CREATED
self.screen = screen
self.model = NimModel(self)
self.view = NimView(self)
self.controller = NimController(self)
-
-mainscreen = turtle.Screen()
-mainscreen.mode("standard")
-mainscreen.setup(SCREENWIDTH, SCREENHEIGHT)
def main():
+ mainscreen = turtle.Screen()
+ mainscreen.mode("standard")
+ mainscreen.setup(SCREENWIDTH, SCREENHEIGHT)
nim = Nim(mainscreen)
return "EVENTLOOP!"
if __name__ == "__main__":
main()
turtle.mainloop()
-
diff --git a/Demo/turtle/tdemo_paint.py b/Demo/turtle/tdemo_paint.py
index e1d63030..105a06b6 100644
--- a/Demo/turtle/tdemo_paint.py
+++ b/Demo/turtle/tdemo_paint.py
@@ -3,11 +3,15 @@
tdemo_paint.py
-A simple eventdriven paint program
+A simple event-driven paint program
-- use left mouse button to move turtle
-- middle mouse button to change color
-- right mouse button do turn filling on/off
+- left mouse button moves turtle
+- middle mouse button changes color
+- right mouse button toogles betweem pen up
+(no line drawn when the turtle moves) and
+pen down (line is drawn). If pen up follows
+at least two pen-down moves, the polygon that
+includes the starting point is filled.
-------------------------------------------
Play around by clicking into the canvas
using all three mouse buttons.
diff --git a/Demo/turtle/tdemo_peace.py b/Demo/turtle/tdemo_peace.py
index 13044c98..8bfa9202 100644
--- a/Demo/turtle/tdemo_peace.py
+++ b/Demo/turtle/tdemo_peace.py
@@ -3,14 +3,10 @@
tdemo_peace.py
-A very simple drawing suitable as a beginner's
-programming example.
-
-Uses only commands, which are also available in
-old turtle.py.
-
-Intentionally no variables are used except for the
-colorloop:
+A simple drawing suitable as a beginner's
+programming example. Aside from the
+peacecolors assignment and the for loop,
+it only uses turtle commands.
"""
from turtle import *
@@ -21,7 +17,7 @@ def main():
"royalblue1", "dodgerblue4")
reset()
- s = Screen()
+ Screen()
up()
goto(-320,-195)
width(70)
@@ -58,7 +54,7 @@ def main():
up()
goto(0,300) # vanish if hideturtle() is not available ;-)
- return "Done!!"
+ return "Done!"
if __name__ == "__main__":
main()
diff --git a/Demo/turtle/tdemo_planet_and_moon.py b/Demo/turtle/tdemo_planet_and_moon.py
index 223d87b4..a0280d7a 100644
--- a/Demo/turtle/tdemo_planet_and_moon.py
+++ b/Demo/turtle/tdemo_planet_and_moon.py
@@ -12,9 +12,9 @@
Planet has a circular orbit, moon a stable
orbit around the planet.
-You can hold the movement temporarily by pressing
-the left mouse button with mouse over the
-scrollbar of the canvas.
+You can hold the movement temporarily by
+pressing the left mouse button with the
+mouse over the scrollbar of the canvas.
"""
from turtle import Shape, Turtle, mainloop, Vec2D as Vec
@@ -108,6 +108,5 @@ def main():
return "Done!"
if __name__ == '__main__':
- msg = main()
- print msg
+ main()
mainloop()
diff --git a/Demo/turtle/tdemo_tree.py b/Demo/turtle/tdemo_tree.py
index 6fc87359..6c6121ad 100644
--- a/Demo/turtle/tdemo_tree.py
+++ b/Demo/turtle/tdemo_tree.py
@@ -11,9 +11,9 @@
(1) a tree-generator, where the drawing is
quasi the side-effect, whereas the generator
always yields None.
-(2) Turtle-cloning: At each branching point the
-current pen is cloned. So in the end there
-are 1024 turtles.
+(2) Turtle-cloning: At each branching point
+the current pen is cloned. So in the end
+there are 1024 turtles.
"""
from turtle import Turtle, mainloop
from time import clock
diff --git a/Demo/turtle/tdemo_two_canvases.py b/Demo/turtle/tdemo_two_canvases.py
new file mode 100644
index 00000000..d5798766
--- /dev/null
+++ b/Demo/turtle/tdemo_two_canvases.py
@@ -0,0 +1,54 @@
+"""turtledemo.two_canvases
+
+Use TurtleScreen and RawTurtle to draw on two
+distinct canvases in a separate windows. The
+new window must be separately closed in
+addition to pressing the STOP button.
+"""
+
+from turtle import TurtleScreen, RawTurtle, TK
+
+def main():
+ root = TK.Tk()
+ cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff")
+ cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee")
+ cv1.pack()
+ cv2.pack()
+
+ s1 = TurtleScreen(cv1)
+ s1.bgcolor(0.85, 0.85, 1)
+ s2 = TurtleScreen(cv2)
+ s2.bgcolor(1, 0.85, 0.85)
+
+ p = RawTurtle(s1)
+ q = RawTurtle(s2)
+
+ p.color("red", (1, 0.85, 0.85))
+ p.width(3)
+ q.color("blue", (0.85, 0.85, 1))
+ q.width(3)
+
+ for t in p,q:
+ t.shape("turtle")
+ t.lt(36)
+
+ q.lt(180)
+
+ for t in p, q:
+ t.begin_fill()
+ for i in range(5):
+ for t in p, q:
+ t.fd(50)
+ t.lt(72)
+ for t in p,q:
+ t.end_fill()
+ t.lt(54)
+ t.pu()
+ t.bk(50)
+
+ return "EVENTLOOP"
+
+
+if __name__ == '__main__':
+ main()
+ TK.mainloop() # keep window open until user closes it
diff --git a/Demo/turtle/turtleDemo.py b/Demo/turtle/turtleDemo.py
index 30b5e5bb..12b4355c 100644
--- a/Demo/turtle/turtleDemo.py
+++ b/Demo/turtle/turtleDemo.py
@@ -5,11 +5,17 @@
from Tkinter import *
from idlelib.Percolator import Percolator
from idlelib.ColorDelegator import ColorDelegator
-from idlelib.textView import TextViewer
+from idlelib.textView import view_file
import turtle
import time
+demo_dir = os.getcwd()
+if "turtleDemo.py" not in os.listdir(demo_dir):
+ print "Directory of turtleDemo must be current working directory!"
+ print "But in your case this is", demo_dir
+ sys.exit()
+
STARTUP = 1
READY = 2
RUNNING = 3
@@ -21,12 +27,7 @@
txtfont = ('Lucida Console', 8, 'normal')
def getExampleEntries():
- cwd = os.getcwd()
- if "turtleDemo.py" not in os.listdir(cwd):
- print "Directory of turtleDemo must be current working directory!"
- print "But in your case this is", cwd
- sys.exit()
- entries1 = [entry for entry in os.listdir(cwd) if
+ entries1 = [entry for entry in os.listdir(demo_dir) if
entry.startswith("tdemo_") and
not entry.endswith(".pyc")]
entries2 = []
@@ -34,7 +35,7 @@ def getExampleEntries():
if entry.endswith(".py"):
entries2.append(entry)
else:
- path = os.path.join(cwd,entry)
+ path = os.path.join(demo_dir, entry)
sys.path.append(path)
subdir = [entry]
scripts = [script for script in os.listdir(path) if
@@ -43,122 +44,117 @@ def getExampleEntries():
entries2.append(subdir+scripts)
return entries2
-def showDemoHelp():
- TextViewer(demo.root, "Help on turtleDemo", "demohelp.txt")
-
-def showAboutDemo():
- TextViewer(demo.root, "About turtleDemo", "about_turtledemo.txt")
-
-def showAboutTurtle():
- TextViewer(demo.root, "About the new turtle module", "about_turtle.txt")
+help_entries = ( # (help_label, help_file)
+ ('Turtledemo help', "demohelp.txt"),
+ ('About turtledemo', "about_turtledemo.txt"),
+ ('About turtle module', "about_turtle.txt"),
+ )
class DemoWindow(object):
- def __init__(self, filename=None): #, root=None):
+ def __init__(self, filename=None):
self.root = root = turtle._root = Tk()
+ root.title('Python turtle-graphics examples')
root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
- #################
- self.mBar = Frame(root, relief=RAISED, borderwidth=2)
- self.mBar.pack(fill=X)
+ root.grid_rowconfigure(1, weight=1)
+ root.grid_columnconfigure(0, weight=1)
+ root.grid_columnconfigure(1, minsize=90, weight=1)
+ root.grid_columnconfigure(2, minsize=90, weight=1)
+ root.grid_columnconfigure(3, minsize=90, weight=1)
+ self.mBar = Frame(root, relief=RAISED, borderwidth=2)
self.ExamplesBtn = self.makeLoadDemoMenu()
self.OptionsBtn = self.makeHelpMenu()
- self.mBar.tk_menuBar(self.ExamplesBtn, self.OptionsBtn) #, QuitBtn)
+ self.mBar.grid(row=0, columnspan=4, sticky='news')
+
+ pane = PanedWindow(orient=HORIZONTAL, sashwidth=5,
+ sashrelief=SOLID, bg='#ddd')
+ pane.add(self.makeTextFrame(pane))
+ pane.add(self.makeGraphFrame(pane))
+ pane.grid(row=1, columnspan=4, sticky='news')
+
+ self.output_lbl = Label(root, height= 1, text=" --- ", bg="#ddf",
+ font=("Arial", 16, 'normal'), borderwidth=2,
+ relief=RIDGE)
+ self.start_btn = Button(root, text=" START ", font=btnfont,
+ fg="white", disabledforeground = "#fed",
+ command=self.startDemo)
+ self.stop_btn = Button(root, text=" STOP ", font=btnfont,
+ fg="white", disabledforeground = "#fed",
+ command=self.stopIt)
+ self.clear_btn = Button(root, text=" CLEAR ", font=btnfont,
+ fg="white", disabledforeground="#fed",
+ command = self.clearCanvas)
+ self.output_lbl.grid(row=2, column=0, sticky='news', padx=(0,5))
+ self.start_btn.grid(row=2, column=1, sticky='ew')
+ self.stop_btn.grid(row=2, column=2, sticky='ew')
+ self.clear_btn.grid(row=2, column=3, sticky='ew')
+
+ Percolator(self.text).insertfilter(ColorDelegator())
+ self.dirty = False
+ self.exitflag = False
+ if filename:
+ self.loadfile(filename)
+ self.configGUI(NORMAL, DISABLED, DISABLED, DISABLED,
+ "Choose example from menu", "black")
+ self.state = STARTUP
- root.title('Python turtle-graphics examples')
- #################
- self.left_frame = left_frame = Frame(root)
- self.text_frame = text_frame = Frame(left_frame)
- self.vbar = vbar =Scrollbar(text_frame, name='vbar')
- self.text = text = Text(text_frame,
- name='text', padx=5, wrap='none',
- width=45)
+
+ def onResize(self, event):
+ cwidth = self._canvas.winfo_width()
+ cheight = self._canvas.winfo_height()
+ self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
+ self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
+
+ def makeTextFrame(self, root):
+ self.text_frame = text_frame = Frame(root)
+ self.text = text = Text(text_frame, name='text', padx=5,
+ wrap='none', width=45)
+
+ self.vbar = vbar = Scrollbar(text_frame, name='vbar')
vbar['command'] = text.yview
vbar.pack(side=LEFT, fill=Y)
- #####################
- self.hbar = hbar =Scrollbar(text_frame, name='hbar', orient=HORIZONTAL)
+ self.hbar = hbar = Scrollbar(text_frame, name='hbar', orient=HORIZONTAL)
hbar['command'] = text.xview
hbar.pack(side=BOTTOM, fill=X)
- #####################
+
+ text['font'] = txtfont
text['yscrollcommand'] = vbar.set
- text.config(font=txtfont)
- text.config(xscrollcommand=hbar.set)
- text.pack(side=LEFT, fill=Y, expand=1)
- #####################
- self.output_lbl = Label(left_frame, height= 1,text=" --- ", bg = "#ddf",
- font = ("Arial", 16, 'normal'))
- self.output_lbl.pack(side=BOTTOM, expand=0, fill=X)
- #####################
- text_frame.pack(side=LEFT, fill=BOTH, expand=0)
- left_frame.pack(side=LEFT, fill=BOTH, expand=0)
- self.graph_frame = g_frame = Frame(root)
-
- turtle._Screen._root = g_frame
- turtle._Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800)
- #xturtle.Screen._canvas.pack(expand=1, fill="both")
+ text['xscrollcommand'] = hbar.set
+ text.pack(side=LEFT, fill=BOTH, expand=1)
+ return text_frame
+
+ def makeGraphFrame(self, root):
+ turtle._Screen._root = root
+ self.canvwidth = 1000
+ self.canvheight = 800
+ turtle._Screen._canvas = self._canvas = canvas = turtle.ScrolledCanvas(
+ root, 800, 600, self.canvwidth, self.canvheight)
+ canvas.adjustScrolls()
+ canvas._rootwindow.bind('', self.onResize)
+ canvas._canvas['borderwidth'] = 0
+
self.screen = _s_ = turtle.Screen()
turtle.TurtleScreen.__init__(_s_, _s_._canvas)
self.scanvas = _s_._canvas
- #xturtle.RawTurtle.canvases = [self.scanvas]
turtle.RawTurtle.screens = [_s_]
-
- self.scanvas.pack(side=TOP, fill=BOTH, expand=1)
-
- self.btn_frame = btn_frame = Frame(g_frame, height=100)
- self.start_btn = Button(btn_frame, text=" START ", font=btnfont, fg = "white",
- disabledforeground = "#fed", command=self.startDemo)
- self.start_btn.pack(side=LEFT, fill=X, expand=1)
- self.stop_btn = Button(btn_frame, text=" STOP ", font=btnfont, fg = "white",
- disabledforeground = "#fed", command = self.stopIt)
- self.stop_btn.pack(side=LEFT, fill=X, expand=1)
- self.clear_btn = Button(btn_frame, text=" CLEAR ", font=btnfont, fg = "white",
- disabledforeground = "#fed", command = self.clearCanvas)
- self.clear_btn.pack(side=LEFT, fill=X, expand=1)
-
- self.btn_frame.pack(side=TOP, fill=BOTH, expand=0)
- self.graph_frame.pack(side=TOP, fill=BOTH, expand=1)
-
- Percolator(text).insertfilter(ColorDelegator())
- self.dirty = False
- self.exitflag = False
- if filename:
- self.loadfile(filename)
- self.configGUI(NORMAL, DISABLED, DISABLED, DISABLED,
- "Choose example from menu", "black")
- self.state = STARTUP
-
- def _destroy(self):
- self.root.destroy()
- sys.exit()
+ return canvas
def configGUI(self, menu, start, stop, clear, txt="", color="blue"):
self.ExamplesBtn.config(state=menu)
- self.start_btn.config(state=start)
- if start==NORMAL:
- self.start_btn.config(bg="#d00")
- else:
- self.start_btn.config(bg="#fca")
-
- self.stop_btn.config(state=stop)
- if stop==NORMAL:
- self.stop_btn.config(bg="#d00")
- else:
- self.stop_btn.config(bg="#fca")
- self.clear_btn.config(state=clear)
-
- self.clear_btn.config(state=clear)
- if clear==NORMAL:
- self.clear_btn.config(bg="#d00")
- else:
- self.clear_btn.config(bg="#fca")
-
+ self.start_btn.config(state=start,
+ bg="#d00" if start == NORMAL else "#fca")
+ self.stop_btn.config(state=stop,
+ bg="#d00" if stop == NORMAL else "#fca")
+ self.clear_btn.config(state=clear,
+ bg="#d00" if clear == NORMAL else"#fca")
self.output_lbl.config(text=txt, fg=color)
-
def makeLoadDemoMenu(self):
- CmdBtn = Menubutton(self.mBar, text='Examples', underline=0, font=menufont)
+ CmdBtn = Menubutton(self.mBar, text='Examples',
+ underline=0, font=menufont)
CmdBtn.pack(side=LEFT, padx="2m")
CmdBtn.menu = Menu(CmdBtn)
@@ -168,30 +164,31 @@ def emit():
self.loadfile(x)
return emit
if isinstance(entry,str):
- CmdBtn.menu.add_command(label=entry[6:-3], underline=0, font=menufont,
+ CmdBtn.menu.add_command(label=entry[6:-3], underline=0,
+ font=menufont,
command=loadexample(entry))
else:
_dir, entries = entry[0], entry[1:]
CmdBtn.menu.choices = Menu(CmdBtn.menu)
for e in entries:
- CmdBtn.menu.choices.add_command(label=e[6:-3], underline=0, font=menufont,
- command = loadexample(os.path.join(_dir,e)))
-
- CmdBtn.menu.add_cascade(label=_dir[6:],
- menu = CmdBtn.menu.choices, font=menufont )
+ CmdBtn.menu.choices.add_command(
+ label=e[6:-3], underline=0, font=menufont,
+ command = loadexample(os.path.join(_dir,e)))
+ CmdBtn.menu.add_cascade(
+ label=_dir[6:], menu = CmdBtn.menu.choices, font=menufont)
CmdBtn['menu'] = CmdBtn.menu
return CmdBtn
-
def makeHelpMenu(self):
CmdBtn = Menubutton(self.mBar, text='Help', underline=0, font = menufont)
CmdBtn.pack(side=LEFT, padx='2m')
CmdBtn.menu = Menu(CmdBtn)
- CmdBtn.menu.add_command(label='About turtle.py', font=menufont, command=showAboutTurtle)
- CmdBtn.menu.add_command(label='turtleDemo - Help', font=menufont, command=showDemoHelp)
- CmdBtn.menu.add_command(label='About turtleDemo', font=menufont, command=showAboutDemo)
+ for help_label, help_file in help_entries:
+ def show(help_label=help_label, help_file=help_file):
+ view_file(self.root, help_label, os.path.join(demo_dir, help_file))
+ CmdBtn.menu.add_command(label=help_label, font=menufont, command=show)
CmdBtn['menu'] = CmdBtn.menu
return CmdBtn
@@ -199,7 +196,6 @@ def makeHelpMenu(self):
def refreshCanvas(self):
if not self.dirty: return
self.screen.clear()
- #self.screen.mode("standard")
self.dirty=False
def loadfile(self,filename):
@@ -214,7 +210,6 @@ def loadfile(self,filename):
direc, fname = os.path.split(filename)
self.root.title(fname[6:-3]+" - a Python turtle graphics example")
self.module = __import__(fname[:-3])
- reload(self.module)
self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
"Press start button", "red")
self.state = READY
@@ -236,6 +231,8 @@ def startDemo(self):
else:
self.state = DONE
except turtle.Terminator:
+ if self.root is None:
+ return
self.state = DONE
result = "stopped!"
if self.state == DONE:
@@ -258,23 +255,18 @@ def stopIt(self):
self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
"STOPPED!", "red")
turtle.TurtleScreen._RUNNING = False
- #print "stopIT: exitflag = True"
else:
turtle.TurtleScreen._RUNNING = False
- #print "stopIt: exitflag = False"
-if __name__ == '__main__':
+ def _destroy(self):
+ turtle.TurtleScreen._RUNNING = False
+ self.root.destroy()
+ self.root = None
+ #sys.exit()
+
+def main():
demo = DemoWindow()
- RUN = True
- while RUN:
- try:
- print "ENTERING mainloop"
- demo.root.mainloop()
- except AttributeError:
- print "CRASH!!!- WAIT A MOMENT!"
- time.sleep(0.3)
- print "GOING ON .."
- demo.refreshCanvas()
-## time.sleep(1)
- except:
- RUN = FALSE
+ demo.root.mainloop()
+
+if __name__ == '__main__':
+ main()
diff --git a/Demo/turtle/turtledemo_two_canvases.py b/Demo/turtle/turtledemo_two_canvases.py
deleted file mode 100644
index 5a9831d2..00000000
--- a/Demo/turtle/turtledemo_two_canvases.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-## DEMONSTRATES USE OF 2 CANVASES, SO CANNOT BE RUN IN DEMOVIEWER!
-"""turtle example: Using TurtleScreen and RawTurtle
-for drawing on two distinct canvases.
-"""
-from turtle import TurtleScreen, RawTurtle, TK
-
-root = TK.Tk()
-cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff")
-cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee")
-cv1.pack()
-cv2.pack()
-
-s1 = TurtleScreen(cv1)
-s1.bgcolor(0.85, 0.85, 1)
-s2 = TurtleScreen(cv2)
-s2.bgcolor(1, 0.85, 0.85)
-
-p = RawTurtle(s1)
-q = RawTurtle(s2)
-
-p.color("red", "white")
-p.width(3)
-q.color("blue", "black")
-q.width(3)
-
-for t in p,q:
- t.shape("turtle")
- t.lt(36)
-
-q.lt(180)
-
-for i in range(5):
- for t in p, q:
- t.fd(50)
- t.lt(72)
-for t in p,q:
- t.lt(54)
- t.pu()
- t.bk(50)
-
-## Want to get some info?
-
-print s1, s2
-print p, q
-print s1.turtles()
-print s2.turtles()
-
-TK.mainloop()
diff --git a/Doc/Makefile b/Doc/Makefile
index 4052babc..3d7e4ac2 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -5,27 +5,29 @@
# You can set these variables from the command line.
PYTHON = python
-SVNROOT = http://svn.python.org/projects
-SPHINXOPTS =
+VENVDIR = ./venv
+SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-build
+BLURB = PATH=$(VENVDIR)/bin:$$PATH blurb
PAPER =
SOURCES =
-DISTVERSION = $(shell $(PYTHON) tools/sphinxext/patchlevel.py)
+DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py)
-ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_paper_size=$(PAPER) \
+ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_elements.papersize=$(PAPER) \
$(SPHINXOPTS) . build/$(BUILDER) $(SOURCES)
-.PHONY: help checkout update build html htmlhelp latex text changes linkcheck \
+.PHONY: help build html htmlhelp latex text changes linkcheck \
suspicious coverage doctest pydoc-topics htmlview clean dist check serve \
autobuild-dev autobuild-stable
help:
@echo "Please use \`make ' where is one of"
@echo " clean to remove build files"
- @echo " update to update build tools"
@echo " html to make standalone HTML files"
+ @echo " htmlview to open the index page built by the html target in your browser"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " text to make plain text files"
+ @echo " epub to make EPUB files"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " coverage to check documentation coverage for library and C API"
@@ -36,30 +38,8 @@ help:
@echo " check to run a check for frequent markup errors"
@echo " serve to serve the documentation on the localhost (8000)"
-# Note: if you update versions here, do the same in make.bat and README.txt
-checkout:
- @if [ ! -d tools/sphinx ]; then \
- echo "Checking out Sphinx..."; \
- svn checkout $(SVNROOT)/external/Sphinx-1.0.7/sphinx tools/sphinx; \
- fi
- @if [ ! -d tools/docutils ]; then \
- echo "Checking out Docutils..."; \
- svn checkout $(SVNROOT)/external/docutils-0.6/docutils tools/docutils; \
- fi
- @if [ ! -d tools/jinja2 ]; then \
- echo "Checking out Jinja..."; \
- svn checkout $(SVNROOT)/external/Jinja-2.3.1/jinja2 tools/jinja2; \
- fi
- @if [ ! -d tools/pygments ]; then \
- echo "Checking out Pygments..."; \
- svn checkout $(SVNROOT)/external/Pygments-1.3.1/pygments tools/pygments; \
- fi
-
-update: clean checkout
-
-build: checkout
- mkdir -p build/$(BUILDER) build/doctrees
- $(PYTHON) tools/sphinx-build.py $(ALLSPHINXOPTS)
+build:
+ $(SPHINXBUILD) $(ALLSPHINXOPTS)
@echo
html: BUILDER = html
@@ -81,44 +61,55 @@ text: BUILDER = text
text: build
@echo "Build finished; the text files are in build/text."
+epub: BUILDER = epub
+epub: build
+ @echo "Build finished; the epub files are in build/epub."
+
changes: BUILDER = changes
changes: build
@echo "The overview file is in build/changes."
linkcheck: BUILDER = linkcheck
-linkcheck: build
- @echo "Link check complete; look for any errors in the above output" \
- "or in build/$(BUILDER)/output.txt"
+linkcheck:
+ @$(MAKE) build BUILDER=$(BUILDER) || { \
+ echo "Link check complete; look for any errors in the above output" \
+ "or in build/$(BUILDER)/output.txt"; \
+ false; }
suspicious: BUILDER = suspicious
-suspicious: build
- @echo "Suspicious check complete; look for any errors in the above output" \
- "or in build/$(BUILDER)/suspicious.csv. If all issues are false" \
- "positives, append that file to tools/sphinxext/susp-ignored.csv."
+suspicious:
+ @$(MAKE) build BUILDER=$(BUILDER) || { \
+ echo "Suspicious check complete; look for any errors in the above output" \
+ "or in build/$(BUILDER)/suspicious.csv. If all issues are false" \
+ "positives, append that file to tools/susp-ignored.csv."; \
+ false; }
coverage: BUILDER = coverage
coverage: build
@echo "Coverage finished; see c.txt and python.txt in build/coverage"
doctest: BUILDER = doctest
-doctest: build
- @echo "Testing of doctests in the sources finished, look at the" \
- "results in build/doctest/output.txt"
+doctest:
+ @$(MAKE) build BUILDER=$(BUILDER) || { \
+ echo "Testing of doctests in the sources finished, look at the" \
+ "results in build/doctest/output.txt"; \
+ false; }
pydoc-topics: BUILDER = pydoc-topics
pydoc-topics: build
@echo "Building finished; now copy build/pydoc-topics/topics.py" \
- "to Lib/pydoc_data/topics.py"
+ "to ../Lib/pydoc_data/topics.py"
htmlview: html
$(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')"
clean:
- -rm -rf build/*
- -rm -rf tools/sphinx
- -rm -rf tools/pygments
- -rm -rf tools/jinja2
- -rm -rf tools/docutils
+ -rm -rf build/* $(VENVDIR)/*
+
+venv:
+ $(PYTHON) -m venv $(VENVDIR)
+ $(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb
+ @echo "The venv has been created in the $(VENVDIR) directory"
dist:
rm -rf dist
@@ -158,8 +149,13 @@ dist:
cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-letter.zip
cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-letter.tar.bz2
+ # copy the epub build
+ rm -rf build/epub
+ make epub
+ cp -pPR build/epub/Python.epub dist/python-$(DISTVERSION)-docs.epub
+
check:
- $(PYTHON) tools/rstlint.py -i tools
+ $(PYTHON)2 tools/rstlint.py -i tools -i $(VENVDIR)
serve:
../Tools/scripts/serve.py build/html
@@ -168,18 +164,25 @@ serve:
# for development releases: always build
autobuild-dev:
- make update
- make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1'
+ make dist SPHINXOPTS='$(SPHINXOPTS) -A daily=1 -A switchers=1'
+ -make suspicious
# for quick rebuilds (HTML only)
-autobuild-html:
- make html SPHINXOPTS='-A daily=1 -A versionswitcher=1'
+autobuild-dev-html:
+ make html SPHINXOPTS='$(SPHINXOPTS) -A daily=1 -A switchers=1'
-# for stable releases: only build if not in pre-release stage (alpha, beta, rc)
+# for stable releases: only build if not in pre-release stage (alpha, beta)
+# release candidate downloads are okay, since the stable tree can be in that stage
autobuild-stable:
- @case $(DISTVERSION) in *[abc]*) \
+ @case $(DISTVERSION) in *[ab]*) \
echo "Not building; $(DISTVERSION) is not a release version."; \
exit 1;; \
esac
@make autobuild-dev
+autobuild-stable-html:
+ @case $(DISTVERSION) in *[ab]*) \
+ echo "Not building; $(DISTVERSION) is not a release version."; \
+ exit 1;; \
+ esac
+ @make autobuild-dev-html
diff --git a/Doc/README.txt b/Doc/README.txt
index dfa62d57..625efd47 100644
--- a/Doc/README.txt
+++ b/Doc/README.txt
@@ -3,142 +3,126 @@ Python Documentation README
This directory contains the reStructuredText (reST) sources to the Python
documentation. You don't need to build them yourself, prebuilt versions are
-available at http://docs.python.org/download/.
+available at .
-Documentation on the authoring Python documentation, including information about
+Documentation on authoring Python documentation, including information about
both style and markup, is available in the "Documenting Python" chapter of the
-documentation. There's also a chapter intended to point out differences to
-those familiar with the previous docs written in LaTeX.
+developers guide .
Building the docs
=================
-You need to have Python 2.4 or higher installed; the toolset used to build the
-docs is written in Python. It is called *Sphinx*, it is not included in this
-tree, but maintained separately. Also needed are the docutils, supplying the
-base markup that Sphinx uses, Jinja, a templating engine, and optionally
-Pygments, a code highlighter.
+You need to have Sphinx installed; it is the toolset
+used to build the docs. It is not included in this tree, but maintained
+separately and available from PyPI .
Using make
----------
-Luckily, a Makefile has been prepared so that on Unix, provided you have
-installed Python and Subversion, you can just run ::
+A Makefile has been prepared so that on Unix, provided you have installed
+Sphinx, you can just run ::
make html
-to check out the necessary toolset in the `tools/` subdirectory and build the
-HTML output files. To view the generated HTML, point your favorite browser at
-the top-level index `build/html/index.html` after running "make".
+to build the HTML output files.
-Available make targets are:
+On Windows, we try to emulate the Makefile as closely as possible with a
+``make.bat`` file.
- * "html", which builds standalone HTML files for offline viewing.
+To use a Python interpreter that's not called ``python``, use the standard
+way to set Makefile variables, using e.g. ::
- * "htmlhelp", which builds HTML files and a HTML Help project file usable to
- convert them into a single Compiled HTML (.chm) file -- these are popular
- under Microsoft Windows, but very handy on every platform.
+ make html PYTHON=python3
- To create the CHM file, you need to run the Microsoft HTML Help Workshop over
- the generated project (.hhp) file.
+On Windows, set the PYTHON environment variable instead.
- * "latex", which builds LaTeX source files as input to "pdflatex" to produce
- PDF documents.
+To use a specific sphinx-build (something other than ``sphinx-build``), set
+the SPHINXBUILD variable.
- * "text", which builds a plain text file for each source file.
+Available make targets are:
- * "linkcheck", which checks all external references to see whether they are
- broken, redirected or malformed, and outputs this information to stdout as
- well as a plain-text (.txt) file.
+* "clean", which removes all build files.
- * "changes", which builds an overview over all versionadded/versionchanged/
- deprecated items in the current version. This is meant as a help for the
- writer of the "What's New" document.
+* "html", which builds standalone HTML files for offline viewing.
- * "coverage", which builds a coverage overview for standard library modules and
- C API.
+* "htmlview", which re-uses the "html" builder, but then opens the main page
+ in your default web browser.
- * "pydoc-topics", which builds a Python module containing a dictionary with
- plain text documentation for the labels defined in
- `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and
- keyword help.
+* "htmlhelp", which builds HTML files and a HTML Help project file usable to
+ convert them into a single Compiled HTML (.chm) file -- these are popular
+ under Microsoft Windows, but very handy on every platform.
-A "make update" updates the Subversion checkouts in `tools/`.
+ To create the CHM file, you need to run the Microsoft HTML Help Workshop
+ over the generated project (.hhp) file. The make.bat script does this for
+ you on Windows.
+* "latex", which builds LaTeX source files as input to "pdflatex" to produce
+ PDF documents.
-Without make
-------------
+* "text", which builds a plain text file for each source file.
-You'll need to install the Sphinx package, either by checking it out via ::
+* "epub", which builds an EPUB document, suitable to be viewed on e-book
+ readers.
- svn co http://svn.python.org/projects/external/Sphinx-0.6.7/sphinx tools/sphinx
+* "linkcheck", which checks all external references to see whether they are
+ broken, redirected or malformed, and outputs this information to stdout as
+ well as a plain-text (.txt) file.
-or by installing it from PyPI.
+* "changes", which builds an overview over all versionadded/versionchanged/
+ deprecated items in the current version. This is meant as a help for the
+ writer of the "What's New" document.
-Then, you need to install Docutils, either by checking it out via ::
+* "coverage", which builds a coverage overview for standard library modules and
+ C API.
- svn co http://svn.python.org/projects/external/docutils-0.6/docutils tools/docutils
+* "pydoc-topics", which builds a Python module containing a dictionary with
+ plain text documentation for the labels defined in
+ `tools/pyspecific.py` -- pydoc needs these to show topic and keyword help.
-or by installing it from http://docutils.sf.net/.
+* "suspicious", which checks the parsed markup for text that looks like
+ malformed and thus unconverted reST.
-You also need Jinja2, either by checking it out via ::
+* "check", which checks for frequent markup errors.
- svn co http://svn.python.org/projects/external/Jinja-2.3.1/jinja2 tools/jinja2
+* "serve", which serves the build/html directory on port 8000.
-or by installing it from PyPI.
+* "dist", (Unix only) which creates distributable archives of HTML, text,
+ PDF, and EPUB builds.
-You can optionally also install Pygments, either as a checkout via ::
- svn co http://svn.python.org/projects/external/Pygments-1.3.1/pygments tools/pygments
+Without make
+------------
-or from PyPI at http://pypi.python.org/pypi/Pygments.
+Install the Sphinx package and its dependencies from PyPI.
+Then, from the ``Doc`` directory, run ::
-Then, make an output directory, e.g. under `build/`, and run ::
+ sphinx-build -b . build/
- python tools/sphinx-build.py -b . build/
+where ```` is one of html, text, latex, or htmlhelp (for explanations
+see the make targets above).
-where `` is one of html, text, latex, or htmlhelp (for explanations see
-the make targets above).
+Deprecation header
+==================
+
+Following the sunsetting of Python 2.7, a red banner displays at the
+top of each page redirecting to the corresponding page on
+``https://docs.python.org/3/``.
Contributing
============
Bugs in the content should be reported to the Python bug tracker at
-http://bugs.python.org.
+https://bugs.python.org.
Bugs in the toolset should be reported in the Sphinx bug tracker at
-http://www.bitbucket.org/birkenfeld/sphinx/issues/.
+https://www.bitbucket.org/birkenfeld/sphinx/issues/.
You can also send a mail to the Python Documentation Team at docs@python.org,
and we will process your request as soon as possible.
If you want to help the Documentation Team, you are always welcome. Just send
a mail to docs@python.org.
-
-
-Copyright notice
-================
-
-The Python source is copyrighted, but you can freely use and copy it
-as long as you don't change or remove the copyright notice:
-
-----------------------------------------------------------------------
-Copyright (c) 2000-2013 Python Software Foundation.
-All rights reserved.
-
-Copyright (c) 2000 BeOpen.com.
-All rights reserved.
-
-Copyright (c) 1995-2000 Corporation for National Research Initiatives.
-All rights reserved.
-
-Copyright (c) 1991-1995 Stichting Mathematisch Centrum.
-All rights reserved.
-
-See the file "license.rst" for information on usage and redistribution
-of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-----------------------------------------------------------------------
diff --git a/Doc/about.rst b/Doc/about.rst
index d316f09f..3ea311fa 100644
--- a/Doc/about.rst
+++ b/Doc/about.rst
@@ -6,29 +6,27 @@ About these documents
These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a
document processor specifically written for the Python documentation.
-.. _reStructuredText: http://docutils.sf.net/rst.html
-.. _Sphinx: http://sphinx.pocoo.org/
+.. _reStructuredText: http://docutils.sourceforge.net/rst.html
+.. _Sphinx: http://sphinx-doc.org/
.. In the online version of these documents, you can submit comments and suggest
changes directly on the documentation pages.
-Development of the documentation and its toolchain takes place on the
-docs@python.org mailing list. We're always looking for volunteers wanting
-to help with the docs, so feel free to send a mail there!
+Development of the documentation and its toolchain is an entirely volunteer
+effort, just like Python itself. If you want to contribute, please take a
+look at the :ref:`reporting-bugs` page for information on how to do so. New
+volunteers are always welcome!
Many thanks go to:
* Fred L. Drake, Jr., the creator of the original Python documentation toolset
and writer of much of the content;
-* the `Docutils `_ project for creating
+* the `Docutils `_ project for creating
reStructuredText and the Docutils suite;
* Fredrik Lundh for his `Alternative Python Reference
`_ project from which Sphinx got many good
ideas.
-See :ref:`reporting-bugs` for information how to report bugs in this
-documentation, or Python itself.
-
Contributors to the Python Documentation
----------------------------------------
diff --git a/Doc/bugs.rst b/Doc/bugs.rst
index 3785ccb7..3749f936 100644
--- a/Doc/bugs.rst
+++ b/Doc/bugs.rst
@@ -13,21 +13,24 @@ Documentation bugs
==================
If you find a bug in this documentation or would like to propose an improvement,
-please send an e-mail to docs@python.org describing the bug and where you found
-it. If you have a suggestion how to fix it, include that as well.
+please submit a bug report on the :ref:`tracker `. If you
+have a suggestion on how to fix it, include that as well.
-docs@python.org is a mailing list run by volunteers; your request will be
-noticed, even if it takes a while to be processed.
+If you're short on time, you can also email documentation bug reports to
+docs@python.org (behavioral bugs can be sent to python-list@python.org).
+'docs@' is a mailing list run by volunteers; your request will be noticed,
+though it may take a while to be processed.
-Of course, if you want a more persistent record of your issue, you can use the
-issue tracker for documentation bugs as well.
+.. seealso::
+ `Documentation bugs`_ on the Python issue tracker
+.. _using-the-tracker:
Using the Python issue tracker
==============================
Bug reports for Python itself should be submitted via the Python Bug Tracker
-(http://bugs.python.org/). The bug tracker offers a Web form which allows
+(https://bugs.python.org/). The bug tracker offers a Web form which allows
pertinent information to be entered and submitted to the developers.
The first step in filing a report is to determine whether the problem has
@@ -62,14 +65,24 @@ taken on the bug.
.. seealso::
- `Python Developer's Guide `_
- Detailed description of the issue workflow and developers tools.
-
`How to Report Bugs Effectively `_
Article which goes into some detail about how to create a useful bug report.
This describes what kind of information is useful and why it is useful.
- `Bug Writing Guidelines `_
+ `Bug Writing Guidelines `_
Information about writing a good bug report. Some of this is specific to the
Mozilla project, but describes general good practices.
+
+Getting started contributing to Python yourself
+===============================================
+
+Beyond just reporting bugs that you find, you are also welcome to submit
+patches to fix them. You can find more information on how to get started
+patching Python in the `Python Developer's Guide`_. If you have questions,
+the `core-mentorship mailing list`_ is a friendly place to get answers to
+any and all questions pertaining to the process of fixing issues in Python.
+
+.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity
+.. _Python Developer's Guide: https://devguide.python.org/
+.. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/
diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst
index 32a414b1..7f7435f3 100644
--- a/Doc/c-api/allocation.rst
+++ b/Doc/c-api/allocation.rst
@@ -98,7 +98,7 @@ Allocating Objects on the Heap
Create a new module object based on a name and table of functions,
returning the new module object. If *doc* is non-*NULL*, it will be used
to define the docstring for the module. If *self* is non-*NULL*, it will
- passed to the functions of the module as their (otherwise *NULL*) first
+ be passed to the functions of the module as their (otherwise *NULL*) first
parameter. (This was added as an experimental feature, and there are no
known uses in the current version of Python.) For *apiver*, the only value
which should be passed is defined by the constant
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 8fbdc500..73756833 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -24,7 +24,7 @@ the format unit; the entry in (round) parentheses is the Python object type
that matches the format unit; and the entry in [square] brackets is the type
of the C variable(s) whose address should be passed.
-These formats allow to access an object as a contiguous chunk of memory.
+These formats allow accessing an object as a contiguous chunk of memory.
You don't have to provide raw storage for the returned unicode or bytes
area. Also, you won't have to release any memory yourself, except with the
``es``, ``es#``, ``et`` and ``et#`` formats.
@@ -136,7 +136,8 @@ area. Also, you won't have to release any memory yourself, except with the
:c:func:`PyArg_ParseTuple` will use this location as the buffer and
interpret the initial value of *\*buffer_length* as the buffer size. It
will then copy the encoded data into the buffer and NUL-terminate it. If
- the buffer is not large enough, a :exc:`ValueError` will be set.
+ the buffer is not large enough, a :exc:`TypeError` will be set.
+ Note: starting from Python 3.6 a :exc:`ValueError` will be set.
In both cases, *\*buffer_length* is set to the length of the encoded data
without the trailing NUL byte.
@@ -424,7 +425,7 @@ and the following format units are left untouched.
only if its format string contains two or more format units. If the format
string is empty, it returns ``None``; if it contains exactly one format
unit, it returns whatever object is described by that format unit. To
- force it to return a tuple of size 0 or one, parenthesize the format
+ force it to return a tuple of size ``0`` or one, parenthesize the format
string.
When memory buffers are passed as parameters to supply data to build
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index e028369c..77940aca 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -21,8 +21,10 @@ first.
Two examples of objects that support the buffer interface are strings and
arrays. The string object exposes the character contents in the buffer
-interface's byte-oriented form. An array can also expose its contents, but it
-should be noted that array elements may be multi-byte values.
+interface's byte-oriented form. An array can only expose its contents via the
+old-style buffer interface. This limitation does not apply to Python 3,
+where :class:`memoryview` objects can be constructed from arrays, too.
+Array elements may be multi-byte values.
An example user of the buffer interface is the file object's :meth:`write`
method. Any object that can export a series of bytes through the buffer
@@ -72,7 +74,7 @@ The new-style Py_buffer struct
.. c:member:: int ndim
The number of dimensions the memory represents as a multi-dimensional
- array. If it is 0, :c:data:`strides` and :c:data:`suboffsets` must be
+ array. If it is ``0``, :c:data:`strides` and :c:data:`suboffsets` must be
*NULL*.
.. c:member:: Py_ssize_t *shape
@@ -96,8 +98,11 @@ The new-style Py_buffer struct
suboffset value that it negative indicates that no de-referencing should
occur (striding in a contiguous memory block).
+ If all suboffsets are negative (i.e. no de-referencing is needed), then
+ this field must be NULL (the default value).
+
Here is a function that returns a pointer to the element in an N-D array
- pointed to by an N-dimesional index when there are both non-NULL strides
+ pointed to by an N-dimensional index when there are both non-NULL strides
and suboffsets::
void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
@@ -138,7 +143,7 @@ Buffer related functions
.. c:function:: int PyObject_CheckBuffer(PyObject *obj)
- Return 1 if *obj* supports the buffer interface otherwise 0.
+ Return ``1`` if *obj* supports the buffer interface otherwise ``0``.
.. c:function:: int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
@@ -159,7 +164,7 @@ Buffer related functions
:c:data:`Py_buffer` structure is filled in with non-default values and/or
raise an error if the object can't support a simpler view of its memory.
- 0 is returned on success and -1 on error.
+ ``0`` is returned on success and ``-1`` on error.
The following table gives possible values to the *flags* arguments.
@@ -268,12 +273,12 @@ Buffer related functions
.. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran)
- Return 1 if the memory defined by the *view* is C-style (*fortran* is
+ Return ``1`` if the memory defined by the *view* is C-style (*fortran* is
``'C'``) or Fortran-style (*fortran* is ``'F'``) contiguous or either one
- (*fortran* is ``'A'``). Return 0 otherwise.
+ (*fortran* is ``'A'``). Return ``0`` otherwise.
-.. c:function:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fortran)
+.. c:function:: void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, int itemsize, char fortran)
Fill the *strides* array with byte-strides of a contiguous (C-style if
*fortran* is ``'C'`` or Fortran-style if *fortran* is ``'F'``) array of the
@@ -284,7 +289,7 @@ Buffer related functions
Fill in a buffer-info structure, *view*, correctly for an exporter that can
only share a contiguous chunk of memory of "unsigned bytes" of the given
- length. Return 0 on success and -1 (with raising an error) on error.
+ length. Return ``0`` on success and ``-1`` (with raising an error) on error.
MemoryView objects
diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst
index 6f6250f6..fd4279cd 100644
--- a/Doc/c-api/capsule.rst
+++ b/Doc/c-api/capsule.rst
@@ -9,6 +9,8 @@ Capsules
Refer to :ref:`using-capsules` for more information on using these objects.
+.. versionadded:: 2.7
+
.. c:type:: PyCapsule
@@ -19,6 +21,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
regular import mechanism can be used to access C APIs defined in dynamically
loaded modules.
+
.. c:type:: PyCapsule_Destructor
The type of a destructor callback for a capsule. Defined as::
@@ -104,8 +107,8 @@ Refer to :ref:`using-capsules` for more information on using these objects.
import the module conventionally (using :c:func:`PyImport_ImportModule`).
Return the capsule's internal *pointer* on success. On failure, set an
- exception and return *NULL*. However, if :c:func:`PyCapsule_Import` failed to
- import the module, and *no_block* was true, no exception is set.
+ exception and return *NULL*.
+
.. c:function:: int PyCapsule_IsValid(PyObject *capsule, const char *name)
@@ -120,19 +123,22 @@ Refer to :ref:`using-capsules` for more information on using these objects.
guaranteed to succeed.
Return a nonzero value if the object is valid and matches the name passed in.
- Return 0 otherwise. This function will not fail.
+ Return ``0`` otherwise. This function will not fail.
+
.. c:function:: int PyCapsule_SetContext(PyObject *capsule, void *context)
Set the context pointer inside *capsule* to *context*.
- Return 0 on success. Return nonzero and set an exception on failure.
+ Return ``0`` on success. Return nonzero and set an exception on failure.
+
.. c:function:: int PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor)
Set the destructor inside *capsule* to *destructor*.
- Return 0 on success. Return nonzero and set an exception on failure.
+ Return ``0`` on success. Return nonzero and set an exception on failure.
+
.. c:function:: int PyCapsule_SetName(PyObject *capsule, const char *name)
@@ -140,11 +146,12 @@ Refer to :ref:`using-capsules` for more information on using these objects.
outlive the capsule. If the previous *name* stored in the capsule was not
*NULL*, no attempt is made to free it.
- Return 0 on success. Return nonzero and set an exception on failure.
+ Return ``0`` on success. Return nonzero and set an exception on failure.
+
.. c:function:: int PyCapsule_SetPointer(PyObject *capsule, void *pointer)
Set the void pointer inside *capsule* to *pointer*. The pointer may not be
*NULL*.
- Return 0 on success. Return nonzero and set an exception on failure.
+ Return ``0`` on success. Return nonzero and set an exception on failure.
diff --git a/Doc/c-api/class.rst b/Doc/c-api/class.rst
index 4dbe508e..020309d6 100644
--- a/Doc/c-api/class.rst
+++ b/Doc/c-api/class.rst
@@ -61,5 +61,5 @@ There are very few functions specific to instance objects.
Create a new instance of a specific class without calling its constructor.
*class* is the class of new object. The *dict* parameter will be used as the
- object's :attr:`__dict__`; if *NULL*, a new dictionary will be created for the
+ object's :attr:`~object.__dict__`; if *NULL*, a new dictionary will be created for the
instance.
diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst
index 7d9b4b6c..946ad6e2 100644
--- a/Doc/c-api/code.rst
+++ b/Doc/c-api/code.rst
@@ -2,15 +2,13 @@
.. _codeobjects:
+.. index:: object; code, code object
+
Code Objects
------------
.. sectionauthor:: Jeffrey Yasskin
-
-.. index::
- object: code
-
Code objects are a low-level detail of the CPython implementation.
Each one represents a chunk of executable code that hasn't yet been
bound into a function.
@@ -29,7 +27,7 @@ bound into a function.
.. c:function:: int PyCode_Check(PyObject *co)
- Return true if *co* is a :class:`code` object
+ Return true if *co* is a :class:`code` object.
.. c:function:: int PyCode_GetNumFree(PyObject *co)
diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst
index b987469a..4b4d156e 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -126,7 +126,7 @@ The following functions provide locale-independent string to number conversions.
*format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``,
``'g'``, ``'G'`` or ``'r'``. For ``'r'``, the supplied *precision*
- must be 0 and is ignored. The ``'r'`` format code specifies the
+ must be ``0`` and is ignored. The ``'r'`` format code specifies the
standard :func:`repr` format.
*flags* can be zero or more of the values *Py_DTSF_SIGN*,
diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst
index 3e967bdc..3006b6cf 100644
--- a/Doc/c-api/dict.rst
+++ b/Doc/c-api/dict.rst
@@ -210,8 +210,11 @@ Dictionary Objects
.. c:function:: int PyDict_Update(PyObject *a, PyObject *b)
- This is the same as ``PyDict_Merge(a, b, 1)`` in C, or ``a.update(b)`` in
- Python. Return ``0`` on success or ``-1`` if an exception was raised.
+ This is the same as ``PyDict_Merge(a, b, 1)`` in C, and is similar to
+ ``a.update(b)`` in Python except that :c:func:`PyDict_Update` doesn't fall
+ back to the iterating over a sequence of key value pairs if the second
+ argument has no "keys" attribute. Return ``0`` on success or ``-1`` if an
+ exception was raised.
.. versionadded:: 2.2
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 91964d05..281e4c84 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -44,8 +44,12 @@ is a separate error indicator for each thread.
.. c:function:: void PyErr_PrintEx(int set_sys_last_vars)
Print a standard traceback to ``sys.stderr`` and clear the error indicator.
- Call this function only when the error indicator is set. (Otherwise it will
- cause a fatal error!)
+ **Unless** the error is a ``SystemExit``. In that case the no traceback
+ is printed and Python process will exit with the error code specified by
+ the ``SystemExit`` instance.
+
+ Call this function **only** when the error indicator is set. Otherwise it
+ will cause a fatal error!
If *set_sys_last_vars* is nonzero, the variables :data:`sys.last_type`,
:data:`sys.last_value` and :data:`sys.last_traceback` will be set to the
@@ -70,7 +74,7 @@ is a separate error indicator for each thread.
Do not compare the return value to a specific exception; use
:c:func:`PyErr_ExceptionMatches` instead, shown below. (The comparison could
easily fail since the exception may be an instance instead of a class, in the
- case of a class exception, or it may the a subclass of the expected exception.)
+ case of a class exception, or it may be a subclass of the expected exception.)
.. c:function:: int PyErr_ExceptionMatches(PyObject *exc)
@@ -286,16 +290,11 @@ is a separate error indicator for each thread.
exception handling (for example, :c:func:`Py_DECREF` owned references and return
an error value).
- Warning categories must be subclasses of :c:data:`Warning`; the default warning
- category is :c:data:`RuntimeWarning`. The standard Python warning categories are
- available as global variables whose names are ``PyExc_`` followed by the Python
- exception name. These have the type :c:type:`PyObject\*`; they are all class
- objects. Their names are :c:data:`PyExc_Warning`, :c:data:`PyExc_UserWarning`,
- :c:data:`PyExc_UnicodeWarning`, :c:data:`PyExc_DeprecationWarning`,
- :c:data:`PyExc_SyntaxWarning`, :c:data:`PyExc_RuntimeWarning`, and
- :c:data:`PyExc_FutureWarning`. :c:data:`PyExc_Warning` is a subclass of
- :c:data:`PyExc_Exception`; the other warning categories are subclasses of
- :c:data:`PyExc_Warning`.
+ Warning categories must be subclasses of :c:data:`PyExc_Warning`;
+ :c:data:`PyExc_Warning` is a subclass of :c:data:`PyExc_Exception`;
+ the default warning category is :c:data:`PyExc_RuntimeWarning`. The standard
+ Python warning categories are available as global variables whose names are
+ enumerated at :ref:`standardwarningcategories`.
For information about warning control, see the documentation for the
:mod:`warnings` module and the :option:`-W` option in the command line
@@ -404,8 +403,8 @@ is a separate error indicator for each thread.
:meth:`__del__` method.
The function is called with a single argument *obj* that identifies the context
- in which the unraisable exception occurred. The repr of *obj* will be printed in
- the warning message.
+ in which the unraisable exception occurred. If possible,
+ the repr of *obj* will be printed in the warning message.
.. _unicodeexceptions:
@@ -493,7 +492,7 @@ level, both in the core and in extension modules. They are needed if the
recursive code does not necessarily invoke Python code (which tracks its
recursion depth automatically).
-.. c:function:: int Py_EnterRecursiveCall(char *where)
+.. c:function:: int Py_EnterRecursiveCall(const char *where)
Marks a point where a recursive C-level call is about to be performed.
@@ -525,84 +524,25 @@ All standard Python exceptions are available as global variables whose names are
:c:type:`PyObject\*`; they are all class objects. For completeness, here are all
the variables:
-+-------------------------------------+----------------------------+----------+
-| C Name | Python Name | Notes |
-+=====================================+============================+==========+
-| :c:data:`PyExc_BaseException` | :exc:`BaseException` | (1), (4) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_Exception` | :exc:`Exception` | \(1) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_StandardError` | :exc:`StandardError` | \(1) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_AssertionError` | :exc:`AssertionError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_AttributeError` | :exc:`AttributeError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_EOFError` | :exc:`EOFError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_EnvironmentError` | :exc:`EnvironmentError` | \(1) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_FloatingPointError` | :exc:`FloatingPointError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_IOError` | :exc:`IOError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_ImportError` | :exc:`ImportError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_IndexError` | :exc:`IndexError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_KeyError` | :exc:`KeyError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_MemoryError` | :exc:`MemoryError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_NameError` | :exc:`NameError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_OSError` | :exc:`OSError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_OverflowError` | :exc:`OverflowError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_SyntaxError` | :exc:`SyntaxError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_SystemError` | :exc:`SystemError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_SystemExit` | :exc:`SystemExit` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_TypeError` | :exc:`TypeError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_ValueError` | :exc:`ValueError` | |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_WindowsError` | :exc:`WindowsError` | \(3) |
-+-------------------------------------+----------------------------+----------+
-| :c:data:`PyExc_ZeroDivisionError` | :exc:`ZeroDivisionError` | |
-+-------------------------------------+----------------------------+----------+
-
.. index::
single: PyExc_BaseException
single: PyExc_Exception
single: PyExc_StandardError
single: PyExc_ArithmeticError
- single: PyExc_LookupError
single: PyExc_AssertionError
single: PyExc_AttributeError
- single: PyExc_EOFError
+ single: PyExc_BufferError
single: PyExc_EnvironmentError
+ single: PyExc_EOFError
single: PyExc_FloatingPointError
- single: PyExc_IOError
+ single: PyExc_GeneratorExit
single: PyExc_ImportError
+ single: PyExc_IndentationError
single: PyExc_IndexError
+ single: PyExc_IOError
single: PyExc_KeyError
single: PyExc_KeyboardInterrupt
+ single: PyExc_LookupError
single: PyExc_MemoryError
single: PyExc_NameError
single: PyExc_NotImplementedError
@@ -610,14 +550,106 @@ the variables:
single: PyExc_OverflowError
single: PyExc_ReferenceError
single: PyExc_RuntimeError
+ single: PyExc_StopIteration
single: PyExc_SyntaxError
single: PyExc_SystemError
single: PyExc_SystemExit
+ single: PyExc_TabError
single: PyExc_TypeError
+ single: PyExc_UnboundLocalError
+ single: PyExc_UnicodeDecodeError
+ single: PyExc_UnicodeEncodeError
+ single: PyExc_UnicodeError
+ single: PyExc_UnicodeTranslateError
+ single: PyExc_VMSError
single: PyExc_ValueError
single: PyExc_WindowsError
single: PyExc_ZeroDivisionError
++-----------------------------------------+---------------------------------+----------+
+| C Name | Python Name | Notes |
++=========================================+=================================+==========+
+| :c:data:`PyExc_BaseException` | :exc:`BaseException` | (1), (4) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_Exception` | :exc:`Exception` | \(1) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_StandardError` | :exc:`StandardError` | \(1) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_AssertionError` | :exc:`AssertionError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_AttributeError` | :exc:`AttributeError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_BufferError` | :exc:`BufferError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_EnvironmentError` | :exc:`EnvironmentError` | \(1) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_EOFError` | :exc:`EOFError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_FloatingPointError` | :exc:`FloatingPointError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_GeneratorExit` | :exc:`GeneratorExit` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_ImportError` | :exc:`ImportError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_IndentationError` | :exc:`IndentationError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_IndexError` | :exc:`IndexError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_IOError` | :exc:`IOError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_KeyError` | :exc:`KeyError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_MemoryError` | :exc:`MemoryError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_NameError` | :exc:`NameError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_OSError` | :exc:`OSError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_OverflowError` | :exc:`OverflowError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_StopIteration` | :exc:`StopIteration` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_SyntaxError` | :exc:`SyntaxError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_SystemError` | :exc:`SystemError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_SystemExit` | :exc:`SystemExit` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_TabError` | :exc:`TabError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_TypeError` | :exc:`TypeError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_UnboundLocalError` | :exc:`UnboundLocalError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_UnicodeDecodeError` | :exc:`UnicodeDecodeError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_UnicodeEncodeError` | :exc:`UnicodeEncodeError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_UnicodeError` | :exc:`UnicodeError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_UnicodeTranslateError` | :exc:`UnicodeTranslateError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_VMSError` | :exc:`VMSError` | \(5) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_ValueError` | :exc:`ValueError` | |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_WindowsError` | :exc:`WindowsError` | \(3) |
++-----------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_ZeroDivisionError` | :exc:`ZeroDivisionError` | |
++-----------------------------------------+---------------------------------+----------+
+
Notes:
(1)
@@ -633,6 +665,60 @@ Notes:
(4)
.. versionadded:: 2.5
+(5)
+ Only defined on VMS; protect code that uses this by testing that the
+ preprocessor macro ``__VMS`` is defined.
+
+.. _standardwarningcategories:
+
+Standard Warning Categories
+===========================
+
+All standard Python warning categories are available as global variables whose
+names are ``PyExc_`` followed by the Python exception name. These have the type
+:c:type:`PyObject\*`; they are all class objects. For completeness, here are all
+the variables:
+
+.. index::
+ single: PyExc_Warning
+ single: PyExc_BytesWarning
+ single: PyExc_DeprecationWarning
+ single: PyExc_FutureWarning
+ single: PyExc_ImportWarning
+ single: PyExc_PendingDeprecationWarning
+ single: PyExc_RuntimeWarning
+ single: PyExc_SyntaxWarning
+ single: PyExc_UnicodeWarning
+ single: PyExc_UserWarning
+
++------------------------------------------+---------------------------------+----------+
+| C Name | Python Name | Notes |
++==========================================+=================================+==========+
+| :c:data:`PyExc_Warning` | :exc:`Warning` | \(1) |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_BytesWarning` | :exc:`BytesWarning` | |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_DeprecationWarning` | :exc:`DeprecationWarning` | |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_FutureWarning` | :exc:`FutureWarning` | |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_ImportWarning` | :exc:`ImportWarning` | |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_PendingDeprecationWarning`| :exc:`PendingDeprecationWarning`| |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_RuntimeWarning` | :exc:`RuntimeWarning` | |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_SyntaxWarning` | :exc:`SyntaxWarning` | |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_UnicodeWarning` | :exc:`UnicodeWarning` | |
++------------------------------------------+---------------------------------+----------+
+| :c:data:`PyExc_UserWarning` | :exc:`UserWarning` | |
++------------------------------------------+---------------------------------+----------+
+
+Notes:
+
+(1)
+ This is a base class for other standard warning categories.
String Exceptions
=================
@@ -640,4 +726,3 @@ String Exceptions
.. versionchanged:: 2.6
All exceptions to be raised or caught must be derived from :exc:`BaseException`.
Trying to raise a string exception now raises :exc:`TypeError`.
-
diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst
index bbd42236..e8bc6bf5 100644
--- a/Doc/c-api/file.rst
+++ b/Doc/c-api/file.rst
@@ -136,7 +136,7 @@ change in future releases of Python.
.. c:function:: int PyFile_SetEncoding(PyFileObject *p, const char *enc)
- Set the file's encoding for Unicode output to *enc*. Return 1 on success and 0
+ Set the file's encoding for Unicode output to *enc*. Return ``1`` on success and ``0``
on failure.
.. versionadded:: 2.3
@@ -145,7 +145,7 @@ change in future releases of Python.
.. c:function:: int PyFile_SetEncodingAndErrors(PyFileObject *p, const char *enc, *errors)
Set the file's encoding for Unicode output to *enc*, and its error
- mode to *err*. Return 1 on success and 0 on failure.
+ mode to *err*. Return ``1`` on success and ``0`` on failure.
.. versionadded:: 2.6
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index b0a2d5c0..18ecd071 100644
--- a/Doc/c-api/gcsupport.rst
+++ b/Doc/c-api/gcsupport.rst
@@ -56,7 +56,7 @@ Constructors for container types must conform to two rules:
.. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)
Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the
- resized object or *NULL* on failure.
+ resized object or *NULL* on failure. *op* must not be tracked by the collector yet.
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *newsize*. This might
@@ -137,9 +137,10 @@ must name its arguments exactly *visit* and *arg*:
.. c:function:: void Py_VISIT(PyObject *o)
- Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns
- a non-zero value, then return it. Using this macro, :c:member:`~PyTypeObject.tp_traverse`
- handlers look like::
+ If *o* is not *NULL*, call the *visit* callback, with arguments *o*
+ and *arg*. If *visit* returns a non-zero value, then return it.
+ Using this macro, :c:member:`~PyTypeObject.tp_traverse` handlers
+ look like::
static int
my_traverse(Noddy *self, visitproc visit, void *arg)
diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst
index 33cd27a5..0c851a75 100644
--- a/Doc/c-api/gen.rst
+++ b/Doc/c-api/gen.rst
@@ -17,7 +17,7 @@ than explicitly calling :c:func:`PyGen_New`.
.. c:var:: PyTypeObject PyGen_Type
- The type object corresponding to generator objects
+ The type object corresponding to generator objects.
.. c:function:: int PyGen_Check(ob)
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index 6f5678c9..f0ea2277 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -66,7 +66,7 @@ Importing Modules
.. versionchanged:: 2.6
The function is an alias for :c:func:`PyImport_ImportModuleLevel` with
- -1 as level, meaning relative import.
+ ``-1`` as level, meaning relative import.
.. c:function:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 7a6b0a6a..229cae52 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -43,8 +43,8 @@ Initializing and finalizing the interpreter
.. c:function:: void Py_InitializeEx(int initsigs)
- This function works like :c:func:`Py_Initialize` if *initsigs* is 1. If
- *initsigs* is 0, it skips initialization registration of signal handlers, which
+ This function works like :c:func:`Py_Initialize` if *initsigs* is ``1``. If
+ *initsigs* is ``0``, it skips initialization registration of signal handlers, which
might be useful when Python is embedded.
.. versionadded:: 2.4
@@ -295,9 +295,9 @@ Process-wide parameters
.. note::
It is recommended that applications embedding the Python interpreter
- for purposes other than executing a single script pass 0 as *updatepath*,
+ for purposes other than executing a single script pass ``0`` as *updatepath*,
and update :data:`sys.path` themselves if desired.
- See `CVE-2008-5983 `_.
+ See `CVE-2008-5983 `_.
On versions before 2.6.6, you can achieve the same effect by manually
popping the first :data:`sys.path` element after having called
@@ -307,13 +307,13 @@ Process-wide parameters
.. versionadded:: 2.6.6
- .. XXX impl. doesn't seem consistent in allowing 0/NULL for the params;
+ .. XXX impl. doesn't seem consistent in allowing ``0``/``NULL`` for the params;
check w/ Guido.
.. c:function:: void PySys_SetArgv(int argc, char **argv)
- This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set to 1.
+ This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set to ``1``.
.. c:function:: void Py_SetPythonHome(char *home)
@@ -534,6 +534,7 @@ code, or when embedding the Python interpreter:
.. index:: module: thread
.. note::
+
When only the main thread exists, no GIL operations are needed. This is a
common situation (most Python programs do not use threads), and the lock
operations slow the interpreter down a bit. Therefore, the lock is not
@@ -641,7 +642,7 @@ with sub-interpreters:
.. versionadded:: 2.3
-.. c:function:: PyThreadState PyGILState_GetThisThreadState()
+.. c:function:: PyThreadState* PyGILState_GetThisThreadState()
Get the current thread state for this thread. May return ``NULL`` if no
GILState API has been used on the current thread. Note that the main thread
@@ -916,8 +917,8 @@ pointer and a void pointer argument.
.. index:: single: Py_AddPendingCall()
Schedule a function to be called from the main interpreter thread. On
- success, 0 is returned and *func* is queued for being called in the
- main thread. On failure, -1 is returned without setting any exception.
+ success, ``0`` is returned and *func* is queued for being called in the
+ main thread. On failure, ``-1`` is returned without setting any exception.
When successfully queued, *func* will be *eventually* called from the
main interpreter thread with the argument *arg*. It will be called
@@ -928,7 +929,7 @@ pointer and a void pointer argument.
* with the main thread holding the :term:`global interpreter lock`
(*func* can therefore use the full C API).
- *func* must return 0 on success, or -1 on failure with an exception
+ *func* must return ``0`` on success, or ``-1`` on failure with an exception
set. *func* won't be interrupted to perform another asynchronous
notification recursively, but it can still be interrupted to switch
threads if the global interpreter lock is released.
@@ -982,12 +983,12 @@ in previous versions.
+------------------------------+--------------------------------------+
| Value of *what* | Meaning of *arg* |
+==============================+======================================+
- | :const:`PyTrace_CALL` | Always *NULL*. |
+ | :const:`PyTrace_CALL` | Always :c:data:`Py_None`. |
+------------------------------+--------------------------------------+
| :const:`PyTrace_EXCEPTION` | Exception information as returned by |
| | :func:`sys.exc_info`. |
+------------------------------+--------------------------------------+
- | :const:`PyTrace_LINE` | Always *NULL*. |
+ | :const:`PyTrace_LINE` | Always :c:data:`Py_None`. |
+------------------------------+--------------------------------------+
| :const:`PyTrace_RETURN` | Value being returned to the caller, |
| | or *NULL* if caused by an exception. |
@@ -1029,7 +1030,7 @@ in previous versions.
.. c:var:: int PyTrace_RETURN
The value for the *what* parameter to :c:type:`Py_tracefunc` functions when a
- call is returning without propagating an exception.
+ call is about to return.
.. c:var:: int PyTrace_C_CALL
@@ -1056,15 +1057,19 @@ in previous versions.
function as its first parameter, and may be any Python object, or *NULL*. If
the profile function needs to maintain state, using a different value for *obj*
for each thread provides a convenient and thread-safe place to store it. The
- profile function is called for all monitored events except the line-number
- events.
+ profile function is called for all monitored events except :const:`PyTrace_LINE`
+ and :const:`PyTrace_EXCEPTION`.
.. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)
Set the tracing function to *func*. This is similar to
:c:func:`PyEval_SetProfile`, except the tracing function does receive line-number
- events.
+ events and does not receive any event related to C function objects being called. Any
+ trace function registered using :c:func:`PyEval_SetTrace` will not receive
+ :const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION` or :const:`PyTrace_C_RETURN`
+ as a value for the *what* parameter.
+
.. c:function:: PyObject* PyEval_GetCallStats(PyObject *self)
@@ -1135,7 +1140,7 @@ These functions are only intended to be used by advanced debugging tools.
.. c:function:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp)
- Return the a pointer to the first :c:type:`PyThreadState` object in the list of
+ Return the pointer to the first :c:type:`PyThreadState` object in the list of
threads associated with the interpreter *interp*.
.. versionadded:: 2.2
diff --git a/Doc/c-api/int.rst b/Doc/c-api/int.rst
index 254219cc..b2c5a448 100644
--- a/Doc/c-api/int.rst
+++ b/Doc/c-api/int.rst
@@ -88,7 +88,7 @@ Plain Integer Objects
Will first attempt to cast the object to a :c:type:`PyIntObject`, if it is not
already one, and then return its value. If there is an error, ``-1`` is
returned, and the caller should check ``PyErr_Occurred()`` to find out whether
- there was an error, or whether the value just happened to be -1.
+ there was an error, or whether the value just happened to be ``-1``.
.. c:function:: long PyInt_AS_LONG(PyObject *io)
diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst
index 6414277c..fa2d9f06 100644
--- a/Doc/c-api/intro.rst
+++ b/Doc/c-api/intro.rst
@@ -258,7 +258,7 @@ sets all items of a list (actually, any mutable sequence) to a given item::
if (PyObject_SetItem(target, index, item) < 0) {
Py_DECREF(index);
return -1;
- }
+ }
Py_DECREF(index);
}
return 0;
diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst
index 8d1567c7..4f708829 100644
--- a/Doc/c-api/iter.rst
+++ b/Doc/c-api/iter.rst
@@ -14,6 +14,10 @@ There are two functions specifically for working with iterators.
Return true if the object *o* supports the iterator protocol.
+ This function can return a false positive in the case of old-style
+ classes because those classes always define a :c:member:`tp_iternext`
+ slot with logic that either invokes a :meth:`next` method or raises
+ a :exc:`TypeError`.
.. c:function:: PyObject* PyIter_Next(PyObject *o)
@@ -32,7 +36,7 @@ something like this::
/* propagate error */
}
- while (item = PyIter_Next(iterator)) {
+ while ((item = PyIter_Next(iterator))) {
/* do something with item */
...
/* release reference when done */
diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst
index 0aed0f3e..c28d6b0c 100644
--- a/Doc/c-api/list.rst
+++ b/Doc/c-api/list.rst
@@ -76,9 +76,9 @@ List Objects
.. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)
Return the object at position *index* in the list pointed to by *list*. The
- position must be positive, indexing from the end of the list is not
- supported. If *index* is out of bounds, return *NULL* and set an
- :exc:`IndexError` exception.
+ position must be non-negative; indexing from the end of the list is not
+ supported. If *index* is out of bounds (<0 or >=len(list)),
+ return *NULL* and set an :exc:`IndexError` exception.
.. versionchanged:: 2.5
This function used an :c:type:`int` for *index*. This might require
@@ -96,8 +96,9 @@ List Objects
.. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
- Set the item at index *index* in list to *item*. Return ``0`` on success
- or ``-1`` on failure.
+ Set the item at index *index* in list to *item*. Return ``0`` on success.
+ If *index* is out of bounds, return ``-1`` and set an :exc:`IndexError`
+ exception.
.. note::
@@ -148,8 +149,7 @@ List Objects
Return a list of the objects in *list* containing the objects *between* *low*
and *high*. Return *NULL* and set an exception if unsuccessful. Analogous
- to ``list[low:high]``. Negative indices, as when slicing from Python, are not
- supported.
+ to ``list[low:high]``. Indexing from the end of the list is not supported.
.. versionchanged:: 2.5
This function used an :c:type:`int` for *low* and *high*. This might
@@ -161,8 +161,8 @@ List Objects
Set the slice of *list* between *low* and *high* to the contents of
*itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may
be *NULL*, indicating the assignment of an empty list (slice deletion).
- Return ``0`` on success, ``-1`` on failure. Negative indices, as when
- slicing from Python, are not supported.
+ Return ``0`` on success, ``-1`` on failure. Indexing from the end of the
+ list is not supported.
.. versionchanged:: 2.5
This function used an :c:type:`int` for *low* and *high*. This might
diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst
index 5a8e51dc..4684d1b9 100644
--- a/Doc/c-api/long.rst
+++ b/Doc/c-api/long.rst
@@ -65,22 +65,6 @@ Long Integer Objects
.. versionadded:: 2.6
-.. c:function:: PyObject* PyLong_FromSsize_t(Py_ssize_t v)
-
- Return a new :c:type:`PyLongObject` object with a value of *v*, or *NULL*
- on failure.
-
- .. versionadded:: 2.6
-
-
-.. c:function:: PyObject* PyLong_FromSize_t(size_t v)
-
- Return a new :c:type:`PyLongObject` object with a value of *v*, or *NULL*
- on failure.
-
- .. versionadded:: 2.6
-
-
.. c:function:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v)
Return a new :c:type:`PyLongObject` object from a C :c:type:`long long`, or *NULL*
@@ -199,18 +183,6 @@ Long Integer Objects
raised.
-.. c:function:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)
-
- .. index::
- single: PY_SSIZE_T_MAX
-
- Return a :c:type:`Py_ssize_t` representation of the contents of *pylong*. If
- *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is
- raised.
-
- .. versionadded:: 2.6
-
-
.. c:function:: PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong)
.. index::
@@ -245,6 +217,9 @@ Long Integer Objects
Return a C :c:type:`unsigned long` from a Python long integer, without checking
for overflow.
+ Returns ``(unsigned long)-1`` on error. Use :c:func:`PyErr_Occurred` to
+ disambiguate.
+
.. versionadded:: 2.3
@@ -253,6 +228,9 @@ Long Integer Objects
Return a C :c:type:`unsigned long long` from a Python long integer, without
checking for overflow.
+ Returns ``(unsigned PY_LONG_LONG)-1`` on error. Use
+ :c:func:`PyErr_Occurred` to disambiguate.
+
.. versionadded:: 2.3
diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst
index b82cc96b..76120aef 100644
--- a/Doc/c-api/marshal.rst
+++ b/Doc/c-api/marshal.rst
@@ -13,8 +13,8 @@ binary mode.
Numeric values are stored with the least significant byte first.
-The module supports two versions of the data format: version 0 is the
-historical version, version 1 (new in Python 2.4) shares interned strings in
+The module supports two versions of the data format: version ``0`` is the
+historical version, version ``1`` (new in Python 2.4) shares interned strings in
the file, and upon unmarshalling. Version 2 (new in Python 2.5) uses a binary
format for floating point numbers. *Py_MARSHAL_VERSION* indicates the current
file format (currently 2).
diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst
index 54655719..2b9fb736 100644
--- a/Doc/c-api/memory.rst
+++ b/Doc/c-api/memory.rst
@@ -35,7 +35,7 @@ operate within the bounds of the private heap.
It is important to understand that the management of the Python heap is
performed by the interpreter itself and that the user has no control over it,
-even if she regularly manipulates object pointers to memory blocks inside that
+even if they regularly manipulate object pointers to memory blocks inside that
heap. The allocation of heap space for Python objects and other internal
buffers is performed on demand by the Python memory manager through the Python/C
API functions listed in this document.
@@ -155,6 +155,88 @@ versions and is therefore deprecated in extension modules.
:c:func:`PyMem_NEW`, :c:func:`PyMem_RESIZE`, :c:func:`PyMem_DEL`.
+Object allocators
+=================
+
+The following function sets, modeled after the ANSI C standard, but specifying
+behavior when requesting zero bytes, are available for allocating and releasing
+memory from the Python heap.
+
+By default, these functions use :ref:`pymalloc memory allocator `.
+
+.. warning::
+
+ The :term:`GIL ` must be held when using these
+ functions.
+
+.. c:function:: void* PyObject_Malloc(size_t n)
+
+ Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
+ allocated memory, or *NULL* if the request fails.
+
+ Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as
+ if ``PyObject_Malloc(1)`` had been called instead. The memory will not have
+ been initialized in any way.
+
+
+.. c:function:: void* PyObject_Realloc(void *p, size_t n)
+
+ Resizes the memory block pointed to by *p* to *n* bytes. The contents will be
+ unchanged to the minimum of the old and the new sizes.
+
+ If *p* is *NULL*, the call is equivalent to ``PyObject_Malloc(n)``; else if *n*
+ is equal to zero, the memory block is resized but is not freed, and the
+ returned pointer is non-*NULL*.
+
+ Unless *p* is *NULL*, it must have been returned by a previous call to
+ :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc` or :c:func:`PyObject_Calloc`.
+
+ If the request fails, :c:func:`PyObject_Realloc` returns *NULL* and *p* remains
+ a valid pointer to the previous memory area.
+
+
+.. c:function:: void PyObject_Free(void *p)
+
+ Frees the memory block pointed to by *p*, which must have been returned by a
+ previous call to :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc` or
+ :c:func:`PyObject_Calloc`. Otherwise, or if ``PyObject_Free(p)`` has been called
+ before, undefined behavior occurs.
+
+ If *p* is *NULL*, no operation is performed.
+
+
+In addition, the following macro sets are provided:
+
+* :c:func:`PyObject_MALLOC`: alias to :c:func:`PyObject_Malloc`
+* :c:func:`PyObject_REALLOC`: alias to :c:func:`PyObject_Realloc`
+* :c:func:`PyObject_FREE`: alias to :c:func:`PyObject_Free`
+* :c:func:`PyObject_Del`: alias to :c:func:`PyObject_Free`
+* :c:func:`PyObject_DEL`: alias to :c:func:`PyObject_FREE` (so finally an alias
+ to :c:func:`PyObject_Free`)
+
+
+.. _pymalloc:
+
+The pymalloc allocator
+======================
+
+Python has a *pymalloc* allocator optimized for small objects (smaller or equal
+to 512 bytes) with a short lifetime. It uses memory mappings called "arenas"
+with a fixed size of 256 KiB. It falls back to :c:func:`malloc` and
+:c:func:`realloc` for allocations larger than 512 bytes.
+
+*pymalloc* is the default allocator of :c:func:`PyObject_Malloc`.
+
+The arena allocator uses the following functions:
+
+* :c:func:`mmap` and :c:func:`munmap` if available,
+* :c:func:`malloc` and :c:func:`free` otherwise.
+
+.. versionchanged:: 2.7.7
+ The threshold changed from 256 to 512 bytes. The arena allocator now
+ uses :c:func:`mmap` if available.
+
+
.. _memoryexamples:
Examples
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index 56e63cf8..80e12e1d 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -51,10 +51,10 @@ There are only a few functions special to module objects.
.. index:: single: __dict__ (module attribute)
Return the dictionary object that implements *module*'s namespace; this object
- is the same as the :attr:`__dict__` attribute of the module object. This
+ is the same as the :attr:`~object.__dict__` attribute of the module object. This
function never fails. It is recommended extensions use other
:c:func:`PyModule_\*` and :c:func:`PyObject_\*` functions rather than directly
- manipulate a module's :attr:`__dict__`.
+ manipulate a module's :attr:`~object.__dict__`.
.. c:function:: char* PyModule_GetName(PyObject *module)
diff --git a/Doc/c-api/none.rst b/Doc/c-api/none.rst
index aeaca971..f8909b98 100644
--- a/Doc/c-api/none.rst
+++ b/Doc/c-api/none.rst
@@ -2,8 +2,8 @@
.. _noneobject:
-The None Object
----------------
+The ``None`` Object
+-------------------
.. index:: object: None
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
index 75b73416..39f0e78d 100644
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -316,7 +316,7 @@ Number Protocol
.. c:function:: int PyIndex_Check(PyObject *o)
- Returns True if *o* is an index integer (has the nb_index slot of the
- tp_as_number structure filled in).
+ Returns ``1`` if *o* is an index integer (has the nb_index slot of the
+ tp_as_number structure filled in), and ``0`` otherwise.
.. versionadded:: 2.5
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index 50b83e90..295a1290 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -55,25 +55,35 @@ Object Protocol
.. c:function:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)
Set the value of the attribute named *attr_name*, for object *o*, to the value
- *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement
+ *v*. Raise an exception and return ``-1`` on failure;
+ return ``0`` on success. This is the equivalent of the Python statement
``o.attr_name = v``.
+ If *v* is *NULL*, the attribute is deleted, however this feature is
+ deprecated in favour of using :c:func:`PyObject_DelAttr`.
+
.. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
Set the value of the attribute named *attr_name*, for object *o*, to the value
- *v*. Returns ``-1`` on failure. This is the equivalent of the Python statement
+ *v*. Raise an exception and return ``-1`` on failure;
+ return ``0`` on success. This is the equivalent of the Python statement
``o.attr_name = v``.
+ If *v* is *NULL*, the attribute is deleted, however this feature is
+ deprecated in favour of using :c:func:`PyObject_DelAttrString`.
+
.. c:function:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)
- Generic attribute setter function that is meant to be put into a type
- object's ``tp_setattro`` slot. It looks for a data descriptor in the
+ Generic attribute setter and deleter function that is meant
+ to be put into a type object's :c:member:`~PyTypeObject.tp_setattro`
+ slot. It looks for a data descriptor in the
dictionary of classes in the object's MRO, and if found it takes preference
- over setting the attribute in the instance dictionary. Otherwise, the
- attribute is set in the object's :attr:`~object.__dict__` (if present).
- Otherwise, an :exc:`AttributeError` is raised and ``-1`` is returned.
+ over setting or deleting the attribute in the instance dictionary. Otherwise, the
+ attribute is set or deleted in the object's :attr:`~object.__dict__` (if present).
+ On success, ``0`` is returned, otherwise an :exc:`AttributeError`
+ is raised and ``-1`` is returned.
.. c:function:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name)
@@ -157,7 +167,7 @@ Object Protocol
.. index:: builtin: bytes
- Compute a bytes representation of object *o*. In 2.x, this is just a alias
+ Compute a bytes representation of object *o*. In 2.x, this is just an alias
for :c:func:`PyObject_Str`.
@@ -367,7 +377,8 @@ attribute is considered sufficient for this determination.
.. c:function:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)
- Map the object *key* to the value *v*. Returns ``-1`` on failure. This is the
+ Map the object *key* to the value *v*. Raise an exception and
+ return ``-1`` on failure; return ``0`` on success. This is the
equivalent of the Python statement ``o[key] = v``.
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index 2b668a5d..d95ef239 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -17,9 +17,8 @@ Sequence Protocol
.. index:: builtin: len
- Returns the number of objects in sequence *o* on success, and ``-1`` on failure.
- For objects that do not provide sequence protocol, this is equivalent to the
- Python expression ``len(o)``.
+ Returns the number of objects in sequence *o* on success, and ``-1`` on
+ failure. This is equivalent to the Python expression ``len(o)``.
.. versionchanged:: 2.5
These functions returned an :c:type:`int` type. This might require
@@ -82,10 +81,14 @@ Sequence Protocol
.. c:function:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v)
- Assign object *v* to the *i*\ th element of *o*. Returns ``-1`` on failure. This
+ Assign object *v* to the *i*\ th element of *o*. Raise an exception
+ and return ``-1`` on failure; return ``0`` on success. This
is the equivalent of the Python statement ``o[i] = v``. This function *does
not* steal a reference to *v*.
+ If *v* is *NULL*, the element is deleted, however this feature is
+ deprecated in favour of using :c:func:`PySequence_DelItem`.
+
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *i*. This might require
changes in your code for properly supporting 64-bit systems.
@@ -104,7 +107,11 @@ Sequence Protocol
.. c:function:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v)
Assign the sequence object *v* to the slice in sequence object *o* from *i1* to
- *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``.
+ *i2*. Raise an exception and return ``-1`` on failure; return ``0`` on success.
+ This is the equivalent of the Python statement ``o[i1:i2] = v``.
+
+ If *v* is *NULL*, the slice is deleted, however this feature is
+ deprecated in favour of using :c:func:`PySequence_DelSlice`.
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *i1* and *i2*. This might
@@ -167,10 +174,10 @@ Sequence Protocol
.. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m)
- Returns the sequence *o* as a tuple, unless it is already a tuple or list, in
- which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access the
- members of the result. Returns *NULL* on failure. If the object is not a
- sequence, raises :exc:`TypeError` with *m* as the message text.
+ Return the sequence *o* as a list, unless it is already a tuple or list, in
+ which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access
+ the members of the result. Returns *NULL* on failure. If the object is not
+ a sequence, raises :exc:`TypeError` with *m* as the message text.
.. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)
diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst
index 258530b1..8bc1c8e6 100644
--- a/Doc/c-api/set.rst
+++ b/Doc/c-api/set.rst
@@ -128,7 +128,7 @@ or :class:`frozenset` or instances of their subtypes.
.. c:function:: int PySet_Contains(PyObject *anyset, PyObject *key)
- Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike
+ Return ``1`` if found, ``0`` if not found, and ``-1`` if an error is encountered. Unlike
the Python :meth:`__contains__` method, this function does not automatically
convert unhashable sets into temporary frozensets. Raise a :exc:`TypeError` if
the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a
@@ -138,9 +138,9 @@ or :class:`frozenset` or instances of their subtypes.
.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
Add *key* to a :class:`set` instance. Does not apply to :class:`frozenset`
- instances. Return 0 on success or -1 on failure. Raise a :exc:`TypeError` if
+ instances. Return ``0`` on success or ``-1`` on failure. Raise a :exc:`TypeError` if
the *key* is unhashable. Raise a :exc:`MemoryError` if there is no room to grow.
- Raise a :exc:`SystemError` if *set* is an not an instance of :class:`set` or its
+ Raise a :exc:`SystemError` if *set* is not an instance of :class:`set` or its
subtype.
.. versionchanged:: 2.6
@@ -154,11 +154,11 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
.. c:function:: int PySet_Discard(PyObject *set, PyObject *key)
- Return 1 if found and removed, 0 if not found (no action taken), and -1 if an
+ Return ``1`` if found and removed, ``0`` if not found (no action taken), and ``-1`` if an
error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a
:exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`~set.discard`
method, this function does not automatically convert unhashable sets into
- temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is an not an
+ temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is not an
instance of :class:`set` or its subtype.
@@ -166,7 +166,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
Return a new reference to an arbitrary object in the *set*, and removes the
object from the *set*. Return *NULL* on failure. Raise :exc:`KeyError` if the
- set is empty. Raise a :exc:`SystemError` if *set* is an not an instance of
+ set is empty. Raise a :exc:`SystemError` if *set* is not an instance of
:class:`set` or its subtype.
diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst
index f74230a9..08d5b94e 100644
--- a/Doc/c-api/slice.rst
+++ b/Doc/c-api/slice.rst
@@ -34,9 +34,9 @@ Slice Objects
assuming a sequence of length *length*. Treats indices greater than
*length* as errors.
- Returns 0 on success and -1 on error with no exception set (unless one of
+ Returns ``0`` on success and ``-1`` on error with no exception set (unless one of
the indices was not :const:`None` and failed to be converted to an integer,
- in which case -1 is returned with an exception set).
+ in which case ``-1`` is returned with an exception set).
You probably do not want to use this function. If you want to use slice
objects in versions of Python prior to 2.3, you would probably do well to
@@ -57,7 +57,7 @@ Slice Objects
of bounds indices are clipped in a manner consistent with the handling of
normal slices.
- Returns 0 on success and -1 on error with exception set.
+ Returns ``0`` on success and ``-1`` on error with exception set.
.. versionadded:: 2.3
@@ -66,3 +66,14 @@ Slice Objects
:c:type:`int *` type for *start*, *stop*, *step*, and *slicelength*. This
might require changes in your code for properly supporting 64-bit
systems.
+
+
+Ellipsis Object
+---------------
+
+
+.. c:var:: PyObject *Py_Ellipsis
+
+ The Python ``Ellipsis`` object. This object has no methods. It needs to be
+ treated just like any other object with respect to reference counts. Like
+ :c:data:`Py_None` it is a singleton object.
diff --git a/Doc/c-api/string.rst b/Doc/c-api/string.rst
index 32dc274a..a8baf291 100644
--- a/Doc/c-api/string.rst
+++ b/Doc/c-api/string.rst
@@ -88,7 +88,7 @@ called with a non-string parameter.
| :attr:`%%` | *n/a* | The literal % character. |
+-------------------+---------------+--------------------------------+
| :attr:`%c` | int | A single character, |
- | | | represented as an C int. |
+ | | | represented as a C int. |
+-------------------+---------------+--------------------------------+
| :attr:`%d` | int | Exactly equivalent to |
| | | ``printf("%d")``. |
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index e31687f5..af6a8c38 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -69,6 +69,37 @@ These macros are used in the definition of :c:type:`PyObject` and
expansion varies depending on the definition of :c:macro:`Py_TRACE_REFS`.
+.. c:macro:: Py_TYPE(o)
+
+ This macro is used to access the :attr:`ob_type` member of a Python object.
+ It expands to::
+
+ (((PyObject*)(o))->ob_type)
+
+ .. versionadded:: 2.6
+
+
+.. c:macro:: Py_REFCNT(o)
+
+ This macro is used to access the :attr:`ob_refcnt` member of a Python
+ object.
+ It expands to::
+
+ (((PyObject*)(o))->ob_refcnt)
+
+ .. versionadded:: 2.6
+
+
+.. c:macro:: Py_SIZE(o)
+
+ This macro is used to access the :attr:`ob_size` member of a Python object.
+ It expands to::
+
+ (((PyVarObject*)(o))->ob_size)
+
+ .. versionadded:: 2.6
+
+
.. c:macro:: PyObject_HEAD_INIT(type)
This is a macro which expands to initialization values for a new
@@ -122,15 +153,14 @@ The :attr:`ml_meth` is a C function pointer. The functions may be of different
types, but they always return :c:type:`PyObject\*`. If the function is not of
the :c:type:`PyCFunction`, the compiler will require a cast in the method table.
Even though :c:type:`PyCFunction` defines the first parameter as
-:c:type:`PyObject\*`, it is common that the method implementation uses a the
+:c:type:`PyObject\*`, it is common that the method implementation uses the
specific C type of the *self* object.
The :attr:`ml_flags` field is a bitfield which can include the following flags.
The individual flags indicate either a calling convention or a binding
convention. Of the calling convention flags, only :const:`METH_VARARGS` and
-:const:`METH_KEYWORDS` can be combined (but note that :const:`METH_KEYWORDS`
-alone is equivalent to ``METH_VARARGS | METH_KEYWORDS``). Any of the calling
-convention flags can be combined with a binding flag.
+:const:`METH_KEYWORDS` can be combined. Any of the calling convention flags
+can be combined with a binding flag.
.. data:: METH_VARARGS
@@ -235,7 +265,7 @@ definition with the same method name.
+==================+=============+===============================+
| :attr:`name` | char \* | name of the member |
+------------------+-------------+-------------------------------+
- | :attr:`type` | int | the type of the member in the |
+ | :attr:`!type` | int | the type of the member in the |
| | | C struct |
+------------------+-------------+-------------------------------+
| :attr:`offset` | Py_ssize_t | the offset in bytes that the |
@@ -250,7 +280,7 @@ definition with the same method name.
| | | docstring |
+------------------+-------------+-------------------------------+
- :attr:`type` can be one of many ``T_`` macros corresponding to various C
+ :attr:`!type` can be one of many ``T_`` macros corresponding to various C
types. When the member is accessed in Python, it will be converted to the
equivalent Python type.
@@ -284,12 +314,52 @@ definition with the same method name.
handles use of the :keyword:`del` statement on that attribute more correctly
than :c:macro:`T_OBJECT`.
- :attr:`flags` can be 0 for write and read access or :c:macro:`READONLY` for
+ :attr:`flags` can be ``0`` for write and read access or :c:macro:`READONLY` for
read-only access. Using :c:macro:`T_STRING` for :attr:`type` implies
:c:macro:`READONLY`. Only :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX`
members can be deleted. (They are set to *NULL*).
+.. c:type:: PyGetSetDef
+
+ Structure to define property-like access for a type. See also description of
+ the :c:member:`PyTypeObject.tp_getset` slot.
+
+ +-------------+------------------+-----------------------------------+
+ | Field | C Type | Meaning |
+ +=============+==================+===================================+
+ | name | char \* | attribute name |
+ +-------------+------------------+-----------------------------------+
+ | get | getter | C Function to get the attribute |
+ +-------------+------------------+-----------------------------------+
+ | set | setter | optional C function to set or |
+ | | | delete the attribute, if omitted |
+ | | | the attribute is readonly |
+ +-------------+------------------+-----------------------------------+
+ | doc | char \* | optional docstring |
+ +-------------+------------------+-----------------------------------+
+ | closure | void \* | optional function pointer, |
+ | | | providing additional data for |
+ | | | getter and setter |
+ +-------------+------------------+-----------------------------------+
+
+ The ``get`` function takes one :c:type:`PyObject\*` parameter (the
+ instance) and a function pointer (the associated ``closure``)::
+
+ typedef PyObject *(*getter)(PyObject *, void *);
+
+ It should return a new reference on success or *NULL* with a set exception
+ on failure.
+
+ ``set`` functions take two :c:type:`PyObject\*` parameters (the instance and
+ the value to be set) and a function pointer (the associated ``closure``)::
+
+ typedef int (*setter)(PyObject *, PyObject *, void *);
+
+ In case the attribute should be deleted the second parameter is *NULL*.
+ Should return ``0`` on success or ``-1`` with a set exception on failure.
+
+
.. c:function:: PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name)
Return a bound method object for an extension type implemented in C. This
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index 16de45fb..fd85663a 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -82,7 +82,7 @@ Tuple Objects
.. c:function:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos)
Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is
- out of bounds, return *NULL* and sets an :exc:`IndexError` exception.
+ out of bounds, return *NULL* and set an :exc:`IndexError` exception.
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *pos*. This might require
@@ -100,8 +100,9 @@ Tuple Objects
.. c:function:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high)
- Take a slice of the tuple pointed to by *p* from *low* to *high* and return it
- as a new tuple.
+ Return the slice of the tuple pointed to by *p* between *low* and *high*,
+ or *NULL* on failure. This is the equivalent of the Python expression
+ ``p[low:high]``. Indexing from the end of the list is not supported.
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *low* and *high*. This might
@@ -111,11 +112,13 @@ Tuple Objects
.. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)
Insert a reference to object *o* at position *pos* of the tuple pointed to by
- *p*. Return ``0`` on success.
+ *p*. Return ``0`` on success. If *pos* is out of bounds, return ``-1``
+ and set an :exc:`IndexError` exception.
.. note::
- This function "steals" a reference to *o*.
+ This function "steals" a reference to *o* and discards a reference to
+ an item already in the tuple at the affected position.
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *pos*. This might require
@@ -129,7 +132,10 @@ Tuple Objects
.. note::
- This function "steals" a reference to *o*.
+ This macro "steals" a reference to *o*, and, unlike
+ :c:func:`PyTuple_SetItem`, does *not* discard a reference to any item that
+ is being replaced; any reference in the tuple at position *pos* will be
+ leaked.
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *pos*. This might require
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index 22f7dd0f..68bebc8a 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -71,6 +71,11 @@ Type Objects
.. versionadded:: 2.2
+ This function only checks for actual subtypes, which means that
+ :meth:`~class.__subclasscheck__` is not called on *b*. Call
+ :c:func:`PyObject_IsSubclass` to do the same check that :func:`issubclass`
+ would do.
+
.. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 54f704a7..f0ccf2ea 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -117,12 +117,13 @@ type objects) *must* have the :attr:`ob_size` field.
For statically allocated type objects, the tp_name field should contain a dot.
Everything before the last dot is made accessible as the :attr:`__module__`
attribute, and everything after the last dot is made accessible as the
- :attr:`__name__` attribute.
+ :attr:`~definition.__name__` attribute.
If no dot is present, the entire :c:member:`~PyTypeObject.tp_name` field is made accessible as the
- :attr:`__name__` attribute, and the :attr:`__module__` attribute is undefined
+ :attr:`~definition.__name__` attribute, and the :attr:`__module__` attribute is undefined
(unless explicitly set in the dictionary, as explained above). This means your
- type will be impossible to pickle.
+ type will be impossible to pickle. Additionally, it will not be listed in
+ module documentations created with pydoc.
This field is not inherited by subtypes.
@@ -229,8 +230,9 @@ type objects) *must* have the :attr:`ob_size` field.
This field is deprecated. When it is defined, it should point to a function
that acts the same as the :c:member:`~PyTypeObject.tp_getattro` function, but taking a C string
- instead of a Python string object to give the attribute name. The signature is
- the same as for :c:func:`PyObject_GetAttrString`.
+ instead of a Python string object to give the attribute name. The signature is ::
+
+ PyObject * tp_getattr(PyObject *o, char *attr_name);
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype
inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when
@@ -239,13 +241,15 @@ type objects) *must* have the :attr:`ob_size` field.
.. c:member:: setattrfunc PyTypeObject.tp_setattr
- An optional pointer to the set-attribute-string function.
+ An optional pointer to the function for setting and deleting attributes.
This field is deprecated. When it is defined, it should point to a function
that acts the same as the :c:member:`~PyTypeObject.tp_setattro` function, but taking a C string
- instead of a Python string object to give the attribute name. The signature is
- the same as for :c:func:`PyObject_SetAttrString`.
+ instead of a Python string object to give the attribute name. The signature is ::
+
+ PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v);
+ The *v* argument is set to *NULL* to delete the attribute.
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype
inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when
the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*.
@@ -388,9 +392,10 @@ type objects) *must* have the :attr:`ob_size` field.
.. c:member:: setattrofunc PyTypeObject.tp_setattro
- An optional pointer to the set-attribute function.
+ An optional pointer to the function for setting and deleting attributes.
- The signature is the same as for :c:func:`PyObject_SetAttr`. It is usually
+ The signature is the same as for :c:func:`PyObject_SetAttr`, but setting
+ *v* to *NULL* to delete an attribute must be supported. It is usually
convenient to set this field to :c:func:`PyObject_GenericSetAttr`, which
implements the normal way of setting object attributes.
@@ -770,7 +775,7 @@ set.
exception may or may not be set. When another error occurs, it must return
*NULL* too. Its presence normally signals that the instances of this type
are iterators (although classic instances always have this function, even if
- they don't define a :meth:`next` method).
+ they don't define a :meth:`~iterator.next` method).
Iterator types should also define the :c:member:`~PyTypeObject.tp_iter` function, and that
function should return the iterator instance itself (not a new iterator
@@ -820,21 +825,6 @@ The next fields, up to and including :c:member:`~PyTypeObject.tp_weaklist`, only
This field is not inherited by subtypes (computed attributes are inherited
through a different mechanism).
- .. XXX belongs elsewhere
-
- Docs for PyGetSetDef::
-
- typedef PyObject *(*getter)(PyObject *, void *);
- typedef int (*setter)(PyObject *, PyObject *, void *);
-
- typedef struct PyGetSetDef {
- char *name; /* attribute name */
- getter get; /* C function to get the attribute */
- setter set; /* C function to set the attribute */
- char *doc; /* optional doc string */
- void *closure; /* optional additional data for getter and setter */
- } PyGetSetDef;
-
.. c:member:: PyTypeObject* PyTypeObject.tp_base
@@ -876,12 +866,14 @@ The next fields, up to and including :c:member:`~PyTypeObject.tp_weaklist`, only
.. c:member:: descrsetfunc PyTypeObject.tp_descr_set
- An optional pointer to a "descriptor set" function.
+ An optional pointer to a function for setting and deleting
+ a descriptor's value.
The function signature is ::
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
+ The *value* argument is set to *NULL* to delete the value.
This field is inherited by subtypes.
.. XXX explain.
@@ -1109,7 +1101,7 @@ The next fields, up to and including :c:member:`~PyTypeObject.tp_weaklist`, only
The remaining fields are only defined if the feature test macro
:const:`COUNT_ALLOCS` is defined, and are for internal use only. They are
documented here for completeness. None of these fields are inherited by
-subtypes.
+subtypes. See the :envvar:`PYTHONSHOWALLOCCOUNT` environment variable.
.. c:member:: Py_ssize_t PyTypeObject.tp_allocs
@@ -1262,9 +1254,11 @@ Mapping Object Structures
.. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
- This function is used by :c:func:`PyObject_SetItem` and has the same
- signature. If this slot is *NULL*, the object does not support item
- assignment.
+ This function is used by :c:func:`PyObject_SetItem` and
+ :c:func:`PyObject_DelItem`. It has the same signature as
+ :c:func:`PyObject_SetItem`, but *v* can also be set to *NULL* to delete
+ an item. If this slot is *NULL*, the object does not support item
+ assignment and deletion.
.. _sequence-structs:
@@ -1295,7 +1289,8 @@ Sequence Object Structures
This function is used by :c:func:`PySequence_Repeat` and has the same
signature. It is also used by the ``*`` operator, after trying numeric
- multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_mul` slot.
+ multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_multiply`
+ slot.
.. c:member:: ssizeargfunc PySequenceMethods.sq_item
@@ -1312,7 +1307,7 @@ Sequence Object Structures
This function is used by :c:func:`PySequence_SetItem` and has the same
signature. This slot may be left to *NULL* if the object does not support
- item assignment.
+ item assignment and deletion.
.. c:member:: objobjproc PySequenceMethods.sq_contains
@@ -1367,23 +1362,23 @@ member in the :c:type:`PyTypeObject` structure should be *NULL*. Otherwise, the
Structure used to hold the function pointers which define an implementation of
the buffer protocol.
- The first slot is :attr:`bf_getreadbuffer`, of type :c:type:`getreadbufferproc`.
+ The first slot is :attr:`bf_getreadbuffer`, of type :c:type:`readbufferproc`.
If this slot is *NULL*, then the object does not support reading from the
internal data. This is non-sensical, so implementors should fill this in, but
callers should test that the slot contains a non-*NULL* value.
The next slot is :attr:`bf_getwritebuffer` having type
- :c:type:`getwritebufferproc`. This slot may be *NULL* if the object does not
+ :c:type:`writebufferproc`. This slot may be *NULL* if the object does not
allow writing into its returned buffers.
- The third slot is :attr:`bf_getsegcount`, with type :c:type:`getsegcountproc`.
+ The third slot is :attr:`bf_getsegcount`, with type :c:type:`segcountproc`.
This slot must not be *NULL* and is used to inform the caller how many segments
the object contains. Simple objects such as :c:type:`PyString_Type` and
:c:type:`PyBuffer_Type` objects contain a single segment.
.. index:: single: PyType_HasFeature()
- The last slot is :attr:`bf_getcharbuffer`, of type :c:type:`getcharbufferproc`.
+ The last slot is :attr:`bf_getcharbuffer`, of type :c:type:`charbufferproc`.
This slot will only be present if the :const:`Py_TPFLAGS_HAVE_GETCHARBUFFER`
flag is present in the :c:member:`~PyTypeObject.tp_flags` field of the object's
:c:type:`PyTypeObject`. Before using this slot, the caller should test whether it
@@ -1442,7 +1437,7 @@ member in the :c:type:`PyTypeObject` structure should be *NULL*. Otherwise, the
all segments in ``*lenp``. The function cannot fail.
-.. c:type:: Py_ssize_t (*charbufferproc) (PyObject *self, Py_ssize_t segment, const char **ptrptr)
+.. c:type:: Py_ssize_t (*charbufferproc) (PyObject *self, Py_ssize_t segment, char **ptrptr)
Return the size of the segment *segment* that *ptrptr* is set to. ``*ptrptr``
is set to the memory buffer. Returns ``-1`` on error.
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index ddeaaa24..4d1eaa1d 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -116,52 +116,52 @@ the Python configuration.
.. c:function:: int Py_UNICODE_ISSPACE(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is a whitespace character.
+ Return ``1`` or ``0`` depending on whether *ch* is a whitespace character.
.. c:function:: int Py_UNICODE_ISLOWER(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is a lowercase character.
+ Return ``1`` or ``0`` depending on whether *ch* is a lowercase character.
.. c:function:: int Py_UNICODE_ISUPPER(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is an uppercase character.
+ Return ``1`` or ``0`` depending on whether *ch* is an uppercase character.
.. c:function:: int Py_UNICODE_ISTITLE(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is a titlecase character.
+ Return ``1`` or ``0`` depending on whether *ch* is a titlecase character.
.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is a linebreak character.
+ Return ``1`` or ``0`` depending on whether *ch* is a linebreak character.
.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is a decimal character.
+ Return ``1`` or ``0`` depending on whether *ch* is a decimal character.
.. c:function:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is a digit character.
+ Return ``1`` or ``0`` depending on whether *ch* is a digit character.
.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is a numeric character.
+ Return ``1`` or ``0`` depending on whether *ch* is a numeric character.
.. c:function:: int Py_UNICODE_ISALPHA(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is an alphabetic character.
+ Return ``1`` or ``0`` depending on whether *ch* is an alphabetic character.
.. c:function:: int Py_UNICODE_ISALNUM(Py_UNICODE ch)
- Return 1 or 0 depending on whether *ch* is an alphanumeric character.
+ Return ``1`` or ``0`` depending on whether *ch* is an alphanumeric character.
These APIs can be used for fast direct character conversions:
@@ -234,7 +234,7 @@ APIs:
.. c:function:: PyObject *PyUnicode_FromString(const char *u)
- Create a Unicode object from an UTF-8 encoded null-terminated char buffer
+ Create a Unicode object from a UTF-8 encoded null-terminated char buffer
*u*.
.. versionadded:: 2.6
@@ -260,7 +260,7 @@ APIs:
| :attr:`%%` | *n/a* | The literal % character. |
+-------------------+---------------------+--------------------------------+
| :attr:`%c` | int | A single character, |
- | | | represented as an C int. |
+ | | | represented as a C int. |
+-------------------+---------------------+--------------------------------+
| :attr:`%d` | int | Exactly equivalent to |
| | | ``printf("%d")``. |
@@ -347,7 +347,7 @@ APIs:
.. c:function:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors)
- Coerce an encoded object *obj* to an Unicode object and return a reference with
+ Coerce an encoded object *obj* to a Unicode object and return a reference with
incremented refcount.
String and other char buffer compatible objects are decoded according to the
@@ -393,7 +393,7 @@ wchar_t Support
Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most
*size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing
0-termination character). Return the number of :c:type:`wchar_t` characters
- copied or -1 in case of an error. Note that the resulting :c:type:`wchar_t`
+ copied or ``-1`` in case of an error. Note that the resulting :c:type:`wchar_t`
string may or may not be 0-terminated. It is the responsibility of the caller
to make sure that the :c:type:`wchar_t` string is 0-terminated in case this is
required by the application. Also, note that the :c:type:`wchar_t*` string
@@ -547,7 +547,7 @@ These are the UTF-32 codec APIs:
After completion, *\*byteorder* is set to the current byte order at the end
of input data.
- In a narrow build codepoints outside the BMP will be decoded as surrogate pairs.
+ In a narrow build code points outside the BMP will be decoded as surrogate pairs.
If *byteorder* is *NULL*, the codec starts in native order mode.
@@ -580,7 +580,7 @@ These are the UTF-32 codec APIs:
mark (U+FEFF). In the other two modes, no BOM mark is prepended.
If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output
- as a single codepoint.
+ as a single code point.
Return *NULL* if an exception was raised by the codec.
@@ -663,7 +663,7 @@ These are the UTF-16 codec APIs:
If *Py_UNICODE_WIDE* is defined, a single :c:type:`Py_UNICODE` value may get
represented as a surrogate pair. If it is not defined, each :c:type:`Py_UNICODE`
- values is interpreted as an UCS-2 character.
+ values is interpreted as a UCS-2 character.
Return *NULL* if an exception was raised by the codec.
@@ -856,11 +856,11 @@ included in the :mod:`encodings` package). The codec uses mapping to encode and
decode characters.
Decoding mappings must map single string characters to single Unicode
-characters, integers (which are then interpreted as Unicode ordinals) or None
+characters, integers (which are then interpreted as Unicode ordinals) or ``None``
(meaning "undefined mapping" and causing an error).
Encoding mappings must map single Unicode characters to single string
-characters, integers (which are then interpreted as Latin-1 ordinals) or None
+characters, integers (which are then interpreted as Latin-1 ordinals) or ``None``
(meaning "undefined mapping" and causing an error).
The mapping objects provided must only support the __getitem__ mapping
@@ -917,7 +917,7 @@ The following codec API is special in that maps Unicode to Unicode.
*NULL* when an exception was raised by the codec.
The *mapping* table must map Unicode ordinal integers to Unicode ordinal
- integers or None (causing deletion of the character).
+ integers or ``None`` (causing deletion of the character).
Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries
and sequences work well. Unmapped character ordinals (ones which cause a
@@ -1009,7 +1009,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend)
Split a Unicode string at line breaks, returning a list of Unicode strings.
- CRLF is considered to be one line break. If *keepend* is 0, the Line break
+ CRLF is considered to be one line break. If *keepend* is ``0``, the Line break
characters are not included in the resulting strings.
@@ -1019,7 +1019,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
resulting Unicode object.
The mapping table must map Unicode ordinal integers to Unicode ordinal integers
- or None (causing deletion of the character).
+ or ``None`` (causing deletion of the character).
Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries
and sequences work well. Unmapped character ordinals (ones which cause a
@@ -1035,11 +1035,11 @@ They all return *NULL* or ``-1`` if an exception occurs.
Unicode string.
-.. c:function:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
+.. c:function:: Py_ssize_t PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
- Return 1 if *substr* matches ``str[start:end]`` at the given tail end
- (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match),
- 0 otherwise. Return ``-1`` if an error occurred.
+ Return ``1`` if *substr* matches ``str[start:end]`` at the given tail end
+ (*direction* == ``-1`` means to do a prefix match, *direction* == ``1`` a suffix match),
+ ``0`` otherwise. Return ``-1`` if an error occurred.
.. versionchanged:: 2.5
This function used an :c:type:`int` type for *start* and *end*. This
@@ -1050,7 +1050,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)
Return the first position of *substr* in ``str[start:end]`` using the given
- *direction* (*direction* == 1 means to do a forward search, *direction* == -1 a
+ *direction* (*direction* == ``1`` means to do a forward search, *direction* == ``-1`` a
backward search). The return value is the index of the first match; a value of
``-1`` indicates that no match was found, and ``-2`` indicates that an error
occurred and an exception has been set.
@@ -1075,7 +1075,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount)
Replace at most *maxcount* occurrences of *substr* in *str* with *replstr* and
- return the resulting Unicode object. *maxcount* == -1 means replace all
+ return the resulting Unicode object. *maxcount* == ``-1`` means replace all
occurrences.
.. versionchanged:: 2.5
@@ -1085,7 +1085,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: int PyUnicode_Compare(PyObject *left, PyObject *right)
- Compare two strings and return -1, 0, 1 for less than, equal, and greater than,
+ Compare two strings and return ``-1``, ``0``, ``1`` for less than, equal, and greater than,
respectively.
@@ -1108,7 +1108,7 @@ They all return *NULL* or ``-1`` if an exception occurs.
.. c:function:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args)
Return a new string object from *format* and *args*; this is analogous to
- ``format % args``. The *args* argument must be a tuple.
+ ``format % args``.
.. c:function:: int PyUnicode_Contains(PyObject *container, PyObject *element)
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 61076655..9e54c140 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -168,7 +168,7 @@ the same library that the Python runtime is using.
.. c:function:: struct _node* PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
This is a simplified interface to :c:func:`PyParser_SimpleParseFileFlags` below,
- leaving *flags* set to ``0``
+ leaving *flags* set to ``0``.
.. c:function:: struct _node* PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
diff --git a/Doc/conf.py b/Doc/conf.py
index b6d212d3..29927c3b 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -8,26 +8,18 @@
# that aren't pickleable (module imports are okay, they're removed automatically).
import sys, os, time
-sys.path.append(os.path.abspath('tools/sphinxext'))
+sys.path.append(os.path.abspath('tools/extensions'))
# General configuration
# ---------------------
-extensions = ['sphinx.ext.refcounting', 'sphinx.ext.coverage',
- 'sphinx.ext.doctest', 'pyspecific']
-templates_path = ['tools/sphinxext']
+extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest',
+ 'pyspecific', 'c_annotations']
# General substitutions.
project = 'Python'
copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y')
-# The default replacements for |version| and |release|.
-#
-# The short X.Y version.
-# version = '2.6'
-# The full version, including alpha/beta/rc tags.
-# release = '2.6a0'
-
# We look for the Include/patchlevel.h file in the current Python source tree
# and replace the values accordingly.
import patchlevel
@@ -40,25 +32,17 @@
today_fmt = '%B %d, %Y'
# List of files that shouldn't be included in the build.
-unused_docs = [
- 'maclib/scrap',
- 'library/xmllib',
- 'library/xml.etree',
+exclude_patterns = [
+ 'maclib/scrap.rst',
+ 'library/xmllib.rst',
+ 'library/xml.etree.rst',
]
-# Ignore .rst in Sphinx its self.
-exclude_trees = ['tools/sphinx']
-
-# Relative filename of the reference count data file.
-refcount_file = 'data/refcounts.dat'
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-add_module_names = True
+# Require Sphinx 1.2 for build.
+needs_sphinx = '1.2'
+# Avoid a warning with Sphinx >= 2.0
+master_doc = 'contents'
# Options for HTML output
# -----------------------
@@ -70,13 +54,12 @@
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-html_use_smartypants = True
+# Path to find HTML templates.
+templates_path = ['tools/templates']
# Custom sidebar templates, filenames relative to this file.
html_sidebars = {
- 'index': 'indexsidebar.html',
+ 'index': ['indexsidebar.html'],
}
# Additional templates that should be rendered to pages.
@@ -86,10 +69,10 @@
}
# Output an OpenSearch description file.
-html_use_opensearch = 'http://docs.python.org/'
+html_use_opensearch = 'https://docs.python.org/'
# Additional static files.
-html_static_path = ['tools/sphinxext/static']
+html_static_path = ['tools/static']
# Output file base name for HTML help builder.
htmlhelp_basename = 'python' + release.replace('.', '')
@@ -97,27 +80,47 @@
# Split the index
html_split_index = True
+html_context = {
+ 'outdated': True
+}
+
# Options for LaTeX output
# ------------------------
+latex_engine = 'xelatex'
+
+# Get LaTeX to handle Unicode correctly
+latex_elements = {
+}
+
+# Additional stuff for the LaTeX preamble.
+latex_elements['preamble'] = r'''
+\authoraddress{
+ \sphinxstrong{Python Software Foundation}\\
+ Email: \sphinxemail{docs@python.org}
+}
+\let\Verbatim=\OriginalVerbatim
+\let\endVerbatim=\endOriginalVerbatim
+'''
+
# The paper size ('letter' or 'a4').
-latex_paper_size = 'a4'
+latex_elements['papersize'] = 'a4'
# The font size ('10pt', '11pt' or '12pt').
-latex_font_size = '10pt'
+latex_elements['pointsize'] = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
-_stdauthor = r'Guido van Rossum\\Fred L. Drake, Jr., editor'
+_stdauthor = r'Guido van Rossum\\and the Python development team'
latex_documents = [
('c-api/index', 'c-api.tex',
'The Python/C API', _stdauthor, 'manual'),
- ('distutils/index', 'distutils.tex',
+ ('distributing/index', 'distributing.tex',
'Distributing Python Modules', _stdauthor, 'manual'),
('extending/index', 'extending.tex',
'Extending and Embedding Python', _stdauthor, 'manual'),
- ('install/index', 'install.tex',
+ ('installing/index', 'installing.tex',
'Installing Python Modules', _stdauthor, 'manual'),
('library/index', 'library.tex',
'The Python Library Reference', _stdauthor, 'manual'),
@@ -138,21 +141,14 @@
for fn in os.listdir('howto')
if fn.endswith('.rst') and fn != 'index.rst')
-# Additional stuff for the LaTeX preamble.
-latex_preamble = r'''
-\authoraddress{
- \strong{Python Software Foundation}\\
- Email: \email{docs@python.org}
-}
-\let\Verbatim=\OriginalVerbatim
-\let\endVerbatim=\endOriginalVerbatim
-'''
-
# Documents to append as an appendix to all manuals.
latex_appendices = ['glossary', 'about', 'license', 'copyright']
-# Get LaTeX to handle Unicode correctly
-latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''}
+# Options for Epub output
+# -----------------------
+
+epub_author = 'Python Documentation Authors'
+epub_publisher = 'Python Software Foundation'
# Options for the coverage checker
# --------------------------------
@@ -189,3 +185,19 @@
coverage_ignore_c_items = {
# 'cfunction': [...]
}
+
+
+# Options for the link checker
+# ----------------------------
+
+# Ignore certain URLs.
+linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+',
+ # Ignore PEPs for now, they all have permanent redirects.
+ r'http://www.python.org/dev/peps/pep-\d+']
+
+
+# Options for extensions
+# ----------------------
+
+# Relative filename of the reference count data file.
+refcount_file = 'data/refcounts.dat'
diff --git a/Doc/contents.rst b/Doc/contents.rst
index c0c6af34..8690de77 100644
--- a/Doc/contents.rst
+++ b/Doc/contents.rst
@@ -11,8 +11,8 @@
library/index.rst
extending/index.rst
c-api/index.rst
- distutils/index.rst
- install/index.rst
+ distributing/index.rst
+ installing/index.rst
howto/index.rst
faq/index.rst
glossary.rst
@@ -21,3 +21,11 @@
bugs.rst
copyright.rst
license.rst
+
+.. to include legacy packaging docs in build
+
+.. toctree::
+ :hidden:
+
+ distutils/index.rst
+ install/index.rst
diff --git a/Doc/copyright.rst b/Doc/copyright.rst
index 94f777c4..1b90d9f1 100644
--- a/Doc/copyright.rst
+++ b/Doc/copyright.rst
@@ -4,7 +4,7 @@ Copyright
Python and this documentation is:
-Copyright © 2001-2013 Python Software Foundation. All rights reserved.
+Copyright © 2001-2020 Python Software Foundation. All rights reserved.
Copyright © 2000 BeOpen.com. All rights reserved.
diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst
new file mode 100644
index 00000000..b0dccb3d
--- /dev/null
+++ b/Doc/distributing/index.rst
@@ -0,0 +1,170 @@
+.. _distributing-index:
+
+###############################
+ Distributing Python Modules
+###############################
+
+:Email: distutils-sig@python.org
+
+
+As a popular open source development project, Python has an active
+supporting community of contributors and users that also make their software
+available for other Python developers to use under open source license terms.
+
+This allows Python users to share and collaborate effectively, benefiting
+from the solutions others have already created to common (and sometimes
+even rare!) problems, as well as potentially contributing their own
+solutions to the common pool.
+
+This guide covers the distribution part of the process. For a guide to
+installing other Python projects, refer to the
+:ref:`installation guide `.
+
+.. note::
+
+ For corporate and other institutional users, be aware that many
+ organisations have their own policies around using and contributing to
+ open source software. Please take such policies into account when making
+ use of the distribution and installation tools provided with Python.
+
+
+Key terms
+=========
+
+* the `Python Packaging Index `__ is a public
+ repository of open source licensed packages made available for use by
+ other Python users
+* the `Python Packaging Authority
+ `__ are the group of
+ developers and documentation authors responsible for the maintenance and
+ evolution of the standard packaging tools and the associated metadata and
+ file format standards. They maintain a variety of tools, documentation
+ and issue trackers on both `GitHub `__ and
+ `BitBucket `__.
+* :mod:`distutils` is the original build and distribution system first added
+ to the Python standard library in 1998. While direct use of :mod:`distutils`
+ is being phased out, it still laid the foundation for the current packaging
+ and distribution infrastructure, and it not only remains part of the
+ standard library, but its name lives on in other ways (such as the name
+ of the mailing list used to coordinate Python packaging standards
+ development).
+* `setuptools`_ is a (largely) drop-in replacement for :mod:`distutils` first
+ published in 2004. Its most notable addition over the unmodified
+ :mod:`distutils` tools was the ability to declare dependencies on other
+ packages. It is currently recommended as a more regularly updated
+ alternative to :mod:`distutils` that offers consistent support for more
+ recent packaging standards across a wide range of Python versions.
+* `wheel`_ (in this context) is a project that adds the ``bdist_wheel``
+ command to :mod:`distutils`/`setuptools`_. This produces a cross platform
+ binary packaging format (called "wheels" or "wheel files" and defined in
+ :pep:`427`) that allows Python libraries, even those including binary
+ extensions, to be installed on a system without needing to be built
+ locally.
+
+.. _setuptools: https://setuptools.readthedocs.io/en/latest/
+.. _wheel: https://wheel.readthedocs.org
+
+Open source licensing and collaboration
+=======================================
+
+In most parts of the world, software is automatically covered by copyright.
+This means that other developers require explicit permission to copy, use,
+modify and redistribute the software.
+
+Open source licensing is a way of explicitly granting such permission in a
+relatively consistent way, allowing developers to share and collaborate
+efficiently by making common solutions to various problems freely available.
+This leaves many developers free to spend more time focusing on the problems
+that are relatively unique to their specific situation.
+
+The distribution tools provided with Python are designed to make it
+reasonably straightforward for developers to make their own contributions
+back to that common pool of software if they choose to do so.
+
+The same distribution tools can also be used to distribute software within
+an organisation, regardless of whether that software is published as open
+source software or not.
+
+
+Installing the tools
+====================
+
+The standard library does not include build tools that support modern
+Python packaging standards, as the core development team has found that it
+is important to have standard tools that work consistently, even on older
+versions of Python.
+
+The currently recommended build and distribution tools can be installed
+by invoking the ``pip`` module at the command line::
+
+ python -m pip install setuptools wheel twine
+
+.. note::
+
+ For POSIX users (including Mac OS X and Linux users), these instructions
+ assume the use of a :term:`virtual environment`.
+
+ For Windows users, these instructions assume that the option to
+ adjust the system PATH environment variable was selected when installing
+ Python.
+
+The Python Packaging User Guide includes more details on the `currently
+recommended tools`_.
+
+.. _currently recommended tools: https://packaging.python.org/en/latest/current/#packaging-tool-recommendations
+
+Reading the guide
+=================
+
+The Python Packaging User Guide covers the various key steps and elements
+involved in creating a project:
+
+* `Project structure`_
+* `Building and packaging the project`_
+* `Uploading the project to the Python Packaging Index`_
+
+.. _Project structure: \
+ https://packaging.python.org/en/latest/distributing/
+.. _Building and packaging the project: \
+ https://packaging.python.org/en/latest/distributing/#packaging-your-project
+.. _Uploading the project to the Python Packaging Index: \
+ https://packaging.python.org/en/latest/distributing/#uploading-your-project-to-pypi
+
+
+How do I...?
+============
+
+These are quick answers or links for some common tasks.
+
+... choose a name for my project?
+---------------------------------
+
+This isn't an easy topic, but here are a few tips:
+
+* check the Python Packaging Index to see if the name is already in use
+* check popular hosting sites like GitHub, BitBucket, etc to see if there
+ is already a project with that name
+* check what comes up in a web search for the name you're considering
+* avoid particularly common words, especially ones with multiple meanings,
+ as they can make it difficult for users to find your software when
+ searching for it
+
+
+... create and distribute binary extensions?
+--------------------------------------------
+
+This is actually quite a complex topic, with a variety of alternatives
+available depending on exactly what you're aiming to achieve. See the
+Python Packaging User Guide for more information and recommendations.
+
+.. seealso::
+
+ `Python Packaging User Guide: Binary Extensions
+ `__
+
+.. other topics:
+
+ Once the Development & Deployment part of PPUG is fleshed out, some of
+ those sections should be linked from new questions here (most notably,
+ we should have a question about avoiding depending on PyPI that links to
+ https://packaging.python.org/en/latest/mirrors/)
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index f121b54f..eade9054 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -78,7 +78,7 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
| | be built | :class:`distutils.core.Extension` |
+--------------------+--------------------------------+-------------------------------------------------------------+
| *classifiers* | A list of categories for the | a list of strings; valid classifiers are listed on `PyPI |
- | | package | `_. |
+ | | package | `_. |
+--------------------+--------------------------------+-------------------------------------------------------------+
| *distclass* | the :class:`Distribution` | a subclass of |
| | class to use | :class:`distutils.core.Distribution` |
@@ -166,7 +166,7 @@ the full reference.
.. class:: Extension
- The Extension class describes a single C or C++extension module in a setup
+ The Extension class describes a single C or C++ extension module in a setup
script. It accepts the following keyword arguments in its constructor
.. tabularcolumns:: |l|L|l|
@@ -205,7 +205,7 @@ the full reference.
| | to or ``None`` to define it | |
| | without a particular value | |
| | (equivalent of ``#define FOO`` | |
- | | in source or :option:`-DFOO` | |
+ | | in source or :option:`!-DFOO` | |
| | on Unix C compiler command | |
| | line) | |
+------------------------+--------------------------------+---------------------------+
@@ -314,12 +314,12 @@ This module provides the following functions.
.. function:: gen_preprocess_options(macros, include_dirs)
- Generate C pre-processor options (:option:`-D`, :option:`-U`, :option:`-I`) as
+ Generate C pre-processor options (:option:`!-D`, :option:`!-U`, :option:`!-I`) as
used by at least two types of compilers: the typical Unix compiler and Visual
C++. *macros* is the usual thing, a list of 1- or 2-tuples, where ``(name,)``
- means undefine (:option:`-U`) macro *name*, and ``(name, value)`` means define
- (:option:`-D`) macro *name* to *value*. *include_dirs* is just a list of
- directory names to be added to the header file search path (:option:`-I`).
+ means undefine (:option:`!-U`) macro *name*, and ``(name, value)`` means define
+ (:option:`!-D`) macro *name* to *value*. *include_dirs* is just a list of
+ directory names to be added to the header file search path (:option:`!-I`).
Returns a list of command-line options suitable for either Unix compilers or
Visual C++.
@@ -354,7 +354,7 @@ This module provides the following functions.
.. function:: show_compilers()
- Print list of available compilers (used by the :option:`--help-compiler` options
+ Print list of available compilers (used by the :option:`!--help-compiler` options
to :command:`build`, :command:`build_ext`, :command:`build_clib`).
@@ -516,7 +516,7 @@ This module provides the following functions.
.. method:: CCompiler.library_option(lib)
- Return the compiler option to add *dir* to the list of libraries linked into the
+ Return the compiler option to add *lib* to the list of libraries linked into the
shared library or executable.
@@ -784,23 +784,23 @@ This module provides the following functions.
This module provides the :class:`UnixCCompiler` class, a subclass of
:class:`CCompiler` that handles the typical Unix-style command-line C compiler:
-* macros defined with :option:`-Dname[=value]`
+* macros defined with :option:`!-Dname[=value]`
-* macros undefined with :option:`-Uname`
+* macros undefined with :option:`!-Uname`
-* include search directories specified with :option:`-Idir`
+* include search directories specified with :option:`!-Idir`
-* libraries specified with :option:`-llib`
+* libraries specified with :option:`!-llib`
-* library search directories specified with :option:`-Ldir`
+* library search directories specified with :option:`!-Ldir`
-* compile handled by :program:`cc` (or similar) executable with :option:`-c`
+* compile handled by :program:`cc` (or similar) executable with :option:`!-c`
option: compiles :file:`.c` to :file:`.o`
* link static library handled by :program:`ar` command (possibly with
:program:`ranlib`)
-* link shared library handled by :program:`cc` :option:`-shared`
+* link shared library handled by :program:`cc` :option:`!-shared`
:mod:`distutils.msvccompiler` --- Microsoft Compiler
@@ -832,7 +832,7 @@ selection by :class:`MSVCCompiler`.
.. module:: distutils.bcppcompiler
-This module provides :class:`BorlandCCompiler`, an subclass of the abstract
+This module provides :class:`BorlandCCompiler`, a subclass of the abstract
:class:`CCompiler` class for the Borland C++ compiler.
@@ -926,7 +926,7 @@ timestamp dependency analysis.
Walk two filename lists in parallel, testing if each source is newer than its
corresponding target. Return a pair of lists (*sources*, *targets*) where
- source is newer than target, according to the semantics of :func:`newer`
+ source is newer than target, according to the semantics of :func:`newer`.
.. % % equivalent to a listcomp...
@@ -934,7 +934,7 @@ timestamp dependency analysis.
.. function:: newer_group(sources, target[, missing='error'])
Return true if *target* is out-of-date with respect to any file listed in
- *sources* In other words, if *target* exists and is newer than every file in
+ *sources*. In other words, if *target* exists and is newer than every file in
*sources*, return false; otherwise return true. *missing* controls what we do
when a source file is missing; the default (``'error'``) is to blow up with an
:exc:`OSError` from inside :func:`os.stat`; if it is ``'ignore'``, we silently
@@ -970,7 +970,7 @@ directories.
.. function:: create_tree(base_dir, files[, mode=0777, verbose=0, dry_run=0])
Create all the empty directories under *base_dir* needed to put *files* there.
- *base_dir* is just the a name of a directory which doesn't necessarily exist
+ *base_dir* is just the name of a directory which doesn't necessarily exist
yet; *files* is a list of filenames to be interpreted relative to *base_dir*.
*base_dir* + the directory portion of every file in *files* will be created if
it doesn't already exist. *mode*, *verbose* and *dry_run* flags are as for
@@ -1106,13 +1106,13 @@ other utility module.
during the build of Python), not the OS version of the current system.
For universal binary builds on Mac OS X the architecture value reflects
- the univeral binary status instead of the architecture of the current
+ the universal binary status instead of the architecture of the current
processor. For 32-bit universal binaries the architecture is ``fat``,
for 64-bit universal binaries the architecture is ``fat64``, and
for 4-way universal binaries the architecture is ``universal``. Starting
from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for
a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for
- a univeral build with the i386 and x86_64 architectures
+ a universal build with the i386 and x86_64 architectures
Examples of returned values on Mac OS X:
@@ -1167,15 +1167,6 @@ other utility module.
underscore. No { } or ( ) style quoting is available.
-.. function:: grok_environment_error(exc[, prefix='error: '])
-
- Generate a useful error message from an :exc:`EnvironmentError` (:exc:`IOError`
- or :exc:`OSError`) exception object. Handles Python 1.5.1 and later styles,
- and does what it can to deal with exception objects that don't have a filename
- (which happens when the error is due to a two-file operation, such as
- :func:`~os.rename` or :func:`~os.link`). Returns the error message as a
- string prefixed with *prefix*.
-
.. function:: split_quoted(s)
@@ -1319,8 +1310,8 @@ provides the following additional features:
* options set attributes of a passed-in object
-* boolean options can have "negative aliases" --- eg. if :option:`--quiet` is
- the "negative alias" of :option:`--verbose`, then :option:`--quiet` on the
+* boolean options can have "negative aliases" --- eg. if :option:`!--quiet` is
+ the "negative alias" of :option:`!--verbose`, then :option:`!--quiet` on the
command line sets *verbose* to false.
@@ -1825,7 +1816,7 @@ Subclasses of :class:`Command` must define the following methods.
Builds a `Windows Installer`_ (.msi) binary package.
- .. _Windows Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx
+ .. _Windows Installer: https://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx
In most cases, the ``bdist_msi`` installer is a better choice than the
``bdist_wininst`` installer, because it provides better support for
@@ -1916,8 +1907,12 @@ Subclasses of :class:`Command` must define the following methods.
.. module:: distutils.command.clean
:synopsis: Clean a package build area
+This command removes the temporary files created by :command:`build`
+and its subcommands, like intermediary compiled object files. With
+the ``--all`` option, the complete build directory will be removed.
-.. % todo
+Extension modules built :ref:`in place `
+will not be cleaned, as they are not in the build directory.
:mod:`distutils.command.config` --- Perform package configuration
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index 7a114599..acd499a2 100644
--- a/Doc/distutils/builtdist.rst
+++ b/Doc/distutils/builtdist.rst
@@ -21,7 +21,7 @@ specialty---writing code and creating source distributions---while an
intermediary species called *packagers* springs up to turn source distributions
into built distributions for as many platforms as there are packagers.
-Of course, the module developer could be his own packager; or the packager could
+Of course, the module developer could be their own packager; or the packager could
be a volunteer "out there" somewhere who has access to a platform which the
original developer does not; or it could be software periodically grabbing new
source distributions and turning them into built distributions for as many
@@ -57,7 +57,7 @@ built distributions, such as an RPM package or an executable installer for
Windows, is far more convenient for users even if your distribution doesn't
include any extensions.
-The :command:`bdist` command has a :option:`--formats` option, similar to the
+The :command:`bdist` command has a :option:`!--formats` option, similar to the
:command:`sdist` command, which you can use to select the types of built
distribution to generate: for example, ::
@@ -115,7 +115,7 @@ Notes:
requires external :program:`rpm` utility, version 3.0.4 or better (use ``rpm
--version`` to find out which version you have)
-You don't have to use the :command:`bdist` command with the :option:`--formats`
+You don't have to use the :command:`bdist` command with the :option:`!--formats`
option; you can also use the command that directly implements the format you're
interested in. Some of these :command:`bdist` "sub-commands" actually generate
several similar formats; for instance, the :command:`bdist_dumb` command
@@ -165,7 +165,7 @@ The usual way to create an RPM of your module distribution is to run the
python setup.py bdist_rpm
-or the :command:`bdist` command with the :option:`--format` option::
+or the :command:`bdist` command with the :option:`!--format` option::
python setup.py bdist --formats=rpm
@@ -186,21 +186,21 @@ Distutils configuration files. Various options and sections in the
+------------------------------------------+----------------------------------------------+
| RPM :file:`.spec` file option or section | Distutils setup script option |
+==========================================+==============================================+
-| Name | :option:`name` |
+| Name | ``name`` |
+------------------------------------------+----------------------------------------------+
-| Summary (in preamble) | :option:`description` |
+| Summary (in preamble) | ``description`` |
+------------------------------------------+----------------------------------------------+
-| Version | :option:`version` |
+| Version | ``version`` |
+------------------------------------------+----------------------------------------------+
-| Vendor | :option:`author` and :option:`author_email`, |
-| | or --- & :option:`maintainer` and |
-| | :option:`maintainer_email` |
+| Vendor | ``author`` and ``author_email``, |
+| | or --- & ``maintainer`` and |
+| | ``maintainer_email`` |
+------------------------------------------+----------------------------------------------+
-| Copyright | :option:`license` |
+| Copyright | ``license`` |
+------------------------------------------+----------------------------------------------+
-| Url | :option:`url` |
+| Url | ``url`` |
+------------------------------------------+----------------------------------------------+
-| %description (section) | :option:`long_description` |
+| %description (section) | ``long_description`` |
+------------------------------------------+----------------------------------------------+
Additionally, there are many options in :file:`.spec` files that don't have
@@ -211,27 +211,27 @@ options to the :command:`bdist_rpm` command as follows:
| RPM :file:`.spec` file option | :command:`bdist_rpm` option | default value |
| or section | | |
+===============================+=============================+=========================+
-| Release | :option:`release` | "1" |
+| Release | ``release`` | "1" |
+-------------------------------+-----------------------------+-------------------------+
-| Group | :option:`group` | "Development/Libraries" |
+| Group | ``group`` | "Development/Libraries" |
+-------------------------------+-----------------------------+-------------------------+
-| Vendor | :option:`vendor` | (see above) |
+| Vendor | ``vendor`` | (see above) |
+-------------------------------+-----------------------------+-------------------------+
-| Packager | :option:`packager` | (none) |
+| Packager | ``packager`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
-| Provides | :option:`provides` | (none) |
+| Provides | ``provides`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
-| Requires | :option:`requires` | (none) |
+| Requires | ``requires`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
-| Conflicts | :option:`conflicts` | (none) |
+| Conflicts | ``conflicts`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
-| Obsoletes | :option:`obsoletes` | (none) |
+| Obsoletes | ``obsoletes`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
-| Distribution | :option:`distribution_name` | (none) |
+| Distribution | ``distribution_name`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
-| BuildRequires | :option:`build_requires` | (none) |
+| BuildRequires | ``build_requires`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
-| Icon | :option:`icon` | (none) |
+| Icon | ``icon`` | (none) |
+-------------------------------+-----------------------------+-------------------------+
Obviously, supplying even a few of these options on the command-line would be
@@ -258,10 +258,10 @@ Normally, RPM bundles the last two steps together; when you use the Distutils,
all three steps are typically bundled together.
If you wish, you can separate these three steps. You can use the
-:option:`--spec-only` option to make :command:`bdist_rpm` just create the
+:option:`!--spec-only` option to make :command:`bdist_rpm` just create the
:file:`.spec` file and exit; in this case, the :file:`.spec` file will be
written to the "distribution directory"---normally :file:`dist/`, but
-customizable with the :option:`--dist-dir` option. (Normally, the :file:`.spec`
+customizable with the :option:`!--dist-dir` option. (Normally, the :file:`.spec`
file winds up deep in the "build tree," in a temporary directory created by
:command:`bdist_rpm`.)
@@ -298,7 +298,7 @@ is usually as easy as running::
python setup.py bdist_wininst
-or the :command:`bdist` command with the :option:`--formats` option::
+or the :command:`bdist` command with the :option:`!--formats` option::
python setup.py bdist --formats=wininst
@@ -316,20 +316,20 @@ support.
The installer will try to compile pure modules into :term:`bytecode` after installation
on the target system in normal and optimizing mode. If you don't want this to
happen for some reason, you can run the :command:`bdist_wininst` command with
-the :option:`--no-target-compile` and/or the :option:`--no-target-optimize`
+the :option:`!--no-target-compile` and/or the :option:`!--no-target-optimize`
option.
By default the installer will display the cool "Python Powered" logo when it is
run, but you can also supply your own 152x261 bitmap which must be a Windows
-:file:`.bmp` file with the :option:`--bitmap` option.
+:file:`.bmp` file with the :option:`!--bitmap` option.
The installer will also display a large title on the desktop background window
when it is run, which is constructed from the name of your distribution and the
version number. This can be changed to another text by using the
-:option:`--title` option.
+:option:`!--title` option.
The installer file will be written to the "distribution directory" --- normally
-:file:`dist/`, but customizable with the :option:`--dist-dir` option.
+:file:`dist/`, but customizable with the :option:`!--dist-dir` option.
.. _cross-compile-windows:
@@ -341,7 +341,7 @@ Windows platforms. In practice, this means that with the correct tools
installed, you can use a 32bit version of Windows to create 64bit extensions
and vice-versa.
-To build for an alternate platform, specify the :option:`--plat-name` option
+To build for an alternate platform, specify the :option:`!--plat-name` option
to the build command. Valid values are currently 'win32', 'win-amd64' and
'win-ia64'. For example, on a 32bit version of Windows, you could execute::
@@ -355,7 +355,7 @@ support this option, so the command::
would create a 64bit installation executable on your 32bit version of Windows.
To cross-compile, you must download the Python source code and cross-compile
-Python itself for the platform you are targetting - it is not possible from a
+Python itself for the platform you are targeting - it is not possible from a
binary installation of Python (as the .lib etc file for other platforms are
not included.) In practice, this means the user of a 32 bit operating
system will need to use Visual Studio 2008 to open the
@@ -374,14 +374,14 @@ The Postinstallation script
---------------------------
Starting with Python 2.3, a postinstallation script can be specified with the
-:option:`--install-script` option. The basename of the script must be
+:option:`!--install-script` option. The basename of the script must be
specified, and the script filename must also be listed in the scripts argument
to the setup function.
This script will be run at installation time on the target system after all the
-files have been copied, with ``argv[1]`` set to :option:`-install`, and again at
+files have been copied, with ``argv[1]`` set to :option:`!-install`, and again at
uninstallation time before the files are removed with ``argv[1]`` set to
-:option:`-remove`.
+:option:`!-remove`.
The installation script runs embedded in the windows installer, every output
(``sys.stdout``, ``sys.stderr``) is redirected into a buffer and will be
@@ -444,7 +444,7 @@ built-in functions in the installation script.
Vista User Access Control (UAC)
===============================
-Starting with Python 2.6, bdist_wininst supports a :option:`--user-access-control`
+Starting with Python 2.6, bdist_wininst supports a :option:`!--user-access-control`
option. The default is 'none' (meaning no UAC handling is done), and other
valid values are 'auto' (meaning prompt for UAC elevation if Python was
installed for all users) and 'force' (meaning always prompt for elevation).
diff --git a/Doc/distutils/configfile.rst b/Doc/distutils/configfile.rst
index 890047c0..21f1acda 100644
--- a/Doc/distutils/configfile.rst
+++ b/Doc/distutils/configfile.rst
@@ -51,7 +51,7 @@ option values can be split across multiple lines simply by indenting the
continuation lines.
You can find out the list of options supported by a particular command with the
-universal :option:`--help` option, e.g. ::
+universal :option:`!--help` option, e.g. ::
> python setup.py --help build_ext
[...]
@@ -66,19 +66,21 @@ universal :option:`--help` option, e.g. ::
--swig-opts list of SWIG command line options
[...]
-Note that an option spelled :option:`--foo-bar` on the command-line is spelled
-:option:`foo_bar` in configuration files.
+Note that an option spelled :option:`!--foo-bar` on the command-line is spelled
+``foo_bar`` in configuration files.
+
+.. _distutils-build-ext-inplace:
For example, say you want your extensions to be built "in-place"---that is, you
have an extension :mod:`pkg.ext`, and you want the compiled extension file
(:file:`ext.so` on Unix, say) to be put in the same source directory as your
pure Python modules :mod:`pkg.mod1` and :mod:`pkg.mod2`. You can always use the
-:option:`--inplace` option on the command-line to ensure this::
+:option:`!--inplace` option on the command-line to ensure this::
python setup.py build_ext --inplace
But this requires that you always specify the :command:`build_ext` command
-explicitly, and remember to provide :option:`--inplace`. An easier way is to
+explicitly, and remember to provide :option:`!--inplace`. An easier way is to
"set and forget" this option, by encoding it in :file:`setup.cfg`, the
configuration file for this distribution::
@@ -112,7 +114,7 @@ own :file:`setup.cfg`::
doc/
examples/
-Note that the :option:`doc_files` option is simply a whitespace-separated string
+Note that the ``doc_files`` option is simply a whitespace-separated string
split across multiple lines for readability.
diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst
index b4959286..be108a32 100644
--- a/Doc/distutils/examples.rst
+++ b/Doc/distutils/examples.rst
@@ -11,7 +11,7 @@ Distutils Cookbook.
.. seealso::
- `Distutils Cookbook `_
+ `Distutils Cookbook `_
Collection of recipes showing how to achieve more control over distutils.
@@ -22,7 +22,7 @@ Pure Python distribution (by module)
If you're just distributing a couple of modules, especially if they don't live
in a particular package, you can specify them individually using the
-:option:`py_modules` option in the setup script.
+``py_modules`` option in the setup script.
In the simplest case, you'll have two files to worry about: a setup script and
the single module you're distributing, :file:`foo.py` in this example::
@@ -41,12 +41,12 @@ directory.) A minimal setup script to describe this situation would be::
)
Note that the name of the distribution is specified independently with the
-:option:`name` option, and there's no rule that says it has to be the same as
+``name`` option, and there's no rule that says it has to be the same as
the name of the sole module in the distribution (although that's probably a good
convention to follow). However, the distribution name is used to generate
filenames, so you should stick to letters, digits, underscores, and hyphens.
-Since :option:`py_modules` is a list, you can of course specify multiple
+Since ``py_modules`` is a list, you can of course specify multiple
modules, eg. if you're distributing modules :mod:`foo` and :mod:`bar`, your
setup might look like this::
@@ -130,7 +130,7 @@ requires the least work to describe in your setup script::
)
If you want to put modules in directories not named for their package, then you
-need to use the :option:`package_dir` option again. For example, if the
+need to use the ``package_dir`` option again. For example, if the
:file:`src` directory holds modules in the :mod:`foobar` package::
/
@@ -169,8 +169,8 @@ in which case your setup script would be ::
(The empty string also stands for the current directory.)
-If you have sub-packages, they must be explicitly listed in :option:`packages`,
-but any entries in :option:`package_dir` automatically extend to sub-packages.
+If you have sub-packages, they must be explicitly listed in ``packages``,
+but any entries in ``package_dir`` automatically extend to sub-packages.
(In other words, the Distutils does *not* scan your source tree, trying to
figure out which directories correspond to Python packages by looking for
:file:`__init__.py` files.) Thus, if the default layout grows a sub-package::
@@ -193,17 +193,14 @@ then the corresponding setup script would be ::
packages=['foobar', 'foobar.subfoo'],
)
-(Again, the empty string in :option:`package_dir` stands for the current
-directory.)
-
.. _single-ext:
Single extension module
=======================
-Extension modules are specified using the :option:`ext_modules` option.
-:option:`package_dir` has no effect on where extension source files are found;
+Extension modules are specified using the ``ext_modules`` option.
+``package_dir`` has no effect on where extension source files are found;
it only affects the source for pure Python modules. The simplest case, a
single extension module in a single C source file, is::
diff --git a/Doc/distutils/extending.rst b/Doc/distutils/extending.rst
index 5a70d031..501fd7c5 100644
--- a/Doc/distutils/extending.rst
+++ b/Doc/distutils/extending.rst
@@ -61,8 +61,8 @@ commands to be added which can support existing :file:`setup.py` scripts without
requiring modifications to the Python installation. This is expected to allow
third-party extensions to provide support for additional packaging systems, but
the commands can be used for anything distutils commands can be used for. A new
-configuration option, :option:`command_packages` (command-line option
-:option:`--command-packages`), can be used to specify additional packages to be
+configuration option, ``command_packages`` (command-line option
+:option:`!--command-packages`), can be used to specify additional packages to be
searched for modules implementing commands. Like all distutils options, this
can be specified on the command line or in a configuration file. This option
can only be set in the ``[global]`` section of a configuration file, or before
@@ -75,7 +75,7 @@ This new option can be used to add any number of packages to the list of
packages searched for command implementations; multiple package names should be
separated by commas. When not specified, the search is only performed in the
:mod:`distutils.command` package. When :file:`setup.py` is run with the option
-:option:`--command-packages` :option:`distcmds,buildcmds`, however, the packages
+``--command-packages distcmds,buildcmds``, however, the packages
:mod:`distutils.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched
in that order. New commands are expected to be implemented in modules of the
same name as the command by classes sharing the same name. Given the example
diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst
index 1cd5f3c5..a697f50e 100644
--- a/Doc/distutils/index.rst
+++ b/Doc/distutils/index.rst
@@ -1,17 +1,31 @@
.. _distutils-index:
-###############################
- Distributing Python Modules
-###############################
+##############################################
+ Distributing Python Modules (Legacy version)
+##############################################
:Authors: Greg Ward, Anthony Baxter
:Email: distutils-sig@python.org
+.. seealso::
+
+ :ref:`distributing-index`
+ The up to date module distribution documentations
+
This document describes the Python Distribution Utilities ("Distutils") from
the module developer's point of view, describing how to use the Distutils to
make Python modules and extensions easily available to a wider audience with
very little overhead for build/release/install mechanics.
+.. note::
+
+ This guide only covers the basic tools for building and distributing
+ extensions that are provided as part of this version of Python. Third party
+ tools offer easier to use and more secure alternatives. Refer to the `quick
+ recommendations section `__
+ in the Python Packaging User Guide for more information.
+
+
.. toctree::
:maxdepth: 2
:numbered:
diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst
index fc6184fa..488619e3 100644
--- a/Doc/distutils/introduction.rst
+++ b/Doc/distutils/introduction.rst
@@ -94,7 +94,7 @@ containing your setup script :file:`setup.py`, and your module :file:`foo.py`.
The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and
will unpack into a directory :file:`foo-1.0`.
-If an end-user wishes to install your :mod:`foo` module, all she has to do is
+If an end-user wishes to install your :mod:`foo` module, all they have to do is
download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the
:file:`foo-1.0` directory---run ::
@@ -193,8 +193,8 @@ modules using the Distutils:
module distribution
a collection of Python modules distributed together as a single downloadable
resource and meant to be installed *en masse*. Examples of some well-known
- module distributions are Numeric Python, PyXML, PIL (the Python Imaging
- Library), or mxBase. (This would be called a *package*, except that term is
+ module distributions are Numeric Python, PyXML, Pillow,
+ or mxBase. (This would be called a *package*, except that term is
already taken in the Python context: a single module distribution may contain
zero, one, or many Python packages.)
diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst
index 1d724e2c..f74c4396 100644
--- a/Doc/distutils/packageindex.rst
+++ b/Doc/distutils/packageindex.rst
@@ -8,208 +8,10 @@
The Python Package Index (PyPI)
*******************************
-The `Python Package Index (PyPI)`_ holds :ref:`meta-data `
-describing distributions packaged with distutils, as well as package data like
-distribution files if the package author wishes.
+The `Python Package Index (PyPI)`_ stores metadata describing distributions
+packaged with distutils and other publishing tools, as well the distribution
+archives themselves.
-Distutils exposes two commands for submitting package data to PyPI: the
-:ref:`register ` command for submitting meta-data to PyPI
-and the :ref:`upload ` command for submitting distribution
-files. Both commands read configuration data from a special file called the
-:ref:`.pypirc file `. PyPI :ref:`displays a home page
-` for each package created from the ``long_description``
-submitted by the :command:`register` command.
+Detailed instructions on using PyPI at :ref:`distributing-index`.
-
-.. _package-register:
-
-Registering Packages
-====================
-
-The distutils command :command:`register` is used to submit your distribution's
-meta-data to the index. It is invoked as follows::
-
- python setup.py register
-
-Distutils will respond with the following prompt::
-
- running register
- We need to know who you are, so please choose either:
- 1. use your existing login,
- 2. register as a new user,
- 3. have the server generate a new password for you (and email it to you), or
- 4. quit
- Your selection [default 1]:
-
-Note: if your username and password are saved locally, you will not see this
-menu.
-
-If you have not registered with PyPI, then you will need to do so now. You
-should choose option 2, and enter your details as required. Soon after
-submitting your details, you will receive an email which will be used to confirm
-your registration.
-
-Once you are registered, you may choose option 1 from the menu. You will be
-prompted for your PyPI username and password, and :command:`register` will then
-submit your meta-data to the index.
-
-You may submit any number of versions of your distribution to the index. If you
-alter the meta-data for a particular version, you may submit it again and the
-index will be updated.
-
-PyPI holds a record for each (name, version) combination submitted. The first
-user to submit information for a given name is designated the Owner of that
-name. They may submit changes through the :command:`register` command or through
-the web interface. They may also designate other users as Owners or Maintainers.
-Maintainers may edit the package information, but not designate other Owners or
-Maintainers.
-
-By default PyPI displays only the newest version of a given package. The web
-interface lets one change this default behavior and manually select which
-versions to display and hide.
-
-
-.. _package-upload:
-
-Uploading Packages
-==================
-
-.. versionadded:: 2.5
-
-The distutils command :command:`upload` pushes the distribution files to PyPI.
-
-The command is invoked immediately after building one or more distribution
-files. For example, the command ::
-
- python setup.py sdist bdist_wininst upload
-
-will cause the source distribution and the Windows installer to be uploaded to
-PyPI. Note that these will be uploaded even if they are built using an earlier
-invocation of :file:`setup.py`, but that only distributions named on the command
-line for the invocation including the :command:`upload` command are uploaded.
-
-The :command:`upload` command uses the username, password, and repository URL
-from the :file:`$HOME/.pypirc` file (see section :ref:`pypirc` for more on this
-file). If a :command:`register` command was previously called in the same command,
-and if the password was entered in the prompt, :command:`upload` will reuse the
-entered password. This is useful if you do not want to store a clear text
-password in the :file:`$HOME/.pypirc` file.
-
-You can specify another PyPI server with the ``--repository=url`` option::
-
- python setup.py sdist bdist_wininst upload -r http://example.com/pypi
-
-See section :ref:`pypirc` for more on defining several servers.
-
-You can use the ``--sign`` option to tell :command:`upload` to sign each
-uploaded file using GPG (GNU Privacy Guard). The :program:`gpg` program must
-be available for execution on the system :envvar:`PATH`. You can also specify
-which key to use for signing using the ``--identity=name`` option.
-
-Other :command:`upload` options include ``--repository=url`` or
-``--repository=section`` where *url* is the url of the server and
-*section* the name of the section in :file:`$HOME/.pypirc`, and
-``--show-response`` (which displays the full response text from the PyPI
-server for help in debugging upload problems).
-
-
-.. index::
- single: .pypirc file
- single: Python Package Index (PyPI); .pypirc file
-
-.. _pypirc:
-
-The .pypirc file
-================
-
-The format of the :file:`.pypirc` file is as follows::
-
- [distutils]
- index-servers =
- pypi
-
- [pypi]
- repository:
- username:
- password:
-
-The *distutils* section defines a *index-servers* variable that lists the
-name of all sections describing a repository.
-
-Each section describing a repository defines three variables:
-
-- *repository*, that defines the url of the PyPI server. Defaults to
- ``http://www.python.org/pypi``.
-- *username*, which is the registered username on the PyPI server.
-- *password*, that will be used to authenticate. If omitted the user
- will be prompt to type it when needed.
-
-If you want to define another server a new section can be created and
-listed in the *index-servers* variable::
-
- [distutils]
- index-servers =
- pypi
- other
-
- [pypi]
- repository:
- username:
- password:
-
- [other]
- repository: http://example.com/pypi
- username:
- password:
-
-:command:`register` can then be called with the -r option to point the
-repository to work with::
-
- python setup.py register -r http://example.com/pypi
-
-For convenience, the name of the section that describes the repository
-may also be used::
-
- python setup.py register -r other
-
-
-.. _package-display:
-
-PyPI package display
-====================
-
-The ``long_description`` field plays a special role at PyPI. It is used by
-the server to display a home page for the registered package.
-
-If you use the `reStructuredText `_
-syntax for this field, PyPI will parse it and display an HTML output for
-the package home page.
-
-The ``long_description`` field can be attached to a text file located
-in the package::
-
- from distutils.core import setup
-
- with open('README.txt') as file:
- long_description = file.read()
-
- setup(name='Distutils',
- long_description=long_description)
-
-In that case, :file:`README.txt` is a regular reStructuredText text file located
-in the root of the package besides :file:`setup.py`.
-
-To prevent registering broken reStructuredText content, you can use the
-:program:`rst2html` program that is provided by the :mod:`docutils` package and
-check the ``long_description`` from the command line::
-
- $ python setup.py --long-description | rst2html.py > output.html
-
-:mod:`docutils` will display a warning if there's something wrong with your
-syntax. Because PyPI applies additional checks (e.g. by passing ``--no-raw``
-to ``rst2html.py`` in the command above), being able to run the command above
-without warnings does not guarantee that PyPI will convert the content
-successfully.
-
-
-.. _Python Package Index (PyPI): http://pypi.python.org/
+.. _Python Package Index (PyPI): https://pypi.org
diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst
index 1d13a9cc..fae570f9 100644
--- a/Doc/distutils/setupscript.rst
+++ b/Doc/distutils/setupscript.rst
@@ -28,7 +28,7 @@ the package into Python 1.5.2.) ::
description='Python Distribution Utilities',
author='Greg Ward',
author_email='gward@python.net',
- url='http://www.python.org/sigs/distutils-sig/',
+ url='https://www.python.org/sigs/distutils-sig/',
packages=['distutils', 'distutils.command'],
)
@@ -62,9 +62,9 @@ code instead of hardcoding path separators::
Listing whole packages
======================
-The :option:`packages` option tells the Distutils to process (build, distribute,
+The ``packages`` option tells the Distutils to process (build, distribute,
install, etc.) all pure Python modules found in each package mentioned in the
-:option:`packages` list. In order to do this, of course, there has to be a
+``packages`` list. In order to do this, of course, there has to be a
correspondence between package names and directories in the filesystem. The
default correspondence is the most obvious one, i.e. package :mod:`distutils` is
found in the directory :file:`distutils` relative to the distribution root.
@@ -75,7 +75,7 @@ the directory where your setup script lives. If you break this promise, the
Distutils will issue a warning but still process the broken package anyway.
If you use a different convention to lay out your source directory, that's no
-problem: you just have to supply the :option:`package_dir` option to tell the
+problem: you just have to supply the ``package_dir`` option to tell the
Distutils about your convention. For example, say you keep all Python source
under :file:`lib`, so that modules in the "root package" (i.e., not in any
package at all) are in :file:`lib`, modules in the :mod:`foo` package are in
@@ -94,13 +94,13 @@ written in the setup script as ::
package_dir = {'foo': 'lib'}
-A ``package: dir`` entry in the :option:`package_dir` dictionary implicitly
+A ``package: dir`` entry in the ``package_dir`` dictionary implicitly
applies to all packages below *package*, so the :mod:`foo.bar` case is
automatically handled here. In this example, having ``packages = ['foo',
'foo.bar']`` tells the Distutils to look for :file:`lib/__init__.py` and
-:file:`lib/bar/__init__.py`. (Keep in mind that although :option:`package_dir`
+:file:`lib/bar/__init__.py`. (Keep in mind that although ``package_dir``
applies recursively, you must explicitly list all packages in
-:option:`packages`: the Distutils will *not* recursively scan your source tree
+``packages``: the Distutils will *not* recursively scan your source tree
looking for any directory with an :file:`__init__.py` file.)
@@ -120,7 +120,7 @@ This describes two modules, one of them in the "root" package, the other in the
:mod:`pkg` package. Again, the default package/directory layout implies that
these two modules can be found in :file:`mod1.py` and :file:`pkg/mod2.py`, and
that :file:`pkg/__init__.py` exists as well. And again, you can override the
-package/directory correspondence using the :option:`package_dir` option.
+package/directory correspondence using the ``package_dir`` option.
.. _describing-extensions:
@@ -138,7 +138,7 @@ directories, libraries to link with, etc.).
.. XXX read over this section
All of this is done through another keyword argument to :func:`setup`, the
-:option:`ext_modules` option. :option:`ext_modules` is just a list of
+``ext_modules`` option. ``ext_modules`` is just a list of
:class:`~distutils.core.Extension` instances, each of which describes a
single extension module.
Suppose your distribution includes a single extension, called :mod:`foo` and
@@ -181,7 +181,7 @@ in the filesystem (and therefore where in Python's namespace hierarchy) the
resulting extension lives.
If you have a number of extensions all in the same package (or all under the
-same base package), use the :option:`ext_package` keyword argument to
+same base package), use the ``ext_package`` keyword argument to
:func:`setup`. For example, ::
setup(...,
@@ -201,7 +201,7 @@ The second argument to the :class:`~distutils.core.Extension` constructor is
a list of source
files. Since the Distutils currently only support C, C++, and Objective-C
extensions, these are normally C/C++/Objective-C source files. (Be sure to use
-appropriate extensions to distinguish C++\ source files: :file:`.cc` and
+appropriate extensions to distinguish C++ source files: :file:`.cc` and
:file:`.cpp` seem to be recognized by both Unix and Windows compilers.)
However, you can also include SWIG interface (:file:`.i`) files in the list; the
@@ -336,20 +336,20 @@ Other options
There are still some other options which can be used to handle special cases.
-The :option:`extra_objects` option is a list of object files to be passed to the
+The ``extra_objects`` option is a list of object files to be passed to the
linker. These files must not have extensions, as the default extension for the
compiler is used.
-:option:`extra_compile_args` and :option:`extra_link_args` can be used to
+``extra_compile_args`` and ``extra_link_args`` can be used to
specify additional command line options for the respective compiler and linker
command lines.
-:option:`export_symbols` is only useful on Windows. It can contain a list of
+``export_symbols`` is only useful on Windows. It can contain a list of
symbols (functions or variables) to be exported. This option is not needed when
building compiled extensions: Distutils will automatically add ``initmodule``
to the list of exported symbols.
-The :option:`depends` option is a list of files that the extension depends on
+The ``depends`` option is a list of files that the extension depends on
(for example header files). The build command will call the compiler on the
sources to rebuild extension if any on this files has been modified since the
previous build.
@@ -442,10 +442,10 @@ command line. Scripts don't require Distutils to do anything very complicated.
The only clever feature is that if the first line of the script starts with
``#!`` and contains the word "python", the Distutils will adjust the first line
to refer to the current interpreter location. By default, it is replaced with
-the current interpreter location. The :option:`--executable` (or :option:`-e`)
+the current interpreter location. The :option:`!--executable` (or :option:`!-e`)
option will allow the interpreter path to be explicitly overridden.
-The :option:`scripts` option simply is a list of files to be handled in this
+The ``scripts`` option simply is a list of files to be handled in this
way. From the PyXML setup script::
setup(...,
@@ -510,32 +510,35 @@ The corresponding call to :func:`setup` might be::
Installing Additional Files
===========================
-The :option:`data_files` option can be used to specify additional files needed
+The ``data_files`` option can be used to specify additional files needed
by the module distribution: configuration files, message catalogs, data files,
anything which doesn't fit in the previous categories.
-:option:`data_files` specifies a sequence of (*directory*, *files*) pairs in the
+``data_files`` specifies a sequence of (*directory*, *files*) pairs in the
following way::
setup(...,
data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
('config', ['cfg/data.cfg']),
- ('/etc/init.d', ['init-script'])]
)
-Note that you can specify the directory names where the data files will be
-installed, but you cannot rename the data files themselves.
-
Each (*directory*, *files*) pair in the sequence specifies the installation
-directory and the files to install there. If *directory* is a relative path, it
-is interpreted relative to the installation prefix (Python's ``sys.prefix`` for
-pure-Python packages, ``sys.exec_prefix`` for packages that contain extension
-modules). Each file name in *files* is interpreted relative to the
-:file:`setup.py` script at the top of the package source distribution. No
-directory information from *files* is used to determine the final location of
-the installed file; only the name of the file is used.
-
-You can specify the :option:`data_files` options as a simple sequence of files
+directory and the files to install there.
+
+Each file name in *files* is interpreted relative to the :file:`setup.py`
+script at the top of the package source distribution. Note that you can
+specify the directory where the data files will be installed, but you cannot
+rename the data files themselves.
+
+The *directory* should be a relative path. It is interpreted relative to the
+installation prefix (Python's ``sys.prefix`` for system installations;
+``site.USER_BASE`` for user installations). Distutils allows *directory* to be
+an absolute installation path, but this is discouraged since it is
+incompatible with the wheel packaging format. No directory information from
+*files* is used to determine the final location of the installed file; only
+the name of the file is used.
+
+You can specify the ``data_files`` options as a simple sequence of files
without specifying a target directory, but this is not recommended, and the
:command:`install` command will print a warning in this case. To install data
files directly in the target directory, an empty string should be given as the
@@ -606,12 +609,11 @@ Notes:
(4)
These fields should not be used if your package is to be compatible with Python
versions prior to 2.2.3 or 2.3. The list is available from the `PyPI website
- `_.
+ `_.
(5)
- The ``long_description`` field is used by PyPI when you are
- :ref:`registering ` a package, to
- :ref:`build its home page `.
+ The ``long_description`` field is used by PyPI when you publish a package,
+ to build its project page.
(6)
The ``license`` field is a text indicating the license covering the
@@ -625,7 +627,7 @@ Notes:
'long string'
Multiple lines of plain text in reStructuredText format (see
- http://docutils.sf.net/).
+ http://docutils.sourceforge.net/).
'list of strings'
See below.
@@ -649,7 +651,7 @@ information is sometimes used to indicate sub-releases. These are
1.0.1a2
the second alpha release of the first patch version of 1.0
-:option:`classifiers` are specified in a Python list::
+``classifiers`` are specified in a Python list::
setup(...,
classifiers=[
@@ -684,6 +686,8 @@ include the following code fragment in your :file:`setup.py` before the
DistributionMetadata.download_url = None
+.. _debug-setup-script:
+
Debugging the setup script
==========================
@@ -699,7 +703,8 @@ installation is broken because they don't read all the way down to the bottom
and see that it's a permission problem.
On the other hand, this doesn't help the developer to find the cause of the
-failure. For this purpose, the DISTUTILS_DEBUG environment variable can be set
+failure. For this purpose, the :envvar:`DISTUTILS_DEBUG` environment variable can be set
to anything except an empty string, and distutils will now print detailed
-information what it is doing, and prints the full traceback in case an exception
-occurs.
+information about what it is doing, dump the full traceback when an exception
+occurs, and print the whole command line when an external program (like a C
+compiler) fails.
diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst
index b1695a25..19c2d566 100644
--- a/Doc/distutils/sourcedist.rst
+++ b/Doc/distutils/sourcedist.rst
@@ -14,7 +14,7 @@ or config file), :command:`sdist` creates the archive of the default format for
the current platform. The default format is a gzip'ed tar file
(:file:`.tar.gz`) on Unix, and ZIP file on Windows.
-You can specify as many formats as you like using the :option:`--formats`
+You can specify as many formats as you like using the :option:`!--formats`
option, for example::
python setup.py sdist --formats=gztar,zip
@@ -71,16 +71,16 @@ If you don't supply an explicit list of files (or instructions on how to
generate one), the :command:`sdist` command puts a minimal default set into the
source distribution:
-* all Python source files implied by the :option:`py_modules` and
- :option:`packages` options
+* all Python source files implied by the ``py_modules`` and
+ ``packages`` options
-* all C source files mentioned in the :option:`ext_modules` or
- :option:`libraries` options
+* all C source files mentioned in the ``ext_modules`` or
+ ``libraries`` options
.. XXX Getting C library sources is currently broken -- no
:meth:`get_source_files` method in :file:`build_clib.py`!
-* scripts identified by the :option:`scripts` option
+* scripts identified by the ``scripts`` option
See :ref:`distutils-installing-scripts`.
* anything that looks like a test script: :file:`test/test\*.py` (currently, the
@@ -147,7 +147,7 @@ The normal course of operations for the :command:`sdist` command is as follows:
in) to create the source distribution archive(s)
There are a couple of options that modify this behaviour. First, use the
-:option:`--no-defaults` and :option:`--no-prune` to disable the standard
+:option:`!--no-defaults` and :option:`!--no-prune` to disable the standard
"include" and "exclude" sets.
Second, you might just want to (re)generate the manifest, but not create a
@@ -155,7 +155,7 @@ source distribution::
python setup.py sdist --manifest-only
-:option:`-o` is a shortcut for :option:`--manifest-only`.
+:option:`!-o` is a shortcut for :option:`!--manifest-only`.
.. _manifest_template:
@@ -189,7 +189,7 @@ matching :file:`\*.txt` or :file:`\*.py`, and exclude all directories matching
:file:`examples/sample?/build`. All of this is done *after* the standard
include set, so you can exclude files from the standard set with explicit
instructions in the manifest template. (Or, you can use the
-:option:`--no-defaults` option to disable the standard set entirely.)
+:option:`!--no-defaults` option to disable the standard set entirely.)
The order of commands in the manifest template matters: initially, we have the
list of default files as described above, and each command in the template adds
@@ -206,8 +206,8 @@ Now we have our complete list of files, which is written to the manifest for
future reference, and then used to build the source distribution archive(s).
You can disable the default set of included files with the
-:option:`--no-defaults` option, and you can disable the standard exclude set
-with :option:`--no-prune`.
+:option:`!--no-defaults` option, and you can disable the standard exclude set
+with :option:`!--no-prune`.
Following the Distutils' own manifest template, let's trace how the
:command:`sdist` command builds the list of files to include in the Distutils
@@ -215,7 +215,7 @@ source distribution:
#. include all Python source files in the :file:`distutils` and
:file:`distutils/command` subdirectories (because packages corresponding to
- those two directories were mentioned in the :option:`packages` option in the
+ those two directories were mentioned in the ``packages`` option in the
setup script---see section :ref:`setup-script`)
#. include :file:`README.txt`, :file:`setup.py`, and :file:`setup.cfg` (standard
diff --git a/Doc/docutils.conf b/Doc/docutils.conf
new file mode 100644
index 00000000..bda4f5dc
--- /dev/null
+++ b/Doc/docutils.conf
@@ -0,0 +1,2 @@
+[restructuredtext parser]
+smartquotes-locales: ja: ""''
diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst
index 08b0cc2c..f32192bd 100644
--- a/Doc/extending/building.rst
+++ b/Doc/extending/building.rst
@@ -24,7 +24,9 @@ packages, users don't necessarily need a compiler and distutils to install the
extension.
A distutils package contains a driver script, :file:`setup.py`. This is a plain
-Python file, which, in the most simple case, could look like this::
+Python file, which, in the most simple case, could look like this:
+
+.. code-block:: python
from distutils.core import setup, Extension
@@ -56,7 +58,7 @@ documentation in :ref:`distutils-index` to learn more about the features of
distutils; this section explains building extension modules only.
It is common to pre-compute arguments to :func:`setup`, to better structure the
-driver script. In the example above, the\ ``ext_modules`` argument to
+driver script. In the example above, the ``ext_modules`` argument to
:func:`setup` is a list of extension modules, each of which is an instance of
the :class:`~distutils.extension.Extension`. In the example, the instance
defines an extension named ``demo`` which is build by compiling a single source
@@ -64,7 +66,9 @@ file, :file:`demo.c`.
In many cases, building an extension is more complex, since additional
preprocessor defines and libraries may be needed. This is demonstrated in the
-example below. ::
+example below.
+
+.. code-block:: python
from distutils.core import setup, Extension
@@ -81,7 +85,7 @@ example below. ::
description = 'This is a demo package',
author = 'Martin v. Loewis',
author_email = 'martin@v.loewis.de',
- url = 'http://docs.python.org/extending/building',
+ url = 'https://docs.python.org/extending/building',
long_description = '''
This is really just a demo package.
''',
@@ -129,4 +133,3 @@ commands can be used to do so. ::
python setup.py bdist_wininst
python setup.py bdist_rpm
python setup.py bdist_dumb
-
diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst
index 981e1d54..2330cdbc 100644
--- a/Doc/extending/embedding.rst
+++ b/Doc/extending/embedding.rst
@@ -151,7 +151,9 @@ array. If you compile and link this program (let's call the finished executable
c = c + b
return c
-then the result should be::
+then the result should be:
+
+.. code-block:: shell-session
$ call multiply multiply 3 2
Will compute 3 times 2
@@ -274,16 +276,20 @@ available). This script has several options, of which the following will
be directly useful to you:
* ``pythonX.Y-config --cflags`` will give you the recommended flags when
- compiling::
+ compiling:
+
+ .. code-block:: shell-session
- $ /opt/bin/python2.7-config --cflags
- -I/opt/include/python2.7 -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
+ $ /opt/bin/python2.7-config --cflags
+ -I/opt/include/python2.7 -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
* ``pythonX.Y-config --ldflags`` will give you the recommended flags when
- linking::
+ linking:
+
+ .. code-block:: shell-session
- $ /opt/bin/python2.7-config --ldflags
- -L/opt/lib/python2.7/config -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic
+ $ /opt/bin/python2.7-config --ldflags
+ -L/opt/lib/python2.7/config -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic
.. note::
To avoid confusion between several Python installations (and especially
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index 8e8c3ab5..991289c1 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -20,12 +20,17 @@ source file by including the header ``"Python.h"``.
The compilation of an extension module depends on its intended use as well as on
your system setup; details are given in later chapters.
-Do note that if your use case is calling C library functions or system calls,
-you should consider using the :mod:`ctypes` module rather than writing custom
-C code. Not only does :mod:`ctypes` let you write Python code to interface
-with C code, but it is more portable between implementations of Python than
-writing and compiling an extension module which typically ties you to CPython.
+.. note::
+ The C extension interface is specific to CPython, and extension modules do
+ not work on other Python implementations. In many cases, it is possible to
+ avoid writing C extensions and preserve portability to other implementations.
+ For example, if your use case is calling C library functions or system calls,
+ you should consider using the :mod:`ctypes` module or the `cffi
+ `_ library rather than writing custom C code.
+ These modules let you write Python code to interface with C code and are more
+ portable between implementations of Python than writing and compiling a C
+ extension module.
.. _extending-simpleexample:
@@ -35,7 +40,7 @@ A Simple Example
Let's create an extension module called ``spam`` (the favorite food of Monty
Python fans...) and let's say we want to create a Python interface to the C
-library function :c:func:`system`. [#]_ This function takes a null-terminated
+library function :c:func:`system` [#]_. This function takes a null-terminated
character string as argument and returns an integer. We want this function to
be callable from Python as follows::
@@ -89,8 +94,9 @@ example, the single expression ``"ls -l"``) to the arguments passed to the C
function. The C function always has two arguments, conventionally named *self*
and *args*.
-The *self* argument points to the module object for module-level functions;
-for a method it would point to the object instance.
+For module functions, the *self* argument is *NULL* or a pointer selected while
+initializing the module (see :c:func:`Py_InitModule4`). For a method, it would
+point to the object instance.
The *args* argument will be a pointer to a Python tuple object containing the
arguments. Each item of the tuple corresponds to an argument in the call's
@@ -757,7 +763,9 @@ the format string is empty, it returns ``None``; if it contains exactly one
format unit, it returns whatever object is described by that format unit. To
force it to return a tuple of size 0 or one, parenthesize the format string.
-Examples (to the left the call, to the right the resulting Python value)::
+Examples (to the left the call, to the right the resulting Python value):
+
+.. code-block:: none
Py_BuildValue("") None
Py_BuildValue("i", 123) 123
@@ -850,7 +858,7 @@ The :mod:`gc` module also exposes a way to run the detector (the
:func:`~gc.collect` function), as well as configuration
interfaces and the ability to disable the detector at runtime. The cycle
detector is considered an optional component; though it is included by default,
-it can be disabled at build time using the :option:`--without-cycle-gc` option
+it can be disabled at build time using the :option:`!--without-cycle-gc` option
to the :program:`configure` script on Unix platforms (including Mac OS X) or by
removing the definition of ``WITH_CYCLE_GC`` in the :file:`pyconfig.h` header on
other platforms. If the cycle detector is disabled in this way, the :mod:`gc`
@@ -882,7 +890,7 @@ It is also possible to :dfn:`borrow` [#]_ a reference to an object. The
borrower of a reference should not call :c:func:`Py_DECREF`. The borrower must
not hold on to the object longer than the owner from which it was borrowed.
Using a borrowed reference after the owner has disposed of it risks using freed
-memory and should be avoided completely. [#]_
+memory and should be avoided completely [#]_.
The advantage of borrowing over owning a reference is that you don't need to
take care of disposing of the reference on all possible paths through the code
@@ -1053,7 +1061,7 @@ checking.
The C function calling mechanism guarantees that the argument list passed to C
functions (``args`` in the examples) is never *NULL* --- in fact it guarantees
-that it is always a tuple. [#]_
+that it is always a tuple [#]_.
It is a severe error to ever let a *NULL* pointer "escape" to the Python user.
diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst
index 61129439..1ba5d5aa 100644
--- a/Doc/extending/index.rst
+++ b/Doc/extending/index.rst
@@ -21,6 +21,15 @@ 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`.
+.. note::
+
+ This guide only covers the basic tools for creating extensions provided
+ as part of this version of CPython. Third party tools may offer simpler
+ alternatives. Refer to the `binary extensions section
+ `__ in the Python
+ Packaging User Guide for more information.
+
+
.. toctree::
:maxdepth: 2
:numbered:
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index d76aa249..a60c0244 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -25,7 +25,7 @@ are some details that you need to understand before you can get started.
Python 2.2. This document documents how to define new types for Python 2.2 and
later. If you need to support older versions of Python, you will need to refer
to `older versions of this documentation
- `_.
+ `_.
.. _dnt-basics:
@@ -79,27 +79,26 @@ Python integers::
Moving on, we come to the crunch --- the type object. ::
static PyTypeObject noddy_NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(noddy_NoddyObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- 0, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(noddy_NoddyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
"Noddy objects", /* tp_doc */
};
@@ -111,23 +110,16 @@ it's common practice to not specify them explicitly unless you need them.
This is so important that we're going to pick the top of it apart still
further::
- PyObject_HEAD_INIT(NULL)
+ PyVarObject_HEAD_INIT(NULL, 0)
This line is a bit of a wart; what we'd like to write is::
- PyObject_HEAD_INIT(&PyType_Type)
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
as the type of a type object is "type", but this isn't strictly conforming C and
some compilers complain. Fortunately, this member will be filled in for us by
:c:func:`PyType_Ready`. ::
- 0, /* ob_size */
-
-The :attr:`ob_size` field of the header is not used; its presence in the type
-structure is a historical artifact that is maintained for binary compatibility
-with extension modules compiled for older versions of Python. Always set this
-field to zero. ::
-
"noddy.Noddy", /* tp_name */
The name of our type. This will appear in the default textual representation of
@@ -135,12 +127,14 @@ our objects and in some error messages, for example::
>>> "" + noddy.new_noddy()
Traceback (most recent call last):
- File "", line 1, in ?
+ File "", line 1, in
TypeError: cannot add type "noddy.Noddy" to string
Note that the name is a dotted name that includes both the module name and the
name of the type within the module. The module in this case is :mod:`noddy` and
-the type is :class:`Noddy`, so we set the type name to :class:`noddy.Noddy`. ::
+the type is :class:`Noddy`, so we set the type name to :class:`noddy.Noddy`.
+One side effect of using an undotted name is that the pydoc documentation tool
+will not list the new type in the module documentation. ::
sizeof(noddy_NoddyObject), /* tp_basicsize */
@@ -169,7 +163,7 @@ for now.
Skipping a number of type methods that we don't provide, we set the class flags
to :const:`Py_TPFLAGS_DEFAULT`. ::
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
All types should include this constant in their flags. It enables all of the
members defined by the current version of Python.
@@ -223,7 +217,9 @@ That's it! All that remains is to build it; put the above code in a file called
setup(name="noddy", version="1.0",
ext_modules=[Extension("noddy", ["noddy.c"])])
-in a file called :file:`setup.py`; then typing ::
+in a file called :file:`setup.py`; then typing
+
+.. code-block:: shell-session
$ python setup.py build
@@ -240,7 +236,7 @@ doesn't do anything. It can't even be subclassed.
Adding data and methods to the Basic example
--------------------------------------------
-Let's expend the basic example to add some data and methods. Let's also make
+Let's extend the basic example to add some data and methods. Let's also make
the type usable as a base class. We'll create a new module, :mod:`noddy2` that
adds these capabilities:
@@ -280,7 +276,7 @@ allocation and deallocation. At a minimum, we need a deallocation method::
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::
@@ -493,7 +489,7 @@ concatenation of the first and last names. ::
The method is implemented as a C function that takes a :class:`Noddy` (or
:class:`Noddy` subclass) instance as the first argument. Methods always take an
instance as the first argument. Methods often take positional and keyword
-arguments as well, but in this cased we don't take any and don't need to accept
+arguments as well, but in this case we don't take any and don't need to accept
a positional argument tuple or keyword argument dictionary. This method is
equivalent to the Python method::
@@ -689,7 +685,7 @@ Fortunately, Python's cyclic-garbage collector will eventually figure out that
the list is garbage and free it.
In the second version of the :class:`Noddy` example, we allowed any kind of
-object to be stored in the :attr:`first` or :attr:`last` attributes. [#]_ This
+object to be stored in the :attr:`first` or :attr:`last` attributes [#]_. This
means that :class:`Noddy` objects can participate in cycles::
>>> import noddy2
@@ -752,8 +748,9 @@ simplified::
uniformity across these boring implementations.
We also need to provide a method for clearing any subobjects that can
-participate in cycles. We implement the method and reimplement the deallocator
-to use it::
+participate in cycles.
+
+::
static int
Noddy_clear(Noddy *self)
@@ -771,13 +768,6 @@ to use it::
return 0;
}
- static void
- Noddy_dealloc(Noddy* self)
- {
- Noddy_clear(self);
- self->ob_type->tp_free((PyObject*)self);
- }
-
Notice the use of a temporary variable in :c:func:`Noddy_clear`. We use the
temporary variable so that we can set each member to *NULL* before decrementing
its reference count. We do this because, as was discussed earlier, if the
@@ -800,9 +790,26 @@ decrementing of reference counts. With :c:func:`Py_CLEAR`, the
return 0;
}
+Note that :c:func:`Noddy_dealloc` may call arbitrary functions through
+``__del__`` method or weakref callback. It means circular GC can be
+triggered inside the function. Since GC assumes reference count is not zero,
+we need to untrack the object from GC by calling :c:func:`PyObject_GC_UnTrack`
+before clearing members. Here is reimplemented deallocator which uses
+:c:func:`PyObject_GC_UnTrack` and :c:func:`Noddy_clear`.
+
+::
+
+ static void
+ Noddy_dealloc(Noddy* self)
+ {
+ PyObject_GC_UnTrack(self);
+ Noddy_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+ }
+
Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
That's pretty much it. If we had written custom :c:member:`~PyTypeObject.tp_alloc` or
:c:member:`~PyTypeObject.tp_free` slots, we'd need to modify them for cyclic-garbage collection.
@@ -961,14 +968,15 @@ Finalization and De-allocation
This function is called when the reference count of the instance of your type is
reduced to zero and the Python interpreter wants to reclaim it. If your type
-has memory to free or other clean-up to perform, put it here. The object itself
-needs to be freed here as well. Here is an example of this function::
+has memory to free or other clean-up to perform, you can put it here. The
+object itself needs to be freed here as well. Here is an example of this
+function::
static void
newdatatype_dealloc(newdatatypeobject * obj)
{
free(obj->obj_UnderlyingDatatypePtr);
- obj->ob_type->tp_free(obj);
+ Py_TYPE(obj)->tp_free(obj);
}
.. index::
@@ -1011,7 +1019,7 @@ done. This can be done using the :c:func:`PyErr_Fetch` and
Py_DECREF(self->my_callback);
}
- obj->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(obj)->tp_free((PyObject*)self);
}
@@ -1166,10 +1174,10 @@ If :c:member:`~PyTypeObject.tp_methods` is not *NULL*, it must refer to an array
structure::
typedef struct PyMethodDef {
- char *ml_name; /* method name */
+ const char *ml_name; /* method name */
PyCFunction ml_meth; /* implementation function */
int ml_flags; /* flags */
- char *ml_doc; /* docstring */
+ const char *ml_doc; /* docstring */
} PyMethodDef;
One entry should be defined for each method provided by the type; no entries are
@@ -1580,4 +1588,3 @@ might be something like the following::
.. [#] Even in the third version, we aren't guaranteed to avoid cycles. Instances of
string subclasses are allowed and string subclasses could allow cycles even if
normal strings don't.
-
diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst
index 66b518d8..67bdd475 100644
--- a/Doc/extending/windows.rst
+++ b/Doc/extending/windows.rst
@@ -37,154 +37,9 @@ There are two approaches to building extension modules on Windows, just as there
are on Unix: use the :mod:`distutils` package to control the build process, or
do things manually. The distutils approach works well for most extensions;
documentation on using :mod:`distutils` to build and package extension modules
-is available in :ref:`distutils-index`. This section describes the manual
-approach to building Python extensions written in C or C++.
-
-To build extensions using these instructions, you need to have a copy of the
-Python sources of the same version as your installed Python. You will need
-Microsoft Visual C++ "Developer Studio"; project files are supplied for VC++
-version 7.1, but you can use older versions of VC++. Notice that you should use
-the same version of VC++that was used to build Python itself. The example files
-described here are distributed with the Python sources in the
-:file:`PC\\example_nt\\` directory.
-
-#. **Copy the example files** --- The :file:`example_nt` directory is a
- subdirectory of the :file:`PC` directory, in order to keep all the PC-specific
- files under the same directory in the source distribution. However, the
- :file:`example_nt` directory can't actually be used from this location. You
- first need to copy or move it up one level, so that :file:`example_nt` is a
- sibling of the :file:`PC` and :file:`Include` directories. Do all your work
- from within this new location.
-
-#. **Open the project** --- From VC++, use the :menuselection:`File --> Open
- Solution` dialog (not :menuselection:`File --> Open`!). Navigate to and select
- the file :file:`example.sln`, in the *copy* of the :file:`example_nt` directory
- you made above. Click Open.
-
-#. **Build the example DLL** --- In order to check that everything is set up
- right, try building:
-
-#. Select a configuration. This step is optional. Choose
- :menuselection:`Build --> Configuration Manager --> Active Solution Configuration`
- and select either :guilabel:`Release` or :guilabel:`Debug`. If you skip this
- step, VC++ will use the Debug configuration by default.
-
-#. Build the DLL. Choose :menuselection:`Build --> Build Solution`. This
- creates all intermediate and result files in a subdirectory called either
- :file:`Debug` or :file:`Release`, depending on which configuration you selected
- in the preceding step.
-
-#. **Testing the debug-mode DLL** --- Once the Debug build has succeeded, bring
- up a DOS box, and change to the :file:`example_nt\\Debug` directory. You should
- now be able to repeat the following session (``C>`` is the DOS prompt, ``>>>``
- is the Python prompt; note that build information and various debug output from
- Python may not match this screen dump exactly)::
-
- C>..\..\PCbuild\python_d
- Adding parser accelerators ...
- Done.
- Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32
- Type "copyright", "credits" or "license" for more information.
- >>> import example
- [4897 refs]
- >>> example.foo()
- Hello, world
- [4903 refs]
- >>>
-
- Congratulations! You've successfully built your first Python extension module.
-
-#. **Creating your own project** --- Choose a name and create a directory for
- it. Copy your C sources into it. Note that the module source file name does
- not necessarily have to match the module name, but the name of the
- initialization function should match the module name --- you can only import a
- module :mod:`spam` if its initialization function is called :c:func:`initspam`,
- and it should call :c:func:`Py_InitModule` with the string ``"spam"`` as its
- first argument (use the minimal :file:`example.c` in this directory as a guide).
- By convention, it lives in a file called :file:`spam.c` or :file:`spammodule.c`.
- The output file should be called :file:`spam.pyd` (in Release mode) or
- :file:`spam_d.pyd` (in Debug mode). The extension :file:`.pyd` was chosen
- to avoid confusion with a system library :file:`spam.dll` to which your module
- could be a Python interface.
-
- .. versionchanged:: 2.5
- Previously, file names like :file:`spam.dll` (in release mode) or
- :file:`spam_d.dll` (in debug mode) were also recognized.
-
- Now your options are:
-
-#. Copy :file:`example.sln` and :file:`example.vcproj`, rename them to
- :file:`spam.\*`, and edit them by hand, or
-
-#. Create a brand new project; instructions are below.
-
- In either case, copy :file:`example_nt\\example.def` to :file:`spam\\spam.def`,
- and edit the new :file:`spam.def` so its second line contains the string
- '``initspam``'. If you created a new project yourself, add the file
- :file:`spam.def` to the project now. (This is an annoying little file with only
- two lines. An alternative approach is to forget about the :file:`.def` file,
- and add the option :option:`/export:initspam` somewhere to the Link settings, by
- manually editing the setting in Project Properties dialog).
-
-#. **Creating a brand new project** --- Use the :menuselection:`File --> New
- --> Project` dialog to create a new Project Workspace. Select :guilabel:`Visual
- C++ Projects/Win32/ Win32 Project`, enter the name (``spam``), and make sure the
- Location is set to parent of the :file:`spam` directory you have created (which
- should be a direct subdirectory of the Python build tree, a sibling of
- :file:`Include` and :file:`PC`). Select Win32 as the platform (in my version,
- this is the only choice). Make sure the Create new workspace radio button is
- selected. Click OK.
-
- You should now create the file :file:`spam.def` as instructed in the previous
- section. Add the source files to the project, using :menuselection:`Project -->
- Add Existing Item`. Set the pattern to ``*.*`` and select both :file:`spam.c`
- and :file:`spam.def` and click OK. (Inserting them one by one is fine too.)
-
- Now open the :menuselection:`Project --> spam properties` dialog. You only need
- to change a few settings. Make sure :guilabel:`All Configurations` is selected
- from the :guilabel:`Settings for:` dropdown list. Select the C/C++ tab. Choose
- the General category in the popup menu at the top. Type the following text in
- the entry box labeled :guilabel:`Additional Include Directories`::
-
- ..\Include,..\PC
-
- Then, choose the General category in the Linker tab, and enter ::
-
- ..\PCbuild
-
- in the text box labelled :guilabel:`Additional library Directories`.
-
- Now you need to add some mode-specific settings:
-
- Select :guilabel:`Release` in the :guilabel:`Configuration` dropdown list.
- Choose the :guilabel:`Link` tab, choose the :guilabel:`Input` category, and
- append ``pythonXY.lib`` to the list in the :guilabel:`Additional Dependencies`
- box.
-
- Select :guilabel:`Debug` in the :guilabel:`Configuration` dropdown list, and
- append ``pythonXY_d.lib`` to the list in the :guilabel:`Additional Dependencies`
- box. Then click the C/C++ tab, select :guilabel:`Code Generation`, and select
- :guilabel:`Multi-threaded Debug DLL` from the :guilabel:`Runtime library`
- dropdown list.
-
- Select :guilabel:`Release` again from the :guilabel:`Configuration` dropdown
- list. Select :guilabel:`Multi-threaded DLL` from the :guilabel:`Runtime
- library` dropdown list.
-
-If your module creates a new type, you may have trouble with this line::
-
- PyObject_HEAD_INIT(&PyType_Type)
-
-Static type object initializers in extension modules may cause
-compiles to fail with an error message like "initializer not a
-constant". This shows up when building DLL under MSVC. Change it to::
-
- PyObject_HEAD_INIT(NULL)
-
-and add the following to the module initialization function::
-
- if (PyType_Ready(&MyObject_Type) < 0)
- return NULL;
+is available in :ref:`distutils-index`. If you find you really need to do
+things manually, it may be instructive to study the project file for the
+:source:`winsound ` standard library module.
.. _dynamic-linking:
diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst
index 017c6d4f..8588daaa 100644
--- a/Doc/faq/design.rst
+++ b/Doc/faq/design.rst
@@ -2,6 +2,11 @@
Design and History FAQ
======================
+.. only:: html
+
+ .. contents::
+
+
Why does Python use indentation for grouping of statements?
-----------------------------------------------------------
@@ -31,7 +36,7 @@ least slightly uneasy when reading (or being required to write) another style.
Many coding styles place begin/end brackets on a line by themselves. This makes
programs considerably longer and wastes valuable screen space, making it harder
to get a good overview of a program. Ideally, a function should fit on one
-screen (say, 20-30 lines). 20 lines of Python can do a lot more work than 20
+screen (say, 20--30 lines). 20 lines of Python can do a lot more work than 20
lines of C. This is not solely due to the lack of begin/end brackets -- the
lack of declarations and the high-level data types are also responsible -- but
the indentation-based syntax certainly helps.
@@ -49,7 +54,7 @@ Why are floating point calculations so inaccurate?
People are often very surprised by results like this::
>>> 1.2 - 1.0
- 0.199999999999999996
+ 0.19999999999999996
and think it is a bug in Python. It's not. This has nothing to do with Python,
but with how the underlying C platform handles floating point numbers, and
@@ -169,7 +174,7 @@ where in Python you're forced to write this::
line = f.readline()
if not line:
break
- ... # do something with line
+ ... # do something with line
The reason for not allowing assignment in Python expressions is a common,
hard-to-find bug in those other languages, caused by this construct:
@@ -201,7 +206,7 @@ generally less robust than the "while True" solution::
line = f.readline()
while line:
- ... # do something with line...
+ ... # do something with line...
line = f.readline()
The problem with this is that if you change your mind about exactly how you get
@@ -214,31 +219,32 @@ objects using the ``for`` statement. For example, in the current version of
Python file objects support the iterator protocol, so you can now write simply::
for line in f:
- ... # do something with line...
+ ... # do something with line...
Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?
----------------------------------------------------------------------------------------------------------------
-The major reason is history. Functions were used for those operations that were
-generic for a group of types and which were intended to work even for objects
-that didn't have methods at all (e.g. tuples). It is also convenient to have a
-function that can readily be applied to an amorphous collection of objects when
-you use the functional features of Python (``map()``, ``zip()`` et al).
+As Guido said:
-In fact, implementing ``len()``, ``max()``, ``min()`` as a built-in function is
-actually less code than implementing them as methods for each type. One can
-quibble about individual cases but it's a part of Python, and it's too late to
-make such fundamental changes now. The functions have to remain to avoid massive
-code breakage.
+ (a) For some operations, prefix notation just reads better than
+ postfix -- prefix (and infix!) operations have a long tradition in
+ mathematics which likes notations where the visuals help the
+ mathematician thinking about a problem. Compare the easy with which we
+ rewrite a formula like x*(a+b) into x*a + x*b to the clumsiness of
+ doing the same thing using a raw OO notation.
-.. XXX talk about protocols?
+ (b) When I read code that says len(x) I *know* that it is asking for
+ the length of something. This tells me two things: the result is an
+ integer, and the argument is some kind of container. To the contrary,
+ when I read x.len(), I have to already know that x is some kind of
+ container implementing an interface or inheriting from a class that
+ has a standard len(). Witness the confusion we occasionally have when
+ a class that is not implementing a mapping has a get() or keys()
+ method, or something that isn't a file has a write() method.
-.. note::
-
- For string operations, Python has moved from external functions (the
- ``string`` module) to methods. However, ``len()`` is still a function.
+ -- https://mail.python.org/pipermail/python-3000/2006-November/004643.html
Why is join() a string method instead of a list or tuple method?
@@ -391,50 +397,11 @@ is exactly the same type of object that a lambda expression yields) is assigned!
Can Python be compiled to machine code, C or some other language?
-----------------------------------------------------------------
-Not easily. Python's high level data types, dynamic typing of objects and
-run-time invocation of the interpreter (using :func:`eval` or :keyword:`exec`)
-together mean that a "compiled" Python program would probably consist mostly of
-calls into the Python run-time system, even for seemingly simple operations like
-``x+1``.
-
-Several projects described in the Python newsgroup or at past `Python
-conferences `_ have shown that this
-approach is feasible, although the speedups reached so far are only modest
-(e.g. 2x). Jython uses the same strategy for compiling to Java bytecode. (Jim
-Hugunin has demonstrated that in combination with whole-program analysis,
-speedups of 1000x are feasible for small demo programs. See the proceedings
-from the `1997 Python conference
-`_ for more information.)
-
-Internally, Python source code is always translated into a bytecode
-representation, and this bytecode is then executed by the Python virtual
-machine. In order to avoid the overhead of repeatedly parsing and translating
-modules that rarely change, this byte code is written into a file whose name
-ends in ".pyc" whenever a module is parsed. When the corresponding .py file is
-changed, it is parsed and translated again and the .pyc file is rewritten.
-
-There is no performance difference once the .pyc file has been loaded, as the
-bytecode read from the .pyc file is exactly the same as the bytecode created by
-direct translation. The only difference is that loading code from a .pyc file
-is faster than parsing and translating a .py file, so the presence of
-precompiled .pyc files improves the start-up time of Python scripts. If
-desired, the Lib/compileall.py module can be used to create valid .pyc files for
-a given set of modules.
-
-Note that the main script executed by Python, even if its filename ends in .py,
-is not compiled to a .pyc file. It is compiled to bytecode, but the bytecode is
-not saved to a file. Usually main scripts are quite short, so this doesn't cost
-much speed.
-
-.. XXX check which of these projects are still alive
-
-There are also several programs which make it easier to intermingle Python and C
-code in various ways to increase performance. See, for example, `Psyco
-`_, `Pyrex
-`_, `PyInline
-`_, `Py2Cmod
-`_, and `Weave
-`_.
+`Cython `_ compiles a modified version of Python with
+optional annotations into C extensions. `Nuitka `_ is
+an up-and-coming compiler of Python into C++ code, aiming to support the full
+Python language. For compiling to Java you can consider
+`VOC `_.
How does Python manage memory?
@@ -537,10 +504,10 @@ you can always change a list's elements. Only immutable elements can be used as
dictionary keys, and hence only tuples and not lists can be used as keys.
-How are lists implemented?
---------------------------
+How are lists implemented in CPython?
+-------------------------------------
-Python's lists are really variable-length arrays, not Lisp-style linked lists.
+CPython's lists are really variable-length arrays, not Lisp-style linked lists.
The implementation uses a contiguous array of references to other objects, and
keeps a pointer to this array and the array's length in a list head structure.
@@ -553,10 +520,10 @@ when the array must be grown, some extra space is allocated so the next few
times don't require an actual resize.
-How are dictionaries implemented?
----------------------------------
+How are dictionaries implemented in CPython?
+--------------------------------------------
-Python's dictionaries are implemented as resizable hash tables. Compared to
+CPython's dictionaries are implemented as resizable hash tables. Compared to
B-trees, this gives better performance for lookup (the most common operation by
far) under most circumstances, and the implementation is simpler.
@@ -625,8 +592,10 @@ other structure). ::
class ListWrapper:
def __init__(self, the_list):
self.the_list = the_list
+
def __eq__(self, other):
return self.the_list == other.the_list
+
def __hash__(self):
l = self.the_list
result = 98767 - len(l)*555
@@ -667,7 +636,7 @@ it. For example, here's how to iterate over the keys of a dictionary in sorted
order::
for key in sorted(mydict):
- ... # do whatever with mydict[key]...
+ ... # do whatever with mydict[key]...
How do you specify and enforce an interface spec in Python?
@@ -712,62 +681,6 @@ before you write any of the actual code. Of course Python allows you to be
sloppy and not write test cases at all.
-Why are default values shared between objects?
-----------------------------------------------
-
-This type of bug commonly bites neophyte programmers. Consider this function::
-
- def foo(mydict={}): # Danger: shared reference to one dict for all calls
- ... compute something ...
- mydict[key] = value
- return mydict
-
-The first time you call this function, ``mydict`` contains a single item. The
-second time, ``mydict`` contains two items because when ``foo()`` begins
-executing, ``mydict`` starts out with an item already in it.
-
-It is often expected that a function call creates new objects for default
-values. This is not what happens. Default values are created exactly once, when
-the function is defined. If that object is changed, like the dictionary in this
-example, subsequent calls to the function will refer to this changed object.
-
-By definition, immutable objects such as numbers, strings, tuples, and ``None``,
-are safe from change. Changes to mutable objects such as dictionaries, lists,
-and class instances can lead to confusion.
-
-Because of this feature, it is good programming practice to not use mutable
-objects as default values. Instead, use ``None`` as the default value and
-inside the function, check if the parameter is ``None`` and create a new
-list/dictionary/whatever if it is. For example, don't write::
-
- def foo(mydict={}):
- ...
-
-but::
-
- def foo(mydict=None):
- if mydict is None:
- mydict = {} # create a new dict for local namespace
-
-This feature can be useful. When you have a function that's time-consuming to
-compute, a common technique is to cache the parameters and the resulting value
-of each call to the function, and return the cached value if the same value is
-requested again. This is called "memoizing", and can be implemented like this::
-
- # Callers will never provide a third parameter for this function.
- def expensive(arg1, arg2, _cache={}):
- if (arg1, arg2) in _cache:
- return _cache[(arg1, arg2)]
-
- # Calculate the value
- result = ... expensive computation ...
- _cache[(arg1, arg2)] = result # Store result in the cache
- return result
-
-You could use a global variable containing a dictionary instead of the default
-value; it's a matter of taste.
-
-
Why is there no goto?
---------------------
@@ -779,11 +692,11 @@ languages. For example::
class label: pass # declare a label
try:
- ...
- if condition: raise label() # goto label
- ...
+ ...
+ if condition: raise label() # goto label
+ ...
except label: # where to goto
- pass
+ pass
...
This doesn't allow you to jump into the middle of a loop, but that's usually
diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst
index 4f3cabf0..0a256b56 100644
--- a/Doc/faq/extending.rst
+++ b/Doc/faq/extending.rst
@@ -44,19 +44,20 @@ time-critical functions in your code, and gain a significant improvement with
very little effort, as long as you're running on a machine with an
x86-compatible processor.
-`Pyrex `_ is a compiler
-that accepts a slightly modified form of Python and generates the corresponding
+`Cython `_ and its relative `Pyrex
+`_ are compilers
+that accept a slightly modified form of Python and generate the corresponding
C code. Pyrex makes it possible to write an extension without having to learn
Python's C API.
If you need to interface to some C or C++ library for which no Python extension
currently exists, you can try wrapping the library's data types and functions
with a tool such as `SWIG `_. `SIP
-`__, `CXX
+`__, `CXX
`_ `Boost
`_, or `Weave
-`_ are also alternatives for wrapping
-C++ libraries.
+`_ are also
+alternatives for wrapping C++ libraries.
How can I execute arbitrary Python statements from C?
@@ -155,6 +156,8 @@ The easiest way to do this is to use the StringIO class in the standard library.
Sample code and use for catching stdout:
+.. code-block:: pycon
+
>>> class StdoutCatcher:
... def __init__(self):
... self.data = ''
@@ -218,11 +221,15 @@ How do I debug an extension?
When using GDB with dynamically loaded extensions, you can't set a breakpoint in
your extension until your extension is loaded.
-In your ``.gdbinit`` file (or interactively), add the command::
+In your ``.gdbinit`` file (or interactively), add the command:
+
+.. code-block:: none
br _PyImport_LoadDynamicModule
-Then, when you run GDB::
+Then, when you run GDB:
+
+.. code-block:: shell-session
$ gdb /local/bin/python
gdb) run myscript.py
@@ -279,7 +286,7 @@ However sometimes you have to run the embedded Python interpreter in the same
thread as your rest application and you can't allow the
:c:func:`PyRun_InteractiveLoop` to stop while waiting for user input. The one
solution then is to call :c:func:`PyParser_ParseString` and test for ``e.error``
-equal to ``E_EOF``, which means the input is incomplete). Here's a sample code
+equal to ``E_EOF``, which means the input is incomplete. Here's a sample code
fragment, untested, inspired by code from Alex Farber::
#include
@@ -344,7 +351,7 @@ complete example using the GNU readline library (you may want to ignore
{
line = readline (prompt);
- if (NULL == line) /* CTRL-D pressed */
+ if (NULL == line) /* Ctrl-D pressed */
{
done = 1;
}
@@ -439,8 +446,8 @@ extension module using g++ (e.g., ``g++ -shared -o mymodule.so mymodule.o``).
Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)?
----------------------------------------------------------------------------------------------------------------
-In Python 2.2, you can inherit from built-in classes such as :class:`int`,
-:class:`list`, :class:`dict`, etc.
+Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`,
+:class:`dict`, etc.
The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html)
provides a way of doing this from C++ (i.e. you can inherit from an extension
@@ -468,6 +475,8 @@ parameter specifications for :c:func:`PyArg_ParseTuple`.
You can check the size of the Unicode character a Python interpreter is using by
checking the value of sys.maxunicode:
+.. code-block:: pycon
+
>>> import sys
>>> if sys.maxunicode > 65535:
... print 'UCS4 build'
diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst
index 8cd139c8..27f46810 100644
--- a/Doc/faq/general.rst
+++ b/Doc/faq/general.rst
@@ -25,7 +25,7 @@ Finally, Python is portable: it runs on many Unix variants, on the Mac, and on
PCs under MS-DOS, Windows, Windows NT, and OS/2.
To find out more, start with :ref:`tutorial-index`. The `Beginner's Guide to
-Python `_ links to other
+Python `_ links to other
introductory tutorials and resources for learning Python.
@@ -36,11 +36,11 @@ The Python Software Foundation is an independent non-profit organization that
holds the copyright on Python versions 2.1 and newer. The PSF's mission is to
advance open source technology related to the Python programming language and to
publicize the use of Python. The PSF's home page is at
-http://www.python.org/psf/.
+https://www.python.org/psf/.
Donations to the PSF are tax-exempt in the US. If you use Python and find it
helpful, please contribute via `the PSF donation page
-`_.
+`_.
Are there copyright restrictions on the use of Python?
@@ -53,12 +53,12 @@ commercial use, to sell copies of Python in source or binary form (modified or
unmodified), or to sell products that incorporate Python in some form. We would
still like to know about all commercial use of Python, of course.
-See `the PSF license page `_ to find further
+See `the PSF license page `_ to find further
explanations and a link to the full text of the license.
The Python logo is trademarked, and in certain cases permission is required to
use it. Consult `the Trademark Usage Policy
-`__ for more information.
+`__ for more information.
Why was Python created in the first place?
@@ -117,7 +117,7 @@ programming), software engineering (unit testing, logging, profiling, parsing
Python code), and operating system interfaces (system calls, filesystems, TCP/IP
sockets). Look at the table of contents for :ref:`library-index` to get an idea
of what's available. A wide variety of third-party extensions are also
-available. Consult `the Python Package Index `_ to
+available. Consult `the Python Package Index `_ to
find packages of interest to you.
@@ -146,28 +146,28 @@ labeled 2.0aN precede the versions labeled 2.0bN, which precede versions labeled
2.0cN, and *those* precede 2.0.
You may also find version numbers with a "+" suffix, e.g. "2.2+". These are
-unreleased versions, built directly from the Subversion trunk. In practice,
-after a final minor release is made, the Subversion trunk is incremented to the
-next minor version, which becomes the "a0" version,
-e.g. "2.4a0".
+unreleased versions, built directly from the CPython development repository. In
+practice, after a final minor release is made, the version is incremented to the
+next minor version, which becomes the "a0" version, e.g. "2.4a0".
-See also the documentation for ``sys.version``, ``sys.hexversion``, and
-``sys.version_info``.
+See also the documentation for :data:`sys.version`, :data:`sys.hexversion`, and
+:data:`sys.version_info`.
How do I obtain a copy of the Python source?
--------------------------------------------
The latest Python source distribution is always available from python.org, at
-http://www.python.org/download/. The latest development sources can be obtained
-via anonymous Mercurial access at http://hg.python.org/cpython.
+https://www.python.org/downloads/. The latest development sources can be obtained
+at https://github.com/python/cpython/.
The source distribution is a gzipped tar file containing the complete C source,
Sphinx-formatted documentation, Python library modules, example programs, and
several useful pieces of freely distributable software. The source will compile
and run out of the box on most UNIX platforms.
-Consult the `Developer FAQ `__ for more
+Consult the `Getting Started section of the Python Developer's Guide
+`__ for more
information on getting the source code and compiling it.
@@ -177,12 +177,12 @@ How do I get documentation on Python?
.. XXX mention py3k
The standard documentation for the current stable version of Python is available
-at http://docs.python.org/. PDF, plain text, and downloadable HTML versions are
-also available at http://docs.python.org/download.html.
+at https://docs.python.org/3/. PDF, plain text, and downloadable HTML versions are
+also available at https://docs.python.org/3/download.html.
The documentation is written in reStructuredText and processed by `the Sphinx
-documentation tool `__. The reStructuredText source
-for the documentation is part of the Python source distribution.
+documentation tool `__. The reStructuredText source for
+the documentation is part of the Python source distribution.
I've never programmed before. Is there a Python tutorial?
@@ -191,7 +191,7 @@ I've never programmed before. Is there a Python tutorial?
There are numerous tutorials and books available. The standard documentation
includes :ref:`tutorial-index`.
-Consult `the Beginner's Guide `_ to
+Consult `the Beginner's Guide `_ to
find information for beginning Python programmers, including lists of tutorials.
@@ -199,7 +199,7 @@ Is there a newsgroup or mailing list devoted to Python?
-------------------------------------------------------
There is a newsgroup, :newsgroup:`comp.lang.python`, and a mailing list,
-`python-list `_. The
+`python-list `_. The
newsgroup and mailing list are gatewayed into each other -- if you can read news
it's unnecessary to subscribe to the mailing list.
:newsgroup:`comp.lang.python` is high-traffic, receiving hundreds of postings
@@ -208,38 +208,38 @@ every day, and Usenet readers are often more able to cope with this volume.
Announcements of new software releases and events can be found in
comp.lang.python.announce, a low-traffic moderated list that receives about five
postings per day. It's available as `the python-announce mailing list
-`_.
+`_.
More info about other mailing lists and newsgroups
-can be found at http://www.python.org/community/lists/.
+can be found at https://www.python.org/community/lists/.
How do I get a beta test version of Python?
-------------------------------------------
-Alpha and beta releases are available from http://www.python.org/download/. All
+Alpha and beta releases are available from https://www.python.org/downloads/. All
releases are announced on the comp.lang.python and comp.lang.python.announce
-newsgroups and on the Python home page at http://www.python.org/; an RSS feed of
+newsgroups and on the Python home page at https://www.python.org/; an RSS feed of
news is available.
-You can also access the development version of Python through Subversion. See
-http://docs.python.org/devguide/faq for details.
+You can also access the development version of Python through Git. See
+`The Python Developer's Guide `_ for details.
How do I submit bug reports and patches for Python?
---------------------------------------------------
To report a bug or submit a patch, please use the Roundup installation at
-http://bugs.python.org/.
+https://bugs.python.org/.
You must have a Roundup account to report bugs; this makes it possible for us to
contact you if we have follow-up questions. It will also enable Roundup to send
you updates as we act on your bug. If you had previously used SourceForge to
report bugs to Python, you can obtain your Roundup password through Roundup's
-`password reset procedure `_.
+`password reset procedure `_.
For more information on how Python is developed, consult `the Python Developer's
-Guide `_.
+Guide `_.
Are there any published articles about Python that I can reference?
@@ -252,14 +252,14 @@ outdated.
Guido van Rossum and Jelke de Boer, "Interactively Testing Remote Servers
Using the Python Programming Language", CWI Quarterly, Volume 4, Issue 4
- (December 1991), Amsterdam, pp 283-303.
+ (December 1991), Amsterdam, pp 283--303.
Are there any books on Python?
------------------------------
Yes, there are many, and more are being published. See the python.org wiki at
-http://wiki.python.org/moin/PythonBooks for a list.
+https://wiki.python.org/moin/PythonBooks for a list.
You can also search online bookstores for "Python" and filter out the Monty
Python references; or perhaps search for "Python" and "language".
@@ -268,9 +268,8 @@ Python references; or perhaps search for "Python" and "language".
Where in the world is www.python.org located?
---------------------------------------------
-It's currently in Amsterdam, graciously hosted by `XS4ALL
-`_. Thanks to Thomas Wouters for his work in arranging
-python.org's hosting.
+The Python project's infrastructure is located all over the world and is managed
+by the Python Infrastructure Team. Details `here `__.
Why is it called Python?
@@ -278,7 +277,7 @@ Why is it called Python?
When he began implementing Python, Guido van Rossum was also reading the
published scripts from `"Monty Python's Flying Circus"
-`__, a BBC comedy series from the 1970s. Van Rossum
+`__, a BBC comedy series from the 1970s. Van Rossum
thought he needed a name that was short, unique, and slightly mysterious, so he
decided to call the language Python.
@@ -301,18 +300,16 @@ usually around 18 months between major releases.
The developers issue "bugfix" releases of older versions, so the stability of
existing releases gradually improves. Bugfix releases, indicated by a third
-component of the version number (e.g. 2.5.3, 2.6.2), are managed for stability;
+component of the version number (e.g. 3.5.3, 3.6.2), are managed for stability;
only fixes for known problems are included in a bugfix release, and it's
guaranteed that interfaces will remain the same throughout a series of bugfix
releases.
The latest stable releases can always be found on the `Python download page
-`_. There are two recommended production-ready
-versions at this point in time, because at the moment there are two branches of
-stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since
-currently there is more third party software available for Python 2 than for
-Python 3. Python 2 code will generally not run unchanged in Python 3.
-
+`_. There are two production-ready versions
+of Python: 2.x and 3.x. The recommended version is 3.x, which is supported by
+most widely used libraries. Although 2.x is still widely used, `it will not
+be maintained after January 1, 2020 `_.
How many people are using Python?
---------------------------------
@@ -331,15 +328,15 @@ the group or even read it.
Have any significant projects been done in Python?
--------------------------------------------------
-See http://python.org/about/success for a list of projects that use Python.
+See https://www.python.org/about/success for a list of projects that use Python.
Consulting the proceedings for `past Python conferences
-`_ will reveal contributions from many
+`_ will reveal contributions from many
different companies and organizations.
High-profile Python projects include `the Mailman mailing list manager
`_ and `the Zope application server
`_. Several Linux distributions, most notably `Red Hat
-`_, have written part or all of their installer and
+`_, have written part or all of their installer and
system administration software in Python. Companies that use Python internally
include Google, Yahoo, and Lucasfilm Ltd.
@@ -347,14 +344,14 @@ include Google, Yahoo, and Lucasfilm Ltd.
What new developments are expected for Python in the future?
------------------------------------------------------------
-See http://www.python.org/dev/peps/ for the Python Enhancement Proposals
+See https://www.python.org/dev/peps/ for the Python Enhancement Proposals
(PEPs). PEPs are design documents describing a suggested new feature for Python,
providing a concise technical specification and a rationale. Look for a PEP
titled "Python X.Y Release Schedule", where X.Y is a version that hasn't been
publicly released yet.
New development is discussed on `the python-dev mailing list
-`_.
+`_.
Is it reasonable to propose incompatible changes to Python?
@@ -372,43 +369,6 @@ Providing a gradual upgrade path is necessary if a feature has to be changed.
changes while minimizing disruption for users.
-Is Python Y2K (Year 2000) Compliant?
-------------------------------------
-
-.. remove this question?
-
-As of August, 2003 no major problems have been reported and Y2K compliance seems
-to be a non-issue.
-
-Python does very few date calculations and for those it does perform relies on
-the C library functions. Python generally represents times either as seconds
-since 1970 or as a ``(year, month, day, ...)`` tuple where the year is expressed
-with four digits, which makes Y2K bugs unlikely. So as long as your C library
-is okay, Python should be okay. Of course, it's possible that a particular
-application written in Python makes assumptions about 2-digit years.
-
-Because Python is available free of charge, there are no absolute guarantees.
-If there *are* unforeseen problems, liability is the user's problem rather than
-the developers', and there is nobody you can sue for damages. The Python
-copyright notice contains the following disclaimer:
-
- 4. PSF is making Python 2.3 available to Licensee on an "AS IS"
- basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY
- WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY
- REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
- PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT INFRINGE ANY THIRD PARTY
- RIGHTS.
-
- 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
- 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
- A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
- OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-The good news is that *if* you encounter a problem, you have full source
-available to track it down and fix it. This is one advantage of an open source
-programming environment.
-
-
Is Python a good language for beginning programmers?
----------------------------------------------------
@@ -447,14 +407,22 @@ while they enter their program's source in another window. If they can't
remember the methods for a list, they can do something like this::
>>> L = []
- >>> dir(L)
- ['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove',
- 'reverse', 'sort']
+ >>> dir(L) # doctest: +NORMALIZE_WHITESPACE
+ ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
+ '__delslice__', '__doc__', '__eq__', '__format__', '__ge__',
+ '__getattribute__', '__getitem__', '__getslice__', '__gt__',
+ '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__',
+ '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__',
+ '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
+ '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__',
+ '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert',
+ 'pop', 'remove', 'reverse', 'sort']
>>> help(L.append)
Help on built-in function append:
-
+
append(...)
L.append(object) -- append object to end
+
>>> L.append(1)
>>> L
[1]
@@ -467,11 +435,12 @@ that is written in Python using Tkinter. PythonWin is a Windows-specific IDE.
Emacs users will be happy to know that there is a very good Python mode for
Emacs. All of these programming environments provide syntax highlighting,
auto-indenting, and access to the interactive interpreter while coding. Consult
-http://www.python.org/editors/ for a full list of Python editing environments.
+`the Python wiki `_ for a full list
+of Python editing environments.
If you want to discuss Python's use in education, you may be interested in
joining `the edu-sig mailing list
-`_.
+`_.
Upgrading Python
diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst
index b34be2dc..9228fdde 100644
--- a/Doc/faq/gui.rst
+++ b/Doc/faq/gui.rst
@@ -21,15 +21,15 @@ Tkinter
Standard builds of Python include an object-oriented interface to the Tcl/Tk
widget set, called Tkinter. This is probably the easiest to install and use.
For more info about Tk, including pointers to the source, see the Tcl/Tk home
-page at http://www.tcl.tk. Tcl/Tk is fully portable to the MacOS, Windows, and
-Unix platforms.
+page at https://www.tcl.tk. Tcl/Tk is fully portable to the Mac OS X, Windows,
+and Unix platforms.
wxWidgets
---------
-wxWidgets (http://www.wxwidgets.org) is a free, portable GUI class
+wxWidgets (https://www.wxwidgets.org) is a free, portable GUI class
library written in C++ that provides a native look and feel on a
-number of platforms, with Windows, MacOS X, GTK, X11, all listed as
+number of platforms, with Windows, Mac OS X, GTK, X11, all listed as
current stable targets. Language bindings are available for a number
of languages including Python, Perl, Ruby, etc.
@@ -48,14 +48,14 @@ Qt
---
There are bindings available for the Qt toolkit (using either `PyQt
-`_ or `PySide
-`_) and for KDE (`PyKDE `_).
+`_ or `PySide
+`_) and for KDE (`PyKDE4 `__).
PyQt is currently more mature than PySide, but you must buy a PyQt license from
-`Riverbank Computing `_
+`Riverbank Computing `_
if you want to write proprietary applications. PySide is free for all applications.
Qt 4.5 upwards is licensed under the LGPL license; also, commercial licenses
-are available from `Nokia `_.
+are available from `The Qt Company `_.
Gtk+
----
@@ -70,15 +70,6 @@ Python bindings for `the FLTK toolkit `_, a simple yet
powerful and mature cross-platform windowing system, are available from `the
PyFLTK project `_.
-
-FOX
-----
-
-A wrapper for `the FOX toolkit `_ called `FXpy
-`_ is available. FOX supports both Unix variants
-and Windows.
-
-
OpenGL
------
@@ -88,13 +79,9 @@ For OpenGL bindings, see `PyOpenGL `_.
What platform-specific GUI toolkits exist for Python?
========================================================
-`The Mac port `_ by Jack Jansen has a rich and
-ever-growing set of modules that support the native Mac toolbox calls. The port
-supports MacOS X's Carbon libraries.
-
By installing the `PyObjc Objective-C bridge
-`_, Python programs can use MacOS X's
-Cocoa libraries. See the documentation that comes with the Mac port.
+`_, Python programs can use Mac OS X's
+Cocoa libraries.
:ref:`Pythonwin ` by Mark Hammond includes an interface to the
Microsoft Foundation Classes and a Python programming environment
@@ -129,30 +116,11 @@ might include the Tix libraries as well).
Can I have Tk events handled while waiting for I/O?
---------------------------------------------------
-Yes, and you don't even need threads! But you'll have to restructure your I/O
+On platforms other than Windows, yes, and you don't even
+need threads! But you'll have to restructure your I/O
code a bit. Tk has the equivalent of Xt's :c:func:`XtAddInput()` call, which allows you
to register a callback function which will be called from the Tk mainloop when
-I/O is possible on a file descriptor. Here's what you need::
-
- from Tkinter import tkinter
- tkinter.createfilehandler(file, mask, callback)
-
-The file may be a Python file or socket object (actually, anything with a
-fileno() method), or an integer file descriptor. The mask is one of the
-constants tkinter.READABLE or tkinter.WRITABLE. The callback is called as
-follows::
-
- callback(file, mask)
-
-You must unregister the callback when you're done, using ::
-
- tkinter.deletefilehandler(file)
-
-Note: since you don't know *how many bytes* are available for reading, you can't
-use the Python file object's read or readline methods, since these will insist
-on reading a predefined number of bytes. For sockets, the :meth:`recv` or
-:meth:`recvfrom` methods will work fine; for other files, use
-``os.read(file.fileno(), maxbytecount)``.
+I/O is possible on a file descriptor. See :ref:`tkinter-file-handlers`.
I can't get key bindings to work in Tkinter: why?
diff --git a/Doc/faq/installed.rst b/Doc/faq/installed.rst
index 390c85ab..b9907a6e 100644
--- a/Doc/faq/installed.rst
+++ b/Doc/faq/installed.rst
@@ -11,7 +11,7 @@ language because Python is easy to learn, but it's also used by professional
software developers at places such as Google, NASA, and Lucasfilm Ltd.
If you wish to learn more about Python, start with the `Beginner's Guide to
-Python `_.
+Python `_.
Why is Python installed on my machine?
diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst
index 295ff3bf..a2594653 100644
--- a/Doc/faq/library.rst
+++ b/Doc/faq/library.rst
@@ -19,7 +19,7 @@ standard library module. (Eventually you'll learn what's in the standard
library and will be able to skip this step.)
For third-party packages, search the `Python Package Index
-`_ or try `Google `_ or
+`_ or try `Google `_ or
another Web search engine. Searching for "Python" plus a keyword or two for
your topic of interest will usually find something helpful.
@@ -181,8 +181,8 @@ How do I create documentation from doc strings?
The :mod:`pydoc` module can create HTML from the doc strings in your Python
source code. An alternative for creating API documentation purely from
-docstrings is `epydoc `_. `Sphinx
-`_ can also include docstring content.
+docstrings is `epydoc `_. `Sphinx
+`_ can also include docstring content.
How do I get a single keypress at a time?
@@ -585,7 +585,7 @@ substituted for standard input and output. You will have to use pseudo ttys
("ptys") instead of pipes. Or you can use a Python interface to Don Libes'
"expect" library. A Python extension that interfaces to expect is called "expy"
and available from http://expectpy.sourceforge.net. A pure Python solution that
-works like expect is `pexpect `_.
+works like expect is `pexpect `_.
How do I access the serial (RS232) port?
@@ -597,7 +597,7 @@ For Win32, POSIX (Linux, BSD, etc.), Jython:
For Unix, see a Usenet post by Mitch Chapman:
- http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com
+ https://groups.google.com/groups?selm=34A04430.CF9@ohioee.com
Why doesn't closing sys.stdout (stdin, stderr) really close it?
@@ -640,7 +640,7 @@ and client-side web systems.
.. XXX check if wiki page is still up to date
A summary of available frameworks is maintained by Paul Boddie at
-http://wiki.python.org/moin/WebProgramming .
+https://wiki.python.org/moin/WebProgramming\ .
Cameron Laird maintains a useful set of pages about Python web technologies at
http://phaseit.net/claird/comp.lang.python/web_python.
@@ -658,20 +658,20 @@ Yes. Here's a simple example that uses httplib::
import httplib, sys, time
- ### build the query string
+ # build the query string
qs = "First=Josephine&MI=Q&Last=Public"
- ### connect and send the server a path
+ # connect and send the server a path
httpobj = httplib.HTTP('www.some-server.out-there', 80)
httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')
- ### now generate the rest of the HTTP headers...
+ # now generate the rest of the HTTP headers...
httpobj.putheader('Accept', '*/*')
httpobj.putheader('Connection', 'Keep-Alive')
httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')
httpobj.putheader('Content-length', '%d' % len(qs))
httpobj.endheaders()
httpobj.send(qs)
- ### find out what the server said in response...
+ # find out what the server said in response...
reply, msg, hdrs = httpobj.getreply()
if reply != 200:
sys.stdout.write(httpobj.getfile().read())
@@ -691,7 +691,7 @@ What module should I use to help with generating HTML?
.. XXX add modern template languages
You can find a collection of useful links on the `Web Programming wiki page
-`_.
+`_.
How do I send mail from a Python script?
@@ -724,8 +724,9 @@ varies between systems; sometimes it is ``/usr/lib/sendmail``, sometimes
``/usr/sbin/sendmail``. The sendmail manual page will help you out. Here's
some sample code::
- SENDMAIL = "/usr/sbin/sendmail" # sendmail location
import os
+
+ SENDMAIL = "/usr/sbin/sendmail" # sendmail location
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: receiver@example.com\n")
p.write("Subject: test\n")
@@ -771,7 +772,7 @@ and :mod:`GDBM ` are also included with standard Python.
Support for most relational databases is available. See the
`DatabaseProgramming wiki page
-`_ for details.
+`_ for details.
How do you implement persistent objects in Python?
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
index 54dc4b91..62b34b6e 100644
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -23,15 +23,14 @@ for pdb as an example.
The IDLE interactive development environment, which is part of the standard
Python distribution (normally available as Tools/scripts/idle), includes a
-graphical debugger. There is documentation for the IDLE debugger at
-http://www.python.org/idle/doc/idle2.html#Debugger.
+graphical debugger.
PythonWin is a Python IDE that includes a GUI debugger based on pdb. The
Pythonwin debugger colors breakpoints and has quite a few cool features such as
debugging non-Pythonwin programs. Pythonwin is available as part of the `Python
-for Windows Extensions `__ project and
+for Windows Extensions `__ project and
as a part of the ActivePython distribution (see
-http://www.activestate.com/Products/ActivePython/index.html).
+https://www.activestate.com/activepython\ ).
`Boa Constructor `_ is an IDE and GUI
builder that uses wxWidgets. It offers visual frame creation and manipulation,
@@ -39,19 +38,20 @@ an object inspector, many views on the source like object browsers, inheritance
hierarchies, doc string generated html documentation, an advanced debugger,
integrated help, and Zope support.
-`Eric `_ is an IDE built on PyQt
+`Eric `_ is an IDE built on PyQt
and the Scintilla editing component.
Pydb is a version of the standard Python debugger pdb, modified for use with DDD
(Data Display Debugger), a popular graphical debugger front end. Pydb can be
found at http://bashdb.sourceforge.net/pydb/ and DDD can be found at
-http://www.gnu.org/software/ddd.
+https://www.gnu.org/software/ddd.
There are a number of commercial Python IDEs that include graphical debuggers.
They include:
-* Wing IDE (http://wingware.com/)
-* Komodo IDE (http://www.activestate.com/Products/Komodo)
+* Wing IDE (https://wingware.com/)
+* Komodo IDE (https://komodoide.com/)
+* PyCharm (https://www.jetbrains.com/pycharm/)
Is there a tool to help find bugs or perform static analysis?
@@ -61,16 +61,15 @@ Yes.
PyChecker is a static analysis tool that finds bugs in Python source code and
warns about code complexity and style. You can get PyChecker from
-http://pychecker.sf.net.
+http://pychecker.sourceforge.net/.
-`Pylint `_ is another tool that checks
+`Pylint `_ is another tool that checks
if a module satisfies a coding standard, and also makes it possible to write
plug-ins to add a custom feature. In addition to the bug checking that
PyChecker performs, Pylint offers some additional features such as checking line
length, whether variable names are well-formed according to your coding
standard, whether declared interfaces are fully implemented, and more.
-http://www.logilab.org/card/pylint_manual provides a full list of Pylint's
-features.
+https://docs.pylint.org/ provides a full list of Pylint's features.
How can I create a stand-alone binary from a Python script?
@@ -101,13 +100,7 @@ which don't. One is Thomas Heller's py2exe (Windows only) at
http://www.py2exe.org/
-Another is Christian Tismer's `SQFREEZE `_
-which appends the byte code to a specially-prepared Python interpreter that can
-find the byte code in the executable.
-
-Other tools include Fredrik Lundh's `Squeeze
-`_ and Anthony Tuininga's
-`cx_Freeze `_.
+Another tool is Anthony Tuininga's `cx_Freeze `_.
Are there coding standards or a style guide for Python programs?
@@ -146,10 +139,10 @@ development time, greater likelihood of bugs) unless the resulting performance
benefit is worth it.
There is a page on the wiki devoted to `performance tips
-`_.
+`_.
Guido van Rossum has written up an anecdote related to optimization at
-http://www.python.org/doc/essays/list2str.html.
+https://www.python.org/doc/essays/list2str.
One thing to notice is that function and (especially) method calls are rather
expensive; if you have designed a purely OO interface with lots of tiny
@@ -207,7 +200,7 @@ not dealing with constant string patterns. You may still use :ref:`the old %
operations ` ``string % tuple`` and ``string % dictionary``.
Be sure to use the :meth:`list.sort` built-in method to do sorting, and see the
-`sorting mini-HOWTO `_ for examples
+`sorting mini-HOWTO `_ for examples
of moderately advanced usage. :meth:`list.sort` beats other techniques for
sorting in all but the most extreme circumstances.
@@ -340,10 +333,8 @@ What are the rules for local and global variables in Python?
------------------------------------------------------------
In Python, variables that are only referenced inside a function are implicitly
-global. If a variable is assigned a new value anywhere within the function's
-body, it's assumed to be a local. If a variable is ever assigned a new value
-inside the function, the variable is implicitly local, and you need to
-explicitly declare it as 'global'.
+global. If a variable is assigned a value anywhere within the function's body,
+it's assumed to be a local unless explicitly declared as global.
Though a bit surprising at first, a moment's consideration explains this. On
one hand, requiring :keyword:`global` for assigned variables provides a bar
@@ -362,7 +353,7 @@ functions), e.g.::
>>> squares = []
>>> for x in range(5):
- ... squares.append(lambda: x**2)
+ ... squares.append(lambda: x**2)
This gives you a list that contains 5 lambdas that calculate ``x**2``. You
might expect that, when called, they would return, respectively, ``0``, ``1``,
@@ -389,7 +380,7 @@ lambdas, so that they don't rely on the value of the global ``x``::
>>> squares = []
>>> for x in range(5):
- ... squares.append(lambda n=x: n**2)
+ ... squares.append(lambda n=x: n**2)
Here, ``n=x`` creates a new variable ``n`` local to the lambda and computed
when the lambda is defined so that it has the same value that ``x`` had at
@@ -438,9 +429,8 @@ What are the "best practices" for using import in a module?
-----------------------------------------------------------
In general, don't use ``from modulename import *``. Doing so clutters the
-importer's namespace. Some people avoid this idiom even with the few modules
-that were designed to be imported in this manner. Modules designed in this
-manner include :mod:`Tkinter`, and :mod:`threading`.
+importer's namespace, and makes it much harder for linters to detect undefined
+names.
Import modules at the top of a file. Doing so makes it clear what other modules
your code requires and avoids questions of whether the module name is in scope.
@@ -454,11 +444,10 @@ It's good practice if you import modules in the following order:
directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc.
3. locally-developed modules
-Never use relative package imports. If you're writing code that's in the
-``package.sub.m1`` module and want to import ``package.sub.m2``, do not just
+Only use explicit relative package imports. If you're writing code that's in
+the ``package.sub.m1`` module and want to import ``package.sub.m2``, do not just
write ``import m2``, even though it's legal. Write ``from package.sub import
-m2`` instead. Relative imports can lead to a module being initialized twice,
-leading to confusing bugs. See :pep:`328` for details.
+m2`` or ``from . import m2`` instead.
It is sometimes necessary to move imports to a function or class to avoid
problems with circular imports. Gordon McMillan says:
@@ -490,13 +479,61 @@ module, but loading a module multiple times is virtually free, costing only a
couple of dictionary lookups. Even if the module name has gone out of scope,
the module is probably available in :data:`sys.modules`.
-If only instances of a specific class use a module, then it is reasonable to
-import the module in the class's ``__init__`` method and then assign the module
-to an instance variable so that the module is always available (via that
-instance variable) during the life of the object. Note that to delay an import
-until the class is instantiated, the import must be inside a method. Putting
-the import inside the class but outside of any method still causes the import to
-occur when the module is initialized.
+
+Why are default values shared between objects?
+----------------------------------------------
+
+This type of bug commonly bites neophyte programmers. Consider this function::
+
+ def foo(mydict={}): # Danger: shared reference to one dict for all calls
+ ... compute something ...
+ mydict[key] = value
+ return mydict
+
+The first time you call this function, ``mydict`` contains a single item. The
+second time, ``mydict`` contains two items because when ``foo()`` begins
+executing, ``mydict`` starts out with an item already in it.
+
+It is often expected that a function call creates new objects for default
+values. This is not what happens. Default values are created exactly once, when
+the function is defined. If that object is changed, like the dictionary in this
+example, subsequent calls to the function will refer to this changed object.
+
+By definition, immutable objects such as numbers, strings, tuples, and ``None``,
+are safe from change. Changes to mutable objects such as dictionaries, lists,
+and class instances can lead to confusion.
+
+Because of this feature, it is good programming practice to not use mutable
+objects as default values. Instead, use ``None`` as the default value and
+inside the function, check if the parameter is ``None`` and create a new
+list/dictionary/whatever if it is. For example, don't write::
+
+ def foo(mydict={}):
+ ...
+
+but::
+
+ def foo(mydict=None):
+ if mydict is None:
+ mydict = {} # create a new dict for local namespace
+
+This feature can be useful. When you have a function that's time-consuming to
+compute, a common technique is to cache the parameters and the resulting value
+of each call to the function, and return the cached value if the same value is
+requested again. This is called "memoizing", and can be implemented like this::
+
+ # Callers will never provide a third parameter for this function.
+ def expensive(arg1, arg2, _cache={}):
+ if (arg1, arg2) in _cache:
+ return _cache[(arg1, arg2)]
+
+ # Calculate the value
+ result = ... expensive computation ...
+ _cache[(arg1, arg2)] = result # Store result in the cache
+ return result
+
+You could use a global variable containing a dictionary instead of the default
+value; it's a matter of taste.
How can I pass optional or keyword parameters from one function to another?
@@ -548,6 +585,81 @@ arguments a function can accept. For example, given the function definition::
the values ``42``, ``314``, and ``somevar`` are arguments.
+Why did changing list 'y' also change list 'x'?
+------------------------------------------------
+
+If you wrote code like::
+
+ >>> x = []
+ >>> y = x
+ >>> y.append(10)
+ >>> y
+ [10]
+ >>> x
+ [10]
+
+you might be wondering why appending an element to ``y`` changed ``x`` too.
+
+There are two factors that produce this result:
+
+1) Variables are simply names that refer to objects. Doing ``y = x`` doesn't
+ create a copy of the list -- it creates a new variable ``y`` that refers to
+ the same object ``x`` refers to. This means that there is only one object
+ (the list), and both ``x`` and ``y`` refer to it.
+2) Lists are :term:`mutable`, which means that you can change their content.
+
+After the call to :meth:`~list.append`, the content of the mutable object has
+changed from ``[]`` to ``[10]``. Since both the variables refer to the same
+object, using either name accesses the modified value ``[10]``.
+
+If we instead assign an immutable object to ``x``::
+
+ >>> x = 5 # ints are immutable
+ >>> y = x
+ >>> x = x + 1 # 5 can't be mutated, we are creating a new object here
+ >>> x
+ 6
+ >>> y
+ 5
+
+we can see that in this case ``x`` and ``y`` are not equal anymore. This is
+because integers are :term:`immutable`, and when we do ``x = x + 1`` we are not
+mutating the int ``5`` by incrementing its value; instead, we are creating a
+new object (the int ``6``) and assigning it to ``x`` (that is, changing which
+object ``x`` refers to). After this assignment we have two objects (the ints
+``6`` and ``5``) and two variables that refer to them (``x`` now refers to
+``6`` but ``y`` still refers to ``5``).
+
+Some operations (for example ``y.append(10)`` and ``y.sort()``) mutate the
+object, whereas superficially similar operations (for example ``y = y + [10]``
+and ``sorted(y)``) create a new object. In general in Python (and in all cases
+in the standard library) a method that mutates an object will return ``None``
+to help avoid getting the two types of operations confused. So if you
+mistakenly write ``y.sort()`` thinking it will give you a sorted copy of ``y``,
+you'll instead end up with ``None``, which will likely cause your program to
+generate an easily diagnosed error.
+
+However, there is one class of operations where the same operation sometimes
+has different behaviors with different types: the augmented assignment
+operators. For example, ``+=`` mutates lists but not tuples or ints (``a_list
++= [1, 2, 3]`` is equivalent to ``a_list.extend([1, 2, 3])`` and mutates
+``a_list``, whereas ``some_tuple += (1, 2, 3)`` and ``some_int += 1`` create
+new objects).
+
+In other words:
+
+* If we have a mutable object (:class:`list`, :class:`dict`, :class:`set`,
+ etc.), we can use some specific operations to mutate it and all the variables
+ that refer to it will see the change.
+* If we have an immutable object (:class:`str`, :class:`int`, :class:`tuple`,
+ etc.), all the variables that refer to it will always see the same value,
+ but operations that transform that value into a new value always return a new
+ object.
+
+If you want to know if two variables refer to the same object or not, you can
+use the :keyword:`is` operator, or the built-in function :func:`id`.
+
+
How do I write a function with output parameters (call by reference)?
---------------------------------------------------------------------
@@ -587,7 +699,7 @@ desired effect in a number of ways.
args['a'] = 'new-value' # args is a mutable dictionary
args['b'] = args['b'] + 1 # change it in-place
- args = {'a':' old-value', 'b': 99}
+ args = {'a': 'old-value', 'b': 99}
func3(args)
print args['a'], args['b']
@@ -703,16 +815,15 @@ Essentially, assignment always binds a name to a value; The same is true of
``def`` and ``class`` statements, but in that case the value is a
callable. Consider the following code::
- class A:
- pass
-
- B = A
-
- a = B()
- b = a
- print b
+ >>> class A:
+ ... pass
+ ...
+ >>> B = A
+ >>> a = B()
+ >>> b = a
+ >>> print b
<__main__.A instance at 0x16D07CC>
- print a
+ >>> print a
<__main__.A instance at 0x16D07CC>
Arguably the class has a name: even though it is bound to two names and invoked
@@ -886,9 +997,27 @@ To convert, e.g., the number 144 to the string '144', use the built-in type
constructor :func:`str`. If you want a hexadecimal or octal representation, use
the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see
the :ref:`formatstrings` section, e.g. ``"{:04d}".format(144)`` yields
-``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``. You may also use
-:ref:`the % operator ` on strings. See the library reference
-manual for details.
+``'0144'`` and ``"{:.3f}".format(1.0/3.0)`` yields ``'0.333'``. In Python 2, the
+division (/) operator returns the floor of the mathematical result of division
+if the arguments are ints or longs, but it returns a reasonable approximation of
+the division result if the arguments are floats or complex::
+
+ >>> print('{:.3f}'.format(1/3))
+ 0.000
+ >>> print('{:.3f}'.format(1.0/3))
+ 0.333
+
+In Python 3, the default behaviour of the division operator (see :pep:`238`) has
+been changed but you can have the same behaviour in Python 2 if you import
+``division`` from :mod:`__future__`::
+
+ >>> from __future__ import division
+ >>> print('{:.3f}'.format(1/3))
+ 0.333
+
+
+You may also use :ref:`the % operator ` on strings. See the
+library reference manual for details.
How do I modify a string in place?
@@ -910,7 +1039,7 @@ ability, try converting the string to a list or use the array module::
>>> a = array.array('c', s)
>>> print a
array('c', 'Hello, world')
- >>> a[0] = 'y' ; print a
+ >>> a[0] = 'y'; print a
array('c', 'yello, world')
>>> a.tostring()
'yello, world'
@@ -1097,7 +1226,7 @@ How do I iterate over a sequence in reverse order?
Use the :func:`reversed` built-in function, which is new in Python 2.4::
for x in reversed(sequence):
- ... # do something with x...
+ ... # do something with x ...
This won't touch your original sequence, but build a new copy with reversed
order to iterate over.
@@ -1105,7 +1234,7 @@ order to iterate over.
With Python 2.3, you can use an extended slice syntax::
for x in sequence[::-1]:
- ... # do something with x...
+ ... # do something with x ...
How do you remove duplicates from a list?
@@ -1113,7 +1242,7 @@ How do you remove duplicates from a list?
See the Python Cookbook for a long discussion of many ways to do this:
- http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560
+ https://code.activestate.com/recipes/52560/
If you don't mind reordering the list, sort it and then scan from the end of the
list, deleting duplicates as you go::
@@ -1168,6 +1297,8 @@ analogue of lisp car is ``lisp_list[0]`` and the analogue of cdr is
usually a lot slower than using Python lists.
+.. _faq-multidimensional-list:
+
How do I create a multidimensional list?
----------------------------------------
@@ -1204,7 +1335,7 @@ use a list comprehension::
w, h = 2, 3
A = [[None] * w for i in range(h)]
-Or, you can use an extension that provides a matrix datatype; `Numeric Python
+Or, you can use an extension that provides a matrix datatype; `NumPy
`_ is the best known.
@@ -1347,40 +1478,11 @@ I want to do a complicated sort: can you do a Schwartzian Transform in Python?
The technique, attributed to Randal Schwartz of the Perl community, sorts the
elements of a list by a metric which maps each element to its "sort value". In
-Python, just use the ``key`` argument for the ``sort()`` method::
+Python, use the ``key`` argument for the :func:`sort()` function::
Isorted = L[:]
Isorted.sort(key=lambda s: int(s[10:15]))
-The ``key`` argument is new in Python 2.4, for older versions this kind of
-sorting is quite simple to do with list comprehensions. To sort a list of
-strings by their uppercase values::
-
- tmp1 = [(x.upper(), x) for x in L] # Schwartzian transform
- tmp1.sort()
- Usorted = [x[1] for x in tmp1]
-
-To sort by the integer value of a subfield extending from positions 10-15 in
-each string::
-
- tmp2 = [(int(s[10:15]), s) for s in L] # Schwartzian transform
- tmp2.sort()
- Isorted = [x[1] for x in tmp2]
-
-Note that Isorted may also be computed by ::
-
- def intfield(s):
- return int(s[10:15])
-
- def Icmp(s1, s2):
- return cmp(intfield(s1), intfield(s2))
-
- Isorted = L[:]
- Isorted.sort(Icmp)
-
-but since this method calls ``intfield()`` many times for each element of L, it
-is slower than the Schwartzian Transform.
-
How can I sort one list by values from another list?
----------------------------------------------------
@@ -1438,7 +1540,7 @@ A method is a function on some object ``x`` that you normally call as
definition::
class C:
- def meth (self, arg):
+ def meth(self, arg):
return arg * 2 + self.attribute
@@ -1471,9 +1573,9 @@ that does something::
def search(obj):
if isinstance(obj, Mailbox):
- # ... code to search a mailbox
+ ... # code to search a mailbox
elif isinstance(obj, Document):
- # ... code to search a document
+ ... # code to search a document
elif ...
A better approach is to define a ``search()`` method on all the classes and just
@@ -1481,11 +1583,11 @@ call it::
class Mailbox:
def search(self):
- # ... code to search a mailbox
+ ... # code to search a mailbox
class Document:
def search(self):
- # ... code to search a document
+ ... # code to search a document
obj.search()
@@ -1542,7 +1644,7 @@ How do I call a method defined in a base class from a derived class that overrid
If you're using new-style classes, use the built-in :func:`super` function::
class Derived(Base):
- def meth (self):
+ def meth(self):
super(Derived, self).meth()
If you're using classic classes: For a class definition such as ``class
@@ -1869,19 +1971,10 @@ These solutions are not mutually exclusive.
__import__('x.y.z') returns ; how do I get z?
---------------------------------------------------------
-Try::
-
- __import__('x.y.z').y.z
-
-For more realistic situations, you may have to do something like ::
-
- m = __import__(s)
- for i in s.split(".")[1:]:
- m = getattr(m, i)
-
-See :mod:`importlib` for a convenience function called
-:func:`~importlib.import_module`.
+Consider using the convenience function :func:`~importlib.import_module` from
+:mod:`importlib` instead::
+ z = importlib.import_module('x.y.z')
When I edit an imported module and reimport it, the changes don't show up. Why does this happen?
diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst
index 7cc6033d..7f0c955b 100644
--- a/Doc/faq/windows.rst
+++ b/Doc/faq/windows.rst
@@ -17,18 +17,6 @@ This is not necessarily a straightforward question. If you are already familiar
with running programs from the Windows command line then everything will seem
obvious; otherwise, you might need a little more guidance.
-.. sidebar:: |Python Development on XP|_
- :subtitle: `Python Development on XP`_
-
- This series of screencasts aims to get you up and running with Python on
- Windows XP. The knowledge is distilled into 1.5 hours and will get you up
- and running with the right Python distribution, coding in your choice of IDE,
- and debugging and writing solid code with unit-tests.
-
-.. |Python Development on XP| image:: python-video-icon.png
-.. _`Python Development on XP`:
- http://www.showmedo.com/videos/series?name=pythonOzsvaldPyNewbieSeries
-
Unless you use some sort of integrated development environment, you will end up
*typing* Windows commands into what is variously referred to as a "DOS window"
or "Command prompt window". Usually you can create such a window from your
@@ -74,17 +62,17 @@ by entering a few expressions of your choice and seeing the results::
>>> print "Hello"
Hello
>>> "Hello" * 3
- HelloHelloHello
+ 'HelloHelloHello'
Many people use the interactive mode as a convenient yet highly programmable
-calculator. When you want to end your interactive Python session, hold the Ctrl
-key down while you enter a Z, then hit the "Enter" key to get back to your
+calculator. When you want to end your interactive Python session, hold the :kbd:`Ctrl`
+key down while you enter a :kbd:`Z`, then hit the ":kbd:`Enter`" key to get back to your
Windows command prompt.
You may also find that you have a Start-menu entry such as :menuselection:`Start
--> Programs --> Python 2.7 --> Python (command line)` that results in you
seeing the ``>>>`` prompt in a new window. If so, the window will disappear
-after you enter the Ctrl-Z character; Windows is running a single "python"
+after you enter the :kbd:`Ctrl-Z` character; Windows is running a single "python"
command in the window, and closes it when you terminate the interpreter.
If the ``python`` command, instead of displaying the interpreter prompt ``>>>``,
@@ -92,18 +80,6 @@ gives you a message like::
'python' is not recognized as an internal or external command, operable program or batch file.
-.. sidebar:: |Adding Python to DOS Path|_
- :subtitle: `Adding Python to DOS Path`_
-
- Python is not added to the DOS path by default. This screencast will walk
- you through the steps to add the correct entry to the `System Path`, allowing
- Python to be executed from the command-line by all users.
-
-.. |Adding Python to DOS Path| image:: python-video-icon.png
-.. _`Adding Python to DOS Path`:
- http://showmedo.com/videos/video?name=960000&fromSeriesID=96
-
-
or::
Bad command or filename
@@ -127,8 +103,8 @@ you should make sure that entering the command ::
c:\Python27\python
-starts up the interpreter as above (and don't forget you'll need a "CTRL-Z" and
-an "Enter" to get out of it). Once you have verified the directory, you can
+starts up the interpreter as above (and don't forget you'll need a ":kbd:`Ctrl-Z`" and
+an ":kbd:`Enter`" to get out of it). Once you have verified the directory, you can
add it to the system path to make it easier to start Python by just running
the ``python`` command. This is currently an option in the installer as of
CPython 2.7.
@@ -243,7 +219,7 @@ Embedding the Python interpreter in a Windows app can be summarized as follows:
...
Py_Initialize(); // Initialize Python.
initmyAppc(); // Initialize (import) the helper class.
- PyRun_SimpleString("import myApp") ; // Import the shadow class.
+ PyRun_SimpleString("import myApp"); // Import the shadow class.
5. There are two problems with Python's C API which will become apparent if you
use a compiler other than MSVC, the compiler used to build pythonNN.dll.
@@ -295,7 +271,7 @@ this respect, and is easily configured to use spaces: Take :menuselection:`Tools
size" to 4, and select the "Insert spaces" radio button.
If you suspect mixed tabs and spaces are causing problems in leading whitespace,
-run Python with the :option:`-t` switch or run ``Tools/Scripts/tabnanny.py`` to
+run Python with the :option:`-t` switch or run the :mod:`tabnanny` module to
check a directory tree in batch mode.
@@ -321,7 +297,7 @@ Prior to Python 2.7 and 3.2, to terminate a process, you can use :mod:`ctypes`::
return (0 != kernel32.TerminateProcess(handle, 0))
In 2.7 and 3.2, :func:`os.kill` is implemented similar to the above function,
-with the additional feature of being able to send CTRL+C and CTRL+BREAK
+with the additional feature of being able to send :kbd:`Ctrl+C` and :kbd:`Ctrl+Break`
to console subprocesses which are designed to handle those signals. See
:func:`os.kill` for further details.
@@ -334,5 +310,5 @@ This is a mistake; the extension should be .TGZ.
Simply rename the downloaded file to have the .TGZ extension, and WinZip will be
able to handle it. (If your copy of WinZip doesn't, get a newer one from
-http://www.winzip.com.)
+https://www.winzip.com.)
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index b5e81717..43abf504 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -14,8 +14,9 @@ Glossary
``...``
The default Python prompt of the interactive shell when entering code for
- an indented code block or within a pair of matching left and right
- delimiters (parentheses, square brackets or curly braces).
+ an indented code block, when within a pair of matching left and right
+ delimiters (parentheses, square brackets, curly braces or triple quotes),
+ or after specifying a decorator.
2to3
A tool that tries to convert Python 2.x code to Python 3.x code by
@@ -75,7 +76,7 @@ Glossary
BDFL
Benevolent Dictator For Life, a.k.a. `Guido van Rossum
- `_, Python's creator.
+ `_, Python's creator.
bytes-like object
An object that supports the :ref:`buffer protocol `,
@@ -140,7 +141,7 @@ Glossary
CPython
The canonical implementation of the Python programming language, as
- distributed on `python.org `_. The term "CPython"
+ distributed on `python.org `_. The term "CPython"
is used when necessary to distinguish this implementation from others
such as Jython or IronPython.
@@ -182,6 +183,14 @@ Glossary
keys can be any object with :meth:`__hash__` and :meth:`__eq__` methods.
Called a hash in Perl.
+ dictionary view
+ The objects returned from :meth:`dict.viewkeys`, :meth:`dict.viewvalues`,
+ and :meth:`dict.viewitems` are called dictionary views. They provide a dynamic
+ view on the dictionary’s entries, which means that when the dictionary
+ changes, the view reflects these changes. To force the
+ dictionary view to become a full list use ``list(dictview)``. See
+ :ref:`dict-views`.
+
docstring
A string literal which appears as the first expression in a class,
function or module. While ignored when the suite is executed, it is
@@ -284,11 +293,11 @@ Glossary
generator
A function which returns an iterator. It looks like a normal function
except that it contains :keyword:`yield` statements for producing a series
- a values usable in a for-loop or that can be retrieved one at a time with
+ of values usable in a for-loop or that can be retrieved one at a time with
the :func:`next` function. Each :keyword:`yield` temporarily suspends
processing, remembering the location execution state (including local
variables and pending try-statements). When the generator resumes, it
- picks-up where it left-off (in contrast to functions which start fresh on
+ picks up where it left off (in contrast to functions which start fresh on
every invocation).
.. index:: single: generator expression
@@ -338,8 +347,8 @@ Glossary
All of Python's immutable built-in objects are hashable, while no mutable
containers (such as lists or dictionaries) are. Objects which are
instances of user-defined classes are hashable by default; they all
- compare unequal (except with themselves), and their hash value is their
- :func:`id`.
+ compare unequal (except with themselves), and their hash value is derived
+ from their :func:`id`.
IDLE
An Integrated Development Environment for Python. IDLE is a basic editor
@@ -408,10 +417,10 @@ Glossary
iterator
An object representing a stream of data. Repeated calls to the iterator's
- :meth:`next` method return successive items in the stream. When no more
+ :meth:`~generator.next` method return successive items in the stream. When no more
data are available a :exc:`StopIteration` exception is raised instead. At
this point, the iterator object is exhausted and any further calls to its
- :meth:`next` method just raise :exc:`StopIteration` again. Iterators are
+ :meth:`~generator.next` method just raise :exc:`StopIteration` again. Iterators are
required to have an :meth:`__iter__` method that returns the iterator
object itself so every iterator is also iterable and may be used in most
places where other iterables are accepted. One notable exception is code
@@ -449,7 +458,7 @@ Glossary
lambda
An anonymous inline function consisting of a single :term:`expression`
which is evaluated when the function is called. The syntax to create
- a lambda function is ``lambda [arguments]: expression``
+ a lambda function is ``lambda [parameters]: expression``
LBYL
Look before you leap. This coding style explicitly tests for
@@ -466,7 +475,7 @@ Glossary
list
A built-in Python :term:`sequence`. Despite its name it is more akin
to an array in other languages than to a linked list since access to
- elements are O(1).
+ elements is O(1).
list comprehension
A compact way to process all or part of the elements in a sequence and
@@ -481,6 +490,11 @@ Glossary
:meth:`load_module`. A loader is typically returned by a
:term:`finder`. See :pep:`302` for details.
+ magic method
+ .. index:: pair: magic; method
+
+ An informal synonym for :term:`special method`.
+
mapping
A container object that supports arbitrary key lookups and implements the
methods specified in the :class:`~collections.Mapping` or
@@ -511,7 +525,8 @@ Glossary
method resolution order
Method Resolution Order is the order in which base classes are searched
for a member during lookup. See `The Python 2.3 Method Resolution Order
- `_.
+ `_ for details of the
+ algorithm used by the Python interpreter since the 2.3 release.
module
An object that serves as an organizational unit of Python code. Modules
@@ -616,6 +631,21 @@ Glossary
:ref:`the difference between arguments and parameters
`, and the :ref:`function` section.
+ PEP
+ Python Enhancement Proposal. A PEP is a design document
+ providing information to the Python community, or describing a new
+ feature for Python or its processes or environment. PEPs should
+ provide a concise technical specification and a rationale for proposed
+ features.
+
+ PEPs are intended to be the primary mechanisms for proposing major new
+ features, for collecting community input on an issue, and for documenting
+ the design decisions that have gone into Python. The PEP author is
+ responsible for building consensus within the community and documenting
+ dissenting opinions.
+
+ See :pep:`1`.
+
positional argument
See :term:`argument`.
@@ -673,6 +703,8 @@ Glossary
versions, :meth:`__getslice__` and :meth:`__setslice__`).
special method
+ .. index:: pair: special; method
+
A method that is called implicitly by Python to execute a certain
operation on a type, such as addition. Such methods have names starting
and ending with double underscores. Special methods are documented in
@@ -685,7 +717,7 @@ Glossary
struct sequence
A tuple with named elements. Struct sequences expose an interface similiar
- to :term:`named tuple` in that elements can either be accessed either by
+ to :term:`named tuple` in that elements can be accessed either by
index or as an attribute. However, they do not have any of the named tuple
methods like :meth:`~collections.somenamedtuple._make` or
:meth:`~collections.somenamedtuple._asdict`. Examples of struct sequences
@@ -713,12 +745,11 @@ Glossary
``'\r'``. See :pep:`278` and :pep:`3116`, as well as
:func:`str.splitlines` for an additional use.
- view
- The objects returned from :meth:`dict.viewkeys`, :meth:`dict.viewvalues`,
- and :meth:`dict.viewitems` are called dictionary views. They are lazy
- sequences that will see changes in the underlying dictionary. To force
- the dictionary view to become a full list use ``list(dictview)``. See
- :ref:`dict-views`.
+ virtual environment
+ A cooperatively isolated runtime environment that allows Python users
+ and applications to install and upgrade Python distribution packages
+ without interfering with the behaviour of other Python applications
+ running on the same system.
virtual machine
A computer defined entirely in software. Python's virtual machine
diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst
index f110a55b..63b0b28a 100644
--- a/Doc/howto/argparse.rst
+++ b/Doc/howto/argparse.rst
@@ -8,6 +8,8 @@ Argparse Tutorial
This tutorial is intended to be a gentle introduction to :mod:`argparse`, the
recommended command-line parsing module in the Python standard library.
+This was written for argparse in Python 3. A few details are different in 2.x,
+especially some exception messages, which were improved in 3.x.
.. note::
@@ -221,7 +223,7 @@ before proceeding.
Introducing Optional arguments
==============================
-So far we, have been playing with positional arguments. Let us
+So far we have been playing with positional arguments. Let us
have a look on how to add optional ones::
import argparse
@@ -511,7 +513,7 @@ to count the number of occurrences of a specific optional arguments:
* Sadly, our help output isn't very informative on the new ability our script
has acquired, but that can always be fixed by improving the documentation for
- out script (e.g. via the ``help`` keyword argument).
+ our script (e.g. via the ``help`` keyword argument).
* That last output exposes a bug in our program.
diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst
index 1ad77d68..7cacb0ae 100644
--- a/Doc/howto/cporting.rst
+++ b/Doc/howto/cporting.rst
@@ -43,10 +43,9 @@ separating others.
str/unicode Unification
-----------------------
-
-Python 3's :func:`str` (``PyString_*`` functions in C) type is equivalent to
-Python 2's :func:`unicode` (``PyUnicode_*``). The old 8-bit string type has
-become :func:`bytes`. Python 2.6 and later provide a compatibility header,
+Python 3's :func:`str` type is equivalent to Python 2's :func:`unicode`; the C
+functions are called ``PyUnicode_*`` for both. The old 8-bit string type has become
+:func:`bytes`, with C functions called ``PyBytes_*``. Python 2.6 and later provide a compatibility header,
:file:`bytesobject.h`, mapping ``PyBytes`` names to ``PyString`` ones. For best
compatibility with Python 3, :c:type:`PyUnicode` should be used for textual data and
:c:type:`PyBytes` for binary data. It's also important to remember that
@@ -96,7 +95,7 @@ long/int Unification
--------------------
Python 3 has only one integer type, :func:`int`. But it actually
-corresponds to Python 2's :func:`long` type--the :func:`int` type
+corresponds to Python 2's :func:`long` type—the :func:`int` type
used in Python 2 was removed. In the C-API, ``PyInt_*`` functions
are replaced by their ``PyLong_*`` equivalents.
@@ -162,7 +161,7 @@ simple example demonstrates how. ::
#define INITERROR return NULL
- PyObject *
+ PyMODINIT_FUNC
PyInit_myextension(void)
#else
@@ -253,6 +252,6 @@ Other options
=============
If you are writing a new extension module, you might consider `Cython
-`_. It translates a Python-like language to C. The
+`_. It translates a Python-like language to C. The
extension modules it creates are compatible with Python 3 and Python 2.
diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst
index 74c1f2a4..47585f6f 100644
--- a/Doc/howto/curses.rst
+++ b/Doc/howto/curses.rst
@@ -35,7 +35,7 @@ before X is available.
The curses library hides all the details of different terminals, and provides
the programmer with an abstraction of a display, containing multiple
non-overlapping windows. The contents of a window can be changed in various
-ways-- adding text, erasing it, changing its appearance--and the curses library
+ways---adding text, erasing it, changing its appearance---and the curses library
will automagically figure out what control codes need to be sent to the terminal
to produce the right output.
@@ -122,13 +122,12 @@ raises an uncaught exception. Keys are no longer echoed to the screen when
you type them, for example, which makes using the shell difficult.
In Python you can avoid these complications and make debugging much easier by
-importing the module :mod:`curses.wrapper`. It supplies a :func:`wrapper`
-function that takes a callable. It does the initializations described above,
-and also initializes colors if color support is present. It then runs your
-provided callable and finally deinitializes appropriately. The callable is
-called inside a try-catch clause which catches exceptions, performs curses
-deinitialization, and then passes the exception upwards. Thus, your terminal
-won't be left in a funny state on exception.
+importing the :func:`curses.wrapper` function. It takes a callable and does
+the initializations described above, also initializing colors if color support
+is present. It then runs your provided callable and finally deinitializes
+appropriately. The callable is called inside a try-catch clause which catches
+exceptions, performs curses deinitialization, and then passes the exception
+upwards. Thus, your terminal won't be left in a funny state on exception.
Windows and Pads
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index 78281887..37ba6a8b 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -96,9 +96,9 @@ For objects, the machinery is in :meth:`object.__getattribute__` which
transforms ``b.x`` into ``type(b).__dict__['x'].__get__(b, type(b))``. The
implementation works through a precedence chain that gives data descriptors
priority over instance variables, instance variables priority over non-data
-descriptors, and assigns lowest priority to :meth:`__getattr__` if provided. The
-full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in
-`Objects/object.c `_\.
+descriptors, and assigns lowest priority to :meth:`__getattr__` if provided.
+The full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in
+:source:`Objects/object.c`.
For classes, the machinery is in :meth:`type.__getattribute__` which transforms
``B.x`` into ``B.__dict__['x'].__get__(None, B)``. In pure Python, it looks
@@ -108,7 +108,7 @@ like::
"Emulate type_getattro() in Objects/typeobject.c"
v = object.__getattribute__(self, key)
if hasattr(v, '__get__'):
- return v.__get__(None, self)
+ return v.__get__(None, self)
return v
The important points to remember are:
@@ -131,11 +131,9 @@ search using :meth:`object.__getattribute__`.
Note, in Python 2.2, ``super(B, obj).m()`` would only invoke :meth:`__get__` if
``m`` was a data descriptor. In Python 2.3, non-data descriptors also get
invoked unless an old-style class is involved. The implementation details are
-in :c:func:`super_getattro()` in
-`Objects/typeobject.c `_
-and a pure Python equivalent can be found in `Guido's Tutorial`_.
+in :c:func:`super_getattro()` in :source:`Objects/typeobject.c`.
-.. _`Guido's Tutorial`: http://www.python.org/2.2.3/descrintro.html#cooperation
+.. _`Guido's Tutorial`: https://www.python.org/download/releases/2.2.3/descrintro/#cooperation
The details above show that the mechanism for descriptors is embedded in the
:meth:`__getattribute__()` methods for :class:`object`, :class:`type`, and
@@ -167,13 +165,13 @@ descriptor is useful for monitoring just a few chosen attributes::
return self.val
def __set__(self, obj, val):
- print 'Updating' , self.name
+ print 'Updating', self.name
self.val = val
>>> class MyClass(object):
- x = RevealAccess(10, 'var "x"')
- y = 5
-
+ ... x = RevealAccess(10, 'var "x"')
+ ... y = 5
+ ...
>>> m = MyClass()
>>> m.x
Retrieving var "x"
@@ -260,10 +258,10 @@ to wrap access to the value attribute in a property data descriptor::
class Cell(object):
. . .
- def getvalue(self, obj):
- "Recalculate cell before returning value"
+ def getvalue(self):
+ "Recalculate the cell before returning value"
self.recalc()
- return obj._value
+ return self._value
value = property(getvalue)
@@ -295,23 +293,22 @@ this::
Running the interpreter shows how the function descriptor works in practice::
>>> class D(object):
- def f(self, x):
- return x
-
+ ... def f(self, x):
+ ... return x
+ ...
>>> d = D()
- >>> D.__dict__['f'] # Stored internally as a function
+ >>> D.__dict__['f'] # Stored internally as a function
- >>> D.f # Get from a class becomes an unbound method
+ >>> D.f # Get from a class becomes an unbound method
- >>> d.f # Get from an instance becomes a bound method
+ >>> d.f # Get from an instance becomes a bound method
>
The output suggests that bound and unbound methods are two different types.
While they could have been implemented that way, the actual C implementation of
-:c:type:`PyMethod_Type` in
-`Objects/classobject.c `_
-is a single object with two different representations depending on whether the
-:attr:`im_self` field is set or is *NULL* (the C equivalent of *None*).
+:c:type:`PyMethod_Type` in :source:`Objects/classobject.c` is a single object
+with two different representations depending on whether the :attr:`im_self`
+field is set or is *NULL* (the C equivalent of ``None``).
Likewise, the effects of calling a method object depend on the :attr:`im_self`
field. If set (meaning bound), the original function (stored in the
@@ -328,7 +325,7 @@ Non-data descriptors provide a simple mechanism for variations on the usual
patterns of binding functions into methods.
To recap, functions have a :meth:`__get__` method so that they can be converted
-to a method when accessed as attributes. The non-data descriptor transforms a
+to a method when accessed as attributes. The non-data descriptor transforms an
``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``klass.f(*args)``
becomes ``f(*args)``.
@@ -367,10 +364,10 @@ Since staticmethods return the underlying function with no changes, the example
calls are unexciting::
>>> class E(object):
- def f(x):
- print x
- f = staticmethod(f)
-
+ ... def f(x):
+ ... print x
+ ... f = staticmethod(f)
+ ...
>>> print E.f(3)
3
>>> print E().f(3)
@@ -380,23 +377,23 @@ Using the non-data descriptor protocol, a pure Python version of
:func:`staticmethod` would look like this::
class StaticMethod(object):
- "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
+ "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
- def __init__(self, f):
- self.f = f
+ def __init__(self, f):
+ self.f = f
- def __get__(self, obj, objtype=None):
- return self.f
+ def __get__(self, obj, objtype=None):
+ return self.f
Unlike static methods, class methods prepend the class reference to the
argument list before calling the function. This format is the same
for whether the caller is an object or a class::
>>> class E(object):
- def f(klass, x):
- return klass.__name__, x
- f = classmethod(f)
-
+ ... def f(klass, x):
+ ... return klass.__name__, x
+ ... f = classmethod(f)
+ ...
>>> print E.f(3)
('E', 3)
>>> print E().f(3)
@@ -428,15 +425,15 @@ Using the non-data descriptor protocol, a pure Python version of
:func:`classmethod` would look like this::
class ClassMethod(object):
- "Emulate PyClassMethod_Type() in Objects/funcobject.c"
+ "Emulate PyClassMethod_Type() in Objects/funcobject.c"
- def __init__(self, f):
- self.f = f
+ def __init__(self, f):
+ self.f = f
- def __get__(self, obj, klass=None):
- if klass is None:
- klass = type(obj)
- def newfunc(*args):
- return self.f(klass, *args)
- return newfunc
+ def __get__(self, obj, klass=None):
+ if klass is None:
+ klass = type(obj)
+ def newfunc(*args):
+ return self.f(klass, *args)
+ return newfunc
diff --git a/Doc/howto/doanddont.rst b/Doc/howto/doanddont.rst
index 98dbad19..35e15837 100644
--- a/Doc/howto/doanddont.rst
+++ b/Doc/howto/doanddont.rst
@@ -285,7 +285,7 @@ There are also many useful built-in functions people seem not to be aware of
for some reason: :func:`min` and :func:`max` can find the minimum/maximum of
any sequence with comparable semantics, for example, yet many people write
their own :func:`max`/:func:`min`. Another highly useful function is
-:func:`reduce` which can be used to repeatly apply a binary operation to a
+:func:`reduce` which can be used to repeatedly apply a binary operation to a
sequence, reducing it to a single value. For example, compute a factorial
with a series of multiply operations::
diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst
index 836ec6da..a06e29ce 100644
--- a/Doc/howto/functional.rst
+++ b/Doc/howto/functional.rst
@@ -207,7 +207,7 @@ You can experiment with the iteration interface manually:
3
>>> it.next()
Traceback (most recent call last):
- File "", line 1, in ?
+ File "", line 1, in
StopIteration
>>>
@@ -331,7 +331,7 @@ substring.
List comprehensions and generator expressions (short form: "listcomps" and
"genexps") are a concise notation for such operations, borrowed from the
-functional programming language Haskell (http://www.haskell.org/). You can strip
+functional programming language Haskell (https://www.haskell.org/). You can strip
all the whitespace from a stream of strings with the following code::
line_list = [' line 1\n', 'line 2 \n', ...]
@@ -394,14 +394,14 @@ equivalent to the following Python code::
continue # Skip this element
for expr2 in sequence2:
if not (condition2):
- continue # Skip this element
+ continue # Skip this element
...
for exprN in sequenceN:
- if not (conditionN):
- continue # Skip this element
+ if not (conditionN):
+ continue # Skip this element
- # Output the value of
- # the expression.
+ # Output the value of
+ # the expression.
This means that when there are multiple ``for...in`` clauses but no ``if``
clauses, the length of the resulting output will be equal to the product of the
@@ -477,7 +477,7 @@ Here's a sample usage of the ``generate_ints()`` generator:
2
>>> gen.next()
Traceback (most recent call last):
- File "stdin", line 1, in ?
+ File "stdin", line 1, in
File "stdin", line 2, in generate_ints
StopIteration
@@ -581,13 +581,14 @@ And here's an example of changing the counter:
9
>>> print it.next()
Traceback (most recent call last):
- File "t.py", line 15, in ?
+ File "t.py", line 15, in
print it.next()
StopIteration
Because ``yield`` will often be returning ``None``, you should always check for
this case. Don't just use its value in expressions unless you're sure that the
-``send()`` method will be the only method used resume your generator function.
+``send()`` method will be the only method used to resume your generator
+function.
In addition to ``send()``, there are two other new methods on generators:
@@ -740,11 +741,11 @@ the constructed list's ``.sort()`` method. ::
[9878, 9828, 8442, 7953, 6431, 6213, 2207, 769]
(For a more detailed discussion of sorting, see the Sorting mini-HOWTO in the
-Python wiki at http://wiki.python.org/moin/HowTo/Sorting.)
+Python wiki at https://wiki.python.org/moin/HowTo/Sorting.)
The ``any(iter)`` and ``all(iter)`` built-ins look at the truth values of an
-iterable's contents. :func:`any` returns True if any element in the iterable is
-a true value, and :func:`all` returns True if all of the elements are true
+iterable's contents. :func:`any` returns ``True`` if any element in the iterable is
+a true value, and :func:`all` returns ``True`` if all of the elements are true
values:
>>> any([0,1,0])
@@ -1143,7 +1144,7 @@ General
**Structure and Interpretation of Computer Programs**, by Harold Abelson and
Gerald Jay Sussman with Julie Sussman. Full text at
-http://mitpress.mit.edu/sicp/. In this classic textbook of computer science,
+https://mitpress.mit.edu/sicp/. In this classic textbook of computer science,
chapters 2 and 3 discuss the use of sequences and streams to organize the data
flow inside a program. The book uses Scheme for its examples, but many of the
design approaches described in these chapters are applicable to functional-style
@@ -1152,12 +1153,12 @@ Python code.
http://www.defmacro.org/ramblings/fp.html: A general introduction to functional
programming that uses Java examples and has a lengthy historical introduction.
-http://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry
+https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry
describing functional programming.
-http://en.wikipedia.org/wiki/Coroutine: Entry for coroutines.
+https://en.wikipedia.org/wiki/Coroutine: Entry for coroutines.
-http://en.wikipedia.org/wiki/Currying: Entry for the concept of currying.
+https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying.
Python-specific
---------------
@@ -1170,9 +1171,9 @@ Text Processing".
Mertz also wrote a 3-part series of articles on functional programming
for IBM's DeveloperWorks site; see
-`part 1 `__,
-`part 2 `__, and
-`part 3 `__,
+`part 1 `__,
+`part 2 `__, and
+`part 3 `__,
Python documentation
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index e5d75a64..50ff76e7 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -63,6 +63,7 @@ Here is the auxiliary module::
def __init__(self):
self.logger = logging.getLogger('spam_application.auxiliary.Auxiliary')
self.logger.info('creating an instance of Auxiliary')
+
def do_something(self):
self.logger.info('doing something')
a = 1 + 1
@@ -94,6 +95,61 @@ The output looks like this::
2005-03-23 23:47:11,673 - spam_application - INFO -
done with auxiliary_module.some_function()
+Logging from multiple threads
+-----------------------------
+
+Logging from multiple threads requires no special effort. The following example
+shows logging from the main (initIal) thread and another thread::
+
+ import logging
+ import threading
+ import time
+
+ def worker(arg):
+ while not arg['stop']:
+ logging.debug('Hi from myfunc')
+ time.sleep(0.5)
+
+ def main():
+ logging.basicConfig(level=logging.DEBUG, format='%(relativeCreated)6d %(threadName)s %(message)s')
+ info = {'stop': False}
+ thread = threading.Thread(target=worker, args=(info,))
+ thread.start()
+ while True:
+ try:
+ logging.debug('Hello from main')
+ time.sleep(0.75)
+ except KeyboardInterrupt:
+ info['stop'] = True
+ break
+ thread.join()
+
+ if __name__ == '__main__':
+ main()
+
+When run, the script should print something like the following::
+
+ 0 Thread-1 Hi from myfunc
+ 3 MainThread Hello from main
+ 505 Thread-1 Hi from myfunc
+ 755 MainThread Hello from main
+ 1007 Thread-1 Hi from myfunc
+ 1507 MainThread Hello from main
+ 1508 Thread-1 Hi from myfunc
+ 2010 Thread-1 Hi from myfunc
+ 2258 MainThread Hello from main
+ 2512 Thread-1 Hi from myfunc
+ 3009 MainThread Hello from main
+ 3013 Thread-1 Hi from myfunc
+ 3515 Thread-1 Hi from myfunc
+ 3761 MainThread Hello from main
+ 4017 Thread-1 Hi from myfunc
+ 4513 MainThread Hello from main
+ 4518 Thread-1 Hi from myfunc
+
+This shows the logging output interspersed as one might expect. This approach
+works for more threads than shown here, of course.
+
Multiple handlers and formatters
--------------------------------
@@ -530,21 +586,21 @@ script::
return True
if __name__ == '__main__':
- levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
- logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
- a1 = logging.getLogger('a.b.c')
- a2 = logging.getLogger('d.e.f')
-
- f = ContextFilter()
- a1.addFilter(f)
- a2.addFilter(f)
- a1.debug('A debug message')
- a1.info('An info message with %s', 'some parameters')
- for x in range(10):
- lvl = choice(levels)
- lvlname = logging.getLevelName(lvl)
- a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
+ levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
+ a1 = logging.getLogger('a.b.c')
+ a2 = logging.getLogger('d.e.f')
+
+ f = ContextFilter()
+ a1.addFilter(f)
+ a2.addFilter(f)
+ a1.debug('A debug message')
+ a1.info('An info message with %s', 'some parameters')
+ for x in range(10):
+ lvl = choice(levels)
+ lvlname = logging.getLevelName(lvl)
+ a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
which, when run, produces something like::
@@ -587,14 +643,14 @@ file from your processes. The existing :class:`FileHandler` and subclasses do
not make use of :mod:`multiprocessing` at present, though they may do so in the
future. Note that at present, the :mod:`multiprocessing` module does not provide
working lock functionality on all platforms (see
-http://bugs.python.org/issue3770).
+https://bugs.python.org/issue3770).
Using file rotation
-------------------
.. sectionauthor:: Doug Hellmann, Vinay Sajip (changes)
-.. (see )
+.. (see )
Sometimes you want to let a log file grow to a certain size, then open a new
file and log to that. You may want to keep a certain number of these files, and
@@ -650,7 +706,7 @@ An example dictionary-based configuration
-----------------------------------------
Below is an example of a logging configuration dictionary - it's taken from
-the `documentation on the Django project `_.
+the `documentation on the Django project `_.
This dictionary is passed to :func:`~config.dictConfig` to put the configuration into effect::
LOGGING = {
@@ -706,17 +762,17 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration
}
For more information about this configuration, you can see the `relevant
-section `_
+section `_
of the Django documentation.
Inserting a BOM into messages sent to a SysLogHandler
-----------------------------------------------------
-`RFC 5424 `_ requires that a
+`RFC 5424 `_ requires that a
Unicode message be sent to a syslog daemon as a set of bytes which have the
following structure: an optional pure-ASCII component, followed by a UTF-8 Byte
Order Mark (BOM), followed by Unicode encoded using UTF-8. (See the `relevant
-section of the specification `_.)
+section of the specification `_.)
In Python 2.6 and 2.7, code was added to
:class:`~logging.handlers.SysLogHandler` to insert a BOM into the message, but
@@ -758,7 +814,7 @@ Implementing structured logging
-------------------------------
Although most logging messages are intended for reading by humans, and thus not
-readily machine-parseable, there might be cirumstances where you want to output
+readily machine-parseable, there might be circumstances where you want to output
messages in a structured format which *is* capable of being parsed by a program
(without needing complex regular expressions to parse the log message). This is
straightforward to achieve using the logging package. There are a number of
@@ -835,3 +891,648 @@ When the above script is run, it prints::
Note that the order of items might be different according to the version of
Python used.
+
+.. _custom-handlers:
+
+.. currentmodule:: logging.config
+
+Customizing handlers with :func:`dictConfig`
+--------------------------------------------
+
+There are times when you want to customize logging handlers in particular ways,
+and if you use :func:`dictConfig` you may be able to do this without
+subclassing. As an example, consider that you may want to set the ownership of a
+log file. On POSIX, this is easily done using :func:`os.chown`, but the file
+handlers in the stdlib don't offer built-in support. You can customize handler
+creation using a plain function such as::
+
+ def owned_file_handler(filename, mode='a', encoding=None, owner=None):
+ if owner:
+ import os, pwd, grp
+ # convert user and group names to uid and gid
+ uid = pwd.getpwnam(owner[0]).pw_uid
+ gid = grp.getgrnam(owner[1]).gr_gid
+ owner = (uid, gid)
+ if not os.path.exists(filename):
+ open(filename, 'a').close()
+ os.chown(filename, *owner)
+ return logging.FileHandler(filename, mode, encoding)
+
+You can then specify, in a logging configuration passed to :func:`dictConfig`,
+that a logging handler be created by calling this function::
+
+ LOGGING = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+ 'formatters': {
+ 'default': {
+ 'format': '%(asctime)s %(levelname)s %(name)s %(message)s'
+ },
+ },
+ 'handlers': {
+ 'file':{
+ # The values below are popped from this dictionary and
+ # used to create the handler, set the handler's level and
+ # its formatter.
+ '()': owned_file_handler,
+ 'level':'DEBUG',
+ 'formatter': 'default',
+ # The values below are passed to the handler creator callable
+ # as keyword arguments.
+ 'owner': ['pulse', 'pulse'],
+ 'filename': 'chowntest.log',
+ 'mode': 'w',
+ 'encoding': 'utf-8',
+ },
+ },
+ 'root': {
+ 'handlers': ['file'],
+ 'level': 'DEBUG',
+ },
+ }
+
+In this example I am setting the ownership using the ``pulse`` user and group,
+just for the purposes of illustration. Putting it together into a working
+script, ``chowntest.py``::
+
+ import logging, logging.config, os, shutil
+
+ def owned_file_handler(filename, mode='a', encoding=None, owner=None):
+ if owner:
+ if not os.path.exists(filename):
+ open(filename, 'a').close()
+ shutil.chown(filename, *owner)
+ return logging.FileHandler(filename, mode, encoding)
+
+ LOGGING = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+ 'formatters': {
+ 'default': {
+ 'format': '%(asctime)s %(levelname)s %(name)s %(message)s'
+ },
+ },
+ 'handlers': {
+ 'file':{
+ # The values below are popped from this dictionary and
+ # used to create the handler, set the handler's level and
+ # its formatter.
+ '()': owned_file_handler,
+ 'level':'DEBUG',
+ 'formatter': 'default',
+ # The values below are passed to the handler creator callable
+ # as keyword arguments.
+ 'owner': ['pulse', 'pulse'],
+ 'filename': 'chowntest.log',
+ 'mode': 'w',
+ 'encoding': 'utf-8',
+ },
+ },
+ 'root': {
+ 'handlers': ['file'],
+ 'level': 'DEBUG',
+ },
+ }
+
+ logging.config.dictConfig(LOGGING)
+ logger = logging.getLogger('mylogger')
+ logger.debug('A debug message')
+
+To run this, you will probably need to run as ``root``:
+
+.. code-block:: shell-session
+
+ $ sudo python3.3 chowntest.py
+ $ cat chowntest.log
+ 2013-11-05 09:34:51,128 DEBUG mylogger A debug message
+ $ ls -l chowntest.log
+ -rw-r--r-- 1 pulse pulse 55 2013-11-05 09:34 chowntest.log
+
+Note that this example uses Python 3.3 because that's where :func:`shutil.chown`
+makes an appearance. This approach should work with any Python version that
+supports :func:`dictConfig` - namely, Python 2.7, 3.2 or later. With pre-3.3
+versions, you would need to implement the actual ownership change using e.g.
+:func:`os.chown`.
+
+In practice, the handler-creating function may be in a utility module somewhere
+in your project. Instead of the line in the configuration::
+
+ '()': owned_file_handler,
+
+you could use e.g.::
+
+ '()': 'ext://project.util.owned_file_handler',
+
+where ``project.util`` can be replaced with the actual name of the package
+where the function resides. In the above working script, using
+``'ext://__main__.owned_file_handler'`` should work. Here, the actual callable
+is resolved by :func:`dictConfig` from the ``ext://`` specification.
+
+This example hopefully also points the way to how you could implement other
+types of file change - e.g. setting specific POSIX permission bits - in the
+same way, using :func:`os.chmod`.
+
+Of course, the approach could also be extended to types of handler other than a
+:class:`~logging.FileHandler` - for example, one of the rotating file handlers,
+or a different type of handler altogether.
+
+
+.. _filters-dictconfig:
+
+Configuring filters with :func:`dictConfig`
+-------------------------------------------
+
+You *can* configure filters using :func:`~logging.config.dictConfig`, though it
+might not be obvious at first glance how to do it (hence this recipe). Since
+:class:`~logging.Filter` is the only filter class included in the standard
+library, and it is unlikely to cater to many requirements (it's only there as a
+base class), you will typically need to define your own :class:`~logging.Filter`
+subclass with an overridden :meth:`~logging.Filter.filter` method. To do this,
+specify the ``()`` key in the configuration dictionary for the filter,
+specifying a callable which will be used to create the filter (a class is the
+most obvious, but you can provide any callable which returns a
+:class:`~logging.Filter` instance). Here is a complete example::
+
+ import logging
+ import logging.config
+ import sys
+
+ class MyFilter(logging.Filter):
+ def __init__(self, param=None):
+ self.param = param
+
+ def filter(self, record):
+ if self.param is None:
+ allow = True
+ else:
+ allow = self.param not in record.msg
+ if allow:
+ record.msg = 'changed: ' + record.msg
+ return allow
+
+ LOGGING = {
+ 'version': 1,
+ 'filters': {
+ 'myfilter': {
+ '()': MyFilter,
+ 'param': 'noshow',
+ }
+ },
+ 'handlers': {
+ 'console': {
+ 'class': 'logging.StreamHandler',
+ 'filters': ['myfilter']
+ }
+ },
+ 'root': {
+ 'level': 'DEBUG',
+ 'handlers': ['console']
+ },
+ }
+
+ if __name__ == '__main__':
+ logging.config.dictConfig(LOGGING)
+ logging.debug('hello')
+ logging.debug('hello - noshow')
+
+This example shows how you can pass configuration data to the callable which
+constructs the instance, in the form of keyword parameters. When run, the above
+script will print::
+
+ changed: hello
+
+which shows that the filter is working as configured.
+
+A couple of extra points to note:
+
+* If you can't refer to the callable directly in the configuration (e.g. if it
+ lives in a different module, and you can't import it directly where the
+ configuration dictionary is), you can use the form ``ext://...`` as described
+ in :ref:`logging-config-dict-externalobj`. For example, you could have used
+ the text ``'ext://__main__.MyFilter'`` instead of ``MyFilter`` in the above
+ example.
+
+* As well as for filters, this technique can also be used to configure custom
+ handlers and formatters. See :ref:`logging-config-dict-userdef` for more
+ information on how logging supports using user-defined objects in its
+ configuration, and see the other cookbook recipe :ref:`custom-handlers` above.
+
+
+.. _custom-format-exception:
+
+Customized exception formatting
+-------------------------------
+
+There might be times when you want to do customized exception formatting - for
+argument's sake, let's say you want exactly one line per logged event, even
+when exception information is present. You can do this with a custom formatter
+class, as shown in the following example::
+
+ import logging
+
+ class OneLineExceptionFormatter(logging.Formatter):
+ def formatException(self, exc_info):
+ """
+ Format an exception so that it prints on a single line.
+ """
+ result = super(OneLineExceptionFormatter, self).formatException(exc_info)
+ return repr(result) # or format into one line however you want to
+
+ def format(self, record):
+ s = super(OneLineExceptionFormatter, self).format(record)
+ if record.exc_text:
+ s = s.replace('\n', '') + '|'
+ return s
+
+ def configure_logging():
+ fh = logging.FileHandler('output.txt', 'w')
+ f = OneLineExceptionFormatter('%(asctime)s|%(levelname)s|%(message)s|',
+ '%d/%m/%Y %H:%M:%S')
+ fh.setFormatter(f)
+ root = logging.getLogger()
+ root.setLevel(logging.DEBUG)
+ root.addHandler(fh)
+
+ def main():
+ configure_logging()
+ logging.info('Sample message')
+ try:
+ x = 1 / 0
+ except ZeroDivisionError as e:
+ logging.exception('ZeroDivisionError: %s', e)
+
+ if __name__ == '__main__':
+ main()
+
+When run, this produces a file with exactly two lines::
+
+ 28/01/2015 07:21:23|INFO|Sample message|
+ 28/01/2015 07:21:23|ERROR|ZeroDivisionError: integer division or modulo by zero|'Traceback (most recent call last):\n File "logtest7.py", line 30, in main\n x = 1 / 0\nZeroDivisionError: integer division or modulo by zero'|
+
+While the above treatment is simplistic, it points the way to how exception
+information can be formatted to your liking. The :mod:`traceback` module may be
+helpful for more specialized needs.
+
+.. _spoken-messages:
+
+Speaking logging messages
+-------------------------
+
+There might be situations when it is desirable to have logging messages rendered
+in an audible rather than a visible format. This is easy to do if you have
+text-to-speech (TTS) functionality available in your system, even if it doesn't have
+a Python binding. Most TTS systems have a command line program you can run, and
+this can be invoked from a handler using :mod:`subprocess`. It's assumed here
+that TTS command line programs won't expect to interact with users or take a
+long time to complete, and that the frequency of logged messages will be not so
+high as to swamp the user with messages, and that it's acceptable to have the
+messages spoken one at a time rather than concurrently, The example implementation
+below waits for one message to be spoken before the next is processed, and this
+might cause other handlers to be kept waiting. Here is a short example showing
+the approach, which assumes that the ``espeak`` TTS package is available::
+
+ import logging
+ import subprocess
+ import sys
+
+ class TTSHandler(logging.Handler):
+ def emit(self, record):
+ msg = self.format(record)
+ # Speak slowly in a female English voice
+ cmd = ['espeak', '-s150', '-ven+f3', msg]
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ # wait for the program to finish
+ p.communicate()
+
+ def configure_logging():
+ h = TTSHandler()
+ root = logging.getLogger()
+ root.addHandler(h)
+ # the default formatter just returns the message
+ root.setLevel(logging.DEBUG)
+
+ def main():
+ logging.info('Hello')
+ logging.debug('Goodbye')
+
+ if __name__ == '__main__':
+ configure_logging()
+ sys.exit(main())
+
+When run, this script should say "Hello" and then "Goodbye" in a female voice.
+
+The above approach can, of course, be adapted to other TTS systems and even
+other systems altogether which can process messages via external programs run
+from a command line.
+
+.. _buffered-logging:
+
+Buffering logging messages and outputting them conditionally
+------------------------------------------------------------
+
+There might be situations where you want to log messages in a temporary area
+and only output them if a certain condition occurs. For example, you may want to
+start logging debug events in a function, and if the function completes without
+errors, you don't want to clutter the log with the collected debug information,
+but if there is an error, you want all the debug information to be output as well
+as the error.
+
+Here is an example which shows how you could do this using a decorator for your
+functions where you want logging to behave this way. It makes use of the
+:class:`logging.handlers.MemoryHandler`, which allows buffering of logged events
+until some condition occurs, at which point the buffered events are ``flushed``
+- passed to another handler (the ``target`` handler) for processing. By default,
+the ``MemoryHandler`` flushed when its buffer gets filled up or an event whose
+level is greater than or equal to a specified threshold is seen. You can use this
+recipe with a more specialised subclass of ``MemoryHandler`` if you want custom
+flushing behavior.
+
+The example script has a simple function, ``foo``, which just cycles through
+all the logging levels, writing to ``sys.stderr`` to say what level it's about
+to log at, and then actually logging a message at that level. You can pass a
+parameter to ``foo`` which, if true, will log at ERROR and CRITICAL levels -
+otherwise, it only logs at DEBUG, INFO and WARNING levels.
+
+The script just arranges to decorate ``foo`` with a decorator which will do the
+conditional logging that's required. The decorator takes a logger as a parameter
+and attaches a memory handler for the duration of the call to the decorated
+function. The decorator can be additionally parameterised using a target handler,
+a level at which flushing should occur, and a capacity for the buffer. These
+default to a :class:`~logging.StreamHandler` which writes to ``sys.stderr``,
+``logging.ERROR`` and ``100`` respectively.
+
+Here's the script::
+
+ import logging
+ from logging.handlers import MemoryHandler
+ import sys
+
+ logger = logging.getLogger(__name__)
+ logger.addHandler(logging.NullHandler())
+
+ def log_if_errors(logger, target_handler=None, flush_level=None, capacity=None):
+ if target_handler is None:
+ target_handler = logging.StreamHandler()
+ if flush_level is None:
+ flush_level = logging.ERROR
+ if capacity is None:
+ capacity = 100
+ handler = MemoryHandler(capacity, flushLevel=flush_level, target=target_handler)
+
+ def decorator(fn):
+ def wrapper(*args, **kwargs):
+ logger.addHandler(handler)
+ try:
+ return fn(*args, **kwargs)
+ except Exception:
+ logger.exception('call failed')
+ raise
+ finally:
+ super(MemoryHandler, handler).flush()
+ logger.removeHandler(handler)
+ return wrapper
+
+ return decorator
+
+ def write_line(s):
+ sys.stderr.write('%s\n' % s)
+
+ def foo(fail=False):
+ write_line('about to log at DEBUG ...')
+ logger.debug('Actually logged at DEBUG')
+ write_line('about to log at INFO ...')
+ logger.info('Actually logged at INFO')
+ write_line('about to log at WARNING ...')
+ logger.warning('Actually logged at WARNING')
+ if fail:
+ write_line('about to log at ERROR ...')
+ logger.error('Actually logged at ERROR')
+ write_line('about to log at CRITICAL ...')
+ logger.critical('Actually logged at CRITICAL')
+ return fail
+
+ decorated_foo = log_if_errors(logger)(foo)
+
+ if __name__ == '__main__':
+ logger.setLevel(logging.DEBUG)
+ write_line('Calling undecorated foo with False')
+ assert not foo(False)
+ write_line('Calling undecorated foo with True')
+ assert foo(True)
+ write_line('Calling decorated foo with False')
+ assert not decorated_foo(False)
+ write_line('Calling decorated foo with True')
+ assert decorated_foo(True)
+
+When this script is run, the following output should be observed::
+
+ Calling undecorated foo with False
+ about to log at DEBUG ...
+ about to log at INFO ...
+ about to log at WARNING ...
+ Calling undecorated foo with True
+ about to log at DEBUG ...
+ about to log at INFO ...
+ about to log at WARNING ...
+ about to log at ERROR ...
+ about to log at CRITICAL ...
+ Calling decorated foo with False
+ about to log at DEBUG ...
+ about to log at INFO ...
+ about to log at WARNING ...
+ Calling decorated foo with True
+ about to log at DEBUG ...
+ about to log at INFO ...
+ about to log at WARNING ...
+ about to log at ERROR ...
+ Actually logged at DEBUG
+ Actually logged at INFO
+ Actually logged at WARNING
+ Actually logged at ERROR
+ about to log at CRITICAL ...
+ Actually logged at CRITICAL
+
+As you can see, actual logging output only occurs when an event is logged whose
+severity is ERROR or greater, but in that case, any previous events at lower
+severities are also logged.
+
+You can of course use the conventional means of decoration::
+
+ @log_if_errors(logger)
+ def foo(fail=False):
+ ...
+
+
+.. _utc-formatting:
+
+Formatting times using UTC (GMT) via configuration
+--------------------------------------------------
+
+Sometimes you want to format times using UTC, which can be done using a class
+such as `UTCFormatter`, shown below::
+
+ import logging
+ import time
+
+ class UTCFormatter(logging.Formatter):
+ converter = time.gmtime
+
+and you can then use the ``UTCFormatter`` in your code instead of
+:class:`~logging.Formatter`. If you want to do that via configuration, you can
+use the :func:`~logging.config.dictConfig` API with an approach illustrated by
+the following complete example::
+
+ import logging
+ import logging.config
+ import time
+
+ class UTCFormatter(logging.Formatter):
+ converter = time.gmtime
+
+ LOGGING = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+ 'formatters': {
+ 'utc': {
+ '()': UTCFormatter,
+ 'format': '%(asctime)s %(message)s',
+ },
+ 'local': {
+ 'format': '%(asctime)s %(message)s',
+ }
+ },
+ 'handlers': {
+ 'console1': {
+ 'class': 'logging.StreamHandler',
+ 'formatter': 'utc',
+ },
+ 'console2': {
+ 'class': 'logging.StreamHandler',
+ 'formatter': 'local',
+ },
+ },
+ 'root': {
+ 'handlers': ['console1', 'console2'],
+ }
+ }
+
+ if __name__ == '__main__':
+ logging.config.dictConfig(LOGGING)
+ logging.warning('The local time is %s', time.asctime())
+
+When this script is run, it should print something like::
+
+ 2015-10-17 12:53:29,501 The local time is Sat Oct 17 13:53:29 2015
+ 2015-10-17 13:53:29,501 The local time is Sat Oct 17 13:53:29 2015
+
+showing how the time is formatted both as local time and UTC, one for each
+handler.
+
+
+.. _context-manager:
+
+Using a context manager for selective logging
+---------------------------------------------
+
+There are times when it would be useful to temporarily change the logging
+configuration and revert it back after doing something. For this, a context
+manager is the most obvious way of saving and restoring the logging context.
+Here is a simple example of such a context manager, which allows you to
+optionally change the logging level and add a logging handler purely in the
+scope of the context manager::
+
+ import logging
+ import sys
+
+ class LoggingContext(object):
+ def __init__(self, logger, level=None, handler=None, close=True):
+ self.logger = logger
+ self.level = level
+ self.handler = handler
+ self.close = close
+
+ def __enter__(self):
+ if self.level is not None:
+ self.old_level = self.logger.level
+ self.logger.setLevel(self.level)
+ if self.handler:
+ self.logger.addHandler(self.handler)
+
+ def __exit__(self, et, ev, tb):
+ if self.level is not None:
+ self.logger.setLevel(self.old_level)
+ if self.handler:
+ self.logger.removeHandler(self.handler)
+ if self.handler and self.close:
+ self.handler.close()
+ # implicit return of None => don't swallow exceptions
+
+If you specify a level value, the logger's level is set to that value in the
+scope of the with block covered by the context manager. If you specify a
+handler, it is added to the logger on entry to the block and removed on exit
+from the block. You can also ask the manager to close the handler for you on
+block exit - you could do this if you don't need the handler any more.
+
+To illustrate how it works, we can add the following block of code to the
+above::
+
+ if __name__ == '__main__':
+ logger = logging.getLogger('foo')
+ logger.addHandler(logging.StreamHandler())
+ logger.setLevel(logging.INFO)
+ logger.info('1. This should appear just once on stderr.')
+ logger.debug('2. This should not appear.')
+ with LoggingContext(logger, level=logging.DEBUG):
+ logger.debug('3. This should appear once on stderr.')
+ logger.debug('4. This should not appear.')
+ h = logging.StreamHandler(sys.stdout)
+ with LoggingContext(logger, level=logging.DEBUG, handler=h, close=True):
+ logger.debug('5. This should appear twice - once on stderr and once on stdout.')
+ logger.info('6. This should appear just once on stderr.')
+ logger.debug('7. This should not appear.')
+
+We initially set the logger's level to ``INFO``, so message #1 appears and
+message #2 doesn't. We then change the level to ``DEBUG`` temporarily in the
+following ``with`` block, and so message #3 appears. After the block exits, the
+logger's level is restored to ``INFO`` and so message #4 doesn't appear. In the
+next ``with`` block, we set the level to ``DEBUG`` again but also add a handler
+writing to ``sys.stdout``. Thus, message #5 appears twice on the console (once
+via ``stderr`` and once via ``stdout``). After the ``with`` statement's
+completion, the status is as it was before so message #6 appears (like message
+#1) whereas message #7 doesn't (just like message #2).
+
+If we run the resulting script, the result is as follows:
+
+.. code-block:: shell-session
+
+ $ python logctx.py
+ 1. This should appear just once on stderr.
+ 3. This should appear once on stderr.
+ 5. This should appear twice - once on stderr and once on stdout.
+ 5. This should appear twice - once on stderr and once on stdout.
+ 6. This should appear just once on stderr.
+
+If we run it again, but pipe ``stderr`` to ``/dev/null``, we see the following,
+which is the only message written to ``stdout``:
+
+.. code-block:: shell-session
+
+ $ python logctx.py 2>/dev/null
+ 5. This should appear twice - once on stderr and once on stdout.
+
+Once again, but piping ``stdout`` to ``/dev/null``, we get:
+
+.. code-block:: shell-session
+
+ $ python logctx.py >/dev/null
+ 1. This should appear just once on stderr.
+ 3. This should appear once on stderr.
+ 5. This should appear twice - once on stderr and once on stdout.
+ 6. This should appear just once on stderr.
+
+In this case, the message #5 printed to ``stdout`` doesn't appear, as expected.
+
+Of course, the approach described here can be generalised, for example to attach
+logging filters temporarily. Note that the above code works in Python 2 as well
+as Python 3.
diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst
index 1916c47b..698007a5 100644
--- a/Doc/howto/logging.rst
+++ b/Doc/howto/logging.rst
@@ -103,10 +103,12 @@ A simple example
A very simple example is::
import logging
- logging.warning('Watch out!') # will print a message to the console
- logging.info('I told you so') # will not print anything
+ logging.warning('Watch out!') # will print a message to the console
+ logging.info('I told you so') # will not print anything
-If you type these lines into a script and run it, you'll see::
+If you type these lines into a script and run it, you'll see:
+
+.. code-block:: none
WARNING:root:Watch out!
@@ -122,7 +124,8 @@ Logging to a file
^^^^^^^^^^^^^^^^^
A very common situation is that of recording logging events in a file, so let's
-look at that next::
+look at that next. Be sure to try the following in a newly-started Python
+interpreter, and don't just continue from the session described above::
import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
@@ -229,7 +232,9 @@ append the variable data as arguments. For example::
import logging
logging.warning('%s before you %s', 'Look', 'leap!')
-will display::
+will display:
+
+.. code-block:: none
WARNING:root:Look before you leap!
@@ -309,7 +314,7 @@ favourite beverage and carry on.
If your logging needs are simple, then use the above examples to incorporate
logging into your own scripts, and if you run into problems or don't
understand something, please post a question on the comp.lang.python Usenet
-group (available at http://groups.google.com/group/comp.lang.python) and you
+group (available at https://groups.google.com/group/comp.lang.python) and you
should receive help before too long.
Still here? You can carry on reading the next few sections, which provide a
@@ -459,7 +464,7 @@ ancestor loggers. Because of this, it is unnecessary to define and configure
handlers for all the loggers an application uses. It is sufficient to
configure handlers for a top-level logger and create child loggers as needed.
(You can, however, turn off propagation by setting the *propagate*
-attribute of a logger to *False*.)
+attribute of a logger to ``False``.)
.. _handler-basic:
@@ -584,7 +589,9 @@ logger, a console handler, and a simple formatter using Python code::
logger.error('error message')
logger.critical('critical message')
-Running this module from the command line produces the following output::
+Running this module from the command line produces the following output:
+
+.. code-block:: shell-session
$ python simple_logging_module.py
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
@@ -643,7 +650,9 @@ Here is the logging.conf file::
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
-The output is nearly identical to that of the non-config-file-based example::
+The output is nearly identical to that of the non-config-file-based example:
+
+.. code-block:: shell-session
$ python simple_logging_config.py
2005-03-19 15:38:55,977 - simpleExample - DEBUG - debug message
@@ -728,10 +737,10 @@ circumstances is dependent on the Python version.
For Python 2.x, the behaviour is as follows:
-* If *logging.raiseExceptions* is *False* (production mode), the event is
+* If *logging.raiseExceptions* is ``False`` (production mode), the event is
silently dropped.
-* If *logging.raiseExceptions* is *True* (development mode), a message
+* If *logging.raiseExceptions* is ``True`` (development mode), a message
'No handlers could be found for logger X.Y.Z' is printed once.
.. _library-config:
@@ -995,6 +1004,15 @@ You can write code like this::
so that if the logger's threshold is set above ``DEBUG``, the calls to
:func:`expensive_func1` and :func:`expensive_func2` are never made.
+.. note:: In some cases, :meth:`~Logger.isEnabledFor` can itself be more
+ expensive than you'd like (e.g. for deeply nested loggers where an explicit
+ level is only set high up in the logger hierarchy). In such cases (or if you
+ want to avoid calling a method in tight loops), you can cache the result of a
+ call to :meth:`~Logger.isEnabledFor` in a local or instance variable, and use
+ that instead of calling the method each time. Such a cached value would only
+ need to be recomputed when the logging configuration changes dynamically
+ while the application is running (which is not all that common).
+
There are other optimizations which can be made for specific applications which
need more precise control over what logging information is collected. Here's a
list of things you can do to avoid processing during logging which you don't
@@ -1004,6 +1022,11 @@ need:
| What you don't want to collect | How to avoid collecting it |
+===============================================+========================================+
| Information about where calls were made from. | Set ``logging._srcfile`` to ``None``. |
+| | This avoids calling |
+| | :func:`sys._getframe`, which may help |
+| | to speed up your code in environments |
+| | like PyPy (which can't speed up code |
+| | that uses :func:`sys._getframe`). |
+-----------------------------------------------+----------------------------------------+
| Threading information. | Set ``logging.logThreads`` to ``0``. |
+-----------------------------------------------+----------------------------------------+
@@ -1026,4 +1049,3 @@ take up any memory.
Useful handlers included with the logging module.
:ref:`A logging cookbook `
-
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
index 3eca4968..88b01779 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -10,694 +10,443 @@ Porting Python 2 Code to Python 3
With Python 3 being the future of Python while Python 2 is still in active
use, it is good to have your project available for both major releases of
- Python. This guide is meant to help you choose which strategy works best
- for your project to support both Python 2 & 3 along with how to execute
- that strategy.
+ Python. This guide is meant to help you figure out how best to support both
+ Python 2 & 3 simultaneously.
If you are looking to port an extension module instead of pure Python code,
please see :ref:`cporting-howto`.
-
-Choosing a Strategy
-===================
-
-When a project makes the decision that it's time to support both Python 2 & 3,
-a decision needs to be made as to how to go about accomplishing that goal.
-The chosen strategy will depend on how large the project's existing
-codebase is and how much divergence you want from your Python 2 codebase from
-your Python 3 one (e.g., starting a new version with Python 3).
-
-If your project is brand-new or does not have a large codebase, then you may
-want to consider writing/porting :ref:`all of your code for Python 3
-and use 3to2 ` to port your code for Python 2.
-
-If you would prefer to maintain a codebase which is semantically **and**
-syntactically compatible with Python 2 & 3 simultaneously, you can write
-:ref:`use_same_source`. While this tends to lead to somewhat non-idiomatic
-code, it does mean you keep a rapid development process for you, the developer.
-
-Finally, you do have the option of :ref:`using 2to3 ` to translate
-Python 2 code into Python 3 code (with some manual help). This can take the
-form of branching your code and using 2to3 to start a Python 3 branch. You can
-also have users perform the translation at installation time automatically so
-that you only have to maintain a Python 2 codebase.
-
-Regardless of which approach you choose, porting is not as hard or
-time-consuming as you might initially think. You can also tackle the problem
-piece-meal as a good portion of porting is simply updating your code to follow
-current best practices in a Python 2/3 compatible way.
-
-
-Universal Bits of Advice
-------------------------
-
-Regardless of what strategy you pick, there are a few things you should
-consider.
-
-One is make sure you have a robust test suite. You need to make sure everything
-continues to work, just like when you support a new minor version of Python.
-This means making sure your test suite is thorough and is ported properly
-between Python 2 & 3. You will also most likely want to use something like tox_
-to automate testing between both a Python 2 and Python 3 VM.
-
-Two, once your project has Python 3 support, make sure to add the proper
-classifier on the Cheeseshop_ (PyPI_). To have your project listed as Python 3
-compatible it must have the
-`Python 3 classifier `_
-(from
-http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/)::
-
- setup(
- name='Your Library',
- version='1.0',
- classifiers=[
- # make sure to use :: Python *and* :: Python :: 3 so
- # that pypi can list the package on the python 3 page
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 3'
- ],
- packages=['yourlibrary'],
- # make sure to add custom_fixers to the MANIFEST.in
- include_package_data=True,
- # ...
- )
-
-
-Doing so will cause your project to show up in the
-`Python 3 packages list
-`_. You will know
-you set the classifier properly as visiting your project page on the Cheeseshop
-will show a Python 3 logo in the upper-left corner of the page.
-
-Three, the six_ project provides a library which helps iron out differences
-between Python 2 & 3. If you find there is a sticky point that is a continual
-point of contention in your translation or maintenance of code, consider using
-a source-compatible solution relying on six. If you have to create your own
-Python 2/3 compatible solution, you can use ``sys.version_info[0] >= 3`` as a
-guard.
-
-Four, read all the approaches. Just because some bit of advice applies to one
-approach more than another doesn't mean that some advice doesn't apply to other
-strategies.
-
-Five, drop support for older Python versions if possible. `Python 2.5`_
-introduced a lot of useful syntax and libraries which have become idiomatic
-in Python 3. `Python 2.6`_ introduced future statements which makes
-compatibility much easier if you are going from Python 2 to 3.
-`Python 2.7`_ continues the trend in the stdlib. So choose the newest version
-of Python which you believe can be your minimum support version
-and work from there.
-
-
-.. _tox: http://codespeak.net/tox/
-.. _Cheeseshop:
-.. _PyPI: http://pypi.python.org/
-.. _six: http://packages.python.org/six
-.. _Python 2.7: http://www.python.org/2.7.x
-.. _Python 2.6: http://www.python.org/2.6.x
-.. _Python 2.5: http://www.python.org/2.5.x
-.. _Python 2.4: http://www.python.org/2.4.x
-.. _Python 2.3: http://www.python.org/2.3.x
-.. _Python 2.2: http://www.python.org/2.2.x
-
-
-.. _use_3to2:
-
-Python 3 and 3to2
-=================
-
-If you are starting a new project or your codebase is small enough, you may
-want to consider writing your code for Python 3 and backporting to Python 2
-using 3to2_. Thanks to Python 3 being more strict about things than Python 2
-(e.g., bytes vs. strings), the source translation can be easier and more
-straightforward than from Python 2 to 3. Plus it gives you more direct
-experience developing in Python 3 which, since it is the future of Python, is a
-good thing long-term.
-
-A drawback of this approach is that 3to2 is a third-party project. This means
-that the Python core developers (and thus this guide) can make no promises
-about how well 3to2 works at any time. There is nothing to suggest, though,
-that 3to2 is not a high-quality project.
-
-
-.. _3to2: https://bitbucket.org/amentajo/lib3to2/overview
-
-
-.. _use_2to3:
-
-Python 2 and 2to3
-=================
-
-Included with Python since 2.6, the 2to3_ tool (and :mod:`lib2to3` module)
-helps with porting Python 2 to Python 3 by performing various source
-translations. This is a perfect solution for projects which wish to branch
-their Python 3 code from their Python 2 codebase and maintain them as
-independent codebases. You can even begin preparing to use this approach
-today by writing future-compatible Python code which works cleanly in
-Python 2 in conjunction with 2to3; all steps outlined below will work
-with Python 2 code up to the point when the actual use of 2to3 occurs.
-
-Use of 2to3 as an on-demand translation step at install time is also possible,
-preventing the need to maintain a separate Python 3 codebase, but this approach
-does come with some drawbacks. While users will only have to pay the
-translation cost once at installation, you as a developer will need to pay the
-cost regularly during development. If your codebase is sufficiently large
-enough then the translation step ends up acting like a compilation step,
-robbing you of the rapid development process you are used to with Python.
-Obviously the time required to translate a project will vary, so do an
-experimental translation just to see how long it takes to evaluate whether you
-prefer this approach compared to using :ref:`use_same_source` or simply keeping
-a separate Python 3 codebase.
-
-Below are the typical steps taken by a project which uses a 2to3-based approach
-to supporting Python 2 & 3.
-
-
-Support Python 2.7
-------------------
-
-As a first step, make sure that your project is compatible with `Python 2.7`_.
-This is just good to do as Python 2.7 is the last release of Python 2 and thus
-will be used for a rather long time. It also allows for use of the ``-3`` flag
-to Python to help discover places in your code which 2to3 cannot handle but are
-known to cause issues.
-
-Try to Support `Python 2.6`_ and Newer Only
--------------------------------------------
-
-While not possible for all projects, if you can support `Python 2.6`_ and newer
-**only**, your life will be much easier. Various future statements, stdlib
-additions, etc. exist only in Python 2.6 and later which greatly assist in
-porting to Python 3. But if you project must keep support for `Python 2.5`_ (or
-even `Python 2.4`_) then it is still possible to port to Python 3.
-
-Below are the benefits you gain if you only have to support Python 2.6 and
-newer. Some of these options are personal choice while others are
-**strongly** recommended (the ones that are more for personal choice are
-labeled as such). If you continue to support older versions of Python then you
-at least need to watch out for situations that these solutions fix.
-
-
-``from __future__ import print_function``
-'''''''''''''''''''''''''''''''''''''''''
-
-This is a personal choice. 2to3 handles the translation from the print
-statement to the print function rather well so this is an optional step. This
-future statement does help, though, with getting used to typing
-``print('Hello, World')`` instead of ``print 'Hello, World'``.
-
-
-``from __future__ import unicode_literals``
-'''''''''''''''''''''''''''''''''''''''''''
-
-Another personal choice. You can always mark what you want to be a (unicode)
-string with a ``u`` prefix to get the same effect. But regardless of whether
-you use this future statement or not, you **must** make sure you know exactly
-which Python 2 strings you want to be bytes, and which are to be strings. This
-means you should, **at minimum** mark all strings that are meant to be text
-strings with a ``u`` prefix if you do not use this future statement.
-
-
-Bytes literals
-''''''''''''''
-
-This is a **very** important one. The ability to prefix Python 2 strings that
-are meant to contain bytes with a ``b`` prefix help to very clearly delineate
-what is and is not a Python 3 string. When you run 2to3 on code, all Python 2
-strings become Python 3 strings **unless** they are prefixed with ``b``.
-
-There are some differences between byte literals in Python 2 and those in
-Python 3 thanks to the bytes type just being an alias to ``str`` in Python 2.
-Probably the biggest "gotcha" is that indexing results in different values. In
-Python 2, the value of ``b'py'[1]`` is ``'y'``, while in Python 3 it's ``121``.
-You can avoid this disparity by always slicing at the size of a single element:
-``b'py'[1:2]`` is ``'y'`` in Python 2 and ``b'y'`` in Python 3 (i.e., close
-enough).
-
-You cannot concatenate bytes and strings in Python 3. But since Python
-2 has bytes aliased to ``str``, it will succeed: ``b'a' + u'b'`` works in
-Python 2, but ``b'a' + 'b'`` in Python 3 is a :exc:`TypeError`. A similar issue
-also comes about when doing comparisons between bytes and strings.
-
-
-Supporting `Python 2.5`_ and Newer Only
----------------------------------------
-
-If you are supporting `Python 2.5`_ and newer there are still some features of
-Python that you can utilize.
-
-
-``from __future__ import absolute_import``
-''''''''''''''''''''''''''''''''''''''''''
-
-Implicit relative imports (e.g., importing ``spam.bacon`` from within
-``spam.eggs`` with the statement ``import bacon``) does not work in Python 3.
-This future statement moves away from that and allows the use of explicit
-relative imports (e.g., ``from . import bacon``).
-
-In `Python 2.5`_ you must use
-the __future__ statement to get to use explicit relative imports and prevent
-implicit ones. In `Python 2.6`_ explicit relative imports are available without
-the statement, but you still want the __future__ statement to prevent implicit
-relative imports. In `Python 2.7`_ the __future__ statement is not needed. In
-other words, unless you are only supporting Python 2.7 or a version earlier
-than Python 2.5, use the __future__ statement.
-
-
-
-Handle Common "Gotchas"
+ If you would like to read one core Python developer's take on why Python 3
+ came into existence, you can read Nick Coghlan's `Python 3 Q & A`_ or
+ Brett Cannon's `Why Python 3 exists`_.
+
+ For help with porting, you can email the python-porting_ mailing list with
+ questions.
+
+The Short Explanation
+=====================
+
+To make your project be single-source Python 2/3 compatible, the basic steps
+are:
+
+#. Only worry about supporting Python 2.7
+#. Make sure you have good test coverage (coverage.py_ can help;
+ ``pip install coverage``)
+#. Learn the differences between Python 2 & 3
+#. Use Futurize_ (or Modernize_) to update your code (e.g. ``pip install future``)
+#. Use Pylint_ to help make sure you don't regress on your Python 3 support
+ (``pip install pylint``)
+#. Use caniusepython3_ to find out which of your dependencies are blocking your
+ use of Python 3 (``pip install caniusepython3``)
+#. Once your dependencies are no longer blocking you, use continuous integration
+ to make sure you stay compatible with Python 2 & 3 (tox_ can help test
+ against multiple versions of Python; ``pip install tox``)
+#. Consider using optional static type checking to make sure your type usage
+ works in both Python 2 & 3 (e.g. use mypy_ to check your typing under both
+ Python 2 & Python 3).
+
+
+Details
+=======
+
+A key point about supporting Python 2 & 3 simultaneously is that you can start
+**today**! Even if your dependencies are not supporting Python 3 yet that does
+not mean you can't modernize your code **now** to support Python 3. Most changes
+required to support Python 3 lead to cleaner code using newer practices even in
+Python 2 code.
+
+Another key point is that modernizing your Python 2 code to also support
+Python 3 is largely automated for you. While you might have to make some API
+decisions thanks to Python 3 clarifying text data versus binary data, the
+lower-level work is now mostly done for you and thus can at least benefit from
+the automated changes immediately.
+
+Keep those key points in mind while you read on about the details of porting
+your code to support Python 2 & 3 simultaneously.
+
+
+Drop support for Python 2.6 and older
+-------------------------------------
+
+While you can make Python 2.5 work with Python 3, it is **much** easier if you
+only have to work with Python 2.7. If dropping Python 2.5 is not an
+option then the six_ project can help you support Python 2.5 & 3 simultaneously
+(``pip install six``). Do realize, though, that nearly all the projects listed
+in this HOWTO will not be available to you.
+
+If you are able to skip Python 2.5 and older, then the required changes
+to your code should continue to look and feel like idiomatic Python code. At
+worst you will have to use a function instead of a method in some instances or
+have to import a function instead of using a built-in one, but otherwise the
+overall transformation should not feel foreign to you.
+
+But you should aim for only supporting Python 2.7. Python 2.6 is no longer
+freely supported and thus is not receiving bugfixes. This means **you** will have
+to work around any issues you come across with Python 2.6. There are also some
+tools mentioned in this HOWTO which do not support Python 2.6 (e.g., Pylint_),
+and this will become more commonplace as time goes on. It will simply be easier
+for you if you only support the versions of Python that you have to support.
+
+
+Make sure you specify the proper version support in your ``setup.py`` file
+--------------------------------------------------------------------------
+
+In your ``setup.py`` file you should have the proper `trove classifier`_
+specifying what versions of Python you support. As your project does not support
+Python 3 yet you should at least have
+``Programming Language :: Python :: 2 :: Only`` specified. Ideally you should
+also specify each major/minor version of Python that you do support, e.g.
+``Programming Language :: Python :: 2.7``.
+
+
+Have good test coverage
-----------------------
-There are a few things that just consistently come up as sticking points for
-people which 2to3 cannot handle automatically or can easily be done in Python 2
-to help modernize your code.
-
-
-``from __future__ import division``
-'''''''''''''''''''''''''''''''''''
-
-While the exact same outcome can be had by using the ``-Qnew`` argument to
-Python, using this future statement lifts the requirement that your users use
-the flag to get the expected behavior of division in Python 3
-(e.g., ``1/2 == 0.5; 1//2 == 0``).
+Once you have your code supporting the oldest version of Python 2 you want it
+to, you will want to make sure your test suite has good coverage. A good rule of
+thumb is that if you want to be confident enough in your test suite that any
+failures that appear after having tools rewrite your code are actual bugs in the
+tools and not in your code. If you want a number to aim for, try to get over 80%
+coverage (and don't feel bad if you find it hard to get better than 90%
+coverage). If you don't already have a tool to measure test coverage then
+coverage.py_ is recommended.
+Learn the differences between Python 2 & 3
+-------------------------------------------
-Specify when opening a file as binary
-'''''''''''''''''''''''''''''''''''''
-
+Once you have your code well-tested you are ready to begin porting your code to
+Python 3! But to fully understand how your code is going to change and what
+you want to look out for while you code, you will want to learn what changes
+Python 3 makes in terms of Python 2. Typically the two best ways of doing that
+is reading the `"What's New"`_ doc for each release of Python 3 and the
+`Porting to Python 3`_ book (which is free online). There is also a handy
+`cheat sheet`_ from the Python-Future project.
+
+
+Update your code
+----------------
+
+Once you feel like you know what is different in Python 3 compared to Python 2,
+it's time to update your code! You have a choice between two tools in porting
+your code automatically: Futurize_ and Modernize_. Which tool you choose will
+depend on how much like Python 3 you want your code to be. Futurize_ does its
+best to make Python 3 idioms and practices exist in Python 2, e.g. backporting
+the ``bytes`` type from Python 3 so that you have semantic parity between the
+major versions of Python. Modernize_,
+on the other hand, is more conservative and targets a Python 2/3 subset of
+Python, directly relying on six_ to help provide compatibility. As Python 3 is
+the future, it might be best to consider Futurize to begin adjusting to any new
+practices that Python 3 introduces which you are not accustomed to yet.
+
+Regardless of which tool you choose, they will update your code to run under
+Python 3 while staying compatible with the version of Python 2 you started with.
+Depending on how conservative you want to be, you may want to run the tool over
+your test suite first and visually inspect the diff to make sure the
+transformation is accurate. After you have transformed your test suite and
+verified that all the tests still pass as expected, then you can transform your
+application code knowing that any tests which fail is a translation failure.
+
+Unfortunately the tools can't automate everything to make your code work under
+Python 3 and so there are a handful of things you will need to update manually
+to get full Python 3 support (which of these steps are necessary vary between
+the tools). Read the documentation for the tool you choose to use to see what it
+fixes by default and what it can do optionally to know what will (not) be fixed
+for you and what you may have to fix on your own (e.g. using ``io.open()`` over
+the built-in ``open()`` function is off by default in Modernize). Luckily,
+though, there are only a couple of things to watch out for which can be
+considered large issues that may be hard to debug if not watched for.
+
+
+Division
+++++++++
+
+In Python 3, ``5 / 2 == 2.5`` and not ``2``; all division between ``int`` values
+result in a ``float``. This change has actually been planned since Python 2.2
+which was released in 2002. Since then users have been encouraged to add
+``from __future__ import division`` to any and all files which use the ``/`` and
+``//`` operators or to be running the interpreter with the ``-Q`` flag. If you
+have not been doing this then you will need to go through your code and do two
+things:
+
+#. Add ``from __future__ import division`` to your files
+#. Update any division operator as necessary to either use ``//`` to use floor
+ division or continue using ``/`` and expect a float
+
+The reason that ``/`` isn't simply translated to ``//`` automatically is that if
+an object defines a ``__truediv__`` method but not ``__floordiv__`` then your
+code would begin to fail (e.g. a user-defined class that uses ``/`` to
+signify some operation but not ``//`` for the same thing or at all).
+
+
+Text versus binary data
++++++++++++++++++++++++
+
+In Python 2 you could use the ``str`` type for both text and binary data.
+Unfortunately this confluence of two different concepts could lead to brittle
+code which sometimes worked for either kind of data, sometimes not. It also
+could lead to confusing APIs if people didn't explicitly state that something
+that accepted ``str`` accepted either text or binary data instead of one
+specific type. This complicated the situation especially for anyone supporting
+multiple languages as APIs wouldn't bother explicitly supporting ``unicode``
+when they claimed text data support.
+
+To make the distinction between text and binary data clearer and more
+pronounced, Python 3 did what most languages created in the age of the internet
+have done and made text and binary data distinct types that cannot blindly be
+mixed together (Python predates widespread access to the internet). For any code
+that deals only with text or only binary data, this separation doesn't pose an
+issue. But for code that has to deal with both, it does mean you might have to
+now care about when you are using text compared to binary data, which is why
+this cannot be entirely automated.
+
+To start, you will need to decide which APIs take text and which take binary
+(it is **highly** recommended you don't design APIs that can take both due to
+the difficulty of keeping the code working; as stated earlier it is difficult to
+do well). In Python 2 this means making sure the APIs that take text can work
+with ``unicode`` and those that work with binary data work with the
+``bytes`` type from Python 3 (which is a subset of ``str`` in Python 2 and acts
+as an alias for ``bytes`` type in Python 2). Usually the biggest issue is
+realizing which methods exist on which types in Python 2 & 3 simultaneously
+(for text that's ``unicode`` in Python 2 and ``str`` in Python 3, for binary
+that's ``str``/``bytes`` in Python 2 and ``bytes`` in Python 3). The following
+table lists the **unique** methods of each data type across Python 2 & 3
+(e.g., the ``decode()`` method is usable on the equivalent binary data type in
+either Python 2 or 3, but it can't be used by the textual data type consistently
+between Python 2 and 3 because ``str`` in Python 3 doesn't have the method). Do
+note that as of Python 3.5 the ``__mod__`` method was added to the bytes type.
+
+======================== =====================
+**Text data** **Binary data**
+------------------------ ---------------------
+\ decode
+------------------------ ---------------------
+encode
+------------------------ ---------------------
+format
+------------------------ ---------------------
+isdecimal
+------------------------ ---------------------
+isnumeric
+======================== =====================
+
+Making the distinction easier to handle can be accomplished by encoding and
+decoding between binary data and text at the edge of your code. This means that
+when you receive text in binary data, you should immediately decode it. And if
+your code needs to send text as binary data then encode it as late as possible.
+This allows your code to work with only text internally and thus eliminates
+having to keep track of what type of data you are working with.
+
+The next issue is making sure you know whether the string literals in your code
+represent text or binary data. You should add a ``b`` prefix to any
+literal that presents binary data. For text you should add a ``u`` prefix to
+the text literal. (there is a :mod:`__future__` import to force all unspecified
+literals to be Unicode, but usage has shown it isn't as effective as adding a
+``b`` or ``u`` prefix to all literals explicitly)
+
+As part of this dichotomy you also need to be careful about opening files.
Unless you have been working on Windows, there is a chance you have not always
bothered to add the ``b`` mode when opening a binary file (e.g., ``rb`` for
binary reading). Under Python 3, binary files and text files are clearly
distinct and mutually incompatible; see the :mod:`io` module for details.
Therefore, you **must** make a decision of whether a file will be used for
-binary access (allowing to read and/or write bytes data) or text access
-(allowing to read and/or write unicode data).
-
-Text files
-''''''''''
-
-Text files created using ``open()`` under Python 2 return byte strings,
-while under Python 3 they return unicode strings. Depending on your porting
-strategy, this can be an issue.
-
-If you want text files to return unicode strings in Python 2, you have two
-possibilities:
-
-* Under Python 2.6 and higher, use :func:`io.open`. Since :func:`io.open`
- is essentially the same function in both Python 2 and Python 3, it will
- help iron out any issues that might arise.
-
-* If pre-2.6 compatibility is needed, then you should use :func:`codecs.open`
- instead. This will make sure that you get back unicode strings in Python 2.
-
-Subclass ``object``
-'''''''''''''''''''
-
-New-style classes have been around since `Python 2.2`_. You need to make sure
-you are subclassing from ``object`` to avoid odd edge cases involving method
-resolution order, etc. This continues to be totally valid in Python 3 (although
-unneeded as all classes implicitly inherit from ``object``).
-
-
-Deal With the Bytes/String Dichotomy
-''''''''''''''''''''''''''''''''''''
-
-One of the biggest issues people have when porting code to Python 3 is handling
-the bytes/string dichotomy. Because Python 2 allowed the ``str`` type to hold
-textual data, people have over the years been rather loose in their delineation
-of what ``str`` instances held text compared to bytes. In Python 3 you cannot
-be so care-free anymore and need to properly handle the difference. The key
-handling this issue is to make sure that **every** string literal in your
-Python 2 code is either syntactically of functionally marked as either bytes or
-text data. After this is done you then need to make sure your APIs are designed
-to either handle a specific type or made to be properly polymorphic.
-
-
-Mark Up Python 2 String Literals
-********************************
-
-First thing you must do is designate every single string literal in Python 2
-as either textual or bytes data. If you are only supporting Python 2.6 or
-newer, this can be accomplished by marking bytes literals with a ``b`` prefix
-and then designating textual data with a ``u`` prefix or using the
-``unicode_literals`` future statement.
-
-If your project supports versions of Python predating 2.6, then you should use
-the six_ project and its ``b()`` function to denote bytes literals. For text
-literals you can either use six's ``u()`` function or use a ``u`` prefix.
-
-
-Decide what APIs Will Accept
-****************************
-
-In Python 2 it was very easy to accidentally create an API that accepted both
-bytes and textual data. But in Python 3, thanks to the more strict handling of
-disparate types, this loose usage of bytes and text together tends to fail.
-
-Take the dict ``{b'a': 'bytes', u'a': 'text'}`` in Python 2.6. It creates the
-dict ``{u'a': 'text'}`` since ``b'a' == u'a'``. But in Python 3 the equivalent
-dict creates ``{b'a': 'bytes', 'a': 'text'}``, i.e., no lost data. Similar
-issues can crop up when transitioning Python 2 code to Python 3.
-
-This means you need to choose what an API is going to accept and create and
-consistently stick to that API in both Python 2 and 3.
-
-
-Bytes / Unicode Comparison
-**************************
-
-In Python 3, mixing bytes and unicode is forbidden in most situations; it
-will raise a :class:`TypeError` where Python 2 would have attempted an implicit
-coercion between types. However, there is one case where it doesn't and
-it can be very misleading::
-
- >>> b"" == ""
- False
-
-This is because an equality comparison is required by the language to always
-succeed (and return ``False`` for incompatible types). However, this also
-means that code incorrectly ported to Python 3 can display buggy behaviour
-if such comparisons are silently executed. To detect such situations,
-Python 3 has a ``-b`` flag that will display a warning::
-
- $ python3 -b
- >>> b"" == ""
- __main__:1: BytesWarning: Comparison between bytes and string
- False
-
-To turn the warning into an exception, use the ``-bb`` flag instead::
-
- $ python3 -bb
- >>> b"" == ""
- Traceback (most recent call last):
- File "", line 1, in
- BytesWarning: Comparison between bytes and string
-
-
-Indexing bytes objects
-''''''''''''''''''''''
-
-Another potentially surprising change is the indexing behaviour of bytes
-objects in Python 3::
-
- >>> b"xyz"[0]
- 120
-
-Indeed, Python 3 bytes objects (as well as :class:`bytearray` objects)
-are sequences of integers. But code converted from Python 2 will often
-assume that indexing a bytestring produces another bytestring, not an
-integer. To reconcile both behaviours, use slicing::
-
- >>> b"xyz"[0:1]
- b'x'
- >>> n = 1
- >>> b"xyz"[n:n+1]
- b'y'
-
-The only remaining gotcha is that an out-of-bounds slice returns an empty
-bytes object instead of raising ``IndexError``:
-
- >>> b"xyz"[3]
- Traceback (most recent call last):
- File "", line 1, in
- IndexError: index out of range
- >>> b"xyz"[3:4]
- b''
-
-
-``__str__()``/``__unicode__()``
-'''''''''''''''''''''''''''''''
-
-In Python 2, objects can specify both a string and unicode representation of
-themselves. In Python 3, though, there is only a string representation. This
-becomes an issue as people can inadvertently do things in their ``__str__()``
-methods which have unpredictable results (e.g., infinite recursion if you
-happen to use the ``unicode(self).encode('utf8')`` idiom as the body of your
-``__str__()`` method).
-
-There are two ways to solve this issue. One is to use a custom 2to3 fixer. The
-blog post at http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/
-specifies how to do this. That will allow 2to3 to change all instances of ``def
-__unicode(self): ...`` to ``def __str__(self): ...``. This does require that you
-define your ``__str__()`` method in Python 2 before your ``__unicode__()``
-method.
-
-The other option is to use a mixin class. This allows you to only define a
-``__unicode__()`` method for your class and let the mixin derive
-``__str__()`` for you (code from
-http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/)::
-
- import sys
-
- class UnicodeMixin(object):
-
- """Mixin class to handle defining the proper __str__/__unicode__
- methods in Python 2 or 3."""
-
- if sys.version_info[0] >= 3: # Python 3
- def __str__(self):
- return self.__unicode__()
- else: # Python 2
- def __str__(self):
- return self.__unicode__().encode('utf8')
-
-
- class Spam(UnicodeMixin):
-
- def __unicode__(self):
- return u'spam-spam-bacon-spam' # 2to3 will remove the 'u' prefix
-
-
-Don't Index on Exceptions
-'''''''''''''''''''''''''
-
-In Python 2, the following worked::
-
- >>> exc = Exception(1, 2, 3)
- >>> exc.args[1]
- 2
- >>> exc[1] # Python 2 only!
- 2
-
-But in Python 3, indexing directly on an exception is an error. You need to
-make sure to only index on the :attr:`BaseException.args` attribute which is a
-sequence containing all arguments passed to the :meth:`__init__` method.
-
-Even better is to use the documented attributes the exception provides.
-
-Don't use ``__getslice__`` & Friends
-''''''''''''''''''''''''''''''''''''
-
-Been deprecated for a while, but Python 3 finally drops support for
-``__getslice__()``, etc. Move completely over to :meth:`__getitem__` and
-friends.
-
-
-Updating doctests
-'''''''''''''''''
-
-2to3_ will attempt to generate fixes for doctests that it comes across. It's
-not perfect, though. If you wrote a monolithic set of doctests (e.g., a single
-docstring containing all of your doctests), you should at least consider
-breaking the doctests up into smaller pieces to make it more manageable to fix.
-Otherwise it might very well be worth your time and effort to port your tests
-to :mod:`unittest`.
-
-
-Eliminate ``-3`` Warnings
--------------------------
-
-When you run your application's test suite, run it using the ``-3`` flag passed
-to Python. This will cause various warnings to be raised during execution about
-things that 2to3 cannot handle automatically (e.g., modules that have been
-removed). Try to eliminate those warnings to make your code even more portable
-to Python 3.
-
-
-Run 2to3
---------
-
-Once you have made your Python 2 code future-compatible with Python 3, it's
-time to use 2to3_ to actually port your code.
-
-
-Manually
-''''''''
-
-To manually convert source code using 2to3_, you use the ``2to3`` script that
-is installed with Python 2.6 and later.::
-
- 2to3
-
-This will cause 2to3 to write out a diff with all of the fixers applied for the
-converted source code. If you would like 2to3 to go ahead and apply the changes
-you can pass it the ``-w`` flag::
-
- 2to3 -w
-
-There are other flags available to control exactly which fixers are applied,
-etc.
-
-
-During Installation
-'''''''''''''''''''
-
-When a user installs your project for Python 3, you can have either
-:mod:`distutils` or Distribute_ run 2to3_ on your behalf.
-For distutils, use the following idiom::
-
- try: # Python 3
- from distutils.command.build_py import build_py_2to3 as build_py
- except ImportError: # Python 2
- from distutils.command.build_py import build_py
-
- setup(cmdclass = {'build_py': build_py},
- # ...
- )
-
-For Distribute::
-
- setup(use_2to3=True,
- # ...
- )
-
-This will allow you to not have to distribute a separate Python 3 version of
-your project. It does require, though, that when you perform development that
-you at least build your project and use the built Python 3 source for testing.
-
-
-Verify & Test
--------------
-
-At this point you should (hopefully) have your project converted in such a way
-that it works in Python 3. Verify it by running your unit tests and making sure
-nothing has gone awry. If you miss something then figure out how to fix it in
-Python 3, backport to your Python 2 code, and run your code through 2to3 again
-to verify the fix transforms properly.
-
-
-.. _2to3: http://docs.python.org/py3k/library/2to3.html
-.. _Distribute: http://packages.python.org/distribute/
-
-
-.. _use_same_source:
-
-Python 2/3 Compatible Source
-============================
-
-While it may seem counter-intuitive, you can write Python code which is
-source-compatible between Python 2 & 3. It does lead to code that is not
-entirely idiomatic Python (e.g., having to extract the currently raised
-exception from ``sys.exc_info()[1]``), but it can be run under Python 2
-**and** Python 3 without using 2to3_ as a translation step (although the tool
-should be used to help find potential portability problems). This allows you to
-continue to have a rapid development process regardless of whether you are
-developing under Python 2 or Python 3. Whether this approach or using
-:ref:`use_2to3` works best for you will be a per-project decision.
-
-To get a complete idea of what issues you will need to deal with, see the
-`What's New in Python 3.0`_. Others have reorganized the data in other formats
-such as http://docs.pythonsprints.com/python3_porting/py-porting.html .
-
-The following are some steps to take to try to support both Python 2 & 3 from
-the same source code.
-
-
-.. _What's New in Python 3.0: http://docs.python.org/release/3.0/whatsnew/3.0.html
-
-
-Follow The Steps for Using 2to3_
---------------------------------
-
-All of the steps outlined in how to
-:ref:`port Python 2 code with 2to3 ` apply
-to creating a Python 2/3 codebase. This includes trying only support Python 2.6
-or newer (the :mod:`__future__` statements work in Python 3 without issue),
-eliminating warnings that are triggered by ``-3``, etc.
-
-You should even consider running 2to3_ over your code (without committing the
-changes). This will let you know where potential pain points are within your
-code so that you can fix them properly before they become an issue.
-
-
-Use six_
---------
-
-The six_ project contains many things to help you write portable Python code.
-You should make sure to read its documentation from beginning to end and use
-any and all features it provides. That way you will minimize any mistakes you
-might make in writing cross-version code.
-
-
-Capturing the Currently Raised Exception
-----------------------------------------
-
-One change between Python 2 and 3 that will require changing how you code (if
-you support `Python 2.5`_ and earlier) is
-accessing the currently raised exception. In Python 2.5 and earlier the syntax
-to access the current exception is::
-
- try:
- raise Exception()
- except Exception, exc:
- # Current exception is 'exc'
- pass
-
-This syntax changed in Python 3 (and backported to `Python 2.6`_ and later)
-to::
-
- try:
- raise Exception()
- except Exception as exc:
- # Current exception is 'exc'
- # In Python 3, 'exc' is restricted to the block; Python 2.6 will "leak"
- pass
-
-Because of this syntax change you must change to capturing the current
-exception to::
-
- try:
- raise Exception()
- except Exception:
- import sys
- exc = sys.exc_info()[1]
- # Current exception is 'exc'
- pass
-
-You can get more information about the raised exception from
-:func:`sys.exc_info` than simply the current exception instance, but you most
-likely don't need it.
-
-.. note::
- In Python 3, the traceback is attached to the exception instance
- through the ``__traceback__`` attribute. If the instance is saved in
- a local variable that persists outside of the ``except`` block, the
- traceback will create a reference cycle with the current frame and its
- dictionary of local variables. This will delay reclaiming dead
- resources until the next cyclic :term:`garbage collection` pass.
-
- In Python 2, this problem only occurs if you save the traceback itself
- (e.g. the third element of the tuple returned by :func:`sys.exc_info`)
- in a variable.
-
-
-Other Resources
-===============
-
-The authors of the following blog posts, wiki pages, and books deserve special
-thanks for making public their tips for porting Python 2 code to Python 3 (and
-thus helping provide information for this document):
-
-* http://python3porting.com/
-* http://docs.pythonsprints.com/python3_porting/py-porting.html
-* http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/
-* http://dabeaz.blogspot.com/2011/01/porting-py65-and-my-superboard-to.html
-* http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/
-* http://lucumr.pocoo.org/2010/2/11/porting-to-python-3-a-guide/
-* http://wiki.python.org/moin/PortingPythonToPy3k
-
-If you feel there is something missing from this document that should be added,
-please email the python-porting_ mailing list.
-
-.. _python-porting: http://mail.python.org/mailman/listinfo/python-porting
+binary access (allowing binary data to be read and/or written) or textual access
+(allowing text data to be read and/or written). You should also use :func:`io.open`
+for opening files instead of the built-in :func:`open` function as the :mod:`io`
+module is consistent from Python 2 to 3 while the built-in :func:`open` function
+is not (in Python 3 it's actually :func:`io.open`). Do not bother with the
+outdated practice of using :func:`codecs.open` as that's only necessary for
+keeping compatibility with Python 2.5.
+
+The constructors of both ``str`` and ``bytes`` have different semantics for the
+same arguments between Python 2 & 3. Passing an integer to ``bytes`` in Python 2
+will give you the string representation of the integer: ``bytes(3) == '3'``.
+But in Python 3, an integer argument to ``bytes`` will give you a bytes object
+as long as the integer specified, filled with null bytes:
+``bytes(3) == b'\x00\x00\x00'``. A similar worry is necessary when passing a
+bytes object to ``str``. In Python 2 you just get the bytes object back:
+``str(b'3') == b'3'``. But in Python 3 you get the string representation of the
+bytes object: ``str(b'3') == "b'3'"``.
+
+Finally, the indexing of binary data requires careful handling (slicing does
+**not** require any special handling). In Python 2,
+``b'123'[1] == b'2'`` while in Python 3 ``b'123'[1] == 50``. Because binary data
+is simply a collection of binary numbers, Python 3 returns the integer value for
+the byte you index on. But in Python 2 because ``bytes == str``, indexing
+returns a one-item slice of bytes. The six_ project has a function
+named ``six.indexbytes()`` which will return an integer like in Python 3:
+``six.indexbytes(b'123', 1)``.
+
+To summarize:
+
+#. Decide which of your APIs take text and which take binary data
+#. Make sure that your code that works with text also works with ``unicode`` and
+ code for binary data works with ``bytes`` in Python 2 (see the table above
+ for what methods you cannot use for each type)
+#. Mark all binary literals with a ``b`` prefix, textual literals with a ``u``
+ prefix
+#. Decode binary data to text as soon as possible, encode text as binary data as
+ late as possible
+#. Open files using :func:`io.open` and make sure to specify the ``b`` mode when
+ appropriate
+#. Be careful when indexing into binary data
+
+
+Use feature detection instead of version detection
+++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Inevitably you will have code that has to choose what to do based on what
+version of Python is running. The best way to do this is with feature detection
+of whether the version of Python you're running under supports what you need.
+If for some reason that doesn't work then you should make the version check be
+against Python 2 and not Python 3. To help explain this, let's look at an
+example.
+
+Let's pretend that you need access to a feature of importlib_ that
+is available in Python's standard library since Python 3.3 and available for
+Python 2 through importlib2_ on PyPI. You might be tempted to write code to
+access e.g. the ``importlib.abc`` module by doing the following::
+
+ import sys
+
+ if sys.version_info[0] == 3:
+ from importlib import abc
+ else:
+ from importlib2 import abc
+
+The problem with this code is what happens when Python 4 comes out? It would
+be better to treat Python 2 as the exceptional case instead of Python 3 and
+assume that future Python versions will be more compatible with Python 3 than
+Python 2::
+
+ import sys
+
+ if sys.version_info[0] > 2:
+ from importlib import abc
+ else:
+ from importlib2 import abc
+
+The best solution, though, is to do no version detection at all and instead rely
+on feature detection. That avoids any potential issues of getting the version
+detection wrong and helps keep you future-compatible::
+
+ try:
+ from importlib import abc
+ except ImportError:
+ from importlib2 import abc
+
+
+Prevent compatibility regressions
+---------------------------------
+
+Once you have fully translated your code to be compatible with Python 3, you
+will want to make sure your code doesn't regress and stop working under
+Python 3. This is especially true if you have a dependency which is blocking you
+from actually running under Python 3 at the moment.
+
+To help with staying compatible, any new modules you create should have
+at least the following block of code at the top of it::
+
+ from __future__ import absolute_import
+ from __future__ import division
+ from __future__ import print_function
+
+You can also run Python 2 with the ``-3`` flag to be warned about various
+compatibility issues your code triggers during execution. If you turn warnings
+into errors with ``-Werror`` then you can make sure that you don't accidentally
+miss a warning.
+
+You can also use the Pylint_ project and its ``--py3k`` flag to lint your code
+to receive warnings when your code begins to deviate from Python 3
+compatibility. This also prevents you from having to run Modernize_ or Futurize_
+over your code regularly to catch compatibility regressions. This does require
+you only support Python 2.7 and Python 3.4 or newer as that is Pylint's
+minimum Python version support.
+
+
+Check which dependencies block your transition
+----------------------------------------------
+
+**After** you have made your code compatible with Python 3 you should begin to
+care about whether your dependencies have also been ported. The caniusepython3_
+project was created to help you determine which projects
+-- directly or indirectly -- are blocking you from supporting Python 3. There
+is both a command-line tool as well as a web interface at
+https://caniusepython3.com.
+
+The project also provides code which you can integrate into your test suite so
+that you will have a failing test when you no longer have dependencies blocking
+you from using Python 3. This allows you to avoid having to manually check your
+dependencies and to be notified quickly when you can start running on Python 3.
+
+
+Update your ``setup.py`` file to denote Python 3 compatibility
+--------------------------------------------------------------
+
+Once your code works under Python 3, you should update the classifiers in
+your ``setup.py`` to contain ``Programming Language :: Python :: 3`` and to not
+specify sole Python 2 support. This will tell anyone using your code that you
+support Python 2 **and** 3. Ideally you will also want to add classifiers for
+each major/minor version of Python you now support.
+
+
+Use continuous integration to stay compatible
+---------------------------------------------
+
+Once you are able to fully run under Python 3 you will want to make sure your
+code always works under both Python 2 & 3. Probably the best tool for running
+your tests under multiple Python interpreters is tox_. You can then integrate
+tox with your continuous integration system so that you never accidentally break
+Python 2 or 3 support.
+
+You may also want to use the ``-bb`` flag with the Python 3 interpreter to
+trigger an exception when you are comparing bytes to strings or bytes to an int
+(the latter is available starting in Python 3.5). By default type-differing
+comparisons simply return ``False``, but if you made a mistake in your
+separation of text/binary data handling or indexing on bytes you wouldn't easily
+find the mistake. This flag will raise an exception when these kinds of
+comparisons occur, making the mistake much easier to track down.
+
+And that's mostly it! At this point your code base is compatible with both
+Python 2 and 3 simultaneously. Your testing will also be set up so that you
+don't accidentally break Python 2 or 3 compatibility regardless of which version
+you typically run your tests under while developing.
+
+
+Consider using optional static type checking
+--------------------------------------------
+
+Another way to help port your code is to use a static type checker like
+mypy_ or pytype_ on your code. These tools can be used to analyze your code as
+if it's being run under Python 2, then you can run the tool a second time as if
+your code is running under Python 3. By running a static type checker twice like
+this you can discover if you're e.g. misusing binary data type in one version
+of Python compared to another. If you add optional type hints to your code you
+can also explicitly state whether your APIs use textual or binary data, helping
+to make sure everything functions as expected in both versions of Python.
+
+
+.. _2to3: https://docs.python.org/3/library/2to3.html
+.. _caniusepython3: https://pypi.org/project/caniusepython3
+.. _cheat sheet: http://python-future.org/compatible_idioms.html
+.. _coverage.py: https://pypi.org/project/coverage
+.. _Futurize: http://python-future.org/automatic_conversion.html
+.. _importlib: https://docs.python.org/3/library/importlib.html#module-importlib
+.. _importlib2: https://pypi.org/project/importlib2
+.. _Modernize: https://python-modernize.readthedocs.org/en/latest/
+.. _mypy: http://mypy-lang.org/
+.. _Porting to Python 3: http://python3porting.com/
+.. _Pylint: https://pypi.org/project/pylint
+
+.. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.org/en/latest/python3/questions_and_answers.html
+
+.. _pytype: https://github.com/google/pytype
+.. _python-future: http://python-future.org/
+.. _python-porting: https://mail.python.org/mailman/listinfo/python-porting
+.. _six: https://pypi.org/project/six
+.. _tox: https://pypi.org/project/tox
+.. _trove classifier: https://pypi.org/classifiers
+
+.. _"What's New": https://docs.python.org/3/whatsnew/index.html
+
+.. _Why Python 3 exists: http://www.snarky.ca/why-python-3-exists
diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst
index 2f552e39..81c04950 100644
--- a/Doc/howto/regex.rst
+++ b/Doc/howto/regex.rst
@@ -79,7 +79,9 @@ of the RE by repeating them or changing their meaning. Much of this document is
devoted to discussing various metacharacters and what they do.
Here's a complete list of the metacharacters; their meanings will be discussed
-in the rest of this HOWTO. ::
+in the rest of this HOWTO.
+
+.. code-block:: none
. ^ $ * + ? { } [ ] \ | ( )
@@ -99,8 +101,9 @@ special nature.
You can match the characters not listed within the class by :dfn:`complementing`
the set. This is indicated by including a ``'^'`` as the first character of the
-class; ``'^'`` outside a character class will simply match the ``'^'``
-character. For example, ``[^5]`` will match any character except ``'5'``.
+class. For example, ``[^5]`` will match any character except ``'5'``. If the
+caret appears elsewhere in a character class, it does not have special meaning.
+For example: ``[5^]`` will match either a ``'5'`` or a ``'^'``.
Perhaps the most important metacharacter is the backslash, ``\``. As in Python
string literals, the backslash can be followed by various characters to signal
@@ -172,7 +175,7 @@ that limit.
Repetitions such as ``*`` are :dfn:`greedy`; when repeating a RE, the matching
engine will try to repeat it as many times as possible. If later portions of the
pattern don't match, the matching engine will then back up and try again with
-few repetitions.
+fewer repetitions.
A step-by-step example will make this more obvious. Let's consider the
expression ``a[bcd]*b``. This matches the letter ``'a'``, zero or more letters
@@ -838,7 +841,7 @@ backreferences in a RE.
For example, the following RE detects doubled words in a string. ::
- >>> p = re.compile(r'(\b\w+)\s+\1')
+ >>> p = re.compile(r'\b(\w+)\s+\1\b')
>>> p.search('Paris in the the spring').group()
'the the'
@@ -945,9 +948,9 @@ number of the group. There's naturally a variant that uses the group name
instead of the number. This is another Python extension: ``(?P=name)`` indicates
that the contents of the group called *name* should again be matched at the
current point. The regular expression for finding doubled words,
-``(\b\w+)\s+\1`` can also be written as ``(?P\b\w+)\s+(?P=word)``::
+``\b(\w+)\s+\1\b`` can also be written as ``\b(?P\w+)\s+(?P=word)\b``::
- >>> p = re.compile(r'(?P\b\w+)\s+(?P=word)')
+ >>> p = re.compile(r'\b(?P\w+)\s+(?P=word)\b')
>>> p.search('Paris in the the spring').group()
'the the'
@@ -1015,17 +1018,18 @@ confusing.
A negative lookahead cuts through all this confusion:
-``.*[.](?!bat$).*$`` The negative lookahead means: if the expression ``bat``
+``.*[.](?!bat$)[^.]*$`` The negative lookahead means: if the expression ``bat``
doesn't match at this point, try the rest of the pattern; if ``bat$`` does
match, the whole pattern will fail. The trailing ``$`` is required to ensure
that something like ``sample.batch``, where the extension only starts with
-``bat``, will be allowed.
+``bat``, will be allowed. The ``[^.]*`` makes sure that the pattern works
+when there are multiple dots in the filename.
Excluding another filename extension is now easy; simply add it as an
alternative inside the assertion. The following pattern excludes filenames that
end in either ``bat`` or ``exe``:
-``.*[.](?!bat$|exe$).*$``
+``.*[.](?!bat$|exe$)[^.]*$``
Modifying Strings
@@ -1126,19 +1130,19 @@ which can be either a string or a function, and the string to be processed.
Here's a simple example of using the :meth:`sub` method. It replaces colour
names with the word ``colour``::
- >>> p = re.compile( '(blue|white|red)')
- >>> p.sub( 'colour', 'blue socks and red shoes')
+ >>> p = re.compile('(blue|white|red)')
+ >>> p.sub('colour', 'blue socks and red shoes')
'colour socks and colour shoes'
- >>> p.sub( 'colour', 'blue socks and red shoes', count=1)
+ >>> p.sub('colour', 'blue socks and red shoes', count=1)
'colour socks and red shoes'
The :meth:`subn` method does the same work, but returns a 2-tuple containing the
new string value and the number of replacements that were performed::
- >>> p = re.compile( '(blue|white|red)')
- >>> p.subn( 'colour', 'blue socks and red shoes')
+ >>> p = re.compile('(blue|white|red)')
+ >>> p.subn('colour', 'blue socks and red shoes')
('colour socks and colour shoes', 2)
- >>> p.subn( 'colour', 'no colours at all')
+ >>> p.subn('colour', 'no colours at all')
('no colours at all', 0)
Empty matches are replaced only when they're not adjacent to a previous match.
diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst
index e0083edc..69abf78a 100644
--- a/Doc/howto/sockets.rst
+++ b/Doc/howto/sockets.rst
@@ -110,7 +110,7 @@ mainloop of the web server::
There's actually 3 general ways in which this loop could work - dispatching a
thread to handle ``clientsocket``, create a new process to handle
``clientsocket``, or restructure this app to use non-blocking sockets, and
-mulitplex between our "server" socket and any active ``clientsocket``\ s using
+multiplex between our "server" socket and any active ``clientsocket``\ s using
``select``. More about that later. The important thing to understand now is
this: this is *all* a "server" socket does. It doesn't send any data. It doesn't
receive any data. It just produces "client" sockets. Each ``clientsocket`` is
@@ -207,13 +207,15 @@ length message::
totalsent = totalsent + sent
def myreceive(self):
- msg = ''
- while len(msg) < MSGLEN:
- chunk = self.sock.recv(MSGLEN-len(msg))
+ chunks = []
+ bytes_recd = 0
+ while bytes_recd < MSGLEN:
+ chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048))
if chunk == '':
raise RuntimeError("socket connection broken")
- msg = msg + chunk
- return msg
+ chunks.append(chunk)
+ bytes_recd = bytes_recd + len(chunk)
+ return ''.join(chunks)
The sending code here is usable for almost any messaging scheme - in Python you
send strings, and you can use ``len()`` to determine its length (even if it has
@@ -235,7 +237,7 @@ messages to be sent back to back (without some kind of reply), and you pass
following message. You'll need to put that aside and hold onto it, until it's
needed.
-Prefixing the message with it's length (say, as 5 numeric characters) gets more
+Prefixing the message with its length (say, as 5 numeric characters) gets more
complex, because (believe it or not), you may not get all 5 characters in one
``recv``. In playing around, you'll get away with it; but in high network loads,
your code will very quickly break unless you use two ``recv`` loops - the first
diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst
index 56b65b0d..6e316374 100644
--- a/Doc/howto/sorting.rst
+++ b/Doc/howto/sorting.rst
@@ -24,7 +24,7 @@ returns a new sorted list::
[1, 2, 3, 4, 5]
You can also use the :meth:`list.sort` method of a list. It modifies the list
-in-place (and returns *None* to avoid confusion). Usually it's less convenient
+in-place (and returns ``None`` to avoid confusion). Usually it's less convenient
than :func:`sorted` - but if you don't need the original list, it's slightly
more efficient.
@@ -59,28 +59,28 @@ A common pattern is to sort complex objects using some of the object's indices
as keys. For example:
>>> student_tuples = [
- ('john', 'A', 15),
- ('jane', 'B', 12),
- ('dave', 'B', 10),
- ]
+ ... ('john', 'A', 15),
+ ... ('jane', 'B', 12),
+ ... ('dave', 'B', 10),
+ ... ]
>>> sorted(student_tuples, key=lambda student: student[2]) # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
The same technique works for objects with named attributes. For example:
>>> class Student:
- def __init__(self, name, grade, age):
- self.name = name
- self.grade = grade
- self.age = age
- def __repr__(self):
- return repr((self.name, self.grade, self.age))
+ ... def __init__(self, name, grade, age):
+ ... self.name = name
+ ... self.grade = grade
+ ... self.age = age
+ ... def __repr__(self):
+ ... return repr((self.name, self.grade, self.age))
>>> student_objects = [
- Student('john', 'A', 15),
- Student('jane', 'B', 12),
- Student('dave', 'B', 10),
- ]
+ ... Student('john', 'A', 15),
+ ... Student('jane', 'B', 12),
+ ... Student('dave', 'B', 10),
+ ... ]
>>> sorted(student_objects, key=lambda student: student.age) # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
@@ -90,7 +90,7 @@ Operator Module Functions
The key-function patterns shown above are very common, so Python provides
convenience functions to make accessor functions easier and faster. The operator
module has :func:`operator.itemgetter`, :func:`operator.attrgetter`, and
-starting in Python 2.5 a :func:`operator.methodcaller` function.
+starting in Python 2.5 an :func:`operator.methodcaller` function.
Using those functions, the above examples become simpler and faster:
@@ -116,6 +116,7 @@ parameters for each object being sorted. For example, the :meth:`str.count`
method could be used to compute message priority by counting the
number of exclamation marks in a message:
+ >>> from operator import methodcaller
>>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!']
>>> sorted(messages, key=methodcaller('count', '!'))
['standby', 'hurry!', 'immediate!!', 'critical!!!']
@@ -137,7 +138,7 @@ Sort Stability and Complex Sorts
================================
Starting with Python 2.2, sorts are guaranteed to be `stable
-`_\. That means that
+`_\. That means that
when multiple records have the same key, their original order is preserved.
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
@@ -155,7 +156,7 @@ ascending *age*, do the *age* sort first and then sort again using *grade*:
>>> sorted(s, key=attrgetter('grade'), reverse=True) # now sort on primary key, descending
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
-The `Timsort `_ algorithm used in Python
+The `Timsort `_ algorithm used in Python
does multiple sorts efficiently because it can take advantage of any ordering
already present in a dataset.
@@ -194,7 +195,7 @@ decorated list, but including it gives two benefits:
directly.
Another name for this idiom is
-`Schwartzian transform `_\,
+`Schwartzian transform `_\,
after Randal L. Schwartz, who popularized it among Perl programmers.
For large lists and lists where the comparison information is expensive to
@@ -220,15 +221,15 @@ return a negative value for less-than, return zero if they are equal, or return
a positive value for greater-than. For example, we can do:
>>> def numeric_compare(x, y):
- return x - y
- >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
+ ... return x - y
+ >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare) # doctest: +SKIP
[1, 2, 3, 4, 5]
Or you can reverse the order of comparison with:
>>> def reverse_numeric(x, y):
- return y - x
- >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric)
+ ... return y - x
+ >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric) # doctest: +SKIP
[5, 4, 3, 2, 1]
When porting code from Python 2.x to 3.x, the situation can arise when you have
@@ -256,6 +257,12 @@ function. The following wrapper makes that easy to do::
To convert to a key function, just wrap the old comparison function:
+.. testsetup::
+
+ from functools import cmp_to_key
+
+.. doctest::
+
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]
@@ -274,7 +281,11 @@ Odd and Ends
twice:
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
- >>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))
+ >>> standard_way = sorted(data, key=itemgetter(0), reverse=True)
+ >>> double_reversed = list(reversed(sorted(reversed(data), key=itemgetter(0))))
+ >>> assert standard_way == double_reversed
+ >>> standard_way
+ [('red', 1), ('red', 2), ('blue', 1), ('blue', 2)]
* To create a standard sort order for a class, just add the appropriate rich
comparison methods:
diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst
index 10dde016..6724039d 100644
--- a/Doc/howto/unicode.rst
+++ b/Doc/howto/unicode.rst
@@ -7,7 +7,7 @@
This HOWTO discusses Python 2.x's support for Unicode, and explains
various problems that people commonly encounter when trying to work
with Unicode. For the Python 3 version, see
-.
+.
Introduction to Unicode
=======================
@@ -32,8 +32,8 @@ For a while people just wrote programs that didn't display accents. I remember
looking at Apple ][ BASIC programs, published in French-language publications in
the mid-1980s, that had lines like these::
- PRINT "FICHIER EST COMPLETE."
- PRINT "CARACTERE NON ACCEPTE."
+ PRINT "MISE A JOUR TERMINEE"
+ PRINT "PARAMETRES ENREGISTRES"
Those messages should contain accents, and they just look wrong to someone who
can read French.
@@ -42,14 +42,14 @@ In the 1980s, almost all personal computers were 8-bit, meaning that bytes could
hold values ranging from 0 to 255. ASCII codes only went up to 127, so some
machines assigned values between 128 and 255 to accented characters. Different
machines had different codes, however, which led to problems exchanging files.
-Eventually various commonly used sets of values for the 128-255 range emerged.
-Some were true standards, defined by the International Standards Organization,
-and some were **de facto** conventions that were invented by one company or
-another and managed to catch on.
+Eventually various commonly used sets of values for the 128--255 range emerged.
+Some were true standards, defined by the International Organization for
+Standardization, and some were *de facto* conventions that were invented by one
+company or another and managed to catch on.
255 characters aren't very many. For example, you can't fit both the accented
characters used in Western Europe and the Cyrillic alphabet used for Russian
-into the 128-255 range because there are more than 127 such characters.
+into the 128--255 range because there are more than 128 such characters.
You could write files using different codes (all your Russian files in a coding
system called KOI8, all your French files in a different coding system called
@@ -62,7 +62,7 @@ bits means you have 2^16 = 65,536 distinct values available, making it possible
to represent many different characters from many different alphabets; an initial
goal was to have Unicode contain the alphabets for every single human language.
It turns out that even 16 bits isn't enough to meet that goal, and the modern
-Unicode specification uses a wider range of codes, 0-1,114,111 (0x10ffff in
+Unicode specification uses a wider range of codes, 0--1,114,111 (0x10ffff in
base-16).
There's a related ISO standard, ISO 10646. Unicode and ISO 10646 were
@@ -116,7 +116,7 @@ Encodings
To summarize the previous section: a Unicode string is a sequence of code
points, which are numbers from 0 to 0x10ffff. This sequence needs to be
-represented as a set of bytes (meaning, values from 0-255) in memory. The rules
+represented as a set of bytes (meaning, values from 0--255) in memory. The rules
for translating a Unicode string into a sequence of bytes are called an
**encoding**.
@@ -163,7 +163,7 @@ simple; for each code point:
case.)
Latin-1, also known as ISO-8859-1, is a similar encoding. Unicode code points
-0-255 are identical to the Latin-1 values, so converting to this encoding simply
+0--255 are identical to the Latin-1 values, so converting to this encoding simply
requires converting code points to byte values; if a code point larger than 255
is encountered, the string can't be encoded into Latin-1.
@@ -211,7 +211,7 @@ origin and development of Unicode.
To help understand the standard, Jukka Korpela has written an introductory guide
to reading the Unicode character tables, available at
-.
+.
Another good introductory article was written by Joel Spolsky
.
@@ -435,7 +435,7 @@ When you run it with Python 2.4, it will output the following warning::
amk:~$ python2.4 p263.py
sys:1: DeprecationWarning: Non-ASCII character '\xe9'
in file p263.py on line 2, but no encoding declared;
- see http://www.python.org/peps/pep-0263.html for details
+ see https://www.python.org/peps/pep-0263.html for details
Python 2.5 and higher are stricter and will produce a syntax error::
@@ -443,7 +443,7 @@ Python 2.5 and higher are stricter and will produce a syntax error::
File "/tmp/p263.py", line 2
SyntaxError: Non-ASCII character '\xc3' in file /tmp/p263.py
on line 2, but no encoding declared; see
- http://www.python.org/peps/pep-0263.html for details
+ https://www.python.org/peps/pep-0263.html for details
Unicode Properties
@@ -500,7 +500,7 @@ The documentation for the :mod:`codecs` module.
Marc-André Lemburg gave a presentation at EuroPython 2002 titled "Python and
Unicode". A PDF version of his slides is available at
-, and is an
+, and is an
excellent overview of the design of Python's Unicode features.
@@ -619,7 +619,9 @@ default filesystem encoding is UTF-8, running the following program::
print os.listdir('.')
print os.listdir(u'.')
-will produce the following output::
+will produce the following output:
+
+.. code-block:: shell-session
amk:~$ python t.py
['.svn', 'filename\xe4\x94\x80abc', ...]
@@ -687,7 +689,7 @@ References
The PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware
Applications in Python" are available at
-
+
and discuss questions of character encodings as well as how to internationalize
and localize an application.
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index f84bf081..ce639485 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -1,3 +1,5 @@
+.. _urllib-howto:
+
************************************************
HOWTO Fetch Internet Resources Using urllib2
************************************************
@@ -6,7 +8,7 @@
.. note::
- There is an French translation of an earlier revision of this
+ There is a French translation of an earlier revision of this
HOWTO, available at `urllib2 - Le Manuel manquant
`_.
@@ -18,13 +20,13 @@ Introduction
.. sidebar:: Related Articles
You may also find useful the following article on fetching web resources
- with Python :
+ with Python:
* `Basic Authentication `_
A tutorial on *Basic Authentication*, with examples in Python.
-**urllib2** is a `Python `_ module for fetching URLs
+**urllib2** is a Python module for fetching URLs
(Uniform Resource Locators). It offers a very simple interface, in the form of
the *urlopen* function. This is capable of fetching URLs using a variety of
different protocols. It also offers a slightly more complex interface for
@@ -32,8 +34,8 @@ handling common situations - like basic authentication, cookies, proxies and so
on. These are provided by objects called handlers and openers.
urllib2 supports fetching URLs for many "URL schemes" (identified by the string
-before the ":" in URL - for example "ftp" is the URL scheme of
-"ftp://python.org/") using their associated network protocols (e.g. FTP, HTTP).
+before the ``":"`` in URL - for example ``"ftp"`` is the URL scheme of
+``"ftp://python.org/"``) using their associated network protocols (e.g. FTP, HTTP).
This tutorial focuses on the most common case, HTTP.
For straightforward situations *urlopen* is very easy to use. But as soon as you
@@ -55,7 +57,7 @@ The simplest way to use urllib2 is as follows::
html = response.read()
Many uses of urllib2 will be that simple (note that instead of an 'http:' URL we
-could have used an URL starting with 'ftp:', 'file:', etc.). However, it's the
+could have used a URL starting with 'ftp:', 'file:', etc.). However, it's the
purpose of this tutorial to explain the more complicated cases, concentrating on
HTTP.
@@ -112,7 +114,7 @@ argument. The encoding is done using a function from the ``urllib`` library
Note that other encodings are sometimes required (e.g. for file upload from HTML
forms - see `HTML Specification, Form Submission
-`_ for more
+`_ for more
details).
If you do not pass the ``data`` argument, urllib2 uses a **GET** request. One
@@ -150,7 +152,7 @@ We'll discuss here one particular HTTP header, to illustrate how to add headers
to your HTTP request.
Some websites [#]_ dislike being browsed by programs, or send different versions
-to different browsers [#]_ . By default urllib2 identifies itself as
+to different browsers [#]_. By default urllib2 identifies itself as
``Python-urllib/x.y`` (where ``x`` and ``y`` are the major and minor version
numbers of the Python release,
e.g. ``Python-urllib/2.5``), which may confuse the site, or just plain
@@ -164,11 +166,11 @@ Explorer [#]_. ::
import urllib2
url = 'http://www.someserver.com/cgi-bin/register.cgi'
- user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- values = {'name' : 'Michael Foord',
- 'location' : 'Northampton',
- 'language' : 'Python' }
- headers = { 'User-Agent' : user_agent }
+ user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'
+ values = {'name': 'Michael Foord',
+ 'location': 'Northampton',
+ 'language': 'Python' }
+ headers = {'User-Agent': user_agent}
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
@@ -201,7 +203,7 @@ e.g. ::
>>> req = urllib2.Request('http://www.pretend_server.org')
>>> try: urllib2.urlopen(req)
- ... except URLError as e:
+ ... except urllib2.URLError as e:
... print e.reason #doctest: +SKIP
...
(4, 'getaddrinfo failed')
@@ -227,8 +229,8 @@ Error Codes
~~~~~~~~~~~
Because the default handlers handle redirects (codes in the 300 range), and
-codes in the 100-299 range indicate success, you will usually only see error
-codes in the 400-599 range.
+codes in the 100--299 range indicate success, you will usually only see error
+codes in the 400--599 range.
``BaseHTTPServer.BaseHTTPRequestHandler.responses`` is a useful dictionary of
response codes in that shows all the response codes used by RFC 2616. The
@@ -388,7 +390,7 @@ fetched, particularly the headers sent by the server. It is currently an
``httplib.HTTPMessage`` instance.
Typical headers include 'Content-length', 'Content-type', and so on. See the
-`Quick Reference to HTTP Headers `_
+`Quick Reference to HTTP Headers `_
for a useful listing of HTTP headers with brief explanations of their meaning
and use.
@@ -439,7 +441,7 @@ Authentication Tutorial
When authentication is required, the server sends a header (as well as the 401
error code) requesting authentication. This specifies the authentication scheme
-and a 'realm'. The header looks like : ``WWW-Authenticate: SCHEME
+and a 'realm'. The header looks like: ``WWW-Authenticate: SCHEME
realm="REALM"``.
e.g. ::
@@ -496,10 +498,10 @@ than the URL you pass to .add_password() will also match. ::
``top_level_url`` is in fact *either* a full URL (including the 'http:' scheme
component and the hostname and optionally the port number)
-e.g. "http://example.com/" *or* an "authority" (i.e. the hostname,
-optionally including the port number) e.g. "example.com" or "example.com:8080"
+e.g. ``"http://example.com/"`` *or* an "authority" (i.e. the hostname,
+optionally including the port number) e.g. ``"example.com"`` or ``"example.com:8080"``
(the latter example includes a port number). The authority, if present, must
-NOT contain the "userinfo" component - for example "joe@password:example.com" is
+NOT contain the "userinfo" component - for example ``"joe:password@example.com"`` is
not correct.
@@ -511,7 +513,7 @@ the ``ProxyHandler``, which is part of the normal handler chain when a proxy
setting is detected. Normally that's a good thing, but there are occasions
when it may not be helpful [#]_. One way to do this is to setup our own
``ProxyHandler``, with no proxies defined. This is done using similar steps to
-setting up a `Basic Authentication`_ handler : ::
+setting up a `Basic Authentication`_ handler: ::
>>> proxy_support = urllib2.ProxyHandler({})
>>> opener = urllib2.build_opener(proxy_support)
@@ -523,6 +525,11 @@ setting up a `Basic Authentication`_ handler : ::
through a proxy. However, this can be enabled by extending urllib2 as
shown in the recipe [#]_.
+.. note::
+
+ ``HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set; see
+ the documentation on :func:`~urllib.getproxies`.
+
Sockets and Layers
==================
@@ -559,11 +566,8 @@ This document was reviewed and revised by John Lee.
.. [#] For an introduction to the CGI protocol see
`Writing Web Applications in Python `_.
-.. [#] Like Google for example. The *proper* way to use google from a program
- is to use `PyGoogle `_ of course. See
- `Voidspace Google `_
- for some examples of using the Google API.
-.. [#] Browser sniffing is a very bad practise for website design - building
+.. [#] Google for example.
+.. [#] Browser sniffing is a very bad practice for website design - building
sites using web standards is much more sensible. Unfortunately a lot of
sites still send different versions to different browsers.
.. [#] The user agent for MSIE 6 is
@@ -576,5 +580,5 @@ This document was reviewed and revised by John Lee.
scripts with a localhost server, I have to prevent urllib2 from using
the proxy.
.. [#] urllib2 opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe
- `_.
+ `_.
diff --git a/Doc/howto/webservers.rst b/Doc/howto/webservers.rst
index fbc9fd91..5071a8a3 100644
--- a/Doc/howto/webservers.rst
+++ b/Doc/howto/webservers.rst
@@ -26,7 +26,7 @@ of the most popular libraries is provided.
While this HOWTO tries to give an overview of Python in the web, it cannot
always be as up to date as desired. Web development in Python is rapidly
moving forward, so the wiki page on `Web Programming
- `_ may be more in sync with
+ `_ may be more in sync with
recent development.
@@ -86,7 +86,7 @@ available.
applications, instead of presenting a "500 Internal Server Error" message
The Python wiki features a page on `CGI scripts
- `_ with some additional information
+ `_ with some additional information
about CGI in Python.
@@ -146,7 +146,7 @@ server may not be needed.
tutorial also describes the most common gotchas that might arise.
* On lighttpd you need to use the `CGI module
- `_\ , which can be configured
+ `_\ , which can be configured
in a straightforward way. It boils down to setting ``cgi.assign`` properly.
@@ -210,7 +210,7 @@ mod_python
----------
People coming from PHP often find it hard to grasp how to use Python in the web.
-Their first thought is mostly `mod_python `_\ ,
+Their first thought is mostly `mod_python `_\ ,
because they think that this is the equivalent to ``mod_php``. Actually, there
are many differences. What ``mod_python`` does is embed the interpreter into
the Apache process, thus speeding up requests by not having to start a Python
@@ -260,13 +260,6 @@ the latter.
These days, FastCGI is never used directly. Just like ``mod_python``, it is only
used for the deployment of WSGI applications.
-.. seealso::
-
- * `FastCGI, SCGI, and Apache: Background and Future
- `_
- is a discussion on why the concept of FastCGI and SCGI is better than that
- of mod_python.
-
Setting up FastCGI
^^^^^^^^^^^^^^^^^^
@@ -274,17 +267,17 @@ Setting up FastCGI
Each web server requires a specific module.
* Apache has both `mod_fastcgi `_ and `mod_fcgid
- `_. ``mod_fastcgi`` is the original one, but it
+ `_. ``mod_fastcgi`` is the original one, but it
has some licensing issues, which is why it is sometimes considered non-free.
``mod_fcgid`` is a smaller, compatible alternative. One of these modules needs
to be loaded by Apache.
* lighttpd ships its own `FastCGI module
- `_ as well as an
- `SCGI module `_.
+ `_ as well as an
+ `SCGI module `_.
* `nginx `_ also supports `FastCGI
- `_.
+ `_.
Once you have installed and configured the module, you can test it with the
following WSGI-application::
@@ -302,19 +295,19 @@ following WSGI-application::
yield 'FastCGI Environment
'
yield ''
for k, v in sorted(environ.items()):
- yield '| %s | %s |
' % (escape(k), escape(v))
+ yield '| %s | %s |
' % (escape(k), escape(v))
yield '
'
WSGIServer(app).run()
This is a simple WSGI application, but you need to install `flup
-`_ first, as flup handles the low level
+`_ first, as flup handles the low level
FastCGI access.
.. seealso::
- There is some documentation on `setting up Django with FastCGI
- `_, most of
+ There is some documentation on `setting up Django with WSGI
+ `_, most of
which can be reused for other WSGI-compliant frameworks and libraries.
Only the ``manage.py`` part has to be changed, the example used here can be
used instead. Django does more or less the exact same thing.
@@ -364,15 +357,15 @@ testing.
A really great WSGI feature is middleware. Middleware is a layer around your
program which can add various functionality to it. There is quite a bit of
-`middleware `_ already
+`middleware `_ already
available. For example, instead of writing your own session management (HTTP
is a stateless protocol, so to associate multiple HTTP requests with a single
user your application must create and manage such state via a session), you can
just download middleware which does that, plug it in, and get on with coding
the unique parts of your application. The same thing with compression -- there
is existing middleware which handles compressing your HTML using gzip to save
-on your server's bandwidth. Authentication is another a problem easily solved
-using existing middleware.
+on your server's bandwidth. Authentication is another problem that is easily
+solved using existing middleware.
Although WSGI may seem complex, the initial phase of learning can be very
rewarding because WSGI and the associated middleware already have solutions to
@@ -385,7 +378,7 @@ WSGI Servers
The code that is used to connect to various low level gateways like CGI or
mod_python is called a *WSGI server*. One of these servers is ``flup``, which
supports FastCGI and SCGI, as well as `AJP
-`_. Some of these servers
+`_. Some of these servers
are written in Python, as ``flup`` is, but there also exist others which are
written in C and can be used as drop-in replacements.
@@ -396,8 +389,8 @@ compared with other web technologies.
.. seealso::
A good overview of WSGI-related code can be found in the `WSGI homepage
- `_, which contains an extensive list of `WSGI servers
- `_ which can be used by *any* application
+ `_, which contains an extensive list of `WSGI servers
+ `_ which can be used by *any* application
supporting WSGI.
You might be interested in some WSGI-supporting modules already contained in
@@ -414,7 +407,7 @@ an application that's been around for a while, which was written in
Python without using WSGI.
One of the most widely used wiki software packages is `MoinMoin
-`_. It was created in 2000, so it predates WSGI by about
+`_. It was created in 2000, so it predates WSGI by about
three years. Older versions needed separate code to run on CGI, mod_python,
FastCGI and standalone.
@@ -466,7 +459,7 @@ maintainable web sites.
.. seealso::
The English Wikipedia has an article about the `Model-View-Controller pattern
- `_. It includes a long
+ `_. It includes a long
list of web frameworks for various programming languages.
@@ -485,7 +478,7 @@ developing a web site.
There are far more components than can be presented here. The Python wiki
has a page about these components, called
- `Web Components `_.
+ `Web Components `_.
Templates
@@ -526,13 +519,13 @@ Popular template engines include:
* `Mako `_
* `Genshi `_
- * `Jinja `_
+ * `Jinja `_
.. seealso::
There are many template engines competing for attention, because it is
pretty easy to create them in Python. The page `Templating
- `_ in the wiki lists a big,
+ `_ in the wiki lists a big,
ever-growing number of these. The three listed above are considered "second
generation" template engines and are a good place to start.
@@ -554,10 +547,10 @@ module, and which uses only one file. It has no other dependencies. For
smaller sites SQLite is just enough.
Relational databases are *queried* using a language called `SQL
-`_. Python programmers in general do not
+`_. Python programmers in general do not
like SQL too much, as they prefer to work with objects. It is possible to save
Python objects into a database using a technology called `ORM
-`_ (Object Relational
+`_ (Object Relational
Mapping). ORM translates all object-oriented access into SQL code under the
hood, so the developer does not need to think about it. Most `frameworks`_ use
ORMs, and it works quite well.
@@ -582,21 +575,21 @@ alternate storage mechanism.
.. seealso::
- * `Persistence Tools `_ lists
+ * `Persistence Tools `_ lists
possibilities on how to save data in the file system. Some of these
modules are part of the standard library
- * `Database Programming `_
+ * `Database Programming `_
helps with choosing a method for saving data
* `SQLAlchemy `_, the most powerful OR-Mapper
- for Python, and `Elixir `_, which makes
+ for Python, and `Elixir `_, which makes
SQLAlchemy easier to use
* `SQLObject `_, another popular OR-Mapper
* `ZODB `_ and `Durus
- `_, two object oriented
+ `_, two object oriented
databases
@@ -648,7 +641,7 @@ here. Instead we will briefly touch on some of the most popular.
Django
^^^^^^
-`Django `_ is a framework consisting of several
+`Django `_ is a framework consisting of several
tightly coupled elements which were written from scratch and work together very
well. It includes an ORM which is quite powerful while being simple to use,
and has a great online administration interface which makes it possible to edit
@@ -661,7 +654,7 @@ which make it possible to create web sites almost without writing any Python cod
It has a big, international community, the members of which have created many
web sites. There are also a lot of add-on projects which extend Django's normal
functionality. This is partly due to Django's well written `online
-documentation `_ and the `Django book
+documentation `_ and the `Django book
`_.
@@ -669,7 +662,7 @@ documentation `_ and the `Django book
Although Django is an MVC-style framework, it names the elements
differently, which is described in the `Django FAQ
- `_.
+ `_.
TurboGears
@@ -682,16 +675,16 @@ experience. TurboGears gives the user flexibility in choosing components. For
example the ORM and template engine can be changed to use packages different
from those used by default.
-The documentation can be found in the `TurboGears wiki
-`_, where links to screencasts can be found.
+The documentation can be found in the `TurboGears documentation
+`_, where links to screencasts can be found.
TurboGears has also an active user community which can respond to most related
-questions. There is also a `TurboGears book `_
+questions. There is also a `TurboGears book `_
published, which is a good starting point.
The newest version of TurboGears, version 2.0, moves even further in direction
of WSGI support and a component-based architecture. TurboGears 2 is based on
the WSGI stack of another popular component-based web framework, `Pylons
-`_.
+`_.
Zope
@@ -712,7 +705,7 @@ access to these components to the wider Python community. There is even a
separate framework based on the Zope components: `Grok
`_.
-Zope is also the infrastructure used by the `Plone `_ content
+Zope is also the infrastructure used by the `Plone `_ content
management system, one of the most powerful and popular content management
systems available.
@@ -736,9 +729,7 @@ found in the Python wiki.
.. seealso::
The Python wiki contains an extensive list of `web frameworks
- `_.
+ `_.
Most frameworks also have their own mailing lists and IRC channels, look out
- for these on the projects' web sites. There is also a general "Python in the
- Web" IRC channel on freenode called `#python.web
- `_.
+ for these on the projects' web sites.
diff --git a/Doc/includes/email-alternative.py b/Doc/includes/email-alternative.py
index 82d605e0..ccecb424 100644
--- a/Doc/includes/email-alternative.py
+++ b/Doc/includes/email-alternative.py
@@ -17,14 +17,14 @@
msg['To'] = you
# Create the body of the message (a plain-text and an HTML version).
-text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org"
+text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttps://www.python.org"
html = """\
Hi!
How are you?
- Here is the link you wanted.
+ Here is the link you wanted.
diff --git a/Doc/includes/noddy.c b/Doc/includes/noddy.c
index ec2d669d..9d80bbe4 100644
--- a/Doc/includes/noddy.c
+++ b/Doc/includes/noddy.c
@@ -6,27 +6,26 @@ typedef struct {
} noddy_NoddyObject;
static PyTypeObject noddy_NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(noddy_NoddyObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- 0, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(noddy_NoddyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
"Noddy objects", /* tp_doc */
};
diff --git a/Doc/includes/noddy2.c b/Doc/includes/noddy2.c
index 2caf9855..94b92be7 100644
--- a/Doc/includes/noddy2.c
+++ b/Doc/includes/noddy2.c
@@ -13,7 +13,7 @@ Noddy_dealloc(Noddy* self)
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
@@ -24,18 +24,16 @@ Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (Noddy *)type->tp_alloc(type, 0);
if (self != NULL) {
self->first = PyString_FromString("");
- if (self->first == NULL)
- {
+ if (self->first == NULL) {
Py_DECREF(self);
return NULL;
- }
-
+ }
+
self->last = PyString_FromString("");
- if (self->last == NULL)
- {
+ if (self->last == NULL) {
Py_DECREF(self);
return NULL;
- }
+ }
self->number = 0;
}
@@ -50,10 +48,10 @@ Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
static char *kwlist[] = {"first", "last", "number", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
+ &first, &last,
&self->number))
- return -1;
+ return -1;
if (first) {
tmp = self->first;
@@ -111,7 +109,7 @@ Noddy_name(Noddy* self)
result = PyString_Format(format, args);
Py_DECREF(args);
-
+
return result;
}
@@ -123,34 +121,34 @@ static PyMethodDef Noddy_methods[] = {
};
static PyTypeObject NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(Noddy), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Noddy_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(Noddy), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Noddy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
"Noddy objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
Noddy_methods, /* tp_methods */
Noddy_members, /* tp_members */
0, /* tp_getset */
@@ -172,7 +170,7 @@ static PyMethodDef module_methods[] = {
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
-initnoddy2(void)
+initnoddy2(void)
{
PyObject* m;
@@ -183,7 +181,7 @@ initnoddy2(void)
"Example module that creates an extension type.");
if (m == NULL)
- return;
+ return;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
diff --git a/Doc/includes/noddy3.c b/Doc/includes/noddy3.c
index 60260ada..43ec42b6 100644
--- a/Doc/includes/noddy3.c
+++ b/Doc/includes/noddy3.c
@@ -13,7 +13,7 @@ Noddy_dealloc(Noddy* self)
{
Py_XDECREF(self->first);
Py_XDECREF(self->last);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
@@ -24,18 +24,16 @@ Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (Noddy *)type->tp_alloc(type, 0);
if (self != NULL) {
self->first = PyString_FromString("");
- if (self->first == NULL)
- {
+ if (self->first == NULL) {
Py_DECREF(self);
return NULL;
- }
-
+ }
+
self->last = PyString_FromString("");
- if (self->last == NULL)
- {
+ if (self->last == NULL) {
Py_DECREF(self);
return NULL;
- }
+ }
self->number = 0;
}
@@ -50,10 +48,10 @@ Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
static char *kwlist[] = {"first", "last", "number", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
- &first, &last,
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
+ &first, &last,
&self->number))
- return -1;
+ return -1;
if (first) {
tmp = self->first;
@@ -88,22 +86,22 @@ Noddy_getfirst(Noddy *self, void *closure)
static int
Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
- return -1;
- }
-
- if (! PyString_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The first attribute value must be a string");
- return -1;
- }
-
- Py_DECREF(self->first);
- Py_INCREF(value);
- self->first = value;
-
- return 0;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+
+ if (! PyString_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a string");
+ return -1;
+ }
+
+ Py_DECREF(self->first);
+ Py_INCREF(value);
+ self->first = value;
+
+ return 0;
}
static PyObject *
@@ -116,30 +114,30 @@ Noddy_getlast(Noddy *self, void *closure)
static int
Noddy_setlast(Noddy *self, PyObject *value, void *closure)
{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
- return -1;
- }
-
- if (! PyString_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The last attribute value must be a string");
- return -1;
- }
-
- Py_DECREF(self->last);
- Py_INCREF(value);
- self->last = value;
-
- return 0;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
+ return -1;
+ }
+
+ if (! PyString_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The last attribute value must be a string");
+ return -1;
+ }
+
+ Py_DECREF(self->last);
+ Py_INCREF(value);
+ self->last = value;
+
+ return 0;
}
static PyGetSetDef Noddy_getseters[] = {
- {"first",
+ {"first",
(getter)Noddy_getfirst, (setter)Noddy_setfirst,
"first name",
NULL},
- {"last",
+ {"last",
(getter)Noddy_getlast, (setter)Noddy_setlast,
"last name",
NULL},
@@ -164,7 +162,7 @@ Noddy_name(Noddy* self)
result = PyString_Format(format, args);
Py_DECREF(args);
-
+
return result;
}
@@ -176,34 +174,34 @@ static PyMethodDef Noddy_methods[] = {
};
static PyTypeObject NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(Noddy), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Noddy_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(Noddy), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Noddy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
"Noddy objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
Noddy_methods, /* tp_methods */
Noddy_members, /* tp_members */
Noddy_getseters, /* tp_getset */
@@ -225,7 +223,7 @@ static PyMethodDef module_methods[] = {
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
-initnoddy3(void)
+initnoddy3(void)
{
PyObject* m;
@@ -236,7 +234,7 @@ initnoddy3(void)
"Example module that creates an extension type.");
if (m == NULL)
- return;
+ return;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
diff --git a/Doc/includes/noddy4.c b/Doc/includes/noddy4.c
index 878e0861..0fd4dc37 100644
--- a/Doc/includes/noddy4.c
+++ b/Doc/includes/noddy4.c
@@ -27,7 +27,7 @@ Noddy_traverse(Noddy *self, visitproc visit, void *arg)
return 0;
}
-static int
+static int
Noddy_clear(Noddy *self)
{
PyObject *tmp;
@@ -46,8 +46,9 @@ Noddy_clear(Noddy *self)
static void
Noddy_dealloc(Noddy* self)
{
+ PyObject_GC_UnTrack(self);
Noddy_clear(self);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
@@ -58,18 +59,16 @@ Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self = (Noddy *)type->tp_alloc(type, 0);
if (self != NULL) {
self->first = PyString_FromString("");
- if (self->first == NULL)
- {
+ if (self->first == NULL) {
Py_DECREF(self);
return NULL;
- }
-
+ }
+
self->last = PyString_FromString("");
- if (self->last == NULL)
- {
+ if (self->last == NULL) {
Py_DECREF(self);
return NULL;
- }
+ }
self->number = 0;
}
@@ -84,10 +83,10 @@ Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
static char *kwlist[] = {"first", "last", "number", NULL};
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
+ &first, &last,
&self->number))
- return -1;
+ return -1;
if (first) {
tmp = self->first;
@@ -145,7 +144,7 @@ Noddy_name(Noddy* self)
result = PyString_Format(format, args);
Py_DECREF(args);
-
+
return result;
}
@@ -157,34 +156,35 @@ static PyMethodDef Noddy_methods[] = {
};
static PyTypeObject NoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "noddy.Noddy", /*tp_name*/
- sizeof(Noddy), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Noddy_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "noddy.Noddy", /* tp_name */
+ sizeof(Noddy), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Noddy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /* tp_flags */
"Noddy objects", /* tp_doc */
(traverseproc)Noddy_traverse, /* tp_traverse */
(inquiry)Noddy_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
Noddy_methods, /* tp_methods */
Noddy_members, /* tp_members */
0, /* tp_getset */
@@ -206,7 +206,7 @@ static PyMethodDef module_methods[] = {
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
-initnoddy4(void)
+initnoddy4(void)
{
PyObject* m;
@@ -217,7 +217,7 @@ initnoddy4(void)
"Example module that creates an extension type.");
if (m == NULL)
- return;
+ return;
Py_INCREF(&NoddyType);
PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c
index 5a7df0d9..8276b012 100644
--- a/Doc/includes/run-func.c
+++ b/Doc/includes/run-func.c
@@ -3,7 +3,7 @@
int
main(int argc, char *argv[])
{
- PyObject *pName, *pModule, *pDict, *pFunc;
+ PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
int i;
diff --git a/Doc/includes/setup.py b/Doc/includes/setup.py
index b853d23b..a38a39de 100644
--- a/Doc/includes/setup.py
+++ b/Doc/includes/setup.py
@@ -5,4 +5,5 @@
Extension("noddy2", ["noddy2.c"]),
Extension("noddy3", ["noddy3.c"]),
Extension("noddy4", ["noddy4.c"]),
+ Extension("shoddy", ["shoddy.c"]),
])
diff --git a/Doc/includes/shoddy.c b/Doc/includes/shoddy.c
index 07a41775..4cb39db3 100644
--- a/Doc/includes/shoddy.c
+++ b/Doc/includes/shoddy.c
@@ -31,8 +31,7 @@ Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
static PyTypeObject ShoddyType = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
+ PyVarObject_HEAD_INIT(NULL, 0)
"shoddy.Shoddy", /* tp_name */
sizeof(Shoddy), /* tp_basicsize */
0, /* tp_itemsize */
@@ -52,7 +51,7 @@ static PyTypeObject ShoddyType = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py
index 7f893c92..f1a92b3e 100644
--- a/Doc/includes/sqlite3/load_extension.py
+++ b/Doc/includes/sqlite3/load_extension.py
@@ -11,7 +11,7 @@
# alternatively you can load the extension using an API call:
# con.load_extension("./fts3.so")
-# disable extension laoding again
+# disable extension loading again
con.enable_load_extension(False)
# example from SQLite wiki
diff --git a/Doc/install/index.rst b/Doc/install/index.rst
index 159f8481..d391fce9 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -2,14 +2,19 @@
.. _install-index:
-*****************************
- Installing Python Modules
-*****************************
+********************************************
+ Installing Python Modules (Legacy version)
+********************************************
:Author: Greg Ward
.. TODO: Fill in XXX comments
+.. seealso::
+
+ :ref:`installing-index`
+ The up to date module installation documentations
+
.. The audience for this document includes people who don't know anything
about Python and aren't about to learn the language just in order to
install and maintain it for their users, i.e. system administrators.
@@ -20,16 +25,24 @@
Finally, it might be useful to include all the material from my "Care
and Feeding of a Python Installation" talk in here somewhere. Yow!
-.. topic:: Abstract
+This document describes the Python Distribution Utilities ("Distutils") from the
+end-user's point-of-view, describing how to extend the capabilities of a
+standard Python installation by building and installing third-party Python
+modules and extensions.
+
- This document describes the Python Distribution Utilities ("Distutils") from the
- end-user's point-of-view, describing how to extend the capabilities of a
- standard Python installation by building and installing third-party Python
- modules and extensions.
+.. note::
+
+ This guide only covers the basic tools for building and distributing
+ extensions that are provided as part of this version of Python. Third party
+ tools offer easier to use and more secure alternatives. Refer to the `quick
+ recommendations section `__
+ in the Python Packaging User Guide for more information.
.. _inst-intro:
+
Introduction
============
@@ -50,7 +63,9 @@ new goodies to their toolbox. You don't need to know Python to read this
document; there will be some brief forays into using Python's interactive mode
to explore your installation, but that's it. If you're looking for information
on how to distribute your own Python modules so that others may use them, see
-the :ref:`distutils-index` manual.
+the :ref:`distutils-index` manual. :ref:`debug-setup-script` may also be of
+interest.
+
.. _inst-trivial-install:
@@ -139,7 +154,7 @@ into. For example, if you've just downloaded a module source distribution
On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the
archive file to :file:`C:\\Temp`, then it would unpack into
-:file:`C:\\Temp\\foo-1.0`; you can use either a archive manipulator with a
+:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a
graphical user interface (such as WinZip) or a command-line tool (such as
:program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a
command prompt window and run::
@@ -187,7 +202,7 @@ As implied above, the :command:`build` command is responsible for putting the
files to install into a *build directory*. By default, this is :file:`build`
under the distribution root; if you're excessively concerned with speed, or want
to keep the source tree pristine, you can change the build directory with the
-:option:`--build-base` option. For example::
+:option:`!--build-base` option. For example::
python setup.py build --build-base=/path/to/pybuild/foo-1.0
@@ -383,7 +398,7 @@ Installing a new module distribution is as simple as ::
python setup.py install --home=
-where you can supply any directory you like for the :option:`--home` option. On
+where you can supply any directory you like for the :option:`!--home` option. On
Unix, lazy typists can just type a tilde (``~``); the :command:`install` command
will expand this to your home directory::
@@ -394,7 +409,7 @@ to :ref:`modify Python's search path ` or edit
:mod:`sitecustomize` (see :mod:`site`) to call :func:`site.addsitedir` or edit
:data:`sys.path`.
-The :option:`--home` option defines the installation base directory. Files are
+The :option:`!--home` option defines the installation base directory. Files are
installed to the following directories under the installation base as follows:
=============== ===========================================================
@@ -409,7 +424,7 @@ C headers :file:`{home}/include/python/{distname}`
(Mentally replace slashes with backslashes if you're on Windows.)
.. versionchanged:: 2.4
- The :option:`--home` option used to be supported only on Unix.
+ The :option:`!--home` option used to be supported only on Unix.
.. _inst-alt-install-prefix-unix:
@@ -442,12 +457,12 @@ be done with ::
/usr/local/bin/python setup.py install --prefix=/mnt/@server/export
-In either case, the :option:`--prefix` option defines the installation base, and
-the :option:`--exec-prefix` option defines the platform-specific installation
+In either case, the :option:`!--prefix` option defines the installation base, and
+the :option:`!--exec-prefix` option defines the platform-specific installation
base, which is used for platform-specific files. (Currently, this just means
non-pure module distributions, but could be expanded to C libraries, binary
-executables, etc.) If :option:`--exec-prefix` is not supplied, it defaults to
-:option:`--prefix`. Files are installed as follows:
+executables, etc.) If :option:`!--exec-prefix` is not supplied, it defaults to
+:option:`!--prefix`. Files are installed as follows:
================= ==========================================================
Type of file Installation directory
@@ -459,13 +474,13 @@ data :file:`{prefix}`
C headers :file:`{prefix}/include/python{X.Y}/{distname}`
================= ==========================================================
-There is no requirement that :option:`--prefix` or :option:`--exec-prefix`
+There is no requirement that :option:`!--prefix` or :option:`!--exec-prefix`
actually point to an alternate Python installation; if the directories listed
above do not already exist, they are created at installation time.
Incidentally, the real reason the prefix scheme is important is simply that a
-standard Unix installation uses the prefix scheme, but with :option:`--prefix`
-and :option:`--exec-prefix` supplied by Python itself as ``sys.prefix`` and
+standard Unix installation uses the prefix scheme, but with :option:`!--prefix`
+and :option:`!--exec-prefix` supplied by Python itself as ``sys.prefix`` and
``sys.exec_prefix``. Thus, you might think you'll never use the prefix scheme,
but every time you run ``python setup.py install`` without any other options,
you're using it.
@@ -478,7 +493,7 @@ responsibility to ensure that the interpreter used to run extensions installed
in this way is compatible with the interpreter used to build them. The best way
to do this is to ensure that the two interpreters are the same version of Python
(possibly different builds, or possibly copies of the same build). (Of course,
-if your :option:`--prefix` and :option:`--exec-prefix` don't even point to an
+if your :option:`!--prefix` and :option:`!--exec-prefix` don't even point to an
alternate Python installation, this is immaterial.)
@@ -488,7 +503,7 @@ Alternate installation: Windows (the prefix scheme)
---------------------------------------------------
Windows has no concept of a user's home directory, and since the standard Python
-installation under Windows is simpler than under Unix, the :option:`--prefix`
+installation under Windows is simpler than under Unix, the :option:`!--prefix`
option has traditionally been used to install additional packages in separate
locations on Windows. ::
@@ -496,8 +511,8 @@ locations on Windows. ::
to install modules to the :file:`\\Temp\\Python` directory on the current drive.
-The installation base is defined by the :option:`--prefix` option; the
-:option:`--exec-prefix` option is not supported under Windows, which means that
+The installation base is defined by the :option:`!--prefix` option; the
+:option:`!--exec-prefix` option is not supported under Windows, which means that
pure Python modules and extension modules are installed into the same location.
Files are installed as follows:
@@ -549,7 +564,7 @@ difference between Python and extension modules.)
For example, say you're installing a module distribution to your home directory
under Unix---but you want scripts to go in :file:`~/scripts` rather than
:file:`~/bin`. As you might expect, you can override this directory with the
-:option:`--install-scripts` option; in this case, it makes most sense to supply
+:option:`!--install-scripts` option; in this case, it makes most sense to supply
a relative path, which will be interpreted relative to the installation base
directory (your home directory, in this case)::
@@ -559,7 +574,7 @@ Another Unix example: suppose your Python installation was built and installed
with a prefix of :file:`/usr/local/python`, so under a standard installation
scripts will wind up in :file:`/usr/local/python/bin`. If you want them in
:file:`/usr/local/bin` instead, you would supply this absolute directory for the
-:option:`--install-scripts` option::
+:option:`!--install-scripts` option::
python setup.py install --install-scripts=/usr/local/bin
@@ -852,12 +867,12 @@ config file will apply. (Or if other commands that derive values from it are
run, they will use the values in the config file.)
You can find out the complete list of options for any command using the
-:option:`--help` option, e.g.::
+:option:`!--help` option, e.g.::
python setup.py build --help
and you can find out the complete list of global options by using
-:option:`--help` without a command::
+:option:`!--help` without a command::
python setup.py --help
@@ -914,10 +929,10 @@ Let's examine each of the fields in turn.
to be in Objective C.
* *cpparg* is an argument for the C preprocessor, and is anything starting with
- :option:`-I`, :option:`-D`, :option:`-U` or :option:`-C`.
+ :option:`!-I`, :option:`!-D`, :option:`!-U` or :option:`!-C`.
-* *library* is anything ending in :file:`.a` or beginning with :option:`-l` or
- :option:`-L`.
+* *library* is anything ending in :file:`.a` or beginning with :option:`!-l` or
+ :option:`!-L`.
If a particular platform requires a special library on your platform, you can
add it by editing the :file:`Setup` file and running ``python setup.py build``.
@@ -926,20 +941,20 @@ For example, if the module defined by the line ::
foo foomodule.c
must be linked with the math library :file:`libm.a` on your platform, simply add
-:option:`-lm` to the line::
+:option:`!-lm` to the line::
foo foomodule.c -lm
Arbitrary switches intended for the compiler or the linker can be supplied with
-the :option:`-Xcompiler` *arg* and :option:`-Xlinker` *arg* options::
+the :option:`!-Xcompiler` *arg* and :option:`!-Xlinker` *arg* options::
foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm
-The next option after :option:`-Xcompiler` and :option:`-Xlinker` will be
+The next option after :option:`!-Xcompiler` and :option:`!-Xlinker` will be
appended to the proper command line, so in the above example the compiler will
-be passed the :option:`-o32` option, and the linker will be passed
-:option:`-shared`. If a compiler option requires an argument, you'll have to
-supply multiple :option:`-Xcompiler` options; for example, to pass ``-x c++``
+be passed the :option:`!-o32` option, and the linker will be passed
+:option:`!-shared`. If a compiler option requires an argument, you'll have to
+supply multiple :option:`!-Xcompiler` options; for example, to pass ``-x c++``
the :file:`Setup` file would have to contain ``-Xcompiler -x -Xcompiler c++``.
Compiler flags can also be supplied through setting the :envvar:`CFLAGS`
@@ -999,7 +1014,7 @@ section :ref:`inst-config-files`.)
.. seealso::
- `C++Builder Compiler