From 16c2587ce817afcb2c78eb5a6dae7703daa44241 Mon Sep 17 00:00:00 2001
From: Hyunjee Kim
Date: Wed, 20 Mar 2019 10:55:20 +0900
Subject: [PATCH] Imported Upstream version 3.6.6
---
.vsts/docs-release.yml | 43 +
.vsts/docs.yml | 44 +
.vsts/linux-buildbot.yml | 64 ++
.vsts/linux-coverage.yml | 70 ++
.vsts/linux-deps.yml | 30 +
.vsts/linux-pr.yml | 68 ++
.vsts/macos-buildbot.yml | 37 +
.vsts/macos-pr.yml | 37 +
.vsts/windows-buildbot.yml | 49 +
.vsts/windows-pr.yml | 49 +
Doc/c-api/arg.rst | 27 +-
Doc/c-api/buffer.rst | 12 +-
Doc/c-api/capsule.rst | 11 +-
Doc/c-api/gcsupport.rst | 2 +-
Doc/c-api/mapping.rst | 66 +-
Doc/c-api/module.rst | 12 +-
Doc/c-api/object.rst | 8 +-
Doc/c-api/sequence.rst | 31 +-
Doc/c-api/typeobj.rst | 56 +-
Doc/distributing/index.rst | 2 +-
Doc/distutils/apiref.rst | 2 +-
Doc/distutils/configfile.rst | 22 +-
Doc/distutils/introduction.rst | 4 +-
Doc/distutils/packageindex.rst | 10 +-
Doc/distutils/setupscript.rst | 2 +-
Doc/extending/embedding.rst | 2 +-
Doc/extending/extending.rst | 12 +-
Doc/extending/index.rst | 9 +-
Doc/extending/newtypes.rst | 1143 ++-----------------
Doc/extending/newtypes_tutorial.rst | 896 +++++++++++++++
Doc/faq/general.rst | 2 +-
Doc/faq/library.rst | 8 +-
Doc/faq/windows.rst | 26 +-
Doc/glossary.rst | 131 ++-
Doc/howto/argparse.rst | 38 +-
Doc/howto/clinic.rst | 72 +-
Doc/howto/curses.rst | 6 +-
Doc/howto/instrumentation.rst | 8 +-
Doc/howto/logging-cookbook.rst | 62 +-
Doc/howto/logging.rst | 46 +-
Doc/howto/pyporting.rst | 14 +-
Doc/howto/regex.rst | 4 +-
Doc/howto/unicode.rst | 4 +-
Doc/howto/urllib2.rst | 24 +-
Doc/includes/custom.c | 39 +
Doc/includes/custom2.c | 132 +++
Doc/includes/custom3.c | 183 ++++
Doc/includes/custom4.c | 197 ++++
Doc/includes/noddy.c | 56 -
Doc/includes/noddy2.c | 172 ---
Doc/includes/noddy3.c | 225 ----
Doc/includes/noddy4.c | 208 ----
Doc/includes/shoddy.c | 99 --
Doc/includes/sublist.c | 63 ++
Doc/includes/test.py | 218 ++--
Doc/install/index.rst | 24 +-
Doc/installing/index.rst | 2 +-
Doc/library/argparse.rst | 6 +-
Doc/library/asyncio-eventloop.rst | 3 +
Doc/library/asyncio-eventloops.rst | 5 +-
Doc/library/asyncio-task.rst | 4 +
Doc/library/binascii.rst | 2 +-
Doc/library/codecs.rst | 4 +-
Doc/library/configparser.rst | 4 -
Doc/library/csv.rst | 5 +-
Doc/library/curses.rst | 12 +
Doc/library/datetime.rst | 3 +-
Doc/library/distribution.rst | 2 +-
Doc/library/email.contentmanager.rst | 9 -
Doc/library/email.examples.rst | 2 +-
Doc/library/email.generator.rst | 2 +-
Doc/library/faulthandler.rst | 6 +-
Doc/library/ftplib.rst | 2 +-
Doc/library/functions.rst | 23 +-
Doc/library/hashlib.rst | 3 +-
Doc/library/http.cookiejar.rst | 38 +-
Doc/library/idle.rst | 3 +-
Doc/library/imaplib.rst | 2 +-
Doc/library/importlib.rst | 2 +-
Doc/library/index.rst | 2 +-
Doc/library/io.rst | 2 +-
Doc/library/ipaddress.rst | 75 +-
Doc/library/itertools.rst | 28 +-
Doc/library/json.rst | 26 +-
Doc/library/logging.config.rst | 17 +-
Doc/library/logging.handlers.rst | 4 +-
Doc/library/logging.rst | 30 +-
Doc/library/mmap.rst | 2 +-
Doc/library/multiprocessing.rst | 28 +-
Doc/library/nntplib.rst | 2 +-
Doc/library/os.rst | 14 +-
Doc/library/pickle.rst | 2 +-
Doc/library/platform.rst | 6 +-
Doc/library/pprint.rst | 20 +-
Doc/library/profile.rst | 11 +-
Doc/library/re.rst | 20 +-
Doc/library/site.rst | 2 +-
Doc/library/ssl.rst | 57 +-
Doc/library/stringprep.rst | 2 +-
Doc/library/subprocess.rst | 7 +-
Doc/library/timeit.rst | 6 +-
Doc/library/tkinter.rst | 66 +-
Doc/library/tokenize.rst | 4 +-
Doc/library/typing.rst | 19 +
Doc/library/unittest.mock.rst | 4 +-
Doc/library/unittest.rst | 24 +-
Doc/library/urllib.error.rst | 3 +-
Doc/library/urllib.request.rst | 4 +-
Doc/library/uuid.rst | 23 +-
Doc/library/venv.rst | 3 +-
Doc/library/wsgiref.rst | 2 +-
Doc/library/xml.rst | 4 +-
Doc/library/xmlrpc.client.rst | 2 +-
Doc/library/zipapp.rst | 177 ++-
Doc/make.bat | 24 +-
Doc/reference/datamodel.rst | 4 +-
Doc/reference/expressions.rst | 4 +-
Doc/reference/import.rst | 3 +-
Doc/reference/lexical_analysis.rst | 11 +-
Doc/tools/extensions/pyspecific.py | 12 +-
Doc/tools/static/switchers.js | 3 +-
Doc/tools/templates/indexsidebar.html | 4 +-
Doc/tutorial/appendix.rst | 2 +-
Doc/tutorial/controlflow.rst | 4 +-
Doc/tutorial/interpreter.rst | 4 +-
Doc/tutorial/modules.rst | 2 +-
Doc/tutorial/stdlib.rst | 2 +-
Doc/tutorial/venv.rst | 2 +-
Doc/tutorial/whatnow.rst | 2 +-
Doc/using/cmdline.rst | 12 +-
Doc/using/unix.rst | 4 +-
Doc/using/windows.rst | 22 +-
Doc/whatsnew/2.3.rst | 2 +-
Doc/whatsnew/2.4.rst | 2 +-
Doc/whatsnew/2.5.rst | 2 +-
Doc/whatsnew/2.6.rst | 2 +-
Doc/whatsnew/2.7.rst | 189 +++-
Doc/whatsnew/3.5.rst | 38 +-
Doc/whatsnew/3.6.rst | 83 +-
Include/patchlevel.h | 4 +-
Lib/argparse.py | 6 +-
Lib/asyncio/base_events.py | 6 +-
Lib/asyncio/coroutines.py | 23 +-
Lib/asyncio/events.py | 8 +-
Lib/asyncio/futures.py | 3 +
Lib/asyncio/proactor_events.py | 6 +-
Lib/asyncio/selector_events.py | 16 +-
Lib/asyncio/sslproto.py | 2 +-
Lib/asyncio/tasks.py | 13 +-
Lib/cgitb.py | 4 +-
Lib/ctypes/test/test_arrays.py | 7 +
Lib/ctypes/test/test_cast.py | 13 +
Lib/datetime.py | 9 +-
Lib/difflib.py | 20 +-
Lib/ensurepip/__init__.py | 12 +-
.../_bundled/pip-10.0.1-py2.py3-none-any.whl | Bin 0 -> 1307639 bytes
.../_bundled/pip-9.0.3-py2.py3-none-any.whl | Bin 1400985 -> 0 bytes
Lib/enum.py | 2 +-
Lib/http/cookies.py | 2 +
Lib/idlelib/NEWS.txt | 76 +-
Lib/idlelib/codecontext.py | 205 ++--
Lib/idlelib/colorizer.py | 25 +-
Lib/idlelib/config-extensions.def | 5 +-
Lib/idlelib/config-highlight.def | 6 +
Lib/idlelib/config.py | 2 +
Lib/idlelib/configdialog.py | 44 +-
Lib/idlelib/editor.py | 37 +-
Lib/idlelib/help.html | 408 +++----
Lib/idlelib/idle_test/test_codecontext.py | 407 +++++++
Lib/idlelib/idle_test/test_configdialog.py | 2 +-
Lib/idlelib/idle_test/test_editmenu.py | 2 +-
Lib/idlelib/idle_test/test_text.py | 2 +-
Lib/idlelib/pyshell.py | 11 +
Lib/inspect.py | 47 +-
Lib/ipaddress.py | 109 +-
Lib/json/scanner.py | 2 +-
Lib/lib2to3/main.py | 2 +-
Lib/locale.py | 55 +-
Lib/logging/__init__.py | 17 +-
Lib/pydoc.py | 15 +-
Lib/pydoc_data/topics.py | 903 ++++++++-------
Lib/random.py | 2 +
Lib/shelve.py | 2 +-
Lib/site.py | 4 +-
Lib/socketserver.py | 29 +-
Lib/tempfile.py | 6 +-
Lib/test/_test_multiprocessing.py | 63 +-
Lib/test/bisect.py | 6 +-
Lib/test/datetimetester.py | 25 +-
Lib/test/libregrtest/cmdline.py | 2 +-
Lib/test/libregrtest/main.py | 108 +-
Lib/test/libregrtest/refleak.py | 32 +-
Lib/test/libregrtest/runtest.py | 3 +
Lib/test/libregrtest/runtest_mp.py | 8 +-
Lib/test/libregrtest/save_env.py | 8 +-
Lib/test/libregrtest/utils.py | 47 +
Lib/test/lock_tests.py | 26 +-
Lib/test/pickletester.py | 35 +-
Lib/test/pythoninfo.py | 37 +
Lib/test/signalinterproctester.py | 11 +-
Lib/test/support/__init__.py | 129 ++-
Lib/test/test_argparse.py | 42 +-
Lib/test/test_asyncgen.py | 56 +
Lib/test/test_asyncio/test_base_events.py | 1 +
Lib/test/test_asyncio/test_events.py | 40 +
Lib/test/test_asyncio/test_proactor_events.py | 9 +-
Lib/test/test_asyncio/test_selector_events.py | 21 +
Lib/test/test_asyncio/test_sslproto.py | 2 +-
Lib/test/test_asyncio/test_subprocess.py | 1 +
Lib/test/test_asyncio/test_tasks.py | 35 +-
Lib/test/test_bdb.py | 1153 ++++++++++++++++++++
Lib/test/test_cgitb.py | 1 +
Lib/test/test_coroutines.py | 85 +-
Lib/test/test_dbm.py | 32 +-
Lib/test/test_dbm_dumb.py | 9 +
Lib/test/test_dbm_gnu.py | 5 +-
Lib/test/test_dbm_ndbm.py | 24 +-
Lib/test/test_decimal.py | 22 +-
Lib/test/test_difflib.py | 8 +
Lib/test/test_dis.py | 2 +-
Lib/test/test_file.py | 162 ++-
Lib/test/test_fileinput.py | 214 ++--
Lib/test/test_generators.py | 8 +-
Lib/test/test_http_cookies.py | 10 +
Lib/test/test_idle.py | 16 +-
Lib/test/test_importlib/extension/test_loader.py | 25 +-
Lib/test/test_inspect.py | 25 +-
Lib/test/test_io.py | 7 +
Lib/test/test_ipaddress.py | 29 +-
Lib/test/test_itertools.py | 75 ++
Lib/test/test_json/test_decode.py | 4 +-
Lib/test/test_locale.py | 2 +-
Lib/test/test_logging.py | 7 +-
Lib/test/test_mmap.py | 7 +
Lib/test/test_parser.py | 29 +-
Lib/test/test_pathlib.py | 5 +-
Lib/test/test_poplib.py | 11 +-
Lib/test/test_posix.py | 7 +-
Lib/test/test_profile.py | 17 +-
Lib/test/test_pty.py | 9 +-
Lib/test/test_random.py | 5 +-
Lib/test/test_regrtest.py | 59 +-
Lib/test/test_robotparser.py | 27 +
Lib/test/test_selectors.py | 49 +-
Lib/test/test_socket.py | 29 +-
Lib/test/test_socketserver.py | 52 +-
Lib/test/test_ssl.py | 1 +
Lib/test/test_subprocess.py | 50 +
Lib/test/test_sundry.py | 3 +-
Lib/test/test_support.py | 11 +
Lib/test/test_sys_settrace.py | 190 +++-
Lib/test/test_thread.py | 93 +-
Lib/test/test_threading.py | 14 +-
Lib/test/test_threadsignals.py | 102 +-
Lib/test/test_tools/test_i18n.py | 97 +-
Lib/test/test_trace.py | 41 +
Lib/test/test_typing.py | 70 ++
Lib/test/test_urllib2net.py | 1 +
Lib/test/test_uu.py | 104 +-
Lib/test/test_xml_etree.py | 8 +-
Lib/test/test_xmlrpc.py | 10 +-
Lib/threading.py | 2 +-
Lib/tkinter/__init__.py | 4 +-
Lib/tkinter/test/test_ttk/test_widgets.py | 9 +
Lib/tkinter/ttk.py | 2 +-
Lib/trace.py | 39 +-
Lib/typing.py | 13 +-
Lib/unittest/mock.py | 2 +-
Lib/unittest/test/test_discovery.py | 39 +-
Lib/urllib/robotparser.py | 18 +-
Lib/uuid.py | 2 +-
Mac/BuildScript/build-installer.py | 10 +-
Mac/BuildScript/resources/ReadMe.rtf | 28 +-
Mac/BuildScript/resources/Welcome.rtf | 7 +-
.../resources/install_certificates.command | 2 +-
Mac/BuildScript/scripts/postflight.ensurepip | 5 +
Mac/Makefile.in | 4 -
Makefile.pre.in | 6 +-
Misc/ACKS | 6 +
Misc/NEWS | 579 +++++++---
Misc/gdbinit | 14 +-
Misc/python.man | 2 +-
Modules/_asynciomodule.c | 12 +-
Modules/_collectionsmodule.c | 7 +-
Modules/_ctypes/_ctypes.c | 18 +-
Modules/_datetimemodule.c | 11 +
Modules/_dbmmodule.c | 4 +-
Modules/_pickle.c | 5 +-
Modules/_posixsubprocess.c | 2 +-
Modules/_sqlite/connection.c | 4 +-
Modules/_ssl.c | 24 +-
Modules/_testmultiphase.c | 55 +-
Modules/audioop.c | 28 +-
Modules/clinic/_dbmmodule.c.h | 6 +-
Modules/gcmodule.c | 20 +-
Modules/mmapmodule.c | 37 +-
Modules/parsermodule.c | 6 +-
Modules/signalmodule.c | 28 +-
Modules/socketmodule.c | 10 -
Modules/xxlimited.c | 3 +-
Modules/xxsubtype.c | 2 +-
Objects/dictobject.c | 1 +
Objects/floatobject.c | 5 +-
Objects/genobject.c | 15 +-
Objects/moduleobject.c | 21 +
Objects/setobject.c | 4 +-
Objects/typeobject.c | 4 +-
PCbuild/find_msbuild.bat | 11 +-
PCbuild/get_externals.bat | 2 +-
PCbuild/python.props | 2 +-
PCbuild/python3dll.vcxproj | 20 +-
PCbuild/readme.txt | 2 +-
PCbuild/rt.bat | 13 +-
Parser/asdl_c.py | 3 +-
Python/Python-ast.c | 3 +-
Python/_warnings.c | 7 +
Python/ceval.c | 27 +-
Python/codecs.c | 2 -
Python/compile.c | 74 +-
Python/import.c | 28 +-
Python/pyhash.c | 30 +-
Python/random.c | 7 +-
README.rst | 21 +-
Tools/i18n/pygettext.py | 44 +-
Tools/scripts/checkpip.py | 2 +-
Tools/scripts/patchcheck.py | 24 +-
Tools/scripts/pathfix.py | 28 +-
Tools/ssl/multissltests.py | 17 +-
configure | 91 +-
configure.ac | 49 +-
330 files changed, 9488 insertions(+), 4660 deletions(-)
create mode 100644 .vsts/docs-release.yml
create mode 100644 .vsts/docs.yml
create mode 100644 .vsts/linux-buildbot.yml
create mode 100644 .vsts/linux-coverage.yml
create mode 100644 .vsts/linux-deps.yml
create mode 100644 .vsts/linux-pr.yml
create mode 100644 .vsts/macos-buildbot.yml
create mode 100644 .vsts/macos-pr.yml
create mode 100644 .vsts/windows-buildbot.yml
create mode 100644 .vsts/windows-pr.yml
create mode 100644 Doc/extending/newtypes_tutorial.rst
create mode 100644 Doc/includes/custom.c
create mode 100644 Doc/includes/custom2.c
create mode 100644 Doc/includes/custom3.c
create mode 100644 Doc/includes/custom4.c
delete mode 100644 Doc/includes/noddy.c
delete mode 100644 Doc/includes/noddy2.c
delete mode 100644 Doc/includes/noddy3.c
delete mode 100644 Doc/includes/noddy4.c
delete mode 100644 Doc/includes/shoddy.c
create mode 100644 Doc/includes/sublist.c
create mode 100644 Lib/ensurepip/_bundled/pip-10.0.1-py2.py3-none-any.whl
delete mode 100644 Lib/ensurepip/_bundled/pip-9.0.3-py2.py3-none-any.whl
create mode 100644 Lib/idlelib/idle_test/test_codecontext.py
create mode 100644 Lib/test/libregrtest/utils.py
create mode 100644 Lib/test/test_bdb.py
diff --git a/.vsts/docs-release.yml b/.vsts/docs-release.yml
new file mode 100644
index 0000000..e90428a
--- /dev/null
+++ b/.vsts/docs-release.yml
@@ -0,0 +1,43 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted Linux Preview
+
+#variables:
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- script: sudo apt-get update && sudo apt-get install -qy --force-yes texlive-full
+ displayName: 'Install LaTeX'
+
+- task: UsePythonVersion@0
+ displayName: 'Use Python 3.6 or later'
+ inputs:
+ versionSpec: '>=3.6'
+
+- script: python -m pip install sphinx blurb python-docs-theme
+ displayName: 'Install build dependencies'
+
+- script: make dist PYTHON=python SPHINXBUILD='python -m sphinx' BLURB='python -m blurb'
+ workingDirectory: '$(build.sourcesDirectory)/Doc'
+ displayName: 'Build documentation'
+
+- task: PublishBuildArtifacts@1
+ displayName: 'Publish build'
+ inputs:
+ PathToPublish: '$(build.sourcesDirectory)/Doc/build'
+ ArtifactName: build
+ publishLocation: Container
+
+- task: PublishBuildArtifacts@1
+ displayName: 'Publish dist'
+ inputs:
+ PathToPublish: '$(build.sourcesDirectory)/Doc/dist'
+ ArtifactName: dist
+ publishLocation: Container
diff --git a/.vsts/docs.yml b/.vsts/docs.yml
new file mode 100644
index 0000000..62f6123
--- /dev/null
+++ b/.vsts/docs.yml
@@ -0,0 +1,44 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted Linux Preview
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ include:
+ - Doc/*
+
+#variables:
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- task: UsePythonVersion@0
+ displayName: 'Use Python 3.6 or later'
+ inputs:
+ versionSpec: '>=3.6'
+
+- script: python -m pip install sphinx~=1.6.1 blurb python-docs-theme
+ displayName: 'Install build dependencies'
+
+- script: make check suspicious html PYTHON=python
+ workingDirectory: '$(build.sourcesDirectory)/Doc'
+ displayName: 'Build documentation'
+
+- task: PublishBuildArtifacts@1
+ displayName: 'Publish build'
+ condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
+ inputs:
+ PathToPublish: '$(build.sourcesDirectory)/Doc/build'
+ ArtifactName: build
+ publishLocation: Container
diff --git a/.vsts/linux-buildbot.yml b/.vsts/linux-buildbot.yml
new file mode 100644
index 0000000..76222d1
--- /dev/null
+++ b/.vsts/linux-buildbot.yml
@@ -0,0 +1,64 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted Linux Preview
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ exclude:
+ - Doc/*
+ - Tools/*
+
+#variables:
+
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+#- template: linux-deps.yml
+
+# See https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted-templates.md
+# For now, we copy/paste the steps
+- script: echo "deb-src http://archive.ubuntu.com/ubuntu/ xenial main" > /etc/apt/sources.list.d/python.list && sudo apt-get update
+ displayName: 'Update apt-get lists'
+
+- script: >
+ sudo apt-get -yq install
+ build-essential
+ zlib1g-dev
+ libbz2-dev
+ liblzma-dev
+ libncurses5-dev
+ libreadline6-dev
+ libsqlite3-dev
+ libssl-dev
+ libgdbm-dev
+ tk-dev
+ lzma
+ lzma-dev
+ liblzma-dev
+ libffi-dev
+ uuid-dev
+ displayName: 'Install dependencies'
+
+- script: ./configure --with-pydebug
+ displayName: 'Configure CPython (debug)'
+
+- script: make -s -j4
+ displayName: 'Build CPython'
+
+- script: make pythoninfo
+ displayName: 'Display build info'
+
+- script: make buildbottest TESTOPTS="-j4 -uall,-cpu"
+ displayName: 'Tests'
diff --git a/.vsts/linux-coverage.yml b/.vsts/linux-coverage.yml
new file mode 100644
index 0000000..d16d9c9
--- /dev/null
+++ b/.vsts/linux-coverage.yml
@@ -0,0 +1,70 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted Linux Preview
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ exclude:
+ - Doc/*
+ - Tools/*
+
+#variables:
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+#- template: linux-deps.yml
+
+# See https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted-templates.md
+# For now, we copy/paste the steps
+- script: echo "deb-src http://archive.ubuntu.com/ubuntu/ xenial main" > /etc/apt/sources.list.d/python.list && sudo apt-get update
+ displayName: 'Update apt-get lists'
+
+- script: >
+ sudo apt-get -yq install
+ build-essential
+ zlib1g-dev
+ libbz2-dev
+ liblzma-dev
+ libncurses5-dev
+ libreadline6-dev
+ libsqlite3-dev
+ libssl-dev
+ libgdbm-dev
+ tk-dev
+ lzma
+ lzma-dev
+ liblzma-dev
+ libffi-dev
+ uuid-dev
+ displayName: 'Install dependencies'
+
+
+- script: ./configure --with-pydebug
+ displayName: 'Configure CPython (debug)'
+
+- script: make -s -j4
+ displayName: 'Build CPython'
+
+- script: ./python -m venv venv && ./venv/bin/python -m pip install -U coverage
+ displayName: 'Set up virtual environment'
+
+- script: ./venv/bin/python -m test.pythoninfo
+ displayName: 'Display build info'
+
+- script: ./venv/bin/python -m coverage run --pylib -m test -uall,-cpu -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn -x test_concurrent_futures
+ displayName: 'Tests with coverage'
+
+- script: source ./venv/bin/activate && bash <(curl -s https://codecov.io/bash)
+ displayName: 'Publish code coverage results'
diff --git a/.vsts/linux-deps.yml b/.vsts/linux-deps.yml
new file mode 100644
index 0000000..540b76e
--- /dev/null
+++ b/.vsts/linux-deps.yml
@@ -0,0 +1,30 @@
+# Note: this file is not currently used, but when template support comes to VSTS it
+# will be referenced from the other scripts..
+
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+#parameters:
+
+steps:
+- script: echo "deb-src http://archive.ubuntu.com/ubuntu/ xenial main" > /etc/apt/sources.list.d/python.list && sudo apt-get update
+ displayName: 'Update apt-get lists'
+
+- script: >
+ sudo apt-get -yq install
+ build-essential
+ zlib1g-dev
+ libbz2-dev
+ liblzma-dev
+ libncurses5-dev
+ libreadline6-dev
+ libsqlite3-dev
+ libssl-dev
+ libgdbm-dev
+ tk-dev
+ lzma
+ lzma-dev
+ liblzma-dev
+ libffi-dev
+ uuid-dev
+ displayName: 'Install dependencies'
diff --git a/.vsts/linux-pr.yml b/.vsts/linux-pr.yml
new file mode 100644
index 0000000..83df9b4
--- /dev/null
+++ b/.vsts/linux-pr.yml
@@ -0,0 +1,68 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted Linux Preview
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ exclude:
+ - Doc/*
+ - Tools/*
+
+#variables:
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+#- template: linux-deps.yml
+
+# See https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted-templates.md
+# For now, we copy/paste the steps
+- script: echo "deb-src http://archive.ubuntu.com/ubuntu/ xenial main" > /etc/apt/sources.list.d/python.list && sudo apt-get update
+ displayName: 'Update apt-get lists'
+
+- script: >
+ sudo apt-get -yq install
+ build-essential
+ zlib1g-dev
+ libbz2-dev
+ liblzma-dev
+ libncurses5-dev
+ libreadline6-dev
+ libsqlite3-dev
+ libssl-dev
+ libgdbm-dev
+ tk-dev
+ lzma
+ lzma-dev
+ liblzma-dev
+ libffi-dev
+ uuid-dev
+ displayName: 'Install dependencies'
+
+
+- script: ./configure --with-pydebug
+ displayName: 'Configure CPython (debug)'
+
+- script: make -s -j4
+ displayName: 'Build CPython'
+
+- script: make pythoninfo
+ displayName: 'Display build info'
+
+# Run patchcheck and fail if anything is discovered
+- script: ./python Tools/scripts/patchcheck.py --travis true
+ displayName: 'Run patchcheck.py'
+
+- script: make buildbottest TESTOPTS="-j4 -uall,-cpu"
+ displayName: 'Tests'
diff --git a/.vsts/macos-buildbot.yml b/.vsts/macos-buildbot.yml
new file mode 100644
index 0000000..8a4f6ba
--- /dev/null
+++ b/.vsts/macos-buildbot.yml
@@ -0,0 +1,37 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted macOS Preview
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ exclude:
+ - Doc/*
+ - Tools/*
+
+#variables:
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl
+ displayName: 'Configure CPython (debug)'
+
+- script: make -s -j4
+ displayName: 'Build CPython'
+
+- script: make pythoninfo
+ displayName: 'Display build info'
+
+- script: make buildbottest TESTOPTS="-j4 -uall,-cpu"
+ displayName: 'Tests'
diff --git a/.vsts/macos-pr.yml b/.vsts/macos-pr.yml
new file mode 100644
index 0000000..8a4f6ba
--- /dev/null
+++ b/.vsts/macos-pr.yml
@@ -0,0 +1,37 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted macOS Preview
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ exclude:
+ - Doc/*
+ - Tools/*
+
+#variables:
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- script: ./configure --with-pydebug --with-openssl=/usr/local/opt/openssl
+ displayName: 'Configure CPython (debug)'
+
+- script: make -s -j4
+ displayName: 'Build CPython'
+
+- script: make pythoninfo
+ displayName: 'Display build info'
+
+- script: make buildbottest TESTOPTS="-j4 -uall,-cpu"
+ displayName: 'Tests'
diff --git a/.vsts/windows-buildbot.yml b/.vsts/windows-buildbot.yml
new file mode 100644
index 0000000..5ec4522
--- /dev/null
+++ b/.vsts/windows-buildbot.yml
@@ -0,0 +1,49 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted VS2017
+ parallel: 2
+ matrix:
+ amd64:
+ buildOpt: -p x64
+ outDirSuffix: amd64
+ win32:
+ buildOpt:
+ outDirSuffix: win32
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ exclude:
+ - Doc/*
+ - Tools/*
+
+variables:
+ # Relocate build outputs outside of source directory to make cleaning faster
+ Py_IntDir: $(Build.BinariesDirectory)\obj
+ # UNDONE: Do not build to a different directory because of broken tests
+ Py_OutDir: $(Build.SourcesDirectory)\PCbuild
+ EXTERNAL_DIR: $(Build.BinariesDirectory)\externals
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- script: PCbuild\build.bat -e $(buildOpt)
+ displayName: 'Build CPython'
+
+- script: python.bat -m test.pythoninfo
+ displayName: 'Display build info'
+
+- script: PCbuild\rt.bat -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
+ displayName: 'Tests'
+ env:
+ PREFIX: $(Py_OutDir)\$(outDirSuffix)
diff --git a/.vsts/windows-pr.yml b/.vsts/windows-pr.yml
new file mode 100644
index 0000000..5ec4522
--- /dev/null
+++ b/.vsts/windows-pr.yml
@@ -0,0 +1,49 @@
+# Current docs for the syntax of this file are at:
+# https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted.md
+
+name: $(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.rr)
+
+queue:
+ name: Hosted VS2017
+ parallel: 2
+ matrix:
+ amd64:
+ buildOpt: -p x64
+ outDirSuffix: amd64
+ win32:
+ buildOpt:
+ outDirSuffix: win32
+
+trigger:
+ branches:
+ include:
+ - master
+ - 3.7
+ - 3.6
+ paths:
+ exclude:
+ - Doc/*
+ - Tools/*
+
+variables:
+ # Relocate build outputs outside of source directory to make cleaning faster
+ Py_IntDir: $(Build.BinariesDirectory)\obj
+ # UNDONE: Do not build to a different directory because of broken tests
+ Py_OutDir: $(Build.SourcesDirectory)\PCbuild
+ EXTERNAL_DIR: $(Build.BinariesDirectory)\externals
+
+steps:
+- checkout: self
+ clean: true
+ fetchDepth: 5
+
+- script: PCbuild\build.bat -e $(buildOpt)
+ displayName: 'Build CPython'
+
+- script: python.bat -m test.pythoninfo
+ displayName: 'Display build info'
+
+- script: PCbuild\rt.bat -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
+ displayName: 'Tests'
+ env:
+ PREFIX: $(Py_OutDir)\$(outDirSuffix)
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index e8e7e0d..dc58e15 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -151,19 +151,35 @@ which disallows mutable objects such as :class:`bytearray`.
Previously, :exc:`TypeError` was raised when embedded null code points
were encountered in the Python string.
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
+
``u#`` (:class:`str`) [Py_UNICODE \*, int]
This variant on ``u`` stores into two C variables, the first one a pointer to a
Unicode data buffer, the second one its length. This variant allows
null code points.
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
+
``Z`` (:class:`str` or ``None``) [Py_UNICODE \*]
Like ``u``, but the Python object may also be ``None``, in which case the
:c:type:`Py_UNICODE` pointer is set to *NULL*.
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
+
``Z#`` (:class:`str` or ``None``) [Py_UNICODE \*, int]
Like ``u#``, but the Python object may also be ``None``, in which case the
:c:type:`Py_UNICODE` pointer is set to *NULL*.
+ .. deprecated-removed:: 3.3 4.0
+ Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using
+ :c:func:`PyUnicode_AsWideCharString`.
+
``U`` (:class:`str`) [PyObject \*]
Requires that the Python object is a Unicode object, without attempting
any conversion. Raises :exc:`TypeError` if the object is not a Unicode
@@ -552,12 +568,13 @@ Building values
``z#`` (:class:`str` or ``None``) [char \*, int]
Same as ``s#``.
- ``u`` (:class:`str`) [Py_UNICODE \*]
- Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python
- Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned.
+ ``u`` (:class:`str`) [wchar_t \*]
+ Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4)
+ data to a Python Unicode object. If the Unicode buffer pointer is *NULL*,
+ ``None`` is returned.
- ``u#`` (:class:`str`) [Py_UNICODE \*, int]
- Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python
+ ``u#`` (:class:`str`) [wchar_t \*, int]
+ Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python
Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored
and ``None`` is returned.
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index 8c2de96..5a9a46f 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -473,6 +473,15 @@ Buffer-related functions
(*order* is ``'A'``). Return ``0`` otherwise.
+.. c:function:: int PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
+
+ Copy *len* bytes from *src* to its contiguous representation in *buf*.
+ *order* can be ``'C'`` or ``'F'`` (for C-style or Fortran-style ordering).
+ ``0`` is returned on success, ``-1`` on error.
+
+ This function fails if *len* != *src->len*.
+
+
.. c:function:: void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, int itemsize, char order)
Fill the *strides* array with byte-strides of a :term:`contiguous` (C-style if
@@ -497,6 +506,3 @@ Buffer-related functions
If this function is used as part of a :ref:`getbufferproc `,
*exporter* MUST be set to the exporting object and *flags* must be passed
unmodified. Otherwise, *exporter* MUST be NULL.
-
-
-
diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst
index b8642d0..8eb6695 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:: 3.1
+
.. 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)
@@ -122,18 +125,21 @@ Refer to :ref:`using-capsules` for more information on using these objects.
Return a nonzero value if the object is valid and matches the name passed in.
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.
+
.. 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.
+
.. c:function:: int PyCapsule_SetName(PyObject *capsule, const char *name)
Set the name inside *capsule* to *name*. If non-*NULL*, the name must
@@ -142,6 +148,7 @@ Refer to :ref:`using-capsules` for more information on using these objects.
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
diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst
index f5e0d7e..7f54b6a 100644
--- a/Doc/c-api/gcsupport.rst
+++ b/Doc/c-api/gcsupport.rst
@@ -49,7 +49,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.
.. c:function:: void PyObject_GC_Track(PyObject *op)
diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst
index a71e942..c16fcf4 100644
--- a/Doc/c-api/mapping.rst
+++ b/Doc/c-api/mapping.rst
@@ -5,11 +5,17 @@
Mapping Protocol
================
+See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and
+:c:func:`PyObject_DelItem`.
+
.. c:function:: int PyMapping_Check(PyObject *o)
- Return ``1`` if the object provides mapping protocol, and ``0`` otherwise. This
- function always succeeds.
+ Return ``1`` if the object provides mapping protocol or supports slicing,
+ and ``0`` otherwise. Note that it returns ``1`` for Python classes with
+ a :meth:`__getitem__` method since in general case it is impossible to
+ determine what the type of keys it supports. This function always
+ succeeds.
.. c:function:: Py_ssize_t PyMapping_Size(PyObject *o)
@@ -17,35 +23,49 @@ Mapping Protocol
.. index:: builtin: len
- Returns the number of keys in object *o* on success, and ``-1`` on failure. For
- objects that do not provide mapping protocol, this is equivalent to the Python
- expression ``len(o)``.
+ Returns the number of keys in object *o* on success, and ``-1`` on failure.
+ This is equivalent to the Python expression ``len(o)``.
-.. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key)
+.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key)
+
+ Return element of *o* corresponding to the string *key* or *NULL* on failure.
+ This is the equivalent of the Python expression ``o[key]``.
+ See also :c:func:`PyObject_GetItem`.
+
- Remove the mapping for object *key* from the object *o*. Return ``-1`` on
- failure. This is equivalent to the Python statement ``del o[key]``.
+.. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v)
+
+ Map the string *key* to the value *v* in object *o*. Returns ``-1`` on
+ failure. This is the equivalent of the Python statement ``o[key] = v``.
+ See also :c:func:`PyObject_SetItem`.
.. c:function:: int PyMapping_DelItem(PyObject *o, PyObject *key)
- Remove the mapping for object *key* from the object *o*. Return ``-1`` on
- failure. This is equivalent to the Python statement ``del o[key]``.
+ Remove the mapping for the object *key* from the object *o*. Return ``-1``
+ on failure. This is equivalent to the Python statement ``del o[key]``.
+ This is an alias of :c:func:`PyObject_DelItem`.
-.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key)
+.. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key)
- On success, return ``1`` if the mapping object has the key *key* and ``0``
- otherwise. This is equivalent to the Python expression ``key in o``.
- This function always succeeds.
+ Remove the mapping for the string *key* from the object *o*. Return ``-1``
+ on failure. This is equivalent to the Python statement ``del o[key]``.
.. c:function:: int PyMapping_HasKey(PyObject *o, PyObject *key)
- Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This
- is equivalent to the Python expression ``key in o``. This function always
- succeeds.
+ Return ``1`` if the mapping object has the key *key* and ``0`` otherwise.
+ This is equivalent to the Python expression ``key in o``.
+ This function always succeeds.
+
+
+.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key)
+
+ Return ``1`` if the mapping object has the key *key* and ``0`` otherwise.
+ This is equivalent to the Python expression ``key in o``.
+ This function always succeeds.
.. c:function:: PyObject* PyMapping_Keys(PyObject *o)
@@ -64,15 +84,3 @@ Mapping Protocol
On success, return a list or tuple of the items in object *o*, where each item
is a tuple containing a key-value pair. On failure, return *NULL*.
-
-
-.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key)
-
- Return element of *o* corresponding to the object *key* or *NULL* on failure.
- This is the equivalent of the Python expression ``o[key]``.
-
-
-.. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v)
-
- Map the object *key* to the value *v* in object *o*. Returns ``-1`` on failure.
- This is the equivalent of the Python statement ``o[key] = v``.
diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst
index d3125b8..797a67e 100644
--- a/Doc/c-api/module.rst
+++ b/Doc/c-api/module.rst
@@ -196,17 +196,23 @@ or request "multi-phase initialization" by returning the definition struct itsel
.. c:member:: traverseproc m_traverse
A traversal function to call during GC traversal of the module object, or
- *NULL* if not needed.
+ *NULL* if not needed. This function may be called before module state
+ is allocated (:c:func:`PyModule_GetState()` may return `NULL`),
+ and before the :c:member:`Py_mod_exec` function is executed.
.. c:member:: inquiry m_clear
A clear function to call during GC clearing of the module object, or
- *NULL* if not needed.
+ *NULL* if not needed. This function may be called before module state
+ is allocated (:c:func:`PyModule_GetState()` may return `NULL`),
+ and before the :c:member:`Py_mod_exec` function is executed.
.. c:member:: freefunc m_free
A function to call during deallocation of the module object, or *NULL* if
- not needed.
+ not needed. This function may be called before module state
+ is allocated (:c:func:`PyModule_GetState()` may return `NULL`),
+ and before the :c:member:`Py_mod_exec` function is executed.
Single-phase initialization
...........................
diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index b761c80..8692a2c 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -360,8 +360,8 @@ Object Protocol
parameters must be non-*NULL*.
-.. c:function:: Py_ssize_t PyObject_Length(PyObject *o)
- Py_ssize_t PyObject_Size(PyObject *o)
+.. c:function:: Py_ssize_t PyObject_Size(PyObject *o)
+ Py_ssize_t PyObject_Length(PyObject *o)
.. index:: builtin: len
@@ -395,8 +395,8 @@ Object Protocol
.. c:function:: int PyObject_DelItem(PyObject *o, PyObject *key)
- Delete the mapping for *key* from *o*. Returns ``-1`` on failure. This is the
- equivalent of the Python statement ``del o[key]``.
+ Remove the mapping for the object *key* from the object *o*. Return ``-1``
+ on failure. This is equivalent to the Python statement ``del o[key]``.
.. c:function:: PyObject* PyObject_Dir(PyObject *o)
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index 81f8557..6d22f35 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -9,7 +9,10 @@ Sequence Protocol
.. c:function:: int PySequence_Check(PyObject *o)
Return ``1`` if the object provides sequence protocol, and ``0`` otherwise.
- This function always succeeds.
+ Note that it returns ``1`` for Python classes with a :meth:`__getitem__`
+ method unless they are :class:`dict` subclasses since in general case it
+ is impossible to determine what the type of keys it supports. This
+ function always succeeds.
.. c:function:: Py_ssize_t PySequence_Size(PyObject *o)
@@ -119,18 +122,27 @@ Sequence Protocol
.. index:: builtin: tuple
- Return a tuple object with the same contents as the arbitrary sequence *o* or
- *NULL* on failure. If *o* is a tuple, a new reference will be returned,
+ Return a tuple object with the same contents as the sequence or iterable *o*,
+ or *NULL* on failure. If *o* is a tuple, a new reference will be returned,
otherwise a tuple will be constructed with the appropriate contents. This is
equivalent to the Python expression ``tuple(o)``.
.. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m)
- Return the sequence *o* as a list, unless it is already a tuple or list, in
+ Return the sequence or iterable *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.
+ a sequence or iterable, raises :exc:`TypeError` with *m* as the message text.
+
+
+.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
+
+ Returns the length of *o*, assuming that *o* was returned by
+ :c:func:`PySequence_Fast` and that *o* is not *NULL*. The size can also be
+ gotten by calling :c:func:`PySequence_Size` on *o*, but
+ :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list
+ or tuple.
.. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)
@@ -155,12 +167,3 @@ Sequence Protocol
:c:func:`PySequence_GetItem` but without checking that
:c:func:`PySequence_Check` on *o* is true and without adjustment for negative
indices.
-
-
-.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
-
- Returns the length of *o*, assuming that *o* was returned by
- :c:func:`PySequence_Fast` and that *o* is not *NULL*. The size can also be
- gotten by calling :c:func:`PySequence_Size` on *o*, but
- :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list
- or tuple.
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 0b4577f..76515fd 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -1151,21 +1151,24 @@ Mapping Object Structures
.. c:member:: lenfunc PyMappingMethods.mp_length
- This function is used by :c:func:`PyMapping_Length` and
+ This function is used by :c:func:`PyMapping_Size` and
:c:func:`PyObject_Size`, and has the same signature. This slot may be set to
*NULL* if the object has no defined length.
.. c:member:: binaryfunc PyMappingMethods.mp_subscript
- This function is used by :c:func:`PyObject_GetItem` and has the same
- signature. This slot must be filled for the :c:func:`PyMapping_Check`
- function to return ``1``, it can be *NULL* otherwise.
+ This function is used by :c:func:`PyObject_GetItem` and
+ :c:func:`PySequence_GetSlice`, and has the same signature as
+ :c:func:`!PyObject_GetItem`. This slot must be filled for the
+ :c:func:`PyMapping_Check` function to return ``1``, it can be *NULL*
+ otherwise.
.. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
- 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
+ This function is used by :c:func:`PyObject_SetItem`,
+ :c:func:`PyObject_DelItem`, :c:func:`PyObject_SetSlice` and
+ :c:func:`PyObject_DelSlice`. 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.
@@ -1185,26 +1188,29 @@ Sequence Object Structures
.. c:member:: lenfunc PySequenceMethods.sq_length
- This function is used by :c:func:`PySequence_Size` and :c:func:`PyObject_Size`,
- and has the same signature.
+ This function is used by :c:func:`PySequence_Size` and
+ :c:func:`PyObject_Size`, and has the same signature. It is also used for
+ handling negative indices via the :c:member:`~PySequenceMethods.sq_item`
+ and the :c:member:`~PySequenceMethods.sq_ass_item` slots.
.. c:member:: binaryfunc PySequenceMethods.sq_concat
This function is used by :c:func:`PySequence_Concat` and has the same
signature. It is also used by the ``+`` operator, after trying the numeric
- addition via the :c:member:`~PyTypeObject.tp_as_number.nb_add` slot.
+ addition via the :c:member:`~PyNumberMethods.nb_add` slot.
.. c:member:: ssizeargfunc PySequenceMethods.sq_repeat
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_multiply`
- slot.
+ multiplication via the :c:member:`~PyNumberMethods.nb_multiply` slot.
.. c:member:: ssizeargfunc PySequenceMethods.sq_item
This function is used by :c:func:`PySequence_GetItem` and has the same
- signature. This slot must be filled for the :c:func:`PySequence_Check`
+ signature. It is also used by :c:func:`PyObject_GetItem`, after trying
+ the subscription via the :c:member:`~PyMappingMethods.mp_subscript` slot.
+ This slot must be filled for the :c:func:`PySequence_Check`
function to return ``1``, it can be *NULL* otherwise.
Negative indexes are handled as follows: if the :attr:`sq_length` slot is
@@ -1215,28 +1221,36 @@ Sequence Object Structures
.. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item
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
+ signature. It is also used by :c:func:`PyObject_SetItem` and
+ :c:func:`PyObject_DelItem`, after trying the item assignment and deletion
+ via the :c:member:`~PyMappingMethods.mp_ass_subscript` slot.
+ This slot may be left to *NULL* if the object does not support
item assignment and deletion.
.. c:member:: objobjproc PySequenceMethods.sq_contains
This function may be used by :c:func:`PySequence_Contains` and has the same
signature. This slot may be left to *NULL*, in this case
- :c:func:`PySequence_Contains` simply traverses the sequence until it finds a
- match.
+ :c:func:`!PySequence_Contains` simply traverses the sequence until it
+ finds a match.
.. c:member:: binaryfunc PySequenceMethods.sq_inplace_concat
This function is used by :c:func:`PySequence_InPlaceConcat` and has the same
- signature. It should modify its first operand, and return it.
+ signature. It should modify its first operand, and return it. This slot
+ may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceConcat`
+ will fall back to :c:func:`PySequence_Concat`. It is also used by the
+ augmented assignment ``+=``, after trying numeric inplace addition
+ via the :c:member:`~PyNumberMethods.nb_inplace_add` slot.
.. c:member:: ssizeargfunc PySequenceMethods.sq_inplace_repeat
This function is used by :c:func:`PySequence_InPlaceRepeat` and has the same
- signature. It should modify its first operand, and return it.
-
-.. XXX need to explain precedence between mapping and sequence
-.. XXX explains when to implement the sq_inplace_* slots
+ signature. It should modify its first operand, and return it. This slot
+ may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceRepeat`
+ will fall back to :c:func:`PySequence_Repeat`. It is also used by the
+ augmented assignment ``*=``, after trying numeric inplace multiplication
+ via the :c:member:`~PyNumberMethods.nb_inplace_multiply` slot.
.. _buffer-structs:
diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst
index 82ecd2c..b0dccb3 100644
--- a/Doc/distributing/index.rst
+++ b/Doc/distributing/index.rst
@@ -31,7 +31,7 @@ installing other Python projects, refer to the
Key terms
=========
-* the `Python Packaging Index `__ is a public
+* 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
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index b5b7731..f147bb2 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` |
diff --git a/Doc/distutils/configfile.rst b/Doc/distutils/configfile.rst
index 21f1acd..cd10a7f 100644
--- a/Doc/distutils/configfile.rst
+++ b/Doc/distutils/configfile.rst
@@ -36,7 +36,9 @@ consequences:
* installers can override anything in :file:`setup.cfg` using the command-line
options to :file:`setup.py`
-The basic syntax of the configuration file is simple::
+The basic syntax of the configuration file is simple:
+
+.. code-block:: ini
[command]
option=value
@@ -51,9 +53,11 @@ 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.
+
+.. code-block:: shell-session
- > python setup.py --help build_ext
+ $ python setup.py --help build_ext
[...]
Options for 'build_ext' command:
--build-lib (-b) directory for compiled extension modules
@@ -75,14 +79,18 @@ 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:
+
+.. code-block:: sh
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
"set and forget" this option, by encoding it in :file:`setup.cfg`, the
-configuration file for this distribution::
+configuration file for this distribution:
+
+.. code-block:: ini
[build_ext]
inplace=1
@@ -103,7 +111,9 @@ information comes from the setup script, and some is automatically generated by
the Distutils (such as the list of files installed). But some of it has to be
supplied as options to :command:`bdist_rpm`, which would be very tedious to do
on the command-line for every run. Hence, here is a snippet from the Distutils'
-own :file:`setup.cfg`::
+own :file:`setup.cfg`:
+
+.. code-block:: ini
[bdist_rpm]
release = 1
diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst
index 8f46bd7..a385559 100644
--- a/Doc/distutils/introduction.rst
+++ b/Doc/distutils/introduction.rst
@@ -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 NumPy, SciPy, PIL (the Python Imaging
- Library), or mxBase. (This would be called a *package*, except that term is
+ module distributions are NumPy, SciPy, 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 44556e3..50cb74f 100644
--- a/Doc/distutils/packageindex.rst
+++ b/Doc/distutils/packageindex.rst
@@ -156,7 +156,9 @@ The :command:`register` and :command:`upload` commands both check for the
existence of a :file:`.pypirc` file at the location :file:`$HOME/.pypirc`.
If this file exists, the command uses the username, password, and repository
URL configured in the file. The format of a :file:`.pypirc` file is as
-follows::
+follows:
+
+.. code-block:: ini
[distutils]
index-servers =
@@ -179,7 +181,9 @@ Each section describing a repository defines three variables:
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::
+listed in the *index-servers* variable:
+
+.. code-block:: ini
[distutils]
index-servers =
@@ -246,4 +250,4 @@ without warnings does not guarantee that PyPI will convert the content
successfully.
-.. _Python Package Index (PyPI): https://pypi.python.org/pypi
+.. _Python Package Index (PyPI): https://pypi.org
diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst
index 38e0202..21d569b 100644
--- a/Doc/distutils/setupscript.rst
+++ b/Doc/distutils/setupscript.rst
@@ -609,7 +609,7 @@ 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
diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst
index ab2f616..7e4fc19 100644
--- a/Doc/extending/embedding.rst
+++ b/Doc/extending/embedding.rst
@@ -323,7 +323,7 @@ options. In this case, the :mod:`sysconfig` module is a useful tool to
programmatically extract the configuration values that you will want to
combine together. For example:
-.. code-block:: python
+.. code-block:: pycon
>>> import sysconfig
>>> sysconfig.get_config_var('LIBS')
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index a517e13..130f4a7 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -42,7 +42,9 @@ 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
character string as argument and returns an integer. We want this function to
-be callable from Python as follows::
+be callable from Python as follows:
+
+.. code-block:: pycon
>>> import spam
>>> status = spam.system("ls -l")
@@ -438,7 +440,9 @@ part of the Python interpreter, you will have to change the configuration setup
and rebuild the interpreter. Luckily, this is very simple on Unix: just place
your file (:file:`spammodule.c` for example) in the :file:`Modules/` directory
of an unpacked source distribution, add a line to the file
-:file:`Modules/Setup.local` describing your file::
+:file:`Modules/Setup.local` describing your file:
+
+.. code-block:: sh
spam spammodule.o
@@ -449,7 +453,9 @@ subdirectory, but then you must first rebuild :file:`Makefile` there by running
:file:`Setup` file.)
If your module requires additional libraries to link with, these can be listed
-on the line in the configuration file as well, for instance::
+on the line in the configuration file as well, for instance:
+
+.. code-block:: sh
spam spammodule.o -lX11
diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst
index 9eec8c2..533ed98 100644
--- a/Doc/extending/index.rst
+++ b/Doc/extending/index.rst
@@ -26,9 +26,11 @@ Recommended third party tools
=============================
This guide only covers the basic tools for creating extensions provided
-as part of this version of CPython. Third party tools like Cython,
-``cffi``, SWIG and Numba offer both simpler and more sophisticated
-approaches to creating C and C++ extensions for Python.
+as part of this version of CPython. Third party tools like
+`Cython `_, `cffi `_,
+`SWIG `_ and `Numba `_
+offer both simpler and more sophisticated approaches to creating C and C++
+extensions for Python.
.. seealso::
@@ -52,6 +54,7 @@ C extensions.
:numbered:
extending.rst
+ newtypes_tutorial.rst
newtypes.rst
building.rst
windows.rst
diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst
index edba57e..b557964 100644
--- a/Doc/extending/newtypes.rst
+++ b/Doc/extending/newtypes.rst
@@ -1,896 +1,11 @@
.. highlightlang:: c
-
-.. _defining-new-types:
-
-******************
-Defining New Types
-******************
-
-.. sectionauthor:: Michael Hudson
-.. sectionauthor:: Dave Kuhlman
-.. sectionauthor:: Jim Fulton
-
-
-As mentioned in the last chapter, Python allows the writer of an extension
-module to define new types that can be manipulated from Python code, much like
-strings and lists in core Python.
-
-This is not hard; the code for all extension types follows a pattern, but there
-are some details that you need to understand before you can get started.
-
-
-.. _dnt-basics:
-
-The Basics
-==========
-
-The Python runtime sees all Python objects as variables of type
-:c:type:`PyObject\*`, which serves as a "base type" for all Python objects.
-:c:type:`PyObject` itself only contains the refcount and a pointer to the
-object's "type object". This is where the action is; the type object determines
-which (C) functions get called when, for instance, an attribute gets looked
-up on an object or it is multiplied by another object. These C functions
-are called "type methods".
-
-So, if you want to define a new object type, you need to create a new type
-object.
-
-This sort of thing can only be explained by example, so here's a minimal, but
-complete, module that defines a new type:
-
-.. literalinclude:: ../includes/noddy.c
-
-
-Now that's quite a bit to take in at once, but hopefully bits will seem familiar
-from the last chapter.
-
-The first bit that will be new is::
-
- typedef struct {
- PyObject_HEAD
- } noddy_NoddyObject;
-
-This is what a Noddy object will contain---in this case, nothing more than what
-every Python object contains---a field called ``ob_base`` of type
-:c:type:`PyObject`. :c:type:`PyObject` in turn, contains an ``ob_refcnt``
-field and a pointer to a type object. These can be accessed using the macros
-:c:macro:`Py_REFCNT` and :c:macro:`Py_TYPE` respectively. These are the fields
-the :c:macro:`PyObject_HEAD` macro brings in. The reason for the macro is to
-standardize the layout and to enable special debugging fields in debug builds.
-
-Note that there is no semicolon after the :c:macro:`PyObject_HEAD` macro;
-one is included in the macro definition. Be wary of adding one by
-accident; it's easy to do from habit, and your compiler might not complain,
-but someone else's probably will! (On Windows, MSVC is known to call this an
-error and refuse to compile the code.)
-
-For contrast, let's take a look at the corresponding definition for standard
-Python floats::
-
- typedef struct {
- PyObject_HEAD
- double ob_fval;
- } PyFloatObject;
-
-Moving on, we come to the crunch --- the type object. ::
-
- static PyTypeObject noddy_NoddyType = {
- 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_as_async */
- 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 */
- };
-
-Now if you go and look up the definition of :c:type:`PyTypeObject` in
-:file:`object.h` you'll see that it has many more fields that the definition
-above. The remaining fields will be filled with zeros by the C compiler, and
-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::
-
- PyVarObject_HEAD_INIT(NULL, 0)
-
-This line is a bit of a wart; what we'd like to write is::
-
- 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`. ::
-
- "noddy.Noddy", /* tp_name */
-
-The name of our type. This will appear in the default textual representation of
-our objects and in some error messages, for example::
-
- >>> "" + noddy.new_noddy()
- Traceback (most recent call last):
- 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`.
-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 */
-
-This is so that Python knows how much memory to allocate when you call
-:c:func:`PyObject_New`.
-
-.. note::
-
- If you want your type to be subclassable from Python, and your type has the same
- :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have problems with multiple
- inheritance. A Python subclass of your type will have to list your type first
- in its :attr:`~class.__bases__`, or else it will not be able to call your type's
- :meth:`__new__` method without getting an error. You can avoid this problem by
- ensuring that your type has a larger value for :c:member:`~PyTypeObject.tp_basicsize` than its
- base type does. Most of the time, this will be true anyway, because either your
- base type will be :class:`object`, or else you will be adding data members to
- your base type, and therefore increasing its size.
-
-::
-
- 0, /* tp_itemsize */
-
-This has to do with variable length objects like lists and strings. Ignore this
-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 */
-
-All types should include this constant in their flags. It enables all of the
-members defined until at least Python 3.3. If you need further members,
-you will need to OR the corresponding flags.
-
-We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::
-
- "Noddy objects", /* tp_doc */
-
-Now we get into the type methods, the things that make your objects different
-from the others. We aren't going to implement any of these in this version of
-the module. We'll expand this example later to have more interesting behavior.
-
-For now, all we want to be able to do is to create new :class:`Noddy` objects.
-To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new` implementation.
-In this case, we can just use the default implementation provided by the API
-function :c:func:`PyType_GenericNew`. We'd like to just assign this to the
-:c:member:`~PyTypeObject.tp_new` slot, but we can't, for portability sake, On some platforms or
-compilers, we can't statically initialize a structure member with a function
-defined in another C module, so, instead, we'll assign the :c:member:`~PyTypeObject.tp_new` slot
-in the module initialization function just before calling
-:c:func:`PyType_Ready`::
-
- noddy_NoddyType.tp_new = PyType_GenericNew;
- if (PyType_Ready(&noddy_NoddyType) < 0)
- return;
-
-All the other type methods are *NULL*, so we'll go over them later --- that's
-for a later section!
-
-Everything else in the file should be familiar, except for some code in
-:c:func:`PyInit_noddy`::
-
- if (PyType_Ready(&noddy_NoddyType) < 0)
- return;
-
-This initializes the :class:`Noddy` type, filing in a number of members,
-including :attr:`ob_type` that we initially set to *NULL*. ::
-
- PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
-
-This adds the type to the module dictionary. This allows us to create
-:class:`Noddy` instances by calling the :class:`Noddy` class::
-
- >>> import noddy
- >>> mynoddy = noddy.Noddy()
-
-That's it! All that remains is to build it; put the above code in a file called
-:file:`noddy.c` and ::
-
- from distutils.core import setup, Extension
- setup(name="noddy", version="1.0",
- ext_modules=[Extension("noddy", ["noddy.c"])])
-
-in a file called :file:`setup.py`; then typing
-
-.. code-block:: shell-session
-
- $ python setup.py build
-
-at a shell should produce a file :file:`noddy.so` in a subdirectory; move to
-that directory and fire up Python --- you should be able to ``import noddy`` and
-play around with Noddy objects.
-
-That wasn't so hard, was it?
-
-Of course, the current Noddy type is pretty uninteresting. It has no data and
-doesn't do anything. It can't even be subclassed.
-
-
-Adding data and methods to the Basic example
---------------------------------------------
-
-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:
-
-.. literalinclude:: ../includes/noddy2.c
-
-
-This version of the module has a number of changes.
-
-We've added an extra include::
-
- #include
-
-This include provides declarations that we use to handle attributes, as
-described a bit later.
-
-The name of the :class:`Noddy` object structure has been shortened to
-:class:`Noddy`. The type object name has been shortened to :class:`NoddyType`.
-
-The :class:`Noddy` type now has three data attributes, *first*, *last*, and
-*number*. The *first* and *last* variables are Python strings containing first
-and last names. The *number* attribute is an integer.
-
-The object structure is updated accordingly::
-
- typedef struct {
- PyObject_HEAD
- PyObject *first;
- PyObject *last;
- int number;
- } Noddy;
-
-Because we now have data to manage, we have to be more careful about object
-allocation and deallocation. At a minimum, we need a deallocation method::
-
- static void
- Noddy_dealloc(Noddy* self)
- {
- Py_XDECREF(self->first);
- Py_XDECREF(self->last);
- Py_TYPE(self)->tp_free((PyObject*)self);
- }
-
-which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::
-
- (destructor)Noddy_dealloc, /*tp_dealloc*/
-
-This method decrements the reference counts of the two Python attributes. We use
-:c:func:`Py_XDECREF` here because the :attr:`first` and :attr:`last` members
-could be *NULL*. It then calls the :c:member:`~PyTypeObject.tp_free` member of the object's type
-to free the object's memory. Note that the object's type might not be
-:class:`NoddyType`, because the object may be an instance of a subclass.
-
-We want to make sure that the first and last names are initialized to empty
-strings, so we provide a new method::
-
- static PyObject *
- Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
- }
-
-and install it in the :c:member:`~PyTypeObject.tp_new` member::
-
- Noddy_new, /* tp_new */
-
-The new member is responsible for creating (as opposed to initializing) objects
-of the type. It is exposed in Python as the :meth:`__new__` method. See the
-paper titled "Unifying types and classes in Python" for a detailed discussion of
-the :meth:`__new__` method. One reason to implement a new method is to assure
-the initial values of instance variables. In this case, we use the new method
-to make sure that the initial values of the members :attr:`first` and
-:attr:`last` are not *NULL*. If we didn't care whether the initial values were
-*NULL*, we could have used :c:func:`PyType_GenericNew` as our new method, as we
-did before. :c:func:`PyType_GenericNew` initializes all of the instance variable
-members to *NULL*.
-
-The new method is a static method that is passed the type being instantiated and
-any arguments passed when the type was called, and that returns the new object
-created. New methods always accept positional and keyword arguments, but they
-often ignore the arguments, leaving the argument handling to initializer
-methods. Note that if the type supports subclassing, the type passed may not be
-the type being defined. The new method calls the :c:member:`~PyTypeObject.tp_alloc` slot to
-allocate memory. We don't fill the :c:member:`~PyTypeObject.tp_alloc` slot ourselves. Rather
-:c:func:`PyType_Ready` fills it for us by inheriting it from our base class,
-which is :class:`object` by default. Most types use the default allocation.
-
-.. note::
-
- If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one that calls a base type's
- :c:member:`~PyTypeObject.tp_new` or :meth:`__new__`), you must *not* try to determine what method
- to call using method resolution order at runtime. Always statically determine
- what type you are going to call, and call its :c:member:`~PyTypeObject.tp_new` directly, or via
- ``type->tp_base->tp_new``. If you do not do this, Python subclasses of your
- type that also inherit from other Python-defined classes may not work correctly.
- (Specifically, you may not be able to create instances of such subclasses
- without getting a :exc:`TypeError`.)
-
-We provide an initialization function::
-
- static int
- Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
- {
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_XDECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_XDECREF(tmp);
- }
-
- return 0;
- }
-
-by filling the :c:member:`~PyTypeObject.tp_init` slot. ::
-
- (initproc)Noddy_init, /* tp_init */
-
-The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the :meth:`__init__` method. It
-is used to initialize an object after it's created. Unlike the new method, we
-can't guarantee that the initializer is called. The initializer isn't called
-when unpickling objects and it can be overridden. Our initializer accepts
-arguments to provide initial values for our instance. Initializers always accept
-positional and keyword arguments. Initializers should return either ``0`` on
-success or ``-1`` on error.
-
-Initializers can be called multiple times. Anyone can call the :meth:`__init__`
-method on our objects. For this reason, we have to be extra careful when
-assigning the new values. We might be tempted, for example to assign the
-:attr:`first` member like this::
-
- if (first) {
- Py_XDECREF(self->first);
- Py_INCREF(first);
- self->first = first;
- }
-
-But this would be risky. Our type doesn't restrict the type of the
-:attr:`first` member, so it could be any kind of object. It could have a
-destructor that causes code to be executed that tries to access the
-:attr:`first` member. To be paranoid and protect ourselves against this
-possibility, we almost always reassign members before decrementing their
-reference counts. When don't we have to do this?
-
-* when we absolutely know that the reference count is greater than 1
-
-* when we know that deallocation of the object [#]_ will not cause any calls
- back into our type's code
-
-* when decrementing a reference count in a :c:member:`~PyTypeObject.tp_dealloc` handler when
- garbage-collections is not supported [#]_
-
-We want to expose our instance variables as attributes. There are a
-number of ways to do that. The simplest way is to define member definitions::
-
- static PyMemberDef Noddy_members[] = {
- {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
- "first name"},
- {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
- "last name"},
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
- };
-
-and put the definitions in the :c:member:`~PyTypeObject.tp_members` slot::
-
- Noddy_members, /* tp_members */
-
-Each member definition has a member name, type, offset, access flags and
-documentation string. See the :ref:`Generic-Attribute-Management` section below for
-details.
-
-A disadvantage of this approach is that it doesn't provide a way to restrict the
-types of objects that can be assigned to the Python attributes. We expect the
-first and last names to be strings, but any Python objects can be assigned.
-Further, the attributes can be deleted, setting the C pointers to *NULL*. Even
-though we can make sure the members are initialized to non-*NULL* values, the
-members can be set to *NULL* if the attributes are deleted.
-
-We define a single method, :meth:`name`, that outputs the objects name as the
-concatenation of the first and last names. ::
-
- static PyObject *
- Noddy_name(Noddy* self)
- {
- if (self->first == NULL) {
- PyErr_SetString(PyExc_AttributeError, "first");
- return NULL;
- }
-
- if (self->last == NULL) {
- PyErr_SetString(PyExc_AttributeError, "last");
- return NULL;
- }
-
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
- }
-
-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 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::
-
- def name(self):
- return "%s %s" % (self.first, self.last)
-
-Note that we have to check for the possibility that our :attr:`first` and
-:attr:`last` members are *NULL*. This is because they can be deleted, in which
-case they are set to *NULL*. It would be better to prevent deletion of these
-attributes and to restrict the attribute values to be strings. We'll see how to
-do that in the next section.
-
-Now that we've defined the method, we need to create an array of method
-definitions::
-
- static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
- };
-
-and assign them to the :c:member:`~PyTypeObject.tp_methods` slot::
-
- Noddy_methods, /* tp_methods */
-
-Note that we used the :const:`METH_NOARGS` flag to indicate that the method is
-passed no arguments.
-
-Finally, we'll make our type usable as a base class. We've written our methods
-carefully so far so that they don't make any assumptions about the type of the
-object being created or used, so all we need to do is to add the
-:const:`Py_TPFLAGS_BASETYPE` to our class flag definition::
-
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
-
-We rename :c:func:`PyInit_noddy` to :c:func:`PyInit_noddy2` and update the module
-name in the :c:type:`PyModuleDef` struct.
-
-Finally, we update our :file:`setup.py` file to build the new module::
-
- from distutils.core import setup, Extension
- setup(name="noddy", version="1.0",
- ext_modules=[
- Extension("noddy", ["noddy.c"]),
- Extension("noddy2", ["noddy2.c"]),
- ])
-
-
-Providing finer control over data attributes
---------------------------------------------
-
-In this section, we'll provide finer control over how the :attr:`first` and
-:attr:`last` attributes are set in the :class:`Noddy` example. In the previous
-version of our module, the instance variables :attr:`first` and :attr:`last`
-could be set to non-string values or even deleted. We want to make sure that
-these attributes always contain strings.
-
-.. literalinclude:: ../includes/noddy3.c
-
-
-To provide greater control, over the :attr:`first` and :attr:`last` attributes,
-we'll use custom getter and setter functions. Here are the functions for
-getting and setting the :attr:`first` attribute::
-
- Noddy_getfirst(Noddy *self, void *closure)
- {
- Py_INCREF(self->first);
- return self->first;
- }
-
- 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 (! PyUnicode_Check(value)) {
- PyErr_SetString(PyExc_TypeError,
- "The first attribute value must be a str");
- return -1;
- }
-
- Py_DECREF(self->first);
- Py_INCREF(value);
- self->first = value;
-
- return 0;
- }
-
-The getter function is passed a :class:`Noddy` object and a "closure", which is
-void pointer. In this case, the closure is ignored. (The closure supports an
-advanced usage in which definition data is passed to the getter and setter. This
-could, for example, be used to allow a single set of getter and setter functions
-that decide the attribute to get or set based on data in the closure.)
-
-The setter function is passed the :class:`Noddy` object, the new value, and the
-closure. The new value may be *NULL*, in which case the attribute is being
-deleted. In our setter, we raise an error if the attribute is deleted or if the
-attribute value is not a string.
-
-We create an array of :c:type:`PyGetSetDef` structures::
-
- static PyGetSetDef Noddy_getseters[] = {
- {"first",
- (getter)Noddy_getfirst, (setter)Noddy_setfirst,
- "first name",
- NULL},
- {"last",
- (getter)Noddy_getlast, (setter)Noddy_setlast,
- "last name",
- NULL},
- {NULL} /* Sentinel */
- };
-
-and register it in the :c:member:`~PyTypeObject.tp_getset` slot::
-
- Noddy_getseters, /* tp_getset */
-
-to register our attribute getters and setters.
-
-The last item in a :c:type:`PyGetSetDef` structure is the closure mentioned
-above. In this case, we aren't using the closure, so we just pass *NULL*.
-
-We also remove the member definitions for these attributes::
-
- static PyMemberDef Noddy_members[] = {
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
- };
-
-We also need to update the :c:member:`~PyTypeObject.tp_init` handler to only allow strings [#]_ to
-be passed::
-
- static int
- Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
- {
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_DECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_DECREF(tmp);
- }
-
- return 0;
- }
-
-With these changes, we can assure that the :attr:`first` and :attr:`last`
-members are never *NULL* so we can remove checks for *NULL* values in almost all
-cases. This means that most of the :c:func:`Py_XDECREF` calls can be converted to
-:c:func:`Py_DECREF` calls. The only place we can't change these calls is in the
-deallocator, where there is the possibility that the initialization of these
-members failed in the constructor.
-
-We also rename the module initialization function and module name in the
-initialization function, as we did before, and we add an extra definition to the
-:file:`setup.py` file.
-
-
-Supporting cyclic garbage collection
-------------------------------------
-
-Python has a cyclic-garbage collector that can identify unneeded objects even
-when their reference counts are not zero. This can happen when objects are
-involved in cycles. For example, consider::
-
- >>> l = []
- >>> l.append(l)
- >>> del l
-
-In this example, we create a list that contains itself. When we delete it, it
-still has a reference from itself. Its reference count doesn't drop to zero.
-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
-means that :class:`Noddy` objects can participate in cycles::
-
- >>> import noddy2
- >>> n = noddy2.Noddy()
- >>> l = [n]
- >>> n.first = l
-
-This is pretty silly, but it gives us an excuse to add support for the
-cyclic-garbage collector to the :class:`Noddy` example. To support cyclic
-garbage collection, types need to fill two slots and set a class flag that
-enables these slots:
-
-.. literalinclude:: ../includes/noddy4.c
-
-
-The traversal method provides access to subobjects that could participate in
-cycles::
-
- static int
- Noddy_traverse(Noddy *self, visitproc visit, void *arg)
- {
- int vret;
-
- if (self->first) {
- vret = visit(self->first, arg);
- if (vret != 0)
- return vret;
- }
- if (self->last) {
- vret = visit(self->last, arg);
- if (vret != 0)
- return vret;
- }
-
- return 0;
- }
-
-For each subobject that can participate in cycles, we need to call the
-:c:func:`visit` function, which is passed to the traversal method. The
-:c:func:`visit` function takes as arguments the subobject and the extra argument
-*arg* passed to the traversal method. It returns an integer value that must be
-returned if it is non-zero.
-
-Python provides a :c:func:`Py_VISIT` macro that automates calling visit
-functions. With :c:func:`Py_VISIT`, :c:func:`Noddy_traverse` can be simplified::
-
- static int
- Noddy_traverse(Noddy *self, visitproc visit, void *arg)
- {
- Py_VISIT(self->first);
- Py_VISIT(self->last);
- return 0;
- }
-
-.. note::
-
- Note that the :c:member:`~PyTypeObject.tp_traverse` implementation must name its arguments exactly
- *visit* and *arg* in order to use :c:func:`Py_VISIT`. This is to encourage
- uniformity across these boring implementations.
-
-We also need to provide a method for clearing any subobjects that can
-participate in cycles.
-
-::
-
- static int
- Noddy_clear(Noddy *self)
- {
- PyObject *tmp;
-
- tmp = self->first;
- self->first = NULL;
- Py_XDECREF(tmp);
-
- tmp = self->last;
- self->last = NULL;
- Py_XDECREF(tmp);
-
- return 0;
- }
-
-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
-reference count drops to zero, we might cause code to run that calls back into
-the object. In addition, because we now support garbage collection, we also
-have to worry about code being run that triggers garbage collection. If garbage
-collection is run, our :c:member:`~PyTypeObject.tp_traverse` handler could get called. We can't
-take a chance of having :c:func:`Noddy_traverse` called when a member's reference
-count has dropped to zero and its value hasn't been set to *NULL*.
-
-Python provides a :c:func:`Py_CLEAR` that automates the careful decrementing of
-reference counts. With :c:func:`Py_CLEAR`, the :c:func:`Noddy_clear` function can
-be simplified::
-
- static int
- Noddy_clear(Noddy *self)
- {
- Py_CLEAR(self->first);
- Py_CLEAR(self->last);
- 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 */
-
-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.
-Most extensions will use the versions automatically provided.
-
-
-Subclassing other types
------------------------
-
-It is possible to create new extension types that are derived from existing
-types. It is easiest to inherit from the built in types, since an extension can
-easily use the :class:`PyTypeObject` it needs. It can be difficult to share
-these :class:`PyTypeObject` structures between extension modules.
-
-In this example we will create a :class:`Shoddy` type that inherits from the
-built-in :class:`list` type. The new type will be completely compatible with
-regular lists, but will have an additional :meth:`increment` method that
-increases an internal counter. ::
-
- >>> import shoddy
- >>> s = shoddy.Shoddy(range(3))
- >>> s.extend(s)
- >>> print(len(s))
- 6
- >>> print(s.increment())
- 1
- >>> print(s.increment())
- 2
-
-.. literalinclude:: ../includes/shoddy.c
-
-
-As you can see, the source code closely resembles the :class:`Noddy` examples in
-previous sections. We will break down the main differences between them. ::
-
- typedef struct {
- PyListObject list;
- int state;
- } Shoddy;
-
-The primary difference for derived type objects is that the base type's object
-structure must be the first value. The base type will already include the
-:c:func:`PyObject_HEAD` at the beginning of its structure.
-
-When a Python object is a :class:`Shoddy` instance, its *PyObject\** pointer can
-be safely cast to both *PyListObject\** and *Shoddy\**. ::
-
- static int
- Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
- {
- if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
- return -1;
- self->state = 0;
- return 0;
- }
-
-In the :attr:`__init__` method for our type, we can see how to call through to
-the :attr:`__init__` method of the base type.
-
-This pattern is important when writing a type with custom :attr:`new` and
-:attr:`dealloc` methods. The :attr:`new` method should not actually create the
-memory for the object with :c:member:`~PyTypeObject.tp_alloc`, that will be handled by the base
-class when calling its :c:member:`~PyTypeObject.tp_new`.
-
-When filling out the :c:func:`PyTypeObject` for the :class:`Shoddy` type, you see
-a slot for :c:func:`tp_base`. Due to cross platform compiler issues, you can't
-fill that field directly with the :c:func:`PyList_Type`; it can be done later in
-the module's :c:func:`init` function. ::
-
- PyMODINIT_FUNC
- PyInit_shoddy(void)
- {
- PyObject *m;
-
- ShoddyType.tp_base = &PyList_Type;
- if (PyType_Ready(&ShoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&shoddymodule);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&ShoddyType);
- PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
- return m;
- }
-
-Before calling :c:func:`PyType_Ready`, the type structure must have the
-:c:member:`~PyTypeObject.tp_base` slot filled in. When we are deriving a new type, it is not
-necessary to fill out the :c:member:`~PyTypeObject.tp_alloc` slot with :c:func:`PyType_GenericNew`
--- the allocate function from the base type will be inherited.
-
-After that, calling :c:func:`PyType_Ready` and adding the type object to the
-module is the same as with the basic :class:`Noddy` examples.
-
+*****************************************
+Defining Extension Types: Assorted Topics
+*****************************************
.. _dnt-type-methods:
-Type Methods
-============
-
This section aims to give a quick fly-by on the various type methods you can
implement and what they do.
@@ -900,21 +15,20 @@ debug builds omitted:
.. literalinclude:: ../includes/typestruct.h
-Now that's a *lot* of methods. Don't worry too much though - if you have a type
-you want to define, the chances are very good that you will only implement a
-handful of these.
+Now that's a *lot* of methods. Don't worry too much though -- if you have
+a type you want to define, the chances are very good that you will only
+implement a handful of these.
As you probably expect by now, we're going to go over this and give more
information about the various handlers. We won't go in the order they are
defined in the structure, because there is a lot of historical baggage that
-impacts the ordering of the fields; be sure your type initialization keeps the
-fields in the right order! It's often easiest to find an example that includes
-all the fields you need (even if they're initialized to ``0``) and then change
-the values to suit your new type. ::
+impacts the ordering of the fields. It's often easiest to find an example
+that includes the fields you need and then change the values to suit your new
+type. ::
const char *tp_name; /* For printing */
-The name of the type - as mentioned in the last section, this will appear in
+The name of the type -- as mentioned in the previous chapter, this will appear in
various places, almost entirely for diagnostic purposes. Try to choose something
that will be helpful in such a situation! ::
@@ -922,7 +36,7 @@ that will be helpful in such a situation! ::
These fields tell the runtime how much memory to allocate when new objects of
this type are created. Python has some built-in support for variable length
-structures (think: strings, lists) which is where the :c:member:`~PyTypeObject.tp_itemsize` field
+structures (think: strings, tuples) which is where the :c:member:`~PyTypeObject.tp_itemsize` field
comes in. This will be dealt with later. ::
const char *tp_doc;
@@ -930,7 +44,7 @@ comes in. This will be dealt with later. ::
Here you can put a string (or its address) that you want returned when the
Python script references ``obj.__doc__`` to retrieve the doc string.
-Now we come to the basic type methods---the ones most extension types will
+Now we come to the basic type methods -- the ones most extension types will
implement.
@@ -954,7 +68,7 @@ object itself needs to be freed here as well. Here is an example of this
function::
static void
- newdatatype_dealloc(newdatatypeobject * obj)
+ newdatatype_dealloc(newdatatypeobject *obj)
{
free(obj->obj_UnderlyingDatatypePtr);
Py_TYPE(obj)->tp_free(obj);
@@ -1042,7 +156,7 @@ example::
static PyObject *
newdatatype_repr(newdatatypeobject * obj)
{
- return PyUnicode_FromFormat("Repr-ified_newdatatype{{size:\%d}}",
+ return PyUnicode_FromFormat("Repr-ified_newdatatype{{size:%d}}",
obj->obj_UnderlyingDatatypePtr->size);
}
@@ -1062,7 +176,7 @@ Here is a simple example::
static PyObject *
newdatatype_str(newdatatypeobject * obj)
{
- return PyUnicode_FromFormat("Stringified_newdatatype{{size:\%d}}",
+ return PyUnicode_FromFormat("Stringified_newdatatype{{size:%d}}",
obj->obj_UnderlyingDatatypePtr->size);
}
@@ -1243,7 +357,7 @@ example that simply raises an exception; if this were really all you wanted, the
static int
newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v)
{
- (void)PyErr_Format(PyExc_RuntimeError, "Read-only attribute: \%s", name);
+ PyErr_Format(PyExc_RuntimeError, "Read-only attribute: %s", name);
return -1;
}
@@ -1328,17 +442,23 @@ these in the :file:`Objects` directory of the Python source distribution. ::
hashfunc tp_hash;
This function, if you choose to provide it, should return a hash number for an
-instance of your data type. Here is a moderately pointless example::
+instance of your data type. Here is a simple example::
- static long
+ static Py_hash_t
newdatatype_hash(newdatatypeobject *obj)
{
- long result;
- result = obj->obj_UnderlyingDatatypePtr->size;
- result = result * 3;
+ Py_hash_t result;
+ result = obj->some_size + 32767 * obj->some_number;
+ if (result == -1)
+ result = -2;
return result;
}
+:c:type:`Py_hash_t` is a signed integer type with a platform-varying width.
+Returning ``-1`` from :c:member:`~PyTypeObject.tp_hash` indicates an error,
+which is why you should be careful to avoid returning it when hash computation
+is successful, as seen above.
+
::
ternaryfunc tp_call;
@@ -1349,27 +469,22 @@ contains ``obj1('hello')``, the :c:member:`~PyTypeObject.tp_call` handler is inv
This function takes three arguments:
-#. *arg1* is the instance of the data type which is the subject of the call. If
- the call is ``obj1('hello')``, then *arg1* is ``obj1``.
+#. *self* is the instance of the data type which is the subject of the call.
+ If the call is ``obj1('hello')``, then *self* is ``obj1``.
-#. *arg2* is a tuple containing the arguments to the call. You can use
+#. *args* is a tuple containing the arguments to the call. You can use
:c:func:`PyArg_ParseTuple` to extract the arguments.
-#. *arg3* is a dictionary of keyword arguments that were passed. If this is
+#. *kwds* is a dictionary of keyword arguments that were passed. If this is
non-*NULL* and you support keyword arguments, use
- :c:func:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you do not
- want to support keyword arguments and this is non-*NULL*, raise a
+ :c:func:`PyArg_ParseTupleAndKeywords` to extract the arguments. If you
+ do not want to support keyword arguments and this is non-*NULL*, raise a
:exc:`TypeError` with a message saying that keyword arguments are not supported.
-Here is a desultory example of the implementation of the call function. ::
+Here is a toy ``tp_call`` implementation::
- /* Implement the call function.
- * obj1 is the instance receiving the call.
- * obj2 is a tuple containing the arguments to the call, in this
- * case 3 strings.
- */
static PyObject *
- newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *other)
+ newdatatype_call(newdatatypeobject *self, PyObject *args, PyObject *kwds)
{
PyObject *result;
char *arg1;
@@ -1380,7 +495,7 @@ Here is a desultory example of the implementation of the call function. ::
return NULL;
}
result = PyUnicode_FromFormat(
- "Returning -- value: [\%d] arg1: [\%s] arg2: [\%s] arg3: [\%s]\n",
+ "Returning -- value: [%d] arg1: [%s] arg2: [%s] arg3: [%s]\n",
obj->obj_UnderlyingDatatypePtr->size,
arg1, arg2, arg3);
return result;
@@ -1392,32 +507,36 @@ Here is a desultory example of the implementation of the call function. ::
getiterfunc tp_iter;
iternextfunc tp_iternext;
-These functions provide support for the iterator protocol. Any object which
-wishes to support iteration over its contents (which may be generated during
-iteration) must implement the ``tp_iter`` handler. Objects which are returned
-by a ``tp_iter`` handler must implement both the ``tp_iter`` and ``tp_iternext``
-handlers. Both handlers take exactly one parameter, the instance for which they
-are being called, and return a new reference. In the case of an error, they
-should set an exception and return *NULL*.
-
-For an object which represents an iterable collection, the ``tp_iter`` handler
-must return an iterator object. The iterator object is responsible for
-maintaining the state of the iteration. For collections which can support
-multiple iterators which do not interfere with each other (as lists and tuples
-do), a new iterator should be created and returned. Objects which can only be
-iterated over once (usually due to side effects of iteration) should implement
-this handler by returning a new reference to themselves, and should also
-implement the ``tp_iternext`` handler. File objects are an example of such an
-iterator.
-
-Iterator objects should implement both handlers. The ``tp_iter`` handler should
-return a new reference to the iterator (this is the same as the ``tp_iter``
-handler for objects which can only be iterated over destructively). The
-``tp_iternext`` handler should return a new reference to the next object in the
-iteration if there is one. If the iteration has reached the end, it may return
-*NULL* without setting an exception or it may set :exc:`StopIteration`; avoiding
-the exception can yield slightly better performance. If an actual error occurs,
-it should set an exception and return *NULL*.
+These functions provide support for the iterator protocol. Both handlers
+take exactly one parameter, the instance for which they are being called,
+and return a new reference. In the case of an error, they should set an
+exception and return *NULL*. :c:member:`~PyTypeObject.tp_iter` corresponds
+to the Python :meth:`__iter__` method, while :c:member:`~PyTypeObject.tp_iternext`
+corresponds to the Python :meth:`~iterator.__next__` method.
+
+Any :term:`iterable` object must implement the :c:member:`~PyTypeObject.tp_iter`
+handler, which must return an :term:`iterator` object. Here the same guidelines
+apply as for Python classes:
+
+* For collections (such as lists and tuples) which can support multiple
+ independent iterators, a new iterator should be created and returned by
+ each call to :c:member:`~PyTypeObject.tp_iter`.
+* Objects which can only be iterated over once (usually due to side effects of
+ iteration, such as file objects) can implement :c:member:`~PyTypeObject.tp_iter`
+ by returning a new reference to themselves -- and should also therefore
+ implement the :c:member:`~PyTypeObject.tp_iternext` handler.
+
+Any :term:`iterator` object should implement both :c:member:`~PyTypeObject.tp_iter`
+and :c:member:`~PyTypeObject.tp_iternext`. An iterator's
+:c:member:`~PyTypeObject.tp_iter` handler should return a new reference
+to the iterator. Its :c:member:`~PyTypeObject.tp_iternext` handler should
+return a new reference to the next object in the iteration, if there is one.
+If the iteration has reached the end, :c:member:`~PyTypeObject.tp_iternext`
+may return *NULL* without setting an exception, or it may set
+:exc:`StopIteration` *in addition* to returning *NULL*; avoiding
+the exception can yield slightly better performance. If an actual error
+occurs, :c:member:`~PyTypeObject.tp_iternext` should always set an exception
+and return *NULL*.
.. _weakref-support:
@@ -1425,110 +544,76 @@ it should set an exception and return *NULL*.
Weak Reference Support
----------------------
-One of the goals of Python's weak-reference implementation is to allow any type
+One of the goals of Python's weak reference implementation is to allow any type
to participate in the weak reference mechanism without incurring the overhead on
-those objects which do not benefit by weak referencing (such as numbers).
+performance-critical objects (such as numbers).
-For an object to be weakly referencable, the extension must include a
-:c:type:`PyObject\*` field in the instance structure for the use of the weak
-reference mechanism; it must be initialized to *NULL* by the object's
-constructor. It must also set the :c:member:`~PyTypeObject.tp_weaklistoffset` field of the
-corresponding type object to the offset of the field. For example, the instance
-type is defined with the following structure::
+.. seealso::
+ Documentation for the :mod:`weakref` module.
- typedef struct {
- PyObject_HEAD
- PyClassObject *in_class; /* The class object */
- PyObject *in_dict; /* A dictionary */
- PyObject *in_weakreflist; /* List of weak references */
- } PyInstanceObject;
-
-The statically-declared type object for instances is defined this way::
-
- PyTypeObject PyInstance_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- 0,
- "module.instance",
-
- /* Lots of stuff omitted for brevity... */
-
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
- };
+For an object to be weakly referencable, the extension type must do two things:
-The type constructor is responsible for initializing the weak reference list to
-*NULL*::
+#. Include a :c:type:`PyObject\*` field in the C object structure dedicated to
+ the weak reference mechanism. The object's constructor should leave it
+ *NULL* (which is automatic when using the default
+ :c:member:`~PyTypeObject.tp_alloc`).
- static PyObject *
- instance_new() {
- /* Other initialization stuff omitted for brevity */
+#. Set the :c:member:`~PyTypeObject.tp_weaklistoffset` type member
+ to the offset of the aforementioned field in the C object structure,
+ so that the interpreter knows how to access and modify that field.
- self->in_weakreflist = NULL;
+Concretely, here is how a trivial object structure would be augmented
+with the required field::
- return (PyObject *) self;
- }
+ typedef struct {
+ PyObject_HEAD
+ PyObject *weakreflist; /* List of weak references */
+ } TrivialObject;
-The only further addition is that the destructor needs to call the weak
-reference manager to clear any weak references. This is only required if the
-weak reference list is non-*NULL*::
+And the corresponding member in the statically-declared type object::
- static void
- instance_dealloc(PyInstanceObject *inst)
- {
- /* Allocate temporaries if needed, but do not begin
- destruction just yet.
- */
+ static PyTypeObject TrivialType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /* ... other members omitted for brevity ... */
+ .tp_weaklistoffset = offsetof(TrivialObject, weakreflist),
+ };
- if (inst->in_weakreflist != NULL)
- PyObject_ClearWeakRefs((PyObject *) inst);
+The only further addition is that ``tp_dealloc`` needs to clear any weak
+references (by calling :c:func:`PyObject_ClearWeakRefs`) if the field is
+non-*NULL*::
- /* Proceed with object destruction normally. */
+ static void
+ Trivial_dealloc(TrivialObject *self)
+ {
+ /* Clear weakrefs first before calling any destructors */
+ if (self->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) self);
+ /* ... remainder of destruction code omitted for brevity ... */
+ Py_TYPE(self)->tp_free((PyObject *) self);
}
More Suggestions
----------------
-Remember that you can omit most of these functions, in which case you provide
-``0`` as a value. There are type definitions for each of the functions you must
-provide. They are in :file:`object.h` in the Python include directory that
-comes with the source distribution of Python.
-
In order to learn how to implement any specific method for your new data type,
-do the following: Download and unpack the Python source distribution. Go to
-the :file:`Objects` directory, then search the C source files for ``tp_`` plus
-the function you want (for example, ``tp_richcompare``). You will find examples
-of the function you want to implement.
+get the :term:`CPython` source code. Go to the :file:`Objects` directory,
+then search the C source files for ``tp_`` plus the function you want
+(for example, ``tp_richcompare``). You will find examples of the function
+you want to implement.
-When you need to verify that an object is an instance of the type you are
-implementing, use the :c:func:`PyObject_TypeCheck` function. A sample of its use
-might be something like the following::
+When you need to verify that an object is a concrete instance of the type you
+are implementing, use the :c:func:`PyObject_TypeCheck` function. A sample of
+its use might be something like the following::
- if (! PyObject_TypeCheck(some_object, &MyType)) {
+ if (!PyObject_TypeCheck(some_object, &MyType)) {
PyErr_SetString(PyExc_TypeError, "arg #1 not a mything");
return NULL;
}
-.. rubric:: Footnotes
-
-.. [#] This is true when we know that the object is a basic type, like a string or a
- float.
-
-.. [#] We relied on this in the :c:member:`~PyTypeObject.tp_dealloc` handler in this example, because our
- type doesn't support garbage collection. Even if a type supports garbage
- collection, there are calls that can be made to "untrack" the object from
- garbage collection, however, these calls are advanced and not covered here.
-
-.. [#] We now know that the first and last members are strings, so perhaps we could be
- less careful about decrementing their reference counts, however, we accept
- instances of string subclasses. Even though deallocating normal strings won't
- call back into our objects, we can't guarantee that deallocating an instance of
- a string subclass won't call back into our objects.
+.. seealso::
+ Download CPython source releases.
+ https://www.python.org/downloads/source/
-.. [#] 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.
+ The CPython project on GitHub, where the CPython source code is developed.
+ https://github.com/python/cpython
diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst
new file mode 100644
index 0000000..ac48637
--- /dev/null
+++ b/Doc/extending/newtypes_tutorial.rst
@@ -0,0 +1,896 @@
+.. highlightlang:: c
+
+.. _defining-new-types:
+
+**********************************
+Defining Extension Types: Tutorial
+**********************************
+
+.. sectionauthor:: Michael Hudson
+.. sectionauthor:: Dave Kuhlman
+.. sectionauthor:: Jim Fulton
+
+
+Python allows the writer of a C extension module to define new types that
+can be manipulated from Python code, much like the built-in :class:`str`
+and :class:`list` types. The code for all extension types follows a
+pattern, but there are some details that you need to understand before you
+can get started. This document is a gentle introduction to the topic.
+
+
+.. _dnt-basics:
+
+The Basics
+==========
+
+The :term:`CPython` runtime sees all Python objects as variables of type
+:c:type:`PyObject\*`, which serves as a "base type" for all Python objects.
+The :c:type:`PyObject` structure itself only contains the object's
+:term:`reference count` and a pointer to the object's "type object".
+This is where the action is; the type object determines which (C) functions
+get called by the interpreter when, for instance, an attribute gets looked up
+on an object, a method called, or it is multiplied by another object. These
+C functions are called "type methods".
+
+So, if you want to define a new extension type, you need to create a new type
+object.
+
+This sort of thing can only be explained by example, so here's a minimal, but
+complete, module that defines a new type named :class:`Custom` inside a C
+extension module :mod:`custom`:
+
+.. note::
+ What we're showing here is the traditional way of defining *static*
+ extension types. It should be adequate for most uses. The C API also
+ allows defining heap-allocated extension types using the
+ :c:func:`PyType_FromSpec` function, which isn't covered in this tutorial.
+
+.. literalinclude:: ../includes/custom.c
+
+Now that's quite a bit to take in at once, but hopefully bits will seem familiar
+from the previous chapter. This file defines three things:
+
+#. What a :class:`Custom` **object** contains: this is the ``CustomObject``
+ struct, which is allocated once for each :class:`Custom` instance.
+#. How the :class:`Custom` **type** behaves: this is the ``CustomType`` struct,
+ which defines a set of flags and function pointers that the interpreter
+ inspects when specific operations are requested.
+#. How to initialize the :mod:`custom` module: this is the ``PyInit_custom``
+ function and the associated ``custommodule`` struct.
+
+The first bit is::
+
+ typedef struct {
+ PyObject_HEAD
+ } CustomObject;
+
+This is what a Custom object will contain. ``PyObject_HEAD`` is mandatory
+at the start of each object struct and defines a field called ``ob_base``
+of type :c:type:`PyObject`, containing a pointer to a type object and a
+reference count (these can be accessed using the macros :c:macro:`Py_REFCNT`
+and :c:macro:`Py_TYPE` respectively). The reason for the macro is to
+abstract away the layout and to enable additional fields in debug builds.
+
+.. note::
+ There is no semicolon above after the :c:macro:`PyObject_HEAD` macro.
+ Be wary of adding one by accident: some compilers will complain.
+
+Of course, objects generally store additional data besides the standard
+``PyObject_HEAD`` boilerplate; for example, here is the definition for
+standard Python floats::
+
+ typedef struct {
+ PyObject_HEAD
+ double ob_fval;
+ } PyFloatObject;
+
+The second bit is the definition of the type object. ::
+
+ static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_new = PyType_GenericNew,
+ };
+
+.. note::
+ We recommend using C99-style designated initializers as above, to
+ avoid listing all the :c:type:`PyTypeObject` fields that you don't care
+ about and also to avoid caring about the fields' declaration order.
+
+The actual definition of :c:type:`PyTypeObject` in :file:`object.h` has
+many more :ref:`fields ` than the definition above. The
+remaining fields will be filled with zeros by the C compiler, and it's
+common practice to not specify them explicitly unless you need them.
+
+We're going to pick it apart, one field at a time::
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+This line is mandatory boilerplate to initialize the ``ob_base``
+field mentioned above. ::
+
+ .tp_name = "custom.Custom",
+
+The name of our type. This will appear in the default textual representation of
+our objects and in some error messages, for example:
+
+.. code-block:: pycon
+
+ >>> "" + custom.Custom()
+ Traceback (most recent call last):
+ File "", line 1, in
+ TypeError: can only concatenate str (not "custom.Custom") to str
+
+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:`custom` and
+the type is :class:`Custom`, so we set the type name to :class:`custom.Custom`.
+Using the real dotted import path is important to make your type compatible
+with the :mod:`pydoc` and :mod:`pickle` modules. ::
+
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+
+This is so that Python knows how much memory to allocate when creating
+new :class:`Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is
+only used for variable-sized objects and should otherwise be zero.
+
+.. note::
+
+ If you want your type to be subclassable from Python, and your type has the same
+ :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have problems with multiple
+ inheritance. A Python subclass of your type will have to list your type first
+ in its :attr:`~class.__bases__`, or else it will not be able to call your type's
+ :meth:`__new__` method without getting an error. You can avoid this problem by
+ ensuring that your type has a larger value for :c:member:`~PyTypeObject.tp_basicsize` than its
+ base type does. Most of the time, this will be true anyway, because either your
+ base type will be :class:`object`, or else you will be adding data members to
+ your base type, and therefore increasing its size.
+
+We set the class flags to :const:`Py_TPFLAGS_DEFAULT`. ::
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+All types should include this constant in their flags. It enables all of the
+members defined until at least Python 3.3. If you need further members,
+you will need to OR the corresponding flags.
+
+We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. ::
+
+ .tp_doc = "Custom objects",
+
+To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new`
+handler. This is the equivalent of the Python method :meth:`__new__`, but
+has to be specified explicitly. In this case, we can just use the default
+implementation provided by the API function :c:func:`PyType_GenericNew`. ::
+
+ .tp_new = PyType_GenericNew,
+
+Everything else in the file should be familiar, except for some code in
+:c:func:`PyInit_custom`::
+
+ if (PyType_Ready(&CustomType) < 0)
+ return;
+
+This initializes the :class:`Custom` type, filling in a number of members
+to the appropriate default values, including :attr:`ob_type` that we initially
+set to *NULL*. ::
+
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+
+This adds the type to the module dictionary. This allows us to create
+:class:`Custom` instances by calling the :class:`Custom` class:
+
+.. code-block:: pycon
+
+ >>> import custom
+ >>> mycustom = custom.Custom()
+
+That's it! All that remains is to build it; put the above code in a file called
+:file:`custom.c` and:
+
+.. code-block:: python
+
+ from distutils.core import setup, Extension
+ setup(name="custom", version="1.0",
+ ext_modules=[Extension("custom", ["custom.c"])])
+
+in a file called :file:`setup.py`; then typing
+
+.. code-block:: shell-session
+
+ $ python setup.py build
+
+at a shell should produce a file :file:`custom.so` in a subdirectory; move to
+that directory and fire up Python --- you should be able to ``import custom`` and
+play around with Custom objects.
+
+That wasn't so hard, was it?
+
+Of course, the current Custom type is pretty uninteresting. It has no data and
+doesn't do anything. It can't even be subclassed.
+
+.. note::
+ While this documentation showcases the standard :mod:`distutils` module
+ for building C extensions, it is recommended in real-world use cases to
+ use the newer and better-maintained ``setuptools`` library. Documentation
+ on how to do this is out of scope for this document and can be found in
+ the `Python Packaging User's Guide `_.
+
+
+Adding data and methods to the Basic example
+============================================
+
+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:`custom2` that
+adds these capabilities:
+
+.. literalinclude:: ../includes/custom2.c
+
+
+This version of the module has a number of changes.
+
+We've added an extra include::
+
+ #include
+
+This include provides declarations that we use to handle attributes, as
+described a bit later.
+
+The :class:`Custom` type now has three data attributes in its C struct,
+*first*, *last*, and *number*. The *first* and *last* variables are Python
+strings containing first and last names. The *number* attribute is a C integer.
+
+The object structure is updated accordingly::
+
+ typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+ } CustomObject;
+
+Because we now have data to manage, we have to be more careful about object
+allocation and deallocation. At a minimum, we need a deallocation method::
+
+ static void
+ Custom_dealloc(CustomObject *self)
+ {
+ Py_XDECREF(self->first);
+ Py_XDECREF(self->last);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+ }
+
+which is assigned to the :c:member:`~PyTypeObject.tp_dealloc` member::
+
+ .tp_dealloc = (destructor) Custom_dealloc,
+
+This method first clears the reference counts of the two Python attributes.
+:c:func:`Py_XDECREF` correctly handles the case where its argument is
+*NULL* (which might happen here if ``tp_new`` failed midway). It then
+calls the :c:member:`~PyTypeObject.tp_free` member of the object's type
+(computed by ``Py_TYPE(self)``) to free the object's memory. Note that
+the object's type might not be :class:`CustomType`, because the object may
+be an instance of a subclass.
+
+.. note::
+ The explicit cast to ``destructor`` above is needed because we defined
+ ``Custom_dealloc`` to take a ``CustomObject *`` argument, but the ``tp_dealloc``
+ function pointer expects to receive a ``PyObject *`` argument. Otherwise,
+ the compiler will emit a warning. This is object-oriented polymorphism,
+ in C!
+
+We want to make sure that the first and last names are initialized to empty
+strings, so we provide a ``tp_new`` implementation::
+
+ static PyObject *
+ Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+ }
+
+and install it in the :c:member:`~PyTypeObject.tp_new` member::
+
+ .tp_new = Custom_new,
+
+The ``tp_new`` handler is responsible for creating (as opposed to initializing)
+objects of the type. It is exposed in Python as the :meth:`__new__` method.
+It is not required to define a ``tp_new`` member, and indeed many extension
+types will simply reuse :c:func:`PyType_GenericNew` as done in the first
+version of the ``Custom`` type above. In this case, we use the ``tp_new``
+handler to initialize the ``first`` and ``last`` attributes to non-*NULL*
+default values.
+
+``tp_new`` is passed the type being instantiated (not necessarily ``CustomType``,
+if a subclass is instantiated) and any arguments passed when the type was
+called, and is expected to return the instance created. ``tp_new`` handlers
+always accept positional and keyword arguments, but they often ignore the
+arguments, leaving the argument handling to initializer (a.k.a. ``tp_init``
+in C or ``__init__`` in Python) methods.
+
+.. note::
+ ``tp_new`` shouldn't call ``tp_init`` explicitly, as the interpreter
+ will do it itself.
+
+The ``tp_new`` implementation calls the :c:member:`~PyTypeObject.tp_alloc`
+slot to allocate memory::
+
+ self = (CustomObject *) type->tp_alloc(type, 0);
+
+Since memory allocation may fail, we must check the :c:member:`~PyTypeObject.tp_alloc`
+result against *NULL* before proceeding.
+
+.. note::
+ We didn't fill the :c:member:`~PyTypeObject.tp_alloc` slot ourselves. Rather
+ :c:func:`PyType_Ready` fills it for us by inheriting it from our base class,
+ which is :class:`object` by default. Most types use the default allocation
+ strategy.
+
+.. note::
+ If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one
+ that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:`__new__`),
+ you must *not* try to determine what method to call using method resolution
+ order at runtime. Always statically determine what type you are going to
+ call, and call its :c:member:`~PyTypeObject.tp_new` directly, or via
+ ``type->tp_base->tp_new``. If you do not do this, Python subclasses of your
+ type that also inherit from other Python-defined classes may not work correctly.
+ (Specifically, you may not be able to create instances of such subclasses
+ without getting a :exc:`TypeError`.)
+
+We also define an initialization function which accepts arguments to provide
+initial values for our instance::
+
+ static int
+ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+ {
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_XDECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_XDECREF(tmp);
+ }
+ return 0;
+ }
+
+by filling the :c:member:`~PyTypeObject.tp_init` slot. ::
+
+ .tp_init = (initproc) Custom_init,
+
+The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the
+:meth:`__init__` method. It is used to initialize an object after it's
+created. Initializers always accept positional and keyword arguments,
+and they should return either ``0`` on success or ``-1`` on error.
+
+Unlike the ``tp_new`` handler, there is no guarantee that ``tp_init``
+is called at all (for example, the :mod:`pickle` module by default
+doesn't call :meth:`__init__` on unpickled instances). It can also be
+called multiple times. Anyone can call the :meth:`__init__` method on
+our objects. For this reason, we have to be extra careful when assigning
+the new attribute values. We might be tempted, for example to assign the
+``first`` member like this::
+
+ if (first) {
+ Py_XDECREF(self->first);
+ Py_INCREF(first);
+ self->first = first;
+ }
+
+But this would be risky. Our type doesn't restrict the type of the
+``first`` member, so it could be any kind of object. It could have a
+destructor that causes code to be executed that tries to access the
+``first`` member; or that destructor could release the
+:term:`Global interpreter Lock` and let arbitrary code run in other
+threads that accesses and modifies our object.
+
+To be paranoid and protect ourselves against this possibility, we almost
+always reassign members before decrementing their reference counts. When
+don't we have to do this?
+
+* when we absolutely know that the reference count is greater than 1;
+
+* when we know that deallocation of the object [#]_ will neither release
+ the :term:`GIL` nor cause any calls back into our type's code;
+
+* when decrementing a reference count in a :c:member:`~PyTypeObject.tp_dealloc`
+ handler on a type which doesn't support cyclic garbage collection [#]_.
+
+We want to expose our instance variables as attributes. There are a
+number of ways to do that. The simplest way is to define member definitions::
+
+ static PyMemberDef Custom_members[] = {
+ {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0,
+ "first name"},
+ {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0,
+ "last name"},
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+ };
+
+and put the definitions in the :c:member:`~PyTypeObject.tp_members` slot::
+
+ .tp_members = Custom_members,
+
+Each member definition has a member name, type, offset, access flags and
+documentation string. See the :ref:`Generic-Attribute-Management` section
+below for details.
+
+A disadvantage of this approach is that it doesn't provide a way to restrict the
+types of objects that can be assigned to the Python attributes. We expect the
+first and last names to be strings, but any Python objects can be assigned.
+Further, the attributes can be deleted, setting the C pointers to *NULL*. Even
+though we can make sure the members are initialized to non-*NULL* values, the
+members can be set to *NULL* if the attributes are deleted.
+
+We define a single method, :meth:`Custom.name()`, that outputs the objects name as the
+concatenation of the first and last names. ::
+
+ static PyObject *
+ Custom_name(CustomObject *self)
+ {
+ if (self->first == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "first");
+ return NULL;
+ }
+ if (self->last == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "last");
+ return NULL;
+ }
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+ }
+
+The method is implemented as a C function that takes a :class:`Custom` (or
+:class:`Custom` 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 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:
+
+.. code-block:: python
+
+ def name(self):
+ return "%s %s" % (self.first, self.last)
+
+Note that we have to check for the possibility that our :attr:`first` and
+:attr:`last` members are *NULL*. This is because they can be deleted, in which
+case they are set to *NULL*. It would be better to prevent deletion of these
+attributes and to restrict the attribute values to be strings. We'll see how to
+do that in the next section.
+
+Now that we've defined the method, we need to create an array of method
+definitions::
+
+ static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+ };
+
+(note that we used the :const:`METH_NOARGS` flag to indicate that the method
+is expecting no arguments other than *self*)
+
+and assign it to the :c:member:`~PyTypeObject.tp_methods` slot::
+
+ .tp_methods = Custom_methods,
+
+Finally, we'll make our type usable as a base class for subclassing. We've
+written our methods carefully so far so that they don't make any assumptions
+about the type of the object being created or used, so all we need to do is
+to add the :const:`Py_TPFLAGS_BASETYPE` to our class flag definition::
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+We rename :c:func:`PyInit_custom` to :c:func:`PyInit_custom2`, update the
+module name in the :c:type:`PyModuleDef` struct, and update the full class
+name in the :c:type:`PyTypeObject` struct.
+
+Finally, we update our :file:`setup.py` file to build the new module:
+
+.. code-block:: python
+
+ from distutils.core import setup, Extension
+ setup(name="custom", version="1.0",
+ ext_modules=[
+ Extension("custom", ["custom.c"]),
+ Extension("custom2", ["custom2.c"]),
+ ])
+
+
+Providing finer control over data attributes
+============================================
+
+In this section, we'll provide finer control over how the :attr:`first` and
+:attr:`last` attributes are set in the :class:`Custom` example. In the previous
+version of our module, the instance variables :attr:`first` and :attr:`last`
+could be set to non-string values or even deleted. We want to make sure that
+these attributes always contain strings.
+
+.. literalinclude:: ../includes/custom3.c
+
+
+To provide greater control, over the :attr:`first` and :attr:`last` attributes,
+we'll use custom getter and setter functions. Here are the functions for
+getting and setting the :attr:`first` attribute::
+
+ static PyObject *
+ Custom_getfirst(CustomObject *self, void *closure)
+ {
+ Py_INCREF(self->first);
+ return self->first;
+ }
+
+ static int
+ Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
+ {
+ PyObject *tmp;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a string");
+ return -1;
+ }
+ tmp = self->first;
+ Py_INCREF(value);
+ self->first = value;
+ Py_DECREF(tmp);
+ return 0;
+ }
+
+The getter function is passed a :class:`Custom` object and a "closure", which is
+a void pointer. In this case, the closure is ignored. (The closure supports an
+advanced usage in which definition data is passed to the getter and setter. This
+could, for example, be used to allow a single set of getter and setter functions
+that decide the attribute to get or set based on data in the closure.)
+
+The setter function is passed the :class:`Custom` object, the new value, and the
+closure. The new value may be *NULL*, in which case the attribute is being
+deleted. In our setter, we raise an error if the attribute is deleted or if its
+new value is not a string.
+
+We create an array of :c:type:`PyGetSetDef` structures::
+
+ static PyGetSetDef Custom_getsetters[] = {
+ {"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
+ "first name", NULL},
+ {"last", (getter) Custom_getlast, (setter) Custom_setlast,
+ "last name", NULL},
+ {NULL} /* Sentinel */
+ };
+
+and register it in the :c:member:`~PyTypeObject.tp_getset` slot::
+
+ .tp_getset = Custom_getsetters,
+
+The last item in a :c:type:`PyGetSetDef` structure is the "closure" mentioned
+above. In this case, we aren't using a closure, so we just pass *NULL*.
+
+We also remove the member definitions for these attributes::
+
+ static PyMemberDef Custom_members[] = {
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+ };
+
+We also need to update the :c:member:`~PyTypeObject.tp_init` handler to only
+allow strings [#]_ to be passed::
+
+ static int
+ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+ {
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_DECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_DECREF(tmp);
+ }
+ return 0;
+ }
+
+With these changes, we can assure that the ``first`` and ``last`` members are
+never *NULL* so we can remove checks for *NULL* values in almost all cases.
+This means that most of the :c:func:`Py_XDECREF` calls can be converted to
+:c:func:`Py_DECREF` calls. The only place we can't change these calls is in
+the ``tp_dealloc`` implementation, where there is the possibility that the
+initialization of these members failed in ``tp_new``.
+
+We also rename the module initialization function and module name in the
+initialization function, as we did before, and we add an extra definition to the
+:file:`setup.py` file.
+
+
+Supporting cyclic garbage collection
+====================================
+
+Python has a :term:`cyclic garbage collector (GC) ` that
+can identify unneeded objects even when their reference counts are not zero.
+This can happen when objects are involved in cycles. For example, consider:
+
+.. code-block:: pycon
+
+ >>> l = []
+ >>> l.append(l)
+ >>> del l
+
+In this example, we create a list that contains itself. When we delete it, it
+still has a reference from itself. Its reference count doesn't drop to zero.
+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:`Custom` example, we allowed any kind of
+object to be stored in the :attr:`first` or :attr:`last` attributes [#]_.
+Besides, in the second and third versions, we allowed subclassing
+:class:`Custom`, and subclasses may add arbitrary attributes. For any of
+those two reasons, :class:`Custom` objects can participate in cycles:
+
+.. code-block:: pycon
+
+ >>> import custom3
+ >>> class Derived(custom3.Custom): pass
+ ...
+ >>> n = Derived()
+ >>> n.some_attribute = n
+
+To allow a :class:`Custom` instance participating in a reference cycle to
+be properly detected and collected by the cyclic GC, our :class:`Custom` type
+needs to fill two additional slots and to enable a flag that enables these slots:
+
+.. literalinclude:: ../includes/custom4.c
+
+
+First, the traversal method lets the cyclic GC know about subobjects that could
+participate in cycles::
+
+ static int
+ Custom_traverse(CustomObject *self, visitproc visit, void *arg)
+ {
+ int vret;
+ if (self->first) {
+ vret = visit(self->first, arg);
+ if (vret != 0)
+ return vret;
+ }
+ if (self->last) {
+ vret = visit(self->last, arg);
+ if (vret != 0)
+ return vret;
+ }
+ return 0;
+ }
+
+For each subobject that can participate in cycles, we need to call the
+:c:func:`visit` function, which is passed to the traversal method. The
+:c:func:`visit` function takes as arguments the subobject and the extra argument
+*arg* passed to the traversal method. It returns an integer value that must be
+returned if it is non-zero.
+
+Python provides a :c:func:`Py_VISIT` macro that automates calling visit
+functions. With :c:func:`Py_VISIT`, we can minimize the amount of boilerplate
+in ``Custom_traverse``::
+
+ static int
+ Custom_traverse(CustomObject *self, visitproc visit, void *arg)
+ {
+ Py_VISIT(self->first);
+ Py_VISIT(self->last);
+ return 0;
+ }
+
+.. note::
+ The :c:member:`~PyTypeObject.tp_traverse` implementation must name its
+ arguments exactly *visit* and *arg* in order to use :c:func:`Py_VISIT`.
+
+Second, we need to provide a method for clearing any subobjects that can
+participate in cycles::
+
+ static int
+ Custom_clear(CustomObject *self)
+ {
+ Py_CLEAR(self->first);
+ Py_CLEAR(self->last);
+ return 0;
+ }
+
+Notice the use of the :c:func:`Py_CLEAR` macro. It is the recommended and safe
+way to clear data attributes of arbitrary types while decrementing
+their reference counts. If you were to call :c:func:`Py_XDECREF` instead
+on the attribute before setting it to *NULL*, there is a possibility
+that the attribute's destructor would call back into code that reads the
+attribute again (*especially* if there is a reference cycle).
+
+.. note::
+ You could emulate :c:func:`Py_CLEAR` by writing::
+
+ PyObject *tmp;
+ tmp = self->first;
+ self->first = NULL;
+ Py_XDECREF(tmp);
+
+ Nevertheless, it is much easier and less error-prone to always
+ use :c:func:`Py_CLEAR` when deleting an attribute. Don't
+ try to micro-optimize at the expense of robustness!
+
+The deallocator ``Custom_dealloc`` may call arbitrary code when clearing
+attributes. It means the circular GC can be triggered inside the function.
+Since the GC assumes reference count is not zero, we need to untrack the object
+from the GC by calling :c:func:`PyObject_GC_UnTrack` before clearing members.
+Here is our reimplemented deallocator using :c:func:`PyObject_GC_UnTrack`
+and ``Custom_clear``::
+
+ static void
+ Custom_dealloc(CustomObject *self)
+ {
+ PyObject_GC_UnTrack(self);
+ Custom_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+ }
+
+Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags::
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+
+That's pretty much it. If we had written custom :c:member:`~PyTypeObject.tp_alloc` or
+:c:member:`~PyTypeObject.tp_free` handlers, we'd need to modify them for cyclic
+garbage collection. Most extensions will use the versions automatically provided.
+
+
+Subclassing other types
+=======================
+
+It is possible to create new extension types that are derived from existing
+types. It is easiest to inherit from the built in types, since an extension can
+easily use the :c:type:`PyTypeObject` it needs. It can be difficult to share
+these :c:type:`PyTypeObject` structures between extension modules.
+
+In this example we will create a :class:`SubList` type that inherits from the
+built-in :class:`list` type. The new type will be completely compatible with
+regular lists, but will have an additional :meth:`increment` method that
+increases an internal counter:
+
+.. code-block:: pycon
+
+ >>> import sublist
+ >>> s = sublist.SubList(range(3))
+ >>> s.extend(s)
+ >>> print(len(s))
+ 6
+ >>> print(s.increment())
+ 1
+ >>> print(s.increment())
+ 2
+
+.. literalinclude:: ../includes/sublist.c
+
+
+As you can see, the source code closely resembles the :class:`Custom` examples in
+previous sections. We will break down the main differences between them. ::
+
+ typedef struct {
+ PyListObject list;
+ int state;
+ } SubListObject;
+
+The primary difference for derived type objects is that the base type's
+object structure must be the first value. The base type will already include
+the :c:func:`PyObject_HEAD` at the beginning of its structure.
+
+When a Python object is a :class:`SubList` instance, its ``PyObject *`` pointer
+can be safely cast to both ``PyListObject *`` and ``SubListObject *``::
+
+ static int
+ SubList_init(SubListObject *self, PyObject *args, PyObject *kwds)
+ {
+ if (PyList_Type.tp_init((PyObject *) self, args, kwds) < 0)
+ return -1;
+ self->state = 0;
+ return 0;
+ }
+
+We see above how to call through to the :attr:`__init__` method of the base
+type.
+
+This pattern is important when writing a type with custom
+:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_dealloc`
+members. The :c:member:`~PyTypeObject.tp_new` handler should not actually
+create the memory for the object with its :c:member:`~PyTypeObject.tp_alloc`,
+but let the base class handle it by calling its own :c:member:`~PyTypeObject.tp_new`.
+
+The :c:type:`PyTypeObject` struct supports a :c:member:`~PyTypeObject.tp_base`
+specifying the type's concrete base class. Due to cross-platform compiler
+issues, you can't fill that field directly with a reference to
+:c:type:`PyList_Type`; it should be done later in the module initialization
+function::
+
+ PyMODINIT_FUNC
+ PyInit_sublist(void)
+ {
+ PyObject* m;
+ SubListType.tp_base = &PyList_Type;
+ if (PyType_Ready(&SubListType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&sublistmodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&SubListType);
+ PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+ return m;
+ }
+
+Before calling :c:func:`PyType_Ready`, the type structure must have the
+:c:member:`~PyTypeObject.tp_base` slot filled in. When we are deriving an
+existing type, it is not necessary to fill out the :c:member:`~PyTypeObject.tp_alloc`
+slot with :c:func:`PyType_GenericNew` -- the allocation function from the base
+type will be inherited.
+
+After that, calling :c:func:`PyType_Ready` and adding the type object to the
+module is the same as with the basic :class:`Custom` examples.
+
+
+.. rubric:: Footnotes
+
+.. [#] This is true when we know that the object is a basic type, like a string or a
+ float.
+
+.. [#] We relied on this in the :c:member:`~PyTypeObject.tp_dealloc` handler
+ in this example, because our type doesn't support garbage collection.
+
+.. [#] We now know that the first and last members are strings, so perhaps we
+ could be less careful about decrementing their reference counts, however,
+ we accept instances of string subclasses. Even though deallocating normal
+ strings won't call back into our objects, we can't guarantee that deallocating
+ an instance of a string subclass won't call back into our objects.
+
+.. [#] Also, even with our attributes restricted to strings instances, the user
+ could pass arbitrary :class:`str` subclasses and therefore still create
+ reference cycles.
diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst
index d4a97fd..4e842f5 100644
--- a/Doc/faq/general.rst
+++ b/Doc/faq/general.rst
@@ -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.
diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst
index b5fdfa4..1acfc26 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.
@@ -74,7 +74,9 @@ interpreter.
Occasionally, a user's environment is so full that the :program:`/usr/bin/env`
program fails; or there's no env program at all. In that case, you can try the
-following hack (due to Alex Rezinsky)::
+following hack (due to Alex Rezinsky):
+
+.. code-block:: sh
#! /bin/sh
""":"
@@ -609,7 +611,7 @@ use ``p.read(n)``.
"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
- `_.
+ `_.
How do I access the serial (RS232) port?
diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst
index 6ac83e4..f183984 100644
--- a/Doc/faq/windows.rst
+++ b/Doc/faq/windows.rst
@@ -1,5 +1,7 @@
:tocdepth: 2
+.. highlightlang:: none
+
.. _windows-faq:
=====================
@@ -39,12 +41,16 @@ or "Command prompt window". Usually you can create such a window from your
Start menu; under Windows 7 the menu selection is :menuselection:`Start -->
Programs --> Accessories --> Command Prompt`. You should be able to recognize
when you have started such a window because you will see a Windows "command
-prompt", which usually looks like this::
+prompt", which usually looks like this:
+
+.. code-block:: doscon
C:\>
The letter may be different, and there might be other things after it, so you
-might just as easily see something like::
+might just as easily see something like:
+
+.. code-block:: doscon
D:\YourName\Projects\Python>
@@ -60,11 +66,15 @@ program. So, how do you arrange for the interpreter to handle your Python?
First, you need to make sure that your command window recognises the word
"python" as an instruction to start the interpreter. If you have opened a
command window, you should try entering the command ``python`` and hitting
-return.::
+return:
+
+.. code-block:: doscon
C:\Users\YourName> python
-You should then see something like::
+You should then see something like:
+
+.. code-block:: pycon
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
@@ -73,7 +83,9 @@ You should then see something like::
You have started the interpreter in "interactive mode". That means you can enter
Python statements or expressions interactively and have them executed or
evaluated while you wait. This is one of Python's strongest features. Check it
-by entering a few expressions of your choice and seeing the results::
+by entering a few expressions of your choice and seeing the results:
+
+.. code-block:: pycon
>>> print("Hello")
Hello
@@ -317,7 +329,9 @@ present, and ``getch()`` which gets one character without echoing it.
How do I emulate os.kill() in Windows?
--------------------------------------
-Prior to Python 2.7 and 3.2, to terminate a process, you can use :mod:`ctypes`::
+Prior to Python 2.7 and 3.2, to terminate a process, you can use :mod:`ctypes`:
+
+.. code-block:: python
import ctypes
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index aa5f47e..6dbf0c3 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -39,6 +39,20 @@ Glossary
and loaders (in the :mod:`importlib.abc` module). You can create your own
ABCs with the :mod:`abc` module.
+ annotation
+ A label associated with a variable, a class
+ attribute or a function parameter or return value,
+ used by convention as a :term:`type hint`.
+
+ Annotations of local variables cannot be accessed at runtime, but
+ annotations of global variables, class attributes, and functions
+ are stored in the :attr:`__annotations__`
+ special attribute of modules, classes, and functions,
+ respectively.
+
+ See :term:`variable annotation`, :term:`function annotation`, :pep:`484`
+ and :pep:`526`, which describe this functionality.
+
argument
A value passed to a :term:`function` (or :term:`method`) when calling the
function. There are two kinds of argument:
@@ -100,7 +114,7 @@ Glossary
location execution state (including local variables and pending
try-statements). When the *asynchronous generator iterator* effectively
resumes with another awaitable returned by :meth:`__anext__`, it
- picks-up where it left-off. See :pep:`492` and :pep:`525`.
+ picks up where it left off. See :pep:`492` and :pep:`525`.
asynchronous iterable
An object, that can be used in an :keyword:`async for` statement.
@@ -136,8 +150,8 @@ Glossary
:data:`sys.stdout.buffer`, and instances of :class:`io.BytesIO` and
:class:`gzip.GzipFile`.
- .. seealso::
- A :term:`text file` reads and writes :class:`str` objects.
+ See also :term:`text file` for a file object able to read and write
+ :class:`str` objects.
bytes-like object
An object that supports the :ref:`bufferobjects` and can
@@ -175,6 +189,10 @@ Glossary
normally contain method definitions which operate on instances of the
class.
+ class variable
+ A variable defined in a class and intended to be modified only at
+ class level (i.e., not in an instance of the class).
+
coercion
The implicit conversion of an instance of one type to another during an
operation which involves two arguments of the same type. For example,
@@ -367,14 +385,20 @@ Glossary
and the :ref:`function` section.
function annotation
- An arbitrary metadata value associated with a function parameter or return
- value. Its syntax is explained in section :ref:`function`. Annotations
- may be accessed via the :attr:`__annotations__` special attribute of a
- function object.
+ An :term:`annotation` of a function parameter or return value.
- Python itself does not assign any particular meaning to function
- annotations. They are intended to be interpreted by third-party libraries
- or tools. See :pep:`3107`, which describes some of their potential uses.
+ Function annotations are usually used for
+ :term:`type hints `: for example this function is expected to take two
+ :class:`int` arguments and is also expected to have an :class:`int`
+ return value::
+
+ def sum_two_numbers(a: int, b: int) -> int:
+ return a + b
+
+ Function annotation syntax is explained in section :ref:`function`.
+
+ See :term:`variable annotation` and :pep:`484`,
+ which describe this functionality.
__future__
A pseudo-module which programmers can use to enable new language features
@@ -411,8 +435,8 @@ Glossary
Each :keyword:`yield` temporarily suspends processing, remembering the
location execution state (including local variables and pending
- try-statements). When the *generator iterator* resumes, it picks-up where
- it left-off (in contrast to functions which start fresh on every
+ try-statements). When the *generator iterator* resumes, it picks up where
+ it left off (in contrast to functions which start fresh on every
invocation).
.. index:: single: generator expression
@@ -595,7 +619,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
@@ -829,6 +853,21 @@ Glossary
:class:`str` or :class:`bytes` result instead, respectively. Introduced
by :pep:`519`.
+ 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`.
+
portion
A set of files in a single directory (possibly stored in a zip file)
that contribute to a namespace package, as defined in :pep:`420`.
@@ -983,8 +1022,8 @@ Glossary
:data:`sys.stdin`, :data:`sys.stdout`, and instances of
:class:`io.StringIO`.
- .. seealso::
- A :term:`binary file` reads and write :class:`bytes` objects.
+ See also :term:`binary file` for a file object able to read and write
+ :term:`bytes-like objects `.
triple-quoted string
A string which is bound by three instances of either a quotation mark
@@ -1001,6 +1040,43 @@ Glossary
:attr:`~instance.__class__` attribute or can be retrieved with
``type(obj)``.
+ type alias
+ A synonym for a type, created by assigning the type to an identifier.
+
+ Type aliases are useful for simplifying :term:`type hints `.
+ For example::
+
+ from typing import List, Tuple
+
+ def remove_gray_shades(
+ colors: List[Tuple[int, int, int]]) -> List[Tuple[int, int, int]]:
+ pass
+
+ could be made more readable like this::
+
+ from typing import List, Tuple
+
+ Color = Tuple[int, int, int]
+
+ def remove_gray_shades(colors: List[Color]) -> List[Color]:
+ pass
+
+ See :mod:`typing` and :pep:`484`, which describe this functionality.
+
+ type hint
+ An :term:`annotation` that specifies the expected type for a variable, a class
+ attribute, or a function parameter or return value.
+
+ Type hints are optional and are not enforced by Python but
+ they are useful to static type analysis tools, and aid IDEs with code
+ completion and refactoring.
+
+ Type hints of global variables, class attributes, and functions,
+ but not local variables, can be accessed using
+ :func:`typing.get_type_hints`.
+
+ See :mod:`typing` and :pep:`484`, which describe this functionality.
+
universal newlines
A manner of interpreting text streams in which all of the following are
recognized as ending a line: the Unix end-of-line convention ``'\n'``,
@@ -1009,16 +1085,23 @@ Glossary
:func:`bytes.splitlines` for an additional use.
variable annotation
- A type metadata value associated with a module global variable or
- a class attribute. Its syntax is explained in section :ref:`annassign`.
- Annotations are stored in the :attr:`__annotations__` special
- attribute of a class or module object and can be accessed using
- :func:`typing.get_type_hints`.
+ An :term:`annotation` of a variable or a class attribute.
+
+ When annotating a variable or a class attribute, assignment is optional::
+
+ class C:
+ field: 'annotation'
+
+ Variable annotations are usually used for
+ :term:`type hints `: for example this variable is expected to take
+ :class:`int` values::
+
+ count: int = 0
+
+ Variable annotation syntax is explained in section :ref:`annassign`.
- Python itself does not assign any particular meaning to variable
- annotations. They are intended to be interpreted by third-party libraries
- or type checking tools. See :pep:`526`, :pep:`484` which describe
- some of their potential uses.
+ See :term:`function annotation`, :pep:`484`
+ and :pep:`526`, which describe this functionality.
virtual environment
A cooperatively isolated runtime environment that allows Python users
diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst
index 9d770f5..e78a022 100644
--- a/Doc/howto/argparse.rst
+++ b/Doc/howto/argparse.rst
@@ -24,7 +24,7 @@ Concepts
Let's show the sort of functionality that we are going to explore in this
introductory tutorial by making use of the :command:`ls` command:
-.. code-block:: sh
+.. code-block:: shell-session
$ ls
cpython devguide prog.py pypy rm-unused-function.patch
@@ -77,7 +77,7 @@ Let us start with a very simple example which does (almost) nothing::
Following is a result of running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
$ python3 prog.py --help
@@ -119,7 +119,7 @@ An example::
And running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
usage: prog.py [-h] echo
@@ -164,7 +164,7 @@ by reading the source code. So, let's make it a bit more useful::
And we get:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py -h
usage: prog.py [-h] echo
@@ -185,7 +185,7 @@ Now, how about doing something even more useful::
Following is a result of running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
Traceback (most recent call last):
@@ -206,7 +206,7 @@ give it as strings, unless we tell it otherwise. So, let's tell
Following is a result of running the code:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -233,7 +233,7 @@ have a look on how to add optional ones::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py --verbosity 1
verbosity turned on
@@ -279,7 +279,7 @@ Let's modify the code accordingly::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py --verbose
verbosity turned on
@@ -325,7 +325,7 @@ versions of the options. It's quite simple::
And here goes:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py -v
verbosity turned on
@@ -359,7 +359,7 @@ Our program keeps growing in complexity::
And now the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
usage: prog.py [-h] [-v] square
@@ -395,7 +395,7 @@ multiple verbosity values, and actually get to use them::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -429,7 +429,7 @@ Let's fix it by restricting the values the ``--verbosity`` option can accept::
And the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
@@ -470,7 +470,7 @@ verbosity argument (check the output of ``python --help``)::
We have introduced another action, "count",
to count the number of occurrences of a specific optional arguments:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -537,7 +537,7 @@ Let's fix::
And this is what it gives:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 -vvv
the square of 4 equals 16
@@ -581,7 +581,7 @@ it gets the ``None`` value, and that cannot be compared to an int value
And:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4
16
@@ -614,7 +614,7 @@ not just squares::
Output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py
usage: prog.py [-h] [-v] x y
@@ -652,7 +652,7 @@ to display *more* text instead::
Output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 2
16
@@ -695,7 +695,7 @@ which will be the opposite of the ``--verbose`` one::
Our program is now simpler, and we've lost some functionality for the sake of
demonstration. Anyways, here's the output:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py 4 2
4^2 == 16
@@ -739,7 +739,7 @@ Note that slight difference in the usage text. Note the ``[-v | -q]``,
which tells us that we can either use ``-v`` or ``-q``,
but not both at the same time:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 prog.py --help
usage: prog.py [-h] [-v | -q] x y
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 083a299..77b2aae 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -22,8 +22,8 @@ Argument Clinic How-To
compatibility for future versions. In other words: if you
maintain an external C extension for CPython, you're welcome
to experiment with Argument Clinic in your own code. But the
- version of Argument Clinic that ships with CPython 3.5 *could*
- be totally incompatible and break all your code.
+ version of Argument Clinic that ships with the next version
+ of CPython *could* be totally incompatible and break all your code.
The Goals Of Argument Clinic
============================
@@ -267,12 +267,16 @@ Let's dive in!
should get its own line. All the parameter lines should be
indented from the function name and the docstring.
- The general form of these parameter lines is as follows::
+ The general form of these parameter lines is as follows:
+
+ .. code-block:: none
name_of_parameter: converter
If the parameter has a default value, add that after the
- converter::
+ converter:
+
+ .. code-block:: none
name_of_parameter: converter = default_value
@@ -925,13 +929,17 @@ Parameter default values
------------------------
Default values for parameters can be any of a number of values.
-At their simplest, they can be string, int, or float literals::
+At their simplest, they can be string, int, or float literals:
+
+.. code-block:: none
foo: str = "abc"
bar: int = 123
bat: float = 45.6
-They can also use any of Python's built-in constants::
+They can also use any of Python's built-in constants:
+
+.. code-block:: none
yep: bool = True
nope: bool = False
@@ -959,7 +967,9 @@ It can be an entire expression, using math operators and looking up attributes
on objects. However, this support isn't exactly simple, because of some
non-obvious semantics.
-Consider the following example::
+Consider the following example:
+
+.. code-block:: none
foo: Py_ssize_t = sys.maxsize - 1
@@ -970,7 +980,9 @@ runtime, when the user asks for the function's signature.
What namespace is available when the expression is evaluated? It's evaluated
in the context of the module the builtin came from. So, if your module has an
-attribute called "``max_widgets``", you may simply use it::
+attribute called "``max_widgets``", you may simply use it:
+
+.. code-block:: none
foo: Py_ssize_t = max_widgets
@@ -982,7 +994,9 @@ it's best to restrict yourself to modules that are preloaded by Python itself.)
Evaluating default values only at runtime means Argument Clinic can't compute
the correct equivalent C default value. So you need to tell it explicitly.
When you use an expression, you must also specify the equivalent expression
-in C, using the ``c_default`` parameter to the converter::
+in C, using the ``c_default`` parameter to the converter:
+
+.. code-block:: none
foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1
@@ -1359,7 +1373,9 @@ Let's start with defining some terminology:
A field, in this context, is a subsection of Clinic's output.
For example, the ``#define`` for the ``PyMethodDef`` structure
is a field, called ``methoddef_define``. Clinic has seven
- different fields it can output per function definition::
+ different fields it can output per function definition:
+
+ .. code-block:: none
docstring_prototype
docstring_definition
@@ -1416,7 +1432,9 @@ Let's start with defining some terminology:
Clinic defines five new directives that let you reconfigure its output.
-The first new directive is ``dump``::
+The first new directive is ``dump``:
+
+.. code-block:: none
dump
@@ -1425,7 +1443,9 @@ the current block, and empties it. This only works with ``buffer`` and
``two-pass`` destinations.
The second new directive is ``output``. The most basic form of ``output``
-is like this::
+is like this:
+
+.. code-block:: none
output
@@ -1433,7 +1453,9 @@ This tells Clinic to output *field* to *destination*. ``output`` also
supports a special meta-destination, called ``everything``, which tells
Clinic to output *all* fields to that *destination*.
-``output`` has a number of other functions::
+``output`` has a number of other functions:
+
+.. code-block:: none
output push
output pop
@@ -1508,7 +1530,9 @@ preset configurations, as follows:
Suppresses the ``impl_prototype``, write the ``docstring_definition``
and ``parser_definition`` to ``buffer``, write everything else to ``block``.
-The third new directive is ``destination``::
+The third new directive is ``destination``:
+
+.. code-block:: none
destination [...]
@@ -1516,7 +1540,9 @@ This performs an operation on the destination named ``name``.
There are two defined subcommands: ``new`` and ``clear``.
-The ``new`` subcommand works like this::
+The ``new`` subcommand works like this:
+
+.. code-block:: none
destination new
@@ -1564,7 +1590,9 @@ There are five destination types:
A two-pass buffer, like the "two-pass" builtin destination above.
-The ``clear`` subcommand works like this::
+The ``clear`` subcommand works like this:
+
+.. code-block:: none
destination clear
@@ -1572,7 +1600,9 @@ It removes all the accumulated text up to this point in the destination.
(I don't know what you'd need this for, but I thought maybe it'd be
useful while someone's experimenting.)
-The fourth new directive is ``set``::
+The fourth new directive is ``set``:
+
+.. code-block:: none
set line_prefix "string"
set line_suffix "string"
@@ -1590,7 +1620,9 @@ Both of these support two format strings:
Turns into the string ``*/``, the end-comment text sequence for C files.
The final new directive is one you shouldn't need to use directly,
-called ``preserve``::
+called ``preserve``:
+
+.. code-block:: none
preserve
@@ -1638,7 +1670,9 @@ like so::
#endif /* HAVE_FUNCTIONNAME */
Then, remove those three lines from the ``PyMethodDef`` structure,
-replacing them with the macro Argument Clinic generated::
+replacing them with the macro Argument Clinic generated:
+
+.. code-block:: none
MODULE_FUNCTIONNAME_METHODDEF
diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst
index 1d3bfb8..d5c0771 100644
--- a/Doc/howto/curses.rst
+++ b/Doc/howto/curses.rst
@@ -41,7 +41,7 @@ appearance---and the curses library will figure out what control codes
need to be sent to the terminal to produce the right output. curses
doesn't provide many user-interface concepts such as buttons, checkboxes,
or dialogs; if you need such features, consider a user interface library such as
-`Urwid `_.
+`Urwid `_.
The curses library was originally written for BSD Unix; the later System V
versions of Unix from AT&T added many enhancements and new functions. BSD curses
@@ -55,7 +55,7 @@ everything, though.
The Windows version of Python doesn't include the :mod:`curses`
module. A ported version called `UniCurses
-`_ is available. You could
+`_ is available. You could
also try `the Console module `_
written by Fredrik Lundh, which doesn't
use the same API as curses but provides cursor-addressable text output
@@ -432,7 +432,7 @@ User Input
The C curses library offers only very simple input mechanisms. Python's
:mod:`curses` module adds a basic text-input widget. (Other libraries
-such as `Urwid `_ have more extensive
+such as `Urwid `_ have more extensive
collections of widgets.)
There are two methods for getting input from a window:
diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst
index 7fca9aa..54c3fe3 100644
--- a/Doc/howto/instrumentation.rst
+++ b/Doc/howto/instrumentation.rst
@@ -254,11 +254,15 @@ and the remainder indicates the call/return hierarchy as the script executes.
For a `--enable-shared` build of CPython, the markers are contained within the
libpython shared library, and the probe's dotted path needs to reflect this. For
-example, this line from the above example::
+example, this line from the above example:
+
+.. code-block:: none
probe process("python").mark("function__entry") {
-should instead read::
+should instead read:
+
+.. code-block:: none
probe process("python").library("libpython3.6dm.so.1.0").mark("function__entry") {
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 598df53..96d550c 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -72,7 +72,9 @@ Here is the auxiliary module::
def some_function():
module_logger.info('received a call to "some_function"')
-The output looks like this::
+The output looks like this:
+
+.. code-block:: none
2005-03-23 23:47:11,663 - spam_application - INFO -
creating an instance of auxiliary_module.Auxiliary
@@ -127,7 +129,9 @@ shows logging from the main (initial) thread and another thread::
if __name__ == '__main__':
main()
-When run, the script should print something like the following::
+When run, the script should print something like the following:
+
+.. code-block:: none
0 Thread-1 Hi from myfunc
3 MainThread Hello from main
@@ -240,14 +244,18 @@ messages should not. Here's how you can achieve this::
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')
-When you run this, on the console you will see ::
+When you run this, on the console you will see
+
+.. code-block:: none
root : INFO Jackdaws love my big sphinx of quartz.
myapp.area1 : INFO How quickly daft jumping zebras vex.
myapp.area2 : WARNING Jail zesty vixen who grabbed pay from quack.
myapp.area2 : ERROR The five boxing wizards jump quickly.
-and in the file you will see something like ::
+and in the file you will see something like
+
+.. code-block:: none
10-22 22:19 root INFO Jackdaws love my big sphinx of quartz.
10-22 22:19 myapp.area1 DEBUG Quick zephyrs blow, vexing daft Jim.
@@ -515,7 +523,9 @@ module. Here is a basic working example::
main()
First run the server, and then the client. On the client side, nothing is
-printed on the console; on the server side, you should see something like::
+printed on the console; on the server side, you should see something like:
+
+.. code-block:: none
About to start TCP server...
59 root INFO Jackdaws love my big sphinx of quartz.
@@ -675,7 +685,9 @@ script::
lvlname = logging.getLevelName(lvl)
a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
-which, when run, produces something like::
+which, when run, produces something like:
+
+.. code-block:: none
2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred A debug message
2010-09-06 22:38:15,300 a.b.c INFO IP: 192.168.0.1 User: sheila An info message with some parameters
@@ -976,7 +988,9 @@ logging package provides a :class:`~handlers.RotatingFileHandler`::
print(filename)
The result should be 6 separate files, each with part of the log history for the
-application::
+application:
+
+.. code-block:: none
logging_rotatingfile_example.out
logging_rotatingfile_example.out.1
@@ -1638,11 +1652,11 @@ works::
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 `_.)
+Order Mark (BOM), followed by Unicode encoded using UTF-8. (See the
+:rfc:`relevant section of the specification <5424#section-6>`.)
In Python 3.1, code was added to
:class:`~logging.handlers.SysLogHandler` to insert a BOM into the message, but
@@ -1652,7 +1666,7 @@ appear before it.
As this behaviour is broken, the incorrect BOM insertion code is being removed
from Python 3.2.4 and later. However, it is not being replaced, and if you
-want to produce RFC 5424-compliant messages which include a BOM, an optional
+want to produce :rfc:`5424`-compliant messages which include a BOM, an optional
pure-ASCII sequence before it and arbitrary Unicode after it, encoded using
UTF-8, then you need to do the following:
@@ -1675,7 +1689,7 @@ UTF-8, then you need to do the following:
The formatted message *will* be encoded using UTF-8 encoding by
``SysLogHandler``. If you follow the above rules, you should be able to produce
-RFC 5424-compliant messages. If you don't, logging may not complain, but your
+:rfc:`5424`-compliant messages. If you don't, logging may not complain, but your
messages will not be RFC 5424-compliant, and your syslog daemon may complain.
@@ -1706,7 +1720,9 @@ which uses JSON to serialise the event in a machine-parseable manner::
logging.basicConfig(level=logging.INFO, format='%(message)s')
logging.info(_('message 1', foo='bar', bar='baz', num=123, fnum=123.456))
-If the above script is run, it prints::
+If the above script is run, it prints:
+
+.. code-block:: none
message 1 >>> {"fnum": 123.456, "num": 123, "bar": "baz", "foo": "bar"}
@@ -1753,7 +1769,9 @@ as in the following complete example::
if __name__ == '__main__':
main()
-When the above script is run, it prints::
+When the above script is run, it prints:
+
+.. code-block:: none
message 1 >>> {"snowman": "\u2603", "set_value": [1, 2, 3]}
@@ -2083,7 +2101,9 @@ most obvious, but you can provide any callable which returns a
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::
+script will print:
+
+.. code-block:: none
changed: hello
@@ -2150,7 +2170,9 @@ class, as shown in the following example::
if __name__ == '__main__':
main()
-When run, this produces a file with exactly two lines::
+When run, this produces a file with exactly two lines:
+
+.. code-block:: none
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'|
@@ -2312,7 +2334,9 @@ Here's the script::
write_line('Calling decorated foo with True')
assert decorated_foo(True)
-When this script is run, the following output should be observed::
+When this script is run, the following output should be observed:
+
+.. code-block:: none
Calling undecorated foo with False
about to log at DEBUG ...
@@ -2408,7 +2432,9 @@ the following complete example::
logging.config.dictConfig(LOGGING)
logging.warning('The local time is %s', time.asctime())
-When this script is run, it should print something like::
+When this script is run, it should print something like:
+
+.. code-block:: none
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
diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst
index 8074b0f..9914f8d 100644
--- a/Doc/howto/logging.rst
+++ b/Doc/howto/logging.rst
@@ -134,7 +134,9 @@ interpreter, and don't just continue from the session described above::
logging.warning('And this, too')
And now if we open the file and look at what we have, we should find the log
-messages::
+messages:
+
+.. code-block:: none
DEBUG:root:This message should go to the log file
INFO:root:So should this
@@ -144,7 +146,9 @@ This example also shows how you can set the logging level which acts as the
threshold for tracking. In this case, because we set the threshold to
``DEBUG``, all of the messages were printed.
-If you want to set the logging level from a command-line option such as::
+If you want to set the logging level from a command-line option such as:
+
+.. code-block:: none
--log=INFO
@@ -208,7 +212,9 @@ could organize logging in it::
def do_something():
logging.info('Doing something')
-If you run *myapp.py*, you should see this in *myapp.log*::
+If you run *myapp.py*, you should see this in *myapp.log*:
+
+.. code-block:: none
INFO:root:Started
INFO:root:Doing something
@@ -258,7 +264,9 @@ specify the format you want to use::
logging.info('So should this')
logging.warning('And this, too')
-which would print::
+which would print:
+
+.. code-block:: none
DEBUG:This message should appear on the console
INFO:So should this
@@ -282,19 +290,23 @@ your format string::
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.')
-which should print something like this::
+which should print something like this:
+
+.. code-block:: none
2010-12-12 11:41:42,612 is when this event was logged.
-The default format for date/time display (shown above) is ISO8601. If you need
-more control over the formatting of the date/time, provide a *datefmt*
-argument to ``basicConfig``, as in this example::
+The default format for date/time display (shown above) is like ISO8601 or
+:rfc:`3339`. If you need more control over the formatting of the date/time, provide
+a *datefmt* argument to ``basicConfig``, as in this example::
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')
-which would display something like this::
+which would display something like this:
+
+.. code-block:: none
12/12/2010 11:46:36 AM is when this event was logged.
@@ -376,7 +388,9 @@ if no destination is set; and if one is not set, they will set a destination
of the console (``sys.stderr``) and a default format for the displayed
message before delegating to the root logger to do the actual message output.
-The default format set by :func:`basicConfig` for messages is::
+The default format set by :func:`basicConfig` for messages is:
+
+.. code-block:: none
severity:logger name:message
@@ -522,7 +536,9 @@ indicator.
.. method:: logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
If there is no message format string, the default is to use the
-raw message. If there is no date format string, the default date format is::
+raw message. If there is no date format string, the default date format is:
+
+.. code-block:: none
%Y-%m-%d %H:%M:%S
@@ -628,7 +644,9 @@ the names of the objects::
logger.error('error message')
logger.critical('critical message')
-Here is the logging.conf file::
+Here is the logging.conf file:
+
+.. code-block:: ini
[loggers]
keys=root,simpleExample
@@ -713,7 +731,9 @@ construct the dictionary in Python code, receive it in pickled form over a
socket, or use whatever approach makes sense for your application.
Here's an example of the same configuration as above, in YAML format for
-the new dictionary-based approach::
+the new dictionary-based approach:
+
+.. code-block:: yaml
version: 1
formatters:
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
index 8562d23..88b0177 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -427,25 +427,25 @@ to make sure everything functions as expected in both versions of Python.
.. _2to3: https://docs.python.org/3/library/2to3.html
-.. _caniusepython3: https://pypi.python.org/pypi/caniusepython3
+.. _caniusepython3: https://pypi.org/project/caniusepython3
.. _cheat sheet: http://python-future.org/compatible_idioms.html
-.. _coverage.py: https://pypi.python.org/pypi/coverage
+.. _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.python.org/pypi/importlib2
+.. _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.python.org/pypi/pylint
+.. _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.python.org/pypi/six
-.. _tox: https://pypi.python.org/pypi/tox
-.. _trove classifier: https://pypi.python.org/pypi?%3Aaction=list_classifiers
+.. _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
diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst
index a3a6553..65b0945 100644
--- a/Doc/howto/regex.rst
+++ b/Doc/howto/regex.rst
@@ -786,7 +786,9 @@ Frequently you need to obtain more information than just whether the RE matched
or not. Regular expressions are often used to dissect strings by writing a RE
divided into several subgroups which match different components of interest.
For example, an RFC-822 header line is divided into a header name and a value,
-separated by a ``':'``, like this::
+separated by a ``':'``, like this:
+
+.. code-block:: none
From: author@example.com
User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst
index b54e150..ec5d48e 100644
--- a/Doc/howto/unicode.rst
+++ b/Doc/howto/unicode.rst
@@ -30,7 +30,9 @@ spellings such as 'coöperate'.)
For a while people just wrote programs that didn't display accents.
In the mid-1980s an Apple II BASIC program written by a French speaker
-might have lines like these::
+might have lines like these:
+
+.. code-block:: basic
PRINT "MISE A JOUR TERMINEE"
PRINT "PARAMETRES ENREGISTRES"
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index 8d383e0..7505e75 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -56,12 +56,20 @@ The simplest way to use urllib.request is as follows::
with urllib.request.urlopen('http://python.org/') as response:
html = response.read()
-If you wish to retrieve a resource via URL and store it in a temporary location,
-you can do so via the :func:`~urllib.request.urlretrieve` function::
+If you wish to retrieve a resource via URL and store it in a temporary
+location, you can do so via the :func:`shutil.copyfileobj` and
+:func:`tempfile.NamedTemporaryFile` functions::
+ import shutil
+ import tempfile
import urllib.request
- local_filename, headers = urllib.request.urlretrieve('http://python.org/')
- html = open(local_filename)
+
+ with urllib.request.urlopen('http://python.org/') as response:
+ with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
+ shutil.copyfileobj(response, tmp_file)
+
+ with open(tmp_file.name) as html:
+ pass
Many uses of urllib will be that simple (note that instead of an 'http:' URL we
could have used a URL starting with 'ftp:', 'file:', etc.). However, it's the
@@ -231,7 +239,7 @@ a different URL, urllib will handle that for you). For those it can't handle,
urlopen will raise an :exc:`HTTPError`. Typical errors include '404' (page not
found), '403' (request forbidden), and '401' (authentication required).
-See section 10 of RFC 2616 for a reference on all the HTTP error codes.
+See section 10 of :rfc:`2616` for a reference on all the HTTP error codes.
The :exc:`HTTPError` instance raised will have an integer 'code' attribute, which
corresponds to the error sent by the server.
@@ -244,7 +252,7 @@ codes in the 100--299 range indicate success, you will usually only see error
codes in the 400--599 range.
:attr:`http.server.BaseHTTPRequestHandler.responses` is a useful dictionary of
-response codes in that shows all the response codes used by RFC 2616. The
+response codes in that shows all the response codes used by :rfc:`2616`. The
dictionary is reproduced here for convenience ::
# Table mapping response codes to messages; entries have the
@@ -457,7 +465,9 @@ error code) requesting authentication. This specifies the authentication scheme
and a 'realm'. The header looks like: ``WWW-Authenticate: SCHEME
realm="REALM"``.
-e.g. ::
+e.g.
+
+.. code-block:: none
WWW-Authenticate: Basic realm="cPanel Users"
diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c
new file mode 100644
index 0000000..fb2c7b2
--- /dev/null
+++ b/Doc/includes/custom.c
@@ -0,0 +1,39 @@
+#include
+
+typedef struct {
+ PyObject_HEAD
+ /* Type-specific fields go here. */
+} CustomObject;
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_new = PyType_GenericNew,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c
new file mode 100644
index 0000000..51ab4b8
--- /dev/null
+++ b/Doc/includes/custom2.c
@@ -0,0 +1,132 @@
+#include
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+} CustomObject;
+
+static void
+Custom_dealloc(CustomObject *self)
+{
+ Py_XDECREF(self->first);
+ Py_XDECREF(self->last);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static PyObject *
+Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+}
+
+static int
+Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_XDECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_XDECREF(tmp);
+ }
+ return 0;
+}
+
+static PyMemberDef Custom_members[] = {
+ {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0,
+ "first name"},
+ {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0,
+ "last name"},
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
+{
+ if (self->first == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "first");
+ return NULL;
+ }
+ if (self->last == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "last");
+ return NULL;
+ }
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+}
+
+static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom2.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = Custom_new,
+ .tp_init = (initproc) Custom_init,
+ .tp_dealloc = (destructor) Custom_dealloc,
+ .tp_members = Custom_members,
+ .tp_methods = Custom_methods,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom2",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom2(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c
new file mode 100644
index 0000000..09e8735
--- /dev/null
+++ b/Doc/includes/custom3.c
@@ -0,0 +1,183 @@
+#include
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+} CustomObject;
+
+static void
+Custom_dealloc(CustomObject *self)
+{
+ Py_XDECREF(self->first);
+ Py_XDECREF(self->last);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static PyObject *
+Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+}
+
+static int
+Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_DECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_DECREF(tmp);
+ }
+ return 0;
+}
+
+static PyMemberDef Custom_members[] = {
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_getfirst(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->first);
+ return self->first;
+}
+
+static int
+Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
+{
+ PyObject *tmp;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a string");
+ return -1;
+ }
+ tmp = self->first;
+ Py_INCREF(value);
+ self->first = value;
+ Py_DECREF(tmp);
+ return 0;
+}
+
+static PyObject *
+Custom_getlast(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->last);
+ return self->last;
+}
+
+static int
+Custom_setlast(CustomObject *self, PyObject *value, void *closure)
+{
+ PyObject *tmp;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The last attribute value must be a string");
+ return -1;
+ }
+ tmp = self->last;
+ Py_INCREF(value);
+ self->last = value;
+ Py_DECREF(tmp);
+ return 0;
+}
+
+static PyGetSetDef Custom_getsetters[] = {
+ {"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
+ "first name", NULL},
+ {"last", (getter) Custom_getlast, (setter) Custom_setlast,
+ "last name", NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+}
+
+static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom3.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = Custom_new,
+ .tp_init = (initproc) Custom_init,
+ .tp_dealloc = (destructor) Custom_dealloc,
+ .tp_members = Custom_members,
+ .tp_methods = Custom_methods,
+ .tp_getset = Custom_getsetters,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom3",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom3(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c
new file mode 100644
index 0000000..0994d8f
--- /dev/null
+++ b/Doc/includes/custom4.c
@@ -0,0 +1,197 @@
+#include
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *first; /* first name */
+ PyObject *last; /* last name */
+ int number;
+} CustomObject;
+
+static int
+Custom_traverse(CustomObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->first);
+ Py_VISIT(self->last);
+ return 0;
+}
+
+static int
+Custom_clear(CustomObject *self)
+{
+ Py_CLEAR(self->first);
+ Py_CLEAR(self->last);
+ return 0;
+}
+
+static void
+Custom_dealloc(CustomObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ Custom_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static PyObject *
+Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ CustomObject *self;
+ self = (CustomObject *) type->tp_alloc(type, 0);
+ if (self != NULL) {
+ self->first = PyUnicode_FromString("");
+ if (self->first == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->last = PyUnicode_FromString("");
+ if (self->last == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->number = 0;
+ }
+ return (PyObject *) self;
+}
+
+static int
+Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"first", "last", "number", NULL};
+ PyObject *first = NULL, *last = NULL, *tmp;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
+ &first, &last,
+ &self->number))
+ return -1;
+
+ if (first) {
+ tmp = self->first;
+ Py_INCREF(first);
+ self->first = first;
+ Py_DECREF(tmp);
+ }
+ if (last) {
+ tmp = self->last;
+ Py_INCREF(last);
+ self->last = last;
+ Py_DECREF(tmp);
+ }
+ return 0;
+}
+
+static PyMemberDef Custom_members[] = {
+ {"number", T_INT, offsetof(CustomObject, number), 0,
+ "custom number"},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_getfirst(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->first);
+ return self->first;
+}
+
+static int
+Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
+{
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a string");
+ return -1;
+ }
+ Py_INCREF(value);
+ Py_CLEAR(self->first);
+ self->first = value;
+ return 0;
+}
+
+static PyObject *
+Custom_getlast(CustomObject *self, void *closure)
+{
+ Py_INCREF(self->last);
+ return self->last;
+}
+
+static int
+Custom_setlast(CustomObject *self, PyObject *value, void *closure)
+{
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
+ return -1;
+ }
+ if (!PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "The last attribute value must be a string");
+ return -1;
+ }
+ Py_INCREF(value);
+ Py_CLEAR(self->last);
+ self->last = value;
+ return 0;
+}
+
+static PyGetSetDef Custom_getsetters[] = {
+ {"first", (getter) Custom_getfirst, (setter) Custom_setfirst,
+ "first name", NULL},
+ {"last", (getter) Custom_getlast, (setter) Custom_setlast,
+ "last name", NULL},
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+Custom_name(CustomObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return PyUnicode_FromFormat("%S %S", self->first, self->last);
+}
+
+static PyMethodDef Custom_methods[] = {
+ {"name", (PyCFunction) Custom_name, METH_NOARGS,
+ "Return the name, combining the first and last name"
+ },
+ {NULL} /* Sentinel */
+};
+
+static PyTypeObject CustomType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "custom4.Custom",
+ .tp_doc = "Custom objects",
+ .tp_basicsize = sizeof(CustomObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ .tp_new = Custom_new,
+ .tp_init = (initproc) Custom_init,
+ .tp_dealloc = (destructor) Custom_dealloc,
+ .tp_traverse = (traverseproc) Custom_traverse,
+ .tp_clear = (inquiry) Custom_clear,
+ .tp_members = Custom_members,
+ .tp_methods = Custom_methods,
+ .tp_getset = Custom_getsetters,
+};
+
+static PyModuleDef custommodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "custom4",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_custom4(void)
+{
+ PyObject *m;
+ if (PyType_Ready(&CustomType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&custommodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&CustomType);
+ PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+ return m;
+}
diff --git a/Doc/includes/noddy.c b/Doc/includes/noddy.c
deleted file mode 100644
index 19a27a8..0000000
--- a/Doc/includes/noddy.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include
-
-typedef struct {
- PyObject_HEAD
- /* Type-specific fields go here. */
-} noddy_NoddyObject;
-
-static PyTypeObject noddy_NoddyType = {
- 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_reserved */
- 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 */
-};
-
-static PyModuleDef noddymodule = {
- PyModuleDef_HEAD_INIT,
- "noddy",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy(void)
-{
- PyObject* m;
-
- noddy_NoddyType.tp_new = PyType_GenericNew;
- if (PyType_Ready(&noddy_NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddymodule);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&noddy_NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
- return m;
-}
diff --git a/Doc/includes/noddy2.c b/Doc/includes/noddy2.c
deleted file mode 100644
index 9641558..0000000
--- a/Doc/includes/noddy2.c
+++ /dev/null
@@ -1,172 +0,0 @@
-#include
-#include "structmember.h"
-
-typedef struct {
- PyObject_HEAD
- PyObject *first; /* first name */
- PyObject *last; /* last name */
- int number;
-} Noddy;
-
-static void
-Noddy_dealloc(Noddy* self)
-{
- Py_XDECREF(self->first);
- Py_XDECREF(self->last);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
-}
-
-static int
-Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
-{
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_XDECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_XDECREF(tmp);
- }
-
- return 0;
-}
-
-
-static PyMemberDef Noddy_members[] = {
- {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
- "first name"},
- {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
- "last name"},
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_name(Noddy* self)
-{
- if (self->first == NULL) {
- PyErr_SetString(PyExc_AttributeError, "first");
- return NULL;
- }
-
- if (self->last == NULL) {
- PyErr_SetString(PyExc_AttributeError, "last");
- return NULL;
- }
-
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
-}
-
-static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NoddyType = {
- 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_reserved */
- 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 */
- Noddy_methods, /* tp_methods */
- Noddy_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Noddy_init, /* tp_init */
- 0, /* tp_alloc */
- Noddy_new, /* tp_new */
-};
-
-static PyModuleDef noddy2module = {
- PyModuleDef_HEAD_INIT,
- "noddy2",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy2(void)
-{
- PyObject* m;
-
- if (PyType_Ready(&NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddy2module);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
- return m;
-}
diff --git a/Doc/includes/noddy3.c b/Doc/includes/noddy3.c
deleted file mode 100644
index 8a5a753..0000000
--- a/Doc/includes/noddy3.c
+++ /dev/null
@@ -1,225 +0,0 @@
-#include
-#include "structmember.h"
-
-typedef struct {
- PyObject_HEAD
- PyObject *first;
- PyObject *last;
- int number;
-} Noddy;
-
-static void
-Noddy_dealloc(Noddy* self)
-{
- Py_XDECREF(self->first);
- Py_XDECREF(self->last);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
-}
-
-static int
-Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
-{
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_DECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_DECREF(tmp);
- }
-
- return 0;
-}
-
-static PyMemberDef Noddy_members[] = {
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_getfirst(Noddy *self, void *closure)
-{
- Py_INCREF(self->first);
- return self->first;
-}
-
-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 (! PyUnicode_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 *
-Noddy_getlast(Noddy *self, void *closure)
-{
- Py_INCREF(self->last);
- return self->last;
-}
-
-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 (! PyUnicode_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",
- (getter)Noddy_getfirst, (setter)Noddy_setfirst,
- "first name",
- NULL},
- {"last",
- (getter)Noddy_getlast, (setter)Noddy_setlast,
- "last name",
- NULL},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_name(Noddy* self)
-{
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
-}
-
-static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NoddyType = {
- 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_reserved */
- 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 */
- Noddy_methods, /* tp_methods */
- Noddy_members, /* tp_members */
- Noddy_getseters, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Noddy_init, /* tp_init */
- 0, /* tp_alloc */
- Noddy_new, /* tp_new */
-};
-
-static PyModuleDef noddy3module = {
- PyModuleDef_HEAD_INIT,
- "noddy3",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy3(void)
-{
- PyObject* m;
-
- if (PyType_Ready(&NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddy3module);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
- return m;
-}
diff --git a/Doc/includes/noddy4.c b/Doc/includes/noddy4.c
deleted file mode 100644
index 08ba4c3..0000000
--- a/Doc/includes/noddy4.c
+++ /dev/null
@@ -1,208 +0,0 @@
-#include
-#include "structmember.h"
-
-typedef struct {
- PyObject_HEAD
- PyObject *first;
- PyObject *last;
- int number;
-} Noddy;
-
-static int
-Noddy_traverse(Noddy *self, visitproc visit, void *arg)
-{
- int vret;
-
- if (self->first) {
- vret = visit(self->first, arg);
- if (vret != 0)
- return vret;
- }
- if (self->last) {
- vret = visit(self->last, arg);
- if (vret != 0)
- return vret;
- }
-
- return 0;
-}
-
-static int
-Noddy_clear(Noddy *self)
-{
- PyObject *tmp;
-
- tmp = self->first;
- self->first = NULL;
- Py_XDECREF(tmp);
-
- tmp = self->last;
- self->last = NULL;
- Py_XDECREF(tmp);
-
- return 0;
-}
-
-static void
-Noddy_dealloc(Noddy* self)
-{
- PyObject_GC_UnTrack(self);
- Noddy_clear(self);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Noddy *self;
-
- self = (Noddy *)type->tp_alloc(type, 0);
- if (self != NULL) {
- self->first = PyUnicode_FromString("");
- if (self->first == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->last = PyUnicode_FromString("");
- if (self->last == NULL) {
- Py_DECREF(self);
- return NULL;
- }
-
- self->number = 0;
- }
-
- return (PyObject *)self;
-}
-
-static int
-Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
-{
- PyObject *first=NULL, *last=NULL, *tmp;
-
- static char *kwlist[] = {"first", "last", "number", NULL};
-
- if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
- &first, &last,
- &self->number))
- return -1;
-
- if (first) {
- tmp = self->first;
- Py_INCREF(first);
- self->first = first;
- Py_XDECREF(tmp);
- }
-
- if (last) {
- tmp = self->last;
- Py_INCREF(last);
- self->last = last;
- Py_XDECREF(tmp);
- }
-
- return 0;
-}
-
-
-static PyMemberDef Noddy_members[] = {
- {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
- "first name"},
- {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
- "last name"},
- {"number", T_INT, offsetof(Noddy, number), 0,
- "noddy number"},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-Noddy_name(Noddy* self)
-{
- if (self->first == NULL) {
- PyErr_SetString(PyExc_AttributeError, "first");
- return NULL;
- }
-
- if (self->last == NULL) {
- PyErr_SetString(PyExc_AttributeError, "last");
- return NULL;
- }
-
- return PyUnicode_FromFormat("%S %S", self->first, self->last);
-}
-
-static PyMethodDef Noddy_methods[] = {
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
- "Return the name, combining the first and last name"
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NoddyType = {
- 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_reserved */
- 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 */
- Noddy_methods, /* tp_methods */
- Noddy_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Noddy_init, /* tp_init */
- 0, /* tp_alloc */
- Noddy_new, /* tp_new */
-};
-
-static PyModuleDef noddy4module = {
- PyModuleDef_HEAD_INIT,
- "noddy4",
- "Example module that creates an extension type.",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_noddy4(void)
-{
- PyObject* m;
-
- if (PyType_Ready(&NoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&noddy4module);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&NoddyType);
- PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
- return m;
-}
diff --git a/Doc/includes/shoddy.c b/Doc/includes/shoddy.c
deleted file mode 100644
index 0c6d412..0000000
--- a/Doc/includes/shoddy.c
+++ /dev/null
@@ -1,99 +0,0 @@
-#include
-
-typedef struct {
- PyListObject list;
- int state;
-} Shoddy;
-
-
-static PyObject *
-Shoddy_increment(Shoddy *self, PyObject *unused)
-{
- self->state++;
- return PyLong_FromLong(self->state);
-}
-
-
-static PyMethodDef Shoddy_methods[] = {
- {"increment", (PyCFunction)Shoddy_increment, METH_NOARGS,
- PyDoc_STR("increment state counter")},
- {NULL, NULL},
-};
-
-static int
-Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
-{
- if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
- return -1;
- self->state = 0;
- return 0;
-}
-
-
-static PyTypeObject ShoddyType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "shoddy.Shoddy", /* tp_name */
- sizeof(Shoddy), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 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 */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Shoddy_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)Shoddy_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-static PyModuleDef shoddymodule = {
- PyModuleDef_HEAD_INIT,
- "shoddy",
- "Shoddy module",
- -1,
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_shoddy(void)
-{
- PyObject *m;
-
- ShoddyType.tp_base = &PyList_Type;
- if (PyType_Ready(&ShoddyType) < 0)
- return NULL;
-
- m = PyModule_Create(&shoddymodule);
- if (m == NULL)
- return NULL;
-
- Py_INCREF(&ShoddyType);
- PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
- return m;
-}
diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c
new file mode 100644
index 0000000..376dddf
--- /dev/null
+++ b/Doc/includes/sublist.c
@@ -0,0 +1,63 @@
+#include
+
+typedef struct {
+ PyListObject list;
+ int state;
+} SubListObject;
+
+static PyObject *
+SubList_increment(SubListObject *self, PyObject *unused)
+{
+ self->state++;
+ return PyLong_FromLong(self->state);
+}
+
+static PyMethodDef SubList_methods[] = {
+ {"increment", (PyCFunction) SubList_increment, METH_NOARGS,
+ PyDoc_STR("increment state counter")},
+ {NULL},
+};
+
+static int
+SubList_init(SubListObject *self, PyObject *args, PyObject *kwds)
+{
+ if (PyList_Type.tp_init((PyObject *) self, args, kwds) < 0)
+ return -1;
+ self->state = 0;
+ return 0;
+}
+
+static PyTypeObject SubListType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "sublist.SubList",
+ .tp_doc = "SubList objects",
+ .tp_basicsize = sizeof(SubListObject),
+ .tp_itemsize = 0,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_init = (initproc) SubList_init,
+ .tp_methods = SubList_methods,
+};
+
+static PyModuleDef sublistmodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "sublist",
+ .m_doc = "Example module that creates an extension type.",
+ .m_size = -1,
+};
+
+PyMODINIT_FUNC
+PyInit_sublist(void)
+{
+ PyObject *m;
+ SubListType.tp_base = &PyList_Type;
+ if (PyType_Ready(&SubListType) < 0)
+ return NULL;
+
+ m = PyModule_Create(&sublistmodule);
+ if (m == NULL)
+ return NULL;
+
+ Py_INCREF(&SubListType);
+ PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+ return m;
+}
diff --git a/Doc/includes/test.py b/Doc/includes/test.py
index 9e9d4a6..09ebe3f 100644
--- a/Doc/includes/test.py
+++ b/Doc/includes/test.py
@@ -1,181 +1,168 @@
-"""Test module for the noddy examples
+"""Test module for the custom examples
-Noddy 1:
+Custom 1:
->>> import noddy
->>> n1 = noddy.Noddy()
->>> n2 = noddy.Noddy()
->>> del n1
->>> del n2
+>>> import custom
+>>> c1 = custom.Custom()
+>>> c2 = custom.Custom()
+>>> del c1
+>>> del c2
-Noddy 2
+Custom 2
->>> import noddy2
->>> n1 = noddy2.Noddy('jim', 'fulton', 42)
->>> n1.first
+>>> import custom2
+>>> c1 = custom2.Custom('jim', 'fulton', 42)
+>>> c1.first
'jim'
->>> n1.last
+>>> c1.last
'fulton'
->>> n1.number
+>>> c1.number
42
->>> n1.name()
+>>> c1.name()
'jim fulton'
->>> n1.first = 'will'
->>> n1.name()
+>>> c1.first = 'will'
+>>> c1.name()
'will fulton'
->>> n1.last = 'tell'
->>> n1.name()
+>>> c1.last = 'tell'
+>>> c1.name()
'will tell'
->>> del n1.first
->>> n1.name()
+>>> del c1.first
+>>> c1.name()
Traceback (most recent call last):
...
AttributeError: first
->>> n1.first
+>>> c1.first
Traceback (most recent call last):
...
AttributeError: first
->>> n1.first = 'drew'
->>> n1.first
+>>> c1.first = 'drew'
+>>> c1.first
'drew'
->>> del n1.number
+>>> del c1.number
Traceback (most recent call last):
...
TypeError: can't delete numeric/char attribute
->>> n1.number=2
->>> n1.number
+>>> c1.number=2
+>>> c1.number
2
->>> n1.first = 42
->>> n1.name()
+>>> c1.first = 42
+>>> c1.name()
'42 tell'
->>> n2 = noddy2.Noddy()
->>> n2.name()
+>>> c2 = custom2.Custom()
+>>> c2.name()
' '
->>> n2.first
+>>> c2.first
''
->>> n2.last
+>>> c2.last
''
->>> del n2.first
->>> n2.first
+>>> del c2.first
+>>> c2.first
Traceback (most recent call last):
...
AttributeError: first
->>> n2.first
+>>> c2.first
Traceback (most recent call last):
...
AttributeError: first
->>> n2.name()
+>>> c2.name()
Traceback (most recent call last):
File "", line 1, in ?
AttributeError: first
->>> n2.number
+>>> c2.number
0
->>> n3 = noddy2.Noddy('jim', 'fulton', 'waaa')
+>>> n3 = custom2.Custom('jim', 'fulton', 'waaa')
Traceback (most recent call last):
File "", line 1, in ?
-TypeError: an integer is required
->>> del n1
->>> del n2
+TypeError: an integer is required (got type str)
+>>> del c1
+>>> del c2
-Noddy 3
+Custom 3
->>> import noddy3
->>> n1 = noddy3.Noddy('jim', 'fulton', 42)
->>> n1 = noddy3.Noddy('jim', 'fulton', 42)
->>> n1.name()
+>>> import custom3
+>>> c1 = custom3.Custom('jim', 'fulton', 42)
+>>> c1 = custom3.Custom('jim', 'fulton', 42)
+>>> c1.name()
'jim fulton'
->>> del n1.first
+>>> del c1.first
Traceback (most recent call last):
File "", line 1, in ?
TypeError: Cannot delete the first attribute
->>> n1.first = 42
+>>> c1.first = 42
Traceback (most recent call last):
File "", line 1, in ?
TypeError: The first attribute value must be a string
->>> n1.first = 'will'
->>> n1.name()
+>>> c1.first = 'will'
+>>> c1.name()
'will fulton'
->>> n2 = noddy3.Noddy()
->>> n2 = noddy3.Noddy()
->>> n2 = noddy3.Noddy()
->>> n3 = noddy3.Noddy('jim', 'fulton', 'waaa')
+>>> c2 = custom3.Custom()
+>>> c2 = custom3.Custom()
+>>> c2 = custom3.Custom()
+>>> n3 = custom3.Custom('jim', 'fulton', 'waaa')
Traceback (most recent call last):
File "", line 1, in ?
-TypeError: an integer is required
->>> del n1
->>> del n2
+TypeError: an integer is required (got type str)
+>>> del c1
+>>> del c2
-Noddy 4
+Custom 4
->>> import noddy4
->>> n1 = noddy4.Noddy('jim', 'fulton', 42)
->>> n1.first
+>>> import custom4
+>>> c1 = custom4.Custom('jim', 'fulton', 42)
+>>> c1.first
'jim'
->>> n1.last
+>>> c1.last
'fulton'
->>> n1.number
+>>> c1.number
42
->>> n1.name()
+>>> c1.name()
'jim fulton'
->>> n1.first = 'will'
->>> n1.name()
+>>> c1.first = 'will'
+>>> c1.name()
'will fulton'
->>> n1.last = 'tell'
->>> n1.name()
+>>> c1.last = 'tell'
+>>> c1.name()
'will tell'
->>> del n1.first
->>> n1.name()
+>>> del c1.first
Traceback (most recent call last):
...
-AttributeError: first
->>> n1.first
-Traceback (most recent call last):
-...
-AttributeError: first
->>> n1.first = 'drew'
->>> n1.first
+TypeError: Cannot delete the first attribute
+>>> c1.name()
+'will tell'
+>>> c1.first = 'drew'
+>>> c1.first
'drew'
->>> del n1.number
+>>> del c1.number
Traceback (most recent call last):
...
TypeError: can't delete numeric/char attribute
->>> n1.number=2
->>> n1.number
+>>> c1.number=2
+>>> c1.number
2
->>> n1.first = 42
->>> n1.name()
-'42 tell'
->>> n2 = noddy4.Noddy()
->>> n2 = noddy4.Noddy()
->>> n2 = noddy4.Noddy()
->>> n2 = noddy4.Noddy()
->>> n2.name()
+>>> c1.first = 42
+Traceback (most recent call last):
+...
+TypeError: The first attribute value must be a string
+>>> c1.name()
+'drew tell'
+>>> c2 = custom4.Custom()
+>>> c2 = custom4.Custom()
+>>> c2 = custom4.Custom()
+>>> c2 = custom4.Custom()
+>>> c2.name()
' '
->>> n2.first
+>>> c2.first
''
->>> n2.last
+>>> c2.last
''
->>> del n2.first
->>> n2.first
-Traceback (most recent call last):
-...
-AttributeError: first
->>> n2.first
-Traceback (most recent call last):
-...
-AttributeError: first
->>> n2.name()
-Traceback (most recent call last):
- File "", line 1, in ?
-AttributeError: first
->>> n2.number
+>>> c2.number
0
->>> n3 = noddy4.Noddy('jim', 'fulton', 'waaa')
+>>> n3 = custom4.Custom('jim', 'fulton', 'waaa')
Traceback (most recent call last):
- File "", line 1, in ?
-TypeError: an integer is required
+...
+TypeError: an integer is required (got type str)
Test cyclic gc(?)
@@ -183,15 +170,14 @@ Test cyclic gc(?)
>>> import gc
>>> gc.disable()
->>> x = []
->>> l = [x]
->>> n2.first = l
->>> n2.first
-[[]]
->>> l.append(n2)
->>> del l
->>> del n1
->>> del n2
+>>> class Subclass(custom4.Custom): pass
+...
+>>> s = Subclass()
+>>> s.cycle = [s]
+>>> s.cycle.append(s.cycle)
+>>> x = object()
+>>> s.x = x
+>>> del s
>>> sys.getrefcount(x)
3
>>> ignore = gc.collect()
diff --git a/Doc/install/index.rst b/Doc/install/index.rst
index bc080b0..4842313 100644
--- a/Doc/install/index.rst
+++ b/Doc/install/index.rst
@@ -283,7 +283,9 @@ Windows, choose :menuselection:`Start --> Programs --> Python X.Y -->
Python (command line)`. Once the interpreter is started, you type Python code
at the prompt. For example, on my Linux system, I type the three Python
statements shown below, and get the output as shown, to find out my
-:file:`{prefix}` and :file:`{exec-prefix}`::
+:file:`{prefix}` and :file:`{exec-prefix}`:
+
+.. code-block:: pycon
Python 2.4 (#26, Aug 7 2004, 17:19:02)
Type "help", "copyright", "credits" or "license" for more information.
@@ -622,7 +624,9 @@ parsing your configuration file(s).
Obviously, specifying the entire installation scheme every time you install a
new module distribution would be very tedious. Thus, you can put these options
-into your Distutils config file (see section :ref:`inst-config-files`)::
+into your Distutils config file (see section :ref:`inst-config-files`):
+
+.. code-block:: ini
[install]
install-base=$HOME
@@ -631,7 +635,9 @@ into your Distutils config file (see section :ref:`inst-config-files`)::
install-scripts=python/scripts
install-data=python/data
-or, equivalently, ::
+or, equivalently,
+
+.. code-block:: ini
[install]
install-base=$HOME/python
@@ -718,7 +724,9 @@ A slightly less convenient way is to edit the :file:`site.py` file in Python's
standard library, and modify ``sys.path``. :file:`site.py` is automatically
imported when the Python interpreter is executed, unless the :option:`-S` switch
is supplied to suppress this behaviour. So you could simply edit
-:file:`site.py` and add two lines to it::
+:file:`site.py` and add two lines to it:
+
+.. code-block:: python
import sys
sys.path.append('/www/python/')
@@ -839,7 +847,9 @@ plus a ``global`` section for global options that affect every command. Each
section consists of one option per line, specified as ``option=value``.
For example, the following is a complete config file that just forces all
-commands to run quietly by default::
+commands to run quietly by default:
+
+.. code-block:: ini
[global]
verbose=0
@@ -853,7 +863,9 @@ distribution.
You could override the default "build base" directory and make the
:command:`build\*` commands always forcibly rebuild all files with the
-following::
+following:
+
+.. code-block:: ini
[build]
build-base=blib
diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst
index 09bb825..18f5b29 100644
--- a/Doc/installing/index.rst
+++ b/Doc/installing/index.rst
@@ -44,7 +44,7 @@ Key terms
``venv``. It allows virtual environments to be used on versions of
Python prior to 3.4, which either don't provide ``venv`` at all, or
aren't able to automatically install ``pip`` into created environments.
-* The `Python Packaging Index `__ is a public
+* 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
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index 27c7ba5..a9cb5c5 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -712,7 +712,7 @@ be positional::
Namespace(bar='BAR', foo='FOO')
>>> parser.parse_args(['--foo', 'FOO'])
usage: PROG [-h] [-f FOO] bar
- PROG: error: too few arguments
+ PROG: error: the following arguments are required: bar
action
@@ -898,7 +898,7 @@ values are:
Namespace(foo=['a', 'b'])
>>> parser.parse_args([])
usage: PROG [-h] foo [foo ...]
- PROG: error: too few arguments
+ PROG: error: the following arguments are required: foo
.. _`argparse.REMAINDER`:
@@ -981,7 +981,7 @@ is used when no command-line argument was present::
Providing ``default=argparse.SUPPRESS`` causes no attribute to be added if the
-command-line argument was not present.::
+command-line argument was not present::
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 27c170e..bdba996 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -389,6 +389,9 @@ Creating connections
See :ref:`UDP echo client protocol ` and
:ref:`UDP echo server protocol ` examples.
+ .. versionchanged:: 3.4.4
+ The *family*, *proto*, *flags*, *reuse_address*, *reuse_port,
+ *allow_broadcast*, and *sock* parameters were added.
.. coroutinemethod:: AbstractEventLoop.create_unix_connection(protocol_factory, path, \*, ssl=None, sock=None, server_hostname=None)
diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst
index 7970e90..3aa9ffe 100644
--- a/Doc/library/asyncio-eventloops.rst
+++ b/Doc/library/asyncio-eventloops.rst
@@ -169,12 +169,15 @@ An event loop policy must implement the following interface:
Get the event loop for the current context.
Returns an event loop object implementing the :class:`AbstractEventLoop`
- interface.
+ interface. In case called from coroutine, it returns the currently
+ running event loop.
Raises an exception in case no event loop has been set for the current
context and the current policy does not specify to create one. It must
never return ``None``.
+ .. versionchanged:: 3.6
+
.. method:: set_event_loop(loop)
Set the event loop for the current context to *loop*.
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index 5b801aa..c038333 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -568,6 +568,10 @@ Task functions
outer Future is *not* cancelled in this case. (This is to prevent the
cancellation of one child to cause other children to be cancelled.)
+ .. versionchanged:: 3.6.6
+ If the *gather* itself is cancelled, the cancellation is propagated
+ regardless of *return_exceptions*.
+
.. function:: iscoroutine(obj)
Return ``True`` if *obj* is a :ref:`coroutine object `,
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 0476f50..adb087e 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -77,7 +77,7 @@ The :mod:`binascii` module defines the following functions:
*quotetabs* is present and true, all tabs and spaces will be encoded. If the
optional argument *istext* is present and true, newlines are not encoded but
trailing whitespace will be encoded. If the optional argument *header* is
- present and true, spaces will be encoded as underscores per RFC1522. If the
+ present and true, spaces will be encoded as underscores per :rfc:`1522`. If the
optional argument *header* is present and false, newline characters will be
encoded as well; otherwise linefeed conversion might corrupt the binary data
stream.
diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst
index 74b24e1..24008a0 100644
--- a/Doc/library/codecs.rst
+++ b/Doc/library/codecs.rst
@@ -1425,7 +1425,7 @@ to the user.
Python supports this conversion in several ways: the ``idna`` codec performs
conversion between Unicode and ACE, separating an input string into labels
-based on the separator characters defined in `section 3.1`_ (1) of :rfc:`3490`
+based on the separator characters defined in :rfc:`section 3.1 of RFC 3490 <3490#section-3.1>`
and converting each label to ACE as required, and conversely separating an input
byte string into labels based on the ``.`` separator and converting any ACE
labels found into unicode. Furthermore, the :mod:`socket` module
@@ -1436,8 +1436,6 @@ parameters, such as :mod:`http.client` and :mod:`ftplib`, accept Unicode host
names (:mod:`http.client` then also transparently sends an IDNA hostname in the
:mailheader:`Host` field if it sends that field at all).
-.. _section 3.1: https://tools.ietf.org/html/rfc3490#section-3.1
-
When receiving host names from the wire (such as in reverse name lookup), no
automatic conversion to Unicode is performed: Applications wishing to present
such host names to the user should decode them to Unicode.
diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst
index 04c2a82..ba10727 100644
--- a/Doc/library/configparser.rst
+++ b/Doc/library/configparser.rst
@@ -1106,10 +1106,6 @@ ConfigParser Objects
given *section*. Optional arguments have the same meaning as for the
:meth:`get` method.
- .. versionchanged:: 3.2
- Items present in *vars* no longer appear in the result. The previous
- behaviour mixed actual parser options with variables provided for
- interpolation.
.. method:: set(section, option, value)
diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst
index e1290d4..08b8edc 100644
--- a/Doc/library/csv.rst
+++ b/Doc/library/csv.rst
@@ -452,8 +452,9 @@ read CSV files (assuming they support complex numbers at all).
.. method:: csvwriter.writerows(rows)
- Write all the *rows* parameters (a list of *row* objects as described above) to
- the writer's file object, formatted according to the current dialect.
+ Write all elements in *rows* (an iterable of *row* objects as described
+ above) to the writer's file object, formatted according to the current
+ dialect.
Writer objects have the following public attribute:
diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst
index 14e32d7..9d87db6 100644
--- a/Doc/library/curses.rst
+++ b/Doc/library/curses.rst
@@ -685,6 +685,12 @@ the following methods and attributes:
character previously painter at that location. By default, the character
position and attributes are the current settings for the window object.
+ .. note::
+
+ Writing outside the window, subwindow, or pad raises a :exc:`curses.error`.
+ Attempting to write to the lower right corner of a window, subwindow,
+ or pad will cause an exception to be raised after the character is printed.
+
.. method:: window.addnstr(str, n[, attr])
window.addnstr(y, x, str, n[, attr])
@@ -700,6 +706,12 @@ the following methods and attributes:
Paint the character string *str* at ``(y, x)`` with attributes
*attr*, overwriting anything previously on the display.
+ .. note::
+
+ Writing outside the window, subwindow, or pad raises :exc:`curses.error`.
+ Attempting to write to the lower right corner of a window, subwindow,
+ or pad will cause an exception to be raised after the string is printed.
+
.. method:: window.attroff(attr)
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index 98fe86e..06141d1 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -1027,8 +1027,7 @@ Instance methods:
If provided, *tz* must be an instance of a :class:`tzinfo` subclass, and its
:meth:`utcoffset` and :meth:`dst` methods must not return ``None``. If *self*
- is naive (``self.tzinfo is None``), it is presumed to represent time in the
- system timezone.
+ is naive, it is presumed to represent time in the system timezone.
If called without arguments (or with ``tz=None``) the system local
timezone is assumed for the target timezone. The ``.tzinfo`` attribute of the converted
diff --git a/Doc/library/distribution.rst b/Doc/library/distribution.rst
index 3e6e84b..8d4befe 100644
--- a/Doc/library/distribution.rst
+++ b/Doc/library/distribution.rst
@@ -4,7 +4,7 @@ Software Packaging and Distribution
These libraries help you with publishing and installing Python software.
While these modules are designed to work in conjunction with the
-`Python Package Index `__, they can also be used
+`Python Package Index `__, they can also be used
with a local index server, or without any index server at all.
.. toctree::
diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst
index f56836a..e09c7c0 100644
--- a/Doc/library/email.contentmanager.rst
+++ b/Doc/library/email.contentmanager.rst
@@ -126,9 +126,6 @@ Currently the email package provides only one concrete content manager,
set_content(msg, <'EmailMessage'>, cte=None, \
disposition=None, filename=None, cid=None, \
params=None, headers=None)
- set_content(msg, <'list'>, subtype='mixed', \
- disposition=None, filename=None, cid=None, \
- params=None, headers=None)
Add headers and payload to *msg*:
@@ -144,12 +141,6 @@ Currently the email package provides only one concrete content manager,
specified or ``rfc822`` if it is not. If *subtype* is
``partial``, raise an error (``bytes`` objects must be used to
construct ``message/partial`` parts).
- * For *<'list'>*, which should be a list of
- :class:`~email.message.EmailMessage` objects, set the ``maintype``
- to ``multipart``, and the ``subtype`` to *subtype* if it is
- specified, and ``mixed`` if it is not. If the message parts in
- the *<'list'>* have :mailheader:`MIME-Version` headers, remove
- them.
If *charset* is provided (which is valid only for ``str``), encode the
string to bytes using the specified character set. The default is
diff --git a/Doc/library/email.examples.rst b/Doc/library/email.examples.rst
index 84e9aee..fc96462 100644
--- a/Doc/library/email.examples.rst
+++ b/Doc/library/email.examples.rst
@@ -12,7 +12,7 @@ text content and the addresses may contain unicode characters):
.. literalinclude:: ../includes/email-simple.py
-Parsing RFC822 headers can easily be done by the using the classes
+Parsing :rfc:`822` headers can easily be done by the using the classes
from the :mod:`~email.parser` module:
.. literalinclude:: ../includes/email-headers.py
diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst
index 1e64e10..b4ed3b4 100644
--- a/Doc/library/email.generator.rst
+++ b/Doc/library/email.generator.rst
@@ -185,7 +185,7 @@ to be using :class:`BytesGenerator`, and not :class:`Generator`.
Convert any bytes with the high bit set as needed using an
ASCII-compatible :mailheader:`Content-Transfer-Encoding`. That is,
transform parts with non-ASCII :mailheader:`Cotnent-Transfer-Encoding`
- (:mailheader:`Content-Transfer-Encoding: 8bit`) to an ASCII compatibile
+ (:mailheader:`Content-Transfer-Encoding: 8bit`) to an ASCII compatible
:mailheader:`Content-Transfer-Encoding`, and encode RFC-invalid non-ASCII
bytes in headers using the MIME ``unknown-8bit`` character set, thus
rendering them RFC-compliant.
diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst
index d0c4cd0..94ebd87 100644
--- a/Doc/library/faulthandler.rst
+++ b/Doc/library/faulthandler.rst
@@ -152,10 +152,10 @@ these functions again each time that the file is replaced.
Example
-------
-.. highlight:: sh
-
Example of a segmentation fault on Linux with and without enabling the fault
-handler::
+handler:
+
+.. code-block:: shell-session
$ python3 -c "import ctypes; ctypes.string_at(0)"
Segmentation fault
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index 7291dfe..6c39f9a 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -295,7 +295,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
If optional *rest* is given, a ``REST`` command is sent to the server, passing
*rest* as an argument. *rest* is usually a byte offset into the requested file,
telling the server to restart sending the file's bytes at the requested offset,
- skipping over the initial bytes. Note however that RFC 959 requires only that
+ skipping over the initial bytes. Note however that :rfc:`959` requires only that
*rest* be a string containing characters in the printable range from ASCII code
33 to ASCII code 126. The :meth:`transfercmd` method, therefore, converts
*rest* to a string, but no check is performed on the string's contents. If the
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 9cb6b0e..501a3c9 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -657,8 +657,8 @@ are always available. They are listed here in alphabetical order.
.. function:: hex(x)
Convert an integer number to a lowercase hexadecimal string prefixed with
- "0x". If x is not a Python :class:`int` object, it has to define an
- __index__() method that returns an integer. Some examples:
+ "0x". If *x* is not a Python :class:`int` object, it has to define an
+ :meth:`__index__` method that returns an integer. Some examples:
>>> hex(255)
'0xff'
@@ -716,12 +716,10 @@ are always available. They are listed here in alphabetical order.
int(x, base=10)
Return an integer object constructed from a number or string *x*, or return
- ``0`` if no arguments are given. If *x* is a number, return
- :meth:`x.__int__() `. If *x* defines
- :meth:`x.__trunc__() ` but not
- :meth:`x.__int__() `, then return
- if :meth:`x.__trunc__() `. For floating point numbers,
- this truncates towards zero.
+ ``0`` if no arguments are given. If *x* defines :meth:`__int__`,
+ ``int(x)`` returns ``x.__int__()``. If *x* defines :meth:`__trunc__`,
+ it returns ``x.__trunc__()``.
+ For floating point numbers, this truncates towards zero.
If *x* is not a number or if *base* is given, then *x* must be a string,
:class:`bytes`, or :class:`bytearray` instance representing an :ref:`integer
@@ -1317,11 +1315,12 @@ are always available. They are listed here in alphabetical order.
equally close, rounding is done toward the even choice (so, for example,
both ``round(0.5)`` and ``round(-0.5)`` are ``0``, and ``round(1.5)`` is
``2``). Any integer value is valid for *ndigits* (positive, zero, or
- negative). The return value is an integer if called with one argument,
- otherwise of the same type as *number*.
+ negative). The return value is an integer if *ndigits* is omitted or
+ ``None``.
+ Otherwise the return value has the same type as *number*.
- For a general Python object ``number``, ``round(number, ndigits)`` delegates to
- ``number.__round__(ndigits)``.
+ For a general Python object ``number``, ``round`` delegates to
+ ``number.__round__``.
.. note::
diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst
index 3a27a5b..9bd39cb 100644
--- a/Doc/library/hashlib.rst
+++ b/Doc/library/hashlib.rst
@@ -283,7 +283,7 @@ BLAKE2
.. index::
single: blake2b, blake2s
-BLAKE2_ is a cryptographic hash function defined in RFC-7693_ that comes in two
+BLAKE2_ is a cryptographic hash function defined in :rfc:`7693` that comes in two
flavors:
* **BLAKE2b**, optimized for 64-bit platforms and produces digests of any size
@@ -707,7 +707,6 @@ Domain Dedication 1.0 Universal:
* *Alexandr Sokolovskiy*
-.. _RFC-7693: https://tools.ietf.org/html/rfc7693
.. _BLAKE2: https://blake2.net
.. _HMAC: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
.. _BLAKE: https://131002.net/blake/
diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst
index 5370601..d8da668 100644
--- a/Doc/library/http.cookiejar.rst
+++ b/Doc/library/http.cookiejar.rst
@@ -88,7 +88,7 @@ The following classes are provided:
:class:`DefaultCookiePolicy` objects.
:class:`DefaultCookiePolicy` implements the standard accept / reject rules for
- Netscape and RFC 2965 cookies. By default, RFC 2109 cookies (ie. cookies
+ Netscape and :rfc:`2965` cookies. By default, :rfc:`2109` cookies (ie. cookies
received in a :mailheader:`Set-Cookie` header with a version cookie-attribute of
1) are treated according to the RFC 2965 rules. However, if RFC 2965 handling
is turned off or :attr:`rfc2109_as_netscape` is ``True``, RFC 2109 cookies are
@@ -100,7 +100,7 @@ The following classes are provided:
.. class:: Cookie()
- This class represents Netscape, RFC 2109 and RFC 2965 cookies. It is not
+ This class represents Netscape, :rfc:`2109` and :rfc:`2965` cookies. It is not
expected that users of :mod:`http.cookiejar` construct their own :class:`Cookie`
instances. Instead, if necessary, call :meth:`make_cookies` on a
:class:`CookieJar` instance.
@@ -123,14 +123,14 @@ The following classes are provided:
the one sketched out in ``cookie_spec.html``.
:rfc:`2109` - HTTP State Management Mechanism
- Obsoleted by RFC 2965. Uses :mailheader:`Set-Cookie` with version=1.
+ Obsoleted by :rfc:`2965`. Uses :mailheader:`Set-Cookie` with version=1.
:rfc:`2965` - HTTP State Management Mechanism
The Netscape protocol with the bugs fixed. Uses :mailheader:`Set-Cookie2` in
place of :mailheader:`Set-Cookie`. Not widely used.
http://kristol.org/cookie/errata.html
- Unfinished errata to RFC 2965.
+ Unfinished errata to :rfc:`2965`.
:rfc:`2964` - Use of HTTP State Management
@@ -320,7 +320,7 @@ writing.
.. note::
- This loses information about RFC 2965 cookies, and also about newer or
+ This loses information about :rfc:`2965` cookies, and also about newer or
non-standard cookie-attributes such as ``port``.
.. warning::
@@ -410,13 +410,13 @@ be assigned to.
.. attribute:: CookiePolicy.rfc2965
- Implement RFC 2965 protocol.
+ Implement :rfc:`2965` protocol.
.. attribute:: CookiePolicy.hide_cookie2
Don't add :mailheader:`Cookie2` header to requests (the presence of this header
- indicates to the server that we understand RFC 2965 cookies).
+ indicates to the server that we understand :rfc:`2965` cookies).
The most useful way to define a :class:`CookiePolicy` class is by subclassing
from :class:`DefaultCookiePolicy` and overriding some or all of the methods
@@ -431,7 +431,7 @@ DefaultCookiePolicy Objects
Implements the standard rules for accepting and returning cookies.
-Both RFC 2965 and Netscape cookies are covered. RFC 2965 handling is switched
+Both :rfc:`2965` and Netscape cookies are covered. RFC 2965 handling is switched
off by default.
The easiest way to provide your own policy is to override this class and call
@@ -510,11 +510,11 @@ all be assigned to.
.. attribute:: DefaultCookiePolicy.rfc2109_as_netscape
- If true, request that the :class:`CookieJar` instance downgrade RFC 2109 cookies
+ If true, request that the :class:`CookieJar` instance downgrade :rfc:`2109` cookies
(ie. cookies received in a :mailheader:`Set-Cookie` header with a version
cookie-attribute of 1) to Netscape cookies by setting the version attribute of
the :class:`Cookie` instance to 0. The default value is :const:`None`, in which
- case RFC 2109 cookies are downgraded if and only if RFC 2965 handling is turned
+ case RFC 2109 cookies are downgraded if and only if :rfc:`2965` handling is turned
off. Therefore, RFC 2109 cookies are downgraded by default.
@@ -527,11 +527,11 @@ General strictness switches:
and isn't guaranteed to work!
-RFC 2965 protocol strictness switches:
+:rfc:`2965` protocol strictness switches:
.. attribute:: DefaultCookiePolicy.strict_rfc2965_unverifiable
- Follow RFC 2965 rules on unverifiable transactions (usually, an unverifiable
+ Follow :rfc:`2965` rules on unverifiable transactions (usually, an unverifiable
transaction is one resulting from a redirect or a request for an image hosted on
another site). If this is false, cookies are *never* blocked on the basis of
verifiability
@@ -541,7 +541,7 @@ Netscape protocol strictness switches:
.. attribute:: DefaultCookiePolicy.strict_ns_unverifiable
- Apply RFC 2965 rules on unverifiable transactions even to Netscape cookies.
+ Apply :rfc:`2965` rules on unverifiable transactions even to Netscape cookies.
.. attribute:: DefaultCookiePolicy.strict_ns_domain
@@ -581,7 +581,7 @@ both flags are set).
.. attribute:: DefaultCookiePolicy.DomainRFC2965Match
- When setting cookies, require a full RFC 2965 domain-match.
+ When setting cookies, require a full :rfc:`2965` domain-match.
The following attributes are provided for convenience, and are the most useful
combinations of the above flags:
@@ -605,7 +605,7 @@ Cookie Objects
standard cookie-attributes specified in the various cookie standards. The
correspondence is not one-to-one, because there are complicated rules for
assigning default values, because the ``max-age`` and ``expires``
-cookie-attributes contain equivalent information, and because RFC 2109 cookies
+cookie-attributes contain equivalent information, and because :rfc:`2109` cookies
may be 'downgraded' by :mod:`http.cookiejar` from version 1 to version 0 (Netscape)
cookies.
@@ -616,8 +616,8 @@ internal consistency, so you should know what you're doing if you do that.
.. attribute:: Cookie.version
- Integer or :const:`None`. Netscape cookies have :attr:`version` 0. RFC 2965 and
- RFC 2109 cookies have a ``version`` cookie-attribute of 1. However, note that
+ Integer or :const:`None`. Netscape cookies have :attr:`version` 0. :rfc:`2965` and
+ :rfc:`2109` cookies have a ``version`` cookie-attribute of 1. However, note that
:mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in which
case :attr:`version` is 0.
@@ -673,7 +673,7 @@ internal consistency, so you should know what you're doing if you do that.
.. attribute:: Cookie.rfc2109
- ``True`` if this cookie was received as an RFC 2109 cookie (ie. the cookie
+ ``True`` if this cookie was received as an :rfc:`2109` cookie (ie. the cookie
arrived in a :mailheader:`Set-Cookie` header, and the value of the Version
cookie-attribute in that header was 1). This attribute is provided because
:mod:`http.cookiejar` may 'downgrade' RFC 2109 cookies to Netscape cookies, in
@@ -745,7 +745,7 @@ cookies (assumes Unix/Netscape convention for location of the cookies file)::
r = opener.open("http://example.com/")
The next example illustrates the use of :class:`DefaultCookiePolicy`. Turn on
-RFC 2965 cookies, be more strict about domains when setting and returning
+:rfc:`2965` cookies, be more strict about domains when setting and returning
Netscape cookies, and block some domains from setting cookies or having them
returned::
diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst
index af15359..58e6193 100644
--- a/Doc/library/idle.rst
+++ b/Doc/library/idle.rst
@@ -274,7 +274,8 @@ Configure IDLE
Code Context (toggle)(Editor Window only)
Open a pane at the top of the edit window which shows the block context
- of the code which has scrolled above the top of the window.
+ of the code which has scrolled above the top of the window. Clicking a
+ line in this pane exposes that line at the top of the editor.
Window menu (Shell and Editor)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst
index 1632eb7..2e2c59c 100644
--- a/Doc/library/imaplib.rst
+++ b/Doc/library/imaplib.rst
@@ -342,7 +342,7 @@ An :class:`IMAP4` instance has the following methods:
.. method:: IMAP4.namespace()
- Returns IMAP namespaces as defined in RFC2342.
+ Returns IMAP namespaces as defined in :rfc:`2342`.
.. method:: IMAP4.noop()
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index d194362..c1cd948 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -799,7 +799,7 @@ find and load modules.
.. class:: WindowsRegistryFinder
:term:`Finder` for modules declared in the Windows registry. This class
- implements the :class:`importlib.abc.Finder` ABC.
+ implements the :class:`importlib.abc.MetaPathFinder` ABC.
Only class methods are defined by this class to alleviate the need for
instantiation.
diff --git a/Doc/library/index.rst b/Doc/library/index.rst
index a925e10..eadd0e4 100644
--- a/Doc/library/index.rst
+++ b/Doc/library/index.rst
@@ -30,7 +30,7 @@ optional components.
In addition to the standard library, there is a growing collection of
several thousand components (from individual programs and modules to
packages and entire application development frameworks), available from
-the `Python Package Index `_.
+the `Python Package Index `_.
.. toctree::
diff --git a/Doc/library/io.rst b/Doc/library/io.rst
index af38fd7..73b3eff 100644
--- a/Doc/library/io.rst
+++ b/Doc/library/io.rst
@@ -880,7 +880,7 @@ Text I/O
characters written are translated to the given string.
If *line_buffering* is ``True``, :meth:`flush` is implied when a call to
- write contains a newline character.
+ write contains a newline character or a carriage return.
If *write_through* is ``True``, calls to :meth:`write` are guaranteed
not to be buffered: any data written on the :class:`TextIOWrapper`
diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst
index b3c691e..4ce1ed1 100644
--- a/Doc/library/ipaddress.rst
+++ b/Doc/library/ipaddress.rst
@@ -89,7 +89,8 @@ Address objects
The :class:`IPv4Address` and :class:`IPv6Address` objects share a lot of common
attributes. Some attributes that are only meaningful for IPv6 addresses are
also implemented by :class:`IPv4Address` objects, in order to make it easier to
-write code that handles both IP versions correctly.
+write code that handles both IP versions correctly. Address objects are
+:term:`hashable`, so they can be used as keys in dictionaries.
.. class:: IPv4Address(address)
@@ -366,6 +367,8 @@ All attributes implemented by address objects are implemented by network
objects as well. In addition, network objects implement additional attributes.
All of these are common between :class:`IPv4Network` and :class:`IPv6Network`,
so to avoid duplication they are only documented for :class:`IPv4Network`.
+Network objects are :term:`hashable`, so they can be used as keys in
+dictionaries.
.. class:: IPv4Network(address, strict=True)
@@ -375,8 +378,9 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
a slash (``/``). The IP address is the network address, and the mask
can be either a single number, which means it's a *prefix*, or a string
representation of an IPv4 address. If it's the latter, the mask is
- interpreted as a *net mask* if it starts with a non-zero field, or as
- a *host mask* if it starts with a zero field. If no mask is provided,
+ interpreted as a *net mask* if it starts with a non-zero field, or as a
+ *host mask* if it starts with a zero field, with the single exception of
+ an all-zero mask which is treated as a *net mask*. If no mask is provided,
it's considered to be ``/32``.
For example, the following *address* specifications are equivalent:
@@ -406,7 +410,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
Unless stated otherwise, all network methods accepting other network/address
objects will raise :exc:`TypeError` if the argument's IP version is
- incompatible to ``self``
+ incompatible to ``self``.
.. versionchanged:: 3.5
@@ -416,7 +420,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
.. attribute:: max_prefixlen
Refer to the corresponding attribute documentation in
- :class:`IPv4Address`
+ :class:`IPv4Address`.
.. attribute:: is_multicast
.. attribute:: is_private
@@ -426,7 +430,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
.. attribute:: is_link_local
These attributes are true for the network as a whole if they are true
- for both the network address and the broadcast address
+ for both the network address and the broadcast address.
.. attribute:: network_address
@@ -479,12 +483,16 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
Returns an iterator over the usable hosts in the network. The usable
hosts are all the IP addresses that belong to the network, except the
- network address itself and the network broadcast address.
+ network address itself and the network broadcast address. For networks
+ with a mask length of 31, the network address and network broadcast
+ address are also included in the result.
>>> list(ip_network('192.0.2.0/29').hosts()) #doctest: +NORMALIZE_WHITESPACE
[IPv4Address('192.0.2.1'), IPv4Address('192.0.2.2'),
IPv4Address('192.0.2.3'), IPv4Address('192.0.2.4'),
IPv4Address('192.0.2.5'), IPv4Address('192.0.2.6')]
+ >>> list(ip_network('192.0.2.0/31').hosts())
+ [IPv4Address('192.0.2.0'), IPv4Address('192.0.2.1')]
.. method:: overlaps(other)
@@ -563,10 +571,10 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
Construct an IPv6 network definition. *address* can be one of the following:
- 1. A string consisting of an IP address and an optional mask, separated by
- a slash (``/``). The IP address is the network address, and the mask
- is a single number, which represents a *prefix*. If no mask is provided,
- it's considered to be ``/128``.
+ 1. A string consisting of an IP address and an optional prefix length,
+ separated by a slash (``/``). The IP address is the network address,
+ and the prefix length must be a single number, the *prefix*. If no
+ prefix length is provided, it's considered to be ``/128``.
Note that currently expanded netmasks are not supported. That means
``2001:db00::0/24`` is a valid argument while ``2001:db00::0/ffff:ff00::``
@@ -616,6 +624,12 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
.. attribute:: num_addresses
.. attribute:: prefixlen
.. method:: hosts()
+
+ Returns an iterator over the usable hosts in the network. The usable
+ hosts are all the IP addresses that belong to the network, except the
+ Subnet-Router anycast address. For networks with a mask length of 127,
+ the Subnet-Router anycast address is also included in the result.
+
.. method:: overlaps(other)
.. method:: address_exclude(network)
.. method:: subnets(prefixlen_diff=1, new_prefix=None)
@@ -623,12 +637,12 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
.. method:: compare_networks(other)
Refer to the corresponding attribute documentation in
- :class:`IPv4Network`
+ :class:`IPv4Network`.
.. attribute:: is_site_local
These attribute is true for the network as a whole if it is true
- for both the network address and the broadcast address
+ for both the network address and the broadcast address.
Operators
@@ -642,8 +656,8 @@ IPv6).
Logical operators
"""""""""""""""""
-Network objects can be compared with the usual set of logical operators,
-similarly to address objects.
+Network objects can be compared with the usual set of logical operators.
+Network objects are ordered first by network address, then by net mask.
Iteration
@@ -693,6 +707,9 @@ Network objects can act as containers of addresses. Some examples::
Interface objects
-----------------
+Interface objects are :term:`hashable`, so they can be used as keys in
+dictionaries.
+
.. class:: IPv4Interface(address)
Construct an IPv4 interface. The meaning of *address* is as in the
@@ -764,6 +781,30 @@ Interface objects
:class:`IPv4Interface`.
+Operators
+^^^^^^^^^
+
+Interface objects support some operators. Unless stated otherwise, operators
+can only be applied between compatible objects (i.e. IPv4 with IPv4, IPv6 with
+IPv6).
+
+
+Logical operators
+"""""""""""""""""
+
+Interface objects can be compared with the usual set of logical operators.
+
+For equality comparison (``==`` and ``!=``), both the IP address and network
+must be the same for the objects to be equal. An interface will not compare
+equal to any address or network object.
+
+For ordering (``<``, ``>``, etc) the rules are different. Interface and
+address objects with the same IP version can be compared, and the address
+objects will always sort before the interface objects. Two interface objects
+are first compared by their networks and, if those are the same, then by their
+IP addresses.
+
+
Other Module Level Functions
----------------------------
@@ -829,7 +870,7 @@ The module also provides the following module level functions:
doesn't make sense. There are some times however, where you may wish to
have :mod:`ipaddress` sort these anyway. If you need to do this, you can use
- this function as the ``key`` argument to :func:`sorted()`.
+ this function as the *key* argument to :func:`sorted()`.
*obj* is either a network or address object.
@@ -847,4 +888,4 @@ module defines the following exceptions:
.. exception:: NetmaskValueError(ValueError)
- Any value error related to the netmask.
+ Any value error related to the net mask.
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index 700a13a..3739f50 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -435,15 +435,24 @@ loops that truncate the stream.
# islice('ABCDEFG', 2, None) --> C D E F G
# islice('ABCDEFG', 0, None, 2) --> A C E G
s = slice(*args)
- it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1))
+ start, stop, step = s.start or 0, s.stop or sys.maxsize, s.step or 1
+ it = iter(range(start, stop, step))
try:
nexti = next(it)
except StopIteration:
+ # Consume *iterable* up to the *start* position.
+ for i, element in zip(range(start), iterable):
+ pass
return
- for i, element in enumerate(iterable):
- if i == nexti:
- yield element
- nexti = next(it)
+ try:
+ for i, element in enumerate(iterable):
+ if i == nexti:
+ yield element
+ nexti = next(it)
+ except StopIteration:
+ # Consume to *stop*.
+ for i, element in zip(range(i + 1, stop), iterable):
+ pass
If *start* is ``None``, then iteration starts at zero. If *step* is ``None``,
then the step defaults to one.
@@ -679,6 +688,11 @@ which incur interpreter overhead.
"Return first n items of the iterable as a list"
return list(islice(iterable, n))
+ def prepend(value, iterator):
+ "Prepend a single value in front of an iterator"
+ # prepend(1, [2, 3, 4]) -> 1 2 3 4
+ return chain([value], iterator)
+
def tabulate(function, start=0):
"Return function(0), function(1), ..."
return map(function, count(start))
@@ -688,8 +702,8 @@ which incur interpreter overhead.
# tail(3, 'ABCDEFG') --> E F G
return iter(collections.deque(iterable, maxlen=n))
- def consume(iterator, n):
- "Advance the iterator n-steps ahead. If n is none, consume entirely."
+ def consume(iterator, n=None):
+ "Advance the iterator n-steps ahead. If n is None, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
diff --git a/Doc/library/json.rst b/Doc/library/json.rst
index 829218d..d6dcd52 100644
--- a/Doc/library/json.rst
+++ b/Doc/library/json.rst
@@ -100,9 +100,9 @@ Extending :class:`JSONEncoder`::
['[2.0', ', 1.0', ']']
-.. highlight:: bash
+Using :mod:`json.tool` from the shell to validate and pretty-print:
-Using :mod:`json.tool` from the shell to validate and pretty-print::
+.. code-block:: shell-session
$ echo '{"json":"obj"}' | python -m json.tool
{
@@ -113,8 +113,6 @@ Using :mod:`json.tool` from the shell to validate and pretty-print::
See :ref:`json-commandline` for detailed documentation.
-.. highlight:: python3
-
.. note::
JSON is a subset of `YAML `_ 1.2. The JSON produced by
@@ -217,9 +215,9 @@ Basic Usage
.. function:: load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
- Deserialize *fp* (a ``.read()``-supporting :term:`file-like object`
- containing a JSON document) to a Python object using this :ref:`conversion
- table `.
+ Deserialize *fp* (a ``.read()``-supporting :term:`text file` or
+ :term:`binary file` containing a JSON document) to a Python object using
+ this :ref:`conversion table `.
*object_hook* is an optional function that will be called with the result of
any object literal decoded (a :class:`dict`). The return value of
@@ -266,6 +264,10 @@ Basic Usage
.. versionchanged:: 3.6
All optional parameters are now :ref:`keyword-only `.
+ .. versionchanged:: 3.6
+ *fp* can now be a :term:`binary file`. The input encoding should be
+ UTF-8, UTF-16 or UTF-32.
+
.. function:: loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
Deserialize *s* (a :class:`str`, :class:`bytes` or :class:`bytearray`
@@ -651,8 +653,6 @@ when serializing Python :class:`int` values of extremely large magnitude, or
when serializing instances of "exotic" numerical types such as
:class:`decimal.Decimal`.
-.. highlight:: bash
-
.. _json-commandline:
Command Line Interface
@@ -669,7 +669,9 @@ The :mod:`json.tool` module provides a simple command line interface to validate
and pretty-print JSON objects.
If the optional ``infile`` and ``outfile`` arguments are not
-specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively::
+specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively:
+
+.. code-block:: shell-session
$ echo '{"json": "obj"}' | python -m json.tool
{
@@ -688,7 +690,9 @@ Command line options
.. cmdoption:: infile
- The JSON file to be validated or pretty-printed::
+ The JSON file to be validated or pretty-printed:
+
+ .. code-block:: shell-session
$ python -m json.tool mp_films.json
[
diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst
index a7928a0..bf3f375 100644
--- a/Doc/library/logging.config.rst
+++ b/Doc/library/logging.config.rst
@@ -538,7 +538,9 @@ target handler, and the system will resolve to the handler from the
id. If, however, a user defines a ``my.package.MyHandler`` which has
an ``alternate`` handler, the configuration system would not know that
the ``alternate`` referred to a handler. To cater for this, a generic
-resolution system allows the user to specify::
+resolution system allows the user to specify:
+
+.. code-block:: yaml
handlers:
file:
@@ -552,7 +554,9 @@ The literal string ``'cfg://handlers.file'`` will be resolved in an
analogous way to strings with the ``ext://`` prefix, but looking
in the configuration itself rather than the import namespace. The
mechanism allows access by dot or by index, in a similar way to
-that provided by ``str.format``. Thus, given the following snippet::
+that provided by ``str.format``. Thus, given the following snippet:
+
+.. code-block:: yaml
handlers:
email:
@@ -779,11 +783,10 @@ Sections which specify formatter configuration are typified by the following.
The ``format`` entry is the overall format string, and the ``datefmt`` entry is
the :func:`strftime`\ -compatible date/time format string. If empty, the
-package substitutes ISO8601 format date/times, which is almost equivalent to
-specifying the date format string ``'%Y-%m-%d %H:%M:%S'``. The ISO8601 format
-also specifies milliseconds, which are appended to the result of using the above
-format string, with a comma separator. An example time in ISO8601 format is
-``2003-01-23 00:29:50,411``.
+package substitutes something which is almost equivalent to specifying the date
+format string ``'%Y-%m-%d %H:%M:%S'``. This format also specifies milliseconds,
+which are appended to the result of using the above format string, with a comma
+separator. An example time in this format is ``2003-01-23 00:29:50,411``.
The ``class`` entry is optional. It indicates the name of the formatter's class
(as a dotted module and class name.) This option is useful for instantiating a
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index f13f765..a31ee31 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -511,7 +511,7 @@ over UDP sockets.
.. versionchanged:: 3.4
If ``port`` is specified as ``None``, a Unix domain socket is created
- using the value in ``host`` - otherwise, a TCP socket is created.
+ using the value in ``host`` - otherwise, a UDP socket is created.
.. method:: emit()
@@ -583,7 +583,7 @@ supports sending logging messages to a remote or local Unix syslog.
(See: :issue:`12168`.) In earlier versions, the message sent to the
syslog daemons was always terminated with a NUL byte, because early
versions of these daemons expected a NUL terminated message - even
- though it's not in the relevant specification (RFC 5424). More recent
+ though it's not in the relevant specification (:rfc:`5424`). More recent
versions of these daemons don't expect the NUL byte but strip it off
if it's there, and even more recent daemons (which adhere more closely
to RFC 5424) pass the NUL byte on as part of the message.
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index 1ed129c..9ef174e 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -179,7 +179,9 @@ is the module's name in the Python package namespace.
You can specify *stack_info* independently of *exc_info*, e.g. to just show
how you got to a certain point in your code, even when no exceptions were
- raised. The stack frames are printed following a header line which says::
+ raised. The stack frames are printed following a header line which says:
+
+ .. code-block:: none
Stack (most recent call last):
@@ -198,7 +200,9 @@ is the module's name in the Python package namespace.
logger = logging.getLogger('tcpserver')
logger.warning('Protocol problem: %s', 'connection reset', extra=d)
- would print something like ::
+ would print something like
+
+ .. code-block:: none
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
@@ -511,8 +515,8 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
Returns a new instance of the :class:`Formatter` class. The instance is
initialized with a format string for the message as a whole, as well as a
format string for the date/time portion of a message. If no *fmt* is
- specified, ``'%(message)s'`` is used. If no *datefmt* is specified, the
- ISO8601 date format is used.
+ specified, ``'%(message)s'`` is used. If no *datefmt* is specified, a format
+ is used which is described in the :meth:`formatTime` documentation.
The *style* parameter can be one of '%', '{' or '$' and determines how
the format string will be merged with its data: using one of %-formatting,
@@ -552,8 +556,10 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
formatters to provide for any specific requirement, but the basic behavior
is as follows: if *datefmt* (a string) is specified, it is used with
:func:`time.strftime` to format the creation time of the
- record. Otherwise, the ISO8601 format is used. The resulting string is
- returned.
+ record. Otherwise, the format '%Y-%m-%d %H:%M:%S,uuu' is used, where the
+ uuu part is a millisecond value and the other letters are as per the
+ :func:`time.strftime` documentation. An example time in this format is
+ ``2003-01-23 00:29:50,411``. The resulting string is returned.
This function uses a user-configurable function to convert the creation
time to a tuple. By default, :func:`time.localtime` is used; to change
@@ -564,8 +570,8 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on
attribute in the ``Formatter`` class.
.. versionchanged:: 3.3
- Previously, the default ISO 8601 format was hard-coded as in this
- example: ``2010-09-06 22:38:15,292`` where the part before the comma is
+ Previously, the default format was hard-coded as in this example:
+ ``2010-09-06 22:38:15,292`` where the part before the comma is
handled by a strptime format string (``'%Y-%m-%d %H:%M:%S'``), and the
part after the comma is a millisecond value. Because strptime does not
have a format placeholder for milliseconds, the millisecond value is
@@ -939,7 +945,9 @@ functions.
You can specify *stack_info* independently of *exc_info*, e.g. to just show
how you got to a certain point in your code, even when no exceptions were
- raised. The stack frames are printed following a header line which says::
+ raised. The stack frames are printed following a header line which says:
+
+ .. code-block:: none
Stack (most recent call last):
@@ -957,7 +965,9 @@ functions.
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning('Protocol problem: %s', 'connection reset', extra=d)
- would print something like::
+ would print something like:
+
+ .. code-block:: none
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst
index f46bf66..d965fa3 100644
--- a/Doc/library/mmap.rst
+++ b/Doc/library/mmap.rst
@@ -123,7 +123,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
:class:`~mmap.mmap` can also be used as a context manager in a :keyword:`with`
- statement.::
+ statement::
import mmap
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index 9521f77..20d7974 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -719,8 +719,9 @@ For an example of the usage of queues for interprocess communication see
.. function:: Pipe([duplex])
- Returns a pair ``(conn1, conn2)`` of :class:`Connection` objects representing
- the ends of a pipe.
+ Returns a pair ``(conn1, conn2)`` of
+ :class:`~multiprocessing.connection.Connection` objects representing the
+ ends of a pipe.
If *duplex* is ``True`` (the default) then the pipe is bidirectional. If
*duplex* is ``False`` then the pipe is unidirectional: ``conn1`` can only be
@@ -1005,10 +1006,13 @@ Miscellaneous
Connection Objects
~~~~~~~~~~~~~~~~~~
+.. currentmodule:: multiprocessing.connection
+
Connection objects allow the sending and receiving of picklable objects or
strings. They can be thought of as message oriented connected sockets.
-Connection objects are usually created using :func:`Pipe` -- see also
+Connection objects are usually created using
+:func:`Pipe ` -- see also
:ref:`multiprocessing-listeners-clients`.
.. class:: Connection
@@ -1143,6 +1147,8 @@ For example:
Synchronization primitives
~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. currentmodule:: multiprocessing
+
Generally synchronization primitives are not as necessary in a multiprocess
program as they are in a multithreaded program. See the documentation for
:mod:`threading` module.
@@ -2253,7 +2259,7 @@ Listeners and Clients
:synopsis: API for dealing with sockets.
Usually message passing between processes is done using queues or by using
-:class:`~multiprocessing.Connection` objects returned by
+:class:`~Connection` objects returned by
:func:`~multiprocessing.Pipe`.
However, the :mod:`multiprocessing.connection` module allows some extra
@@ -2283,7 +2289,7 @@ multiple connections at the same time.
.. function:: Client(address[, family[, authkey]])
Attempt to set up a connection to the listener which is using address
- *address*, returning a :class:`~multiprocessing.Connection`.
+ *address*, returning a :class:`~Connection`.
The type of the connection is determined by *family* argument, but this can
generally be omitted since it can usually be inferred from the format of
@@ -2333,8 +2339,8 @@ multiple connections at the same time.
.. method:: accept()
Accept a connection on the bound socket or named pipe of the listener
- object and return a :class:`~multiprocessing.Connection` object. If
- authentication is attempted and fails, then
+ object and return a :class:`~Connection` object.
+ If authentication is attempted and fails, then
:exc:`~multiprocessing.AuthenticationError` is raised.
.. method:: close()
@@ -2370,7 +2376,7 @@ multiple connections at the same time.
For both Unix and Windows, an object can appear in *object_list* if
it is
- * a readable :class:`~multiprocessing.Connection` object;
+ * a readable :class:`~multiprocessing.connection.Connection` object;
* a connected and readable :class:`socket.socket` object; or
* the :attr:`~multiprocessing.Process.sentinel` attribute of a
:class:`~multiprocessing.Process` object.
@@ -2493,10 +2499,10 @@ an ``'AF_PIPE'`` address rather than an ``'AF_UNIX'`` address.
Authentication keys
~~~~~~~~~~~~~~~~~~~
-When one uses :meth:`Connection.recv `, the
+When one uses :meth:`Connection.recv `, the
data received is automatically
-unpickled. Unfortunately unpickling data from an untrusted source is a security
-risk. Therefore :class:`Listener` and :func:`Client` use the :mod:`hmac` module
+unpickled. Unfortunately unpickling data from an untrusted source is a security
+risk. Therefore :class:`Listener` and :func:`Client` use the :mod:`hmac` module
to provide digest authentication.
An authentication key is a byte string which can be thought of as a
diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst
index 2c3cd8d..d8ef8a6 100644
--- a/Doc/library/nntplib.rst
+++ b/Doc/library/nntplib.rst
@@ -542,7 +542,7 @@ them have been superseded by newer commands in :rfc:`3977`.
is supplied, then the returned *list* is an empty list. This is an optional NNTP
extension, and may not be supported by all servers.
- RFC2980 says "It is suggested that this extension be deprecated". Use
+ :rfc:`2980` says "It is suggested that this extension be deprecated". Use
:meth:`descriptions` or :meth:`description` instead.
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index b272216..e9ee514 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -2263,7 +2263,13 @@ features:
.. attribute:: st_ino
- Inode number.
+ Platform dependent, but if non-zero, uniquely identifies the
+ file for a given value of ``st_dev``. Typically:
+
+ * the inode number on Unix,
+ * the `file index
+ `_ on
+ Windows
.. attribute:: st_dev
@@ -2416,6 +2422,10 @@ features:
.. versionadded:: 3.5
Added the :attr:`st_file_attributes` member on Windows.
+ .. versionchanged:: 3.5
+ Windows now returns the file index as :attr:`st_ino` when
+ available.
+
.. function:: stat_float_times([newvalue])
@@ -2725,7 +2735,7 @@ features:
no effect on the behavior of the walk, because in bottom-up mode the directories
in *dirnames* are generated before *dirpath* itself is generated.
- By default, errors from the :func:`listdir` call are ignored. If optional
+ By default, errors from the :func:`scandir` call are ignored. If optional
argument *onerror* is specified, it should be a function; it will be called with
one argument, an :exc:`OSError` instance. It can report the error to continue
with the walk, or raise the exception to abort the walk. Note that the filename
diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst
index d0c4cf9..2b10ee2 100644
--- a/Doc/library/pickle.rst
+++ b/Doc/library/pickle.rst
@@ -510,7 +510,7 @@ methods:
.. method:: object.__getnewargs__()
- This method serve a similar purpose as :meth:`__getnewargs_ex__`, but
+ This method serves a similar purpose as :meth:`__getnewargs_ex__`, but
supports only positional arguments. It must return a tuple of arguments
``args`` which will be passed to the :meth:`__new__` method upon unpickling.
diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst
index eea0abb..f5cb52c 100644
--- a/Doc/library/platform.rst
+++ b/Doc/library/platform.rst
@@ -248,7 +248,8 @@ Unix Platforms
This is another name for :func:`linux_distribution`.
- .. deprecated-removed:: 3.5 3.7
+ .. deprecated-removed:: 3.5 3.8
+ See alternative like the `distro `_ package.
.. function:: linux_distribution(distname='', version='', id='', supported_dists=('SuSE','debian','redhat','mandrake',...), full_distribution_name=1)
@@ -266,7 +267,8 @@ Unix Platforms
parameters. ``id`` is the item in parentheses after the version number. It
is usually the version codename.
- .. deprecated-removed:: 3.5 3.7
+ .. deprecated-removed:: 3.5 3.8
+ See alternative like the `distro `_ package.
.. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=2048)
diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst
index 65d94fe..aa97d3e 100644
--- a/Doc/library/pprint.rst
+++ b/Doc/library/pprint.rst
@@ -212,12 +212,12 @@ Example
-------
To demonstrate several uses of the :func:`pprint` function and its parameters,
-let's fetch information about a project from `PyPI `_::
+let's fetch information about a project from `PyPI `_::
>>> import json
>>> import pprint
>>> from urllib.request import urlopen
- >>> with urlopen('http://pypi.python.org/pypi/Twisted/json') as url:
+ >>> with urlopen('http://pypi.org/project/Twisted/json') as url:
... http_info = url.info()
... raw_data = url.read().decode(http_info.get_content_charset())
>>> project_info = json.loads(raw_data)
@@ -248,9 +248,9 @@ In its basic form, :func:`pprint` shows the whole object::
'maintainer': '',
'maintainer_email': '',
'name': 'Twisted',
- 'package_url': 'http://pypi.python.org/pypi/Twisted',
+ 'package_url': 'http://pypi.org/project/Twisted',
'platform': 'UNKNOWN',
- 'release_url': 'http://pypi.python.org/pypi/Twisted/12.3.0',
+ 'release_url': 'http://pypi.org/project/Twisted/12.3.0',
'requires_python': None,
'stable_version': None,
'summary': 'An asynchronous networking framework written in Python',
@@ -264,7 +264,7 @@ In its basic form, :func:`pprint` shows the whole object::
'python_version': 'source',
'size': 2615733,
'upload_time': '2012-12-26T12:47:03',
- 'url': 'https://pypi.python.org/packages/source/T/Twisted/Twisted-12.3.0.tar.bz2'},
+ 'url': 'https://pypi.org/packages/source/T/Twisted/Twisted-12.3.0.tar.bz2'},
{'comment_text': '',
'downloads': 5224,
'filename': 'Twisted-12.3.0.win32-py2.7.msi',
@@ -274,7 +274,7 @@ In its basic form, :func:`pprint` shows the whole object::
'python_version': '2.7',
'size': 2916352,
'upload_time': '2012-12-26T12:48:15',
- 'url': 'https://pypi.python.org/packages/2.7/T/Twisted/Twisted-12.3.0.win32-py2.7.msi'}]}
+ 'url': 'https://pypi.org/packages/2.7/T/Twisted/Twisted-12.3.0.win32-py2.7.msi'}]}
The result can be limited to a certain *depth* (ellipsis is used for deeper
contents)::
@@ -301,9 +301,9 @@ contents)::
'maintainer': '',
'maintainer_email': '',
'name': 'Twisted',
- 'package_url': 'http://pypi.python.org/pypi/Twisted',
+ 'package_url': 'http://pypi.org/project/Twisted',
'platform': 'UNKNOWN',
- 'release_url': 'http://pypi.python.org/pypi/Twisted/12.3.0',
+ 'release_url': 'http://pypi.org/project/Twisted/12.3.0',
'requires_python': None,
'stable_version': None,
'summary': 'An asynchronous networking framework written in Python',
@@ -339,9 +339,9 @@ cannot be split, the specified width will be exceeded::
'maintainer': '',
'maintainer_email': '',
'name': 'Twisted',
- 'package_url': 'http://pypi.python.org/pypi/Twisted',
+ 'package_url': 'http://pypi.org/project/Twisted',
'platform': 'UNKNOWN',
- 'release_url': 'http://pypi.python.org/pypi/Twisted/12.3.0',
+ 'release_url': 'http://pypi.org/project/Twisted/12.3.0',
'requires_python': None,
'stable_version': None,
'summary': 'An asynchronous networking '
diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst
index 5796e3a..32d2116 100644
--- a/Doc/library/profile.rst
+++ b/Doc/library/profile.rst
@@ -310,11 +310,12 @@ Analysis of the profiler data is done using the :class:`~pstats.Stats` class.
corresponding version of :mod:`profile` or :mod:`cProfile`. To be specific,
there is *no* file compatibility guaranteed with future versions of this
profiler, and there is no compatibility with files produced by other
- profilers. If several files are provided, all the statistics for identical
- functions will be coalesced, so that an overall view of several processes can
- be considered in a single report. If additional files need to be combined
- with data in an existing :class:`~pstats.Stats` object, the
- :meth:`~pstats.Stats.add` method can be used.
+ profilers, or the same profiler run on a different operating system. If
+ several files are provided, all the statistics for identical functions will
+ be coalesced, so that an overall view of several processes can be considered
+ in a single report. If additional files need to be combined with data in an
+ existing :class:`~pstats.Stats` object, the :meth:`~pstats.Stats.add` method
+ can be used.
Instead of reading the profile data from a file, a :class:`cProfile.Profile`
or :class:`profile.Profile` object can be used as the profile data source.
diff --git a/Doc/library/re.rst b/Doc/library/re.rst
index db92c48..14360ed 100644
--- a/Doc/library/re.rst
+++ b/Doc/library/re.rst
@@ -45,7 +45,7 @@ fine-tuning parameters.
.. seealso::
- The third-party `regex `_ module,
+ The third-party `regex `_ module,
which has an API compatible with the standard library :mod:`re` module,
but offers additional functionality and a more thorough Unicode support.
@@ -67,8 +67,8 @@ string *pq* will match AB. This holds unless *A* or *B* contain low precedence
operations; boundary conditions between *A* and *B*; or have numbered group
references. Thus, complex expressions can easily be constructed from simpler
primitive expressions like the ones described here. For details of the theory
-and implementation of regular expressions, consult the Friedl book referenced
-above, or almost any textbook about compiler construction.
+and implementation of regular expressions, consult the Friedl book [Frie09]_,
+or almost any textbook about compiler construction.
A brief explanation of the format of regular expressions follows. For further
information and a gentler presentation, consult the :ref:`regex-howto`.
@@ -471,14 +471,6 @@ three digits in length.
Unknown escapes consisting of ``'\'`` and an ASCII letter now are errors.
-.. seealso::
-
- Mastering Regular Expressions
- Book on regular expressions by Jeffrey Friedl, published by O'Reilly. The
- second edition of the book no longer covers Python at all, but the first
- edition covered writing good regular expression patterns in great detail.
-
-
.. _contents-of-module-re:
@@ -1561,3 +1553,9 @@ The tokenizer produces the following output::
Token(typ='END', value=';', line=4, column=27)
Token(typ='ENDIF', value='ENDIF', line=5, column=4)
Token(typ='END', value=';', line=5, column=9)
+
+
+.. [Frie09] Friedl, Jeffrey. Mastering Regular Expressions. 3rd ed., O'Reilly
+ Media, 2009. The third edition of the book no longer covers Python at all,
+ but the first edition covered writing good regular expression patterns in
+ great detail.
diff --git a/Doc/library/site.rst b/Doc/library/site.rst
index 43daf79..71ba999 100644
--- a/Doc/library/site.rst
+++ b/Doc/library/site.rst
@@ -220,7 +220,7 @@ Module contents
The :mod:`site` module also provides a way to get the user directories from the
command line:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 -m site --user-site
/home/user/.local/lib/python3.3/site-packages
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index 677e945..45418c7 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -49,6 +49,9 @@ For more sophisticated applications, the :class:`ssl.SSLContext` class
helps manage settings and certificates, which can then be inherited
by SSL sockets created through the :meth:`SSLContext.wrap_socket` method.
+.. versionchanged:: 3.5.3
+ Updated to support linking with OpenSSL 1.1.0
+
.. versionchanged:: 3.6
OpenSSL 0.9.8, 1.0.0 and 1.0.1 are deprecated and no longer supported.
@@ -533,20 +536,28 @@ Constants
.. data:: CERT_NONE
Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs``
- parameter to :func:`wrap_socket`. In this mode (the default), no
- certificates will be required from the other side of the socket connection.
- If a certificate is received from the other end, no attempt to validate it
- is made.
+ parameter to :func:`wrap_socket`. Except for :const:`PROTOCOL_TLS_CLIENT`,
+ it is the default mode. With client-side sockets, just about any
+ cert is accepted. Validation errors, such as untrusted or expired cert,
+ are ignored and do not abort the TLS/SSL handshake.
+
+ In server mode, no certificate is requested from the client, so the client
+ does not send any for client cert authentication.
See the discussion of :ref:`ssl-security` below.
.. data:: CERT_OPTIONAL
Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs``
- parameter to :func:`wrap_socket`. In this mode no certificates will be
- required from the other side of the socket connection; but if they
- are provided, validation will be attempted and an :class:`SSLError`
- will be raised on failure.
+ parameter to :func:`wrap_socket`. In client mode, :const:`CERT_OPTIONAL`
+ has the same meaning as :const:`CERT_REQUIRED`. It is recommended to
+ use :const:`CERT_REQUIRED` for client-side sockets instead.
+
+ In server mode, a client certificate request is sent to the client. The
+ client may either ignore the request or send a certificate in order
+ perform TLS client cert authentication. If the client chooses to send
+ a certificate, it is verified. Any verification error immediately aborts
+ the TLS handshake.
Use of this setting requires a valid set of CA certificates to
be passed, either to :meth:`SSLContext.load_verify_locations` or as a
@@ -558,6 +569,15 @@ Constants
parameter to :func:`wrap_socket`. In this mode, certificates are
required from the other side of the socket connection; an :class:`SSLError`
will be raised if no certificate is provided, or if its validation fails.
+ This mode is **not** sufficient to verify a certificate in client mode as
+ it does not match hostnames. :attr:`~SSLContext.check_hostname` must be
+ enabled as well to verify the authenticity of a cert.
+ :const:`PROTOCOL_TLS_CLIENT` uses :const:`CERT_REQUIRED` and
+ enables :attr:`~SSLContext.check_hostname` by default.
+
+ With server socket, this mode provides mandatory TLS client cert
+ authentication. A client certificate request is sent to the client and
+ the client must provide a valid and trusted certificate.
Use of this setting requires a valid set of CA certificates to
be passed, either to :meth:`SSLContext.load_verify_locations` or as a
@@ -1911,9 +1931,9 @@ Visual inspection shows that the certificate does identify the desired service
(('commonName', 'www.python.org'),)),
'subjectAltName': (('DNS', 'www.python.org'),
('DNS', 'python.org'),
- ('DNS', 'pypi.python.org'),
+ ('DNS', 'pypi.org'),
('DNS', 'docs.python.org'),
- ('DNS', 'testpypi.python.org'),
+ ('DNS', 'testpypi.org'),
('DNS', 'bugs.python.org'),
('DNS', 'wiki.python.org'),
('DNS', 'hg.python.org'),
@@ -2269,11 +2289,6 @@ In server mode, if you want to authenticate your clients using the SSL layer
(rather than using a higher-level authentication mechanism), you'll also have
to specify :const:`CERT_REQUIRED` and similarly check the client certificate.
- .. note::
-
- In client mode, :const:`CERT_OPTIONAL` and :const:`CERT_REQUIRED` are
- equivalent unless anonymous ciphers are enabled (they are disabled
- by default).
Protocol versions
'''''''''''''''''
@@ -2345,25 +2360,25 @@ with LibreSSL.
`SSL/TLS Strong Encryption: An Introduction `_
Intro from the Apache HTTP Server documentation
- `RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management `_
+ :rfc:`RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management <1422>`
Steve Kent
- `RFC 4086: Randomness Requirements for Security `_
+ :rfc:`RFC 4086: Randomness Requirements for Security <4086>`
Donald E., Jeffrey I. Schiller
- `RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile `_
+ :rfc:`RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile <5280>`
D. Cooper
- `RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 `_
+ :rfc:`RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 <5246>`
T. Dierks et. al.
- `RFC 6066: Transport Layer Security (TLS) Extensions `_
+ :rfc:`RFC 6066: Transport Layer Security (TLS) Extensions <6066>`
D. Eastlake
`IANA TLS: Transport Layer Security (TLS) Parameters `_
IANA
- `RFC 7525: Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) `_
+ :rfc:`RFC 7525: Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) <7525>`
IETF
`Mozilla's Server Side TLS recommendations `_
diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst
index e7fae56..330032b 100644
--- a/Doc/library/stringprep.rst
+++ b/Doc/library/stringprep.rst
@@ -26,7 +26,7 @@ define which tables it uses, and what other optional parts of the ``stringprep``
procedure are part of the profile. One example of a ``stringprep`` profile is
``nameprep``, which is used for internationalized domain names.
-The module :mod:`stringprep` only exposes the tables from RFC 3454. As these
+The module :mod:`stringprep` only exposes the tables from :rfc:`3454`. As these
tables would be very large to represent them as dictionaries or lists, the
module uses the Unicode character database internally. The module source code
itself was generated using the ``mkstringprep.py`` utility.
diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst
index 6a5f276..f624adb 100644
--- a/Doc/library/subprocess.rst
+++ b/Doc/library/subprocess.rst
@@ -39,7 +39,7 @@ compatibility with older versions, see the :ref:`call-function-trio` section.
.. function:: run(args, *, stdin=None, input=None, stdout=None, stderr=None,\
shell=False, cwd=None, timeout=None, check=False, \
- encoding=None, errors=None)
+ encoding=None, errors=None, env=None)
Run the command described by *args*. Wait for command to complete, then
return a :class:`CompletedProcess` instance.
@@ -75,6 +75,11 @@ compatibility with older versions, see the :ref:`call-function-trio` section.
specified *encoding* and *errors* or the :class:`io.TextIOWrapper` default.
Otherwise, file objects are opened in binary mode.
+ If *env* is not ``None``, it must be a mapping that defines the environment
+ variables for the new process; these are used instead of the default
+ behavior of inheriting the current process' environment. It is passed directly
+ to :class:`Popen`.
+
Examples::
>>> subprocess.run(["ls", "-l"]) # doesn't capture output
diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst
index 5793c54..c5efdff 100644
--- a/Doc/library/timeit.rst
+++ b/Doc/library/timeit.rst
@@ -25,7 +25,7 @@ Basic Examples
The following example shows how the :ref:`timeit-command-line-interface`
can be used to compare three different expressions:
-.. code-block:: sh
+.. code-block:: shell-session
$ python3 -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 30.2 usec per loop
@@ -273,7 +273,7 @@ Examples
It is possible to provide a setup statement that is executed only once at the beginning:
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m timeit -s 'text = "sample string"; char = "g"' 'char in text'
10000000 loops, best of 3: 0.0877 usec per loop
@@ -302,7 +302,7 @@ The following examples show how to time expressions that contain multiple lines.
Here we compare the cost of using :func:`hasattr` vs. :keyword:`try`/:keyword:`except`
to test for missing and present object attributes:
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m timeit 'try:' ' str.__bool__' 'except AttributeError:' ' pass'
100000 loops, best of 3: 15.7 usec per loop
diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst
index f51add2..d9c1c35 100644
--- a/Doc/library/tkinter.rst
+++ b/Doc/library/tkinter.rst
@@ -13,12 +13,17 @@
The :mod:`tkinter` package ("Tk interface") is the standard Python interface to
the Tk GUI toolkit. Both Tk and :mod:`tkinter` are available on most Unix
platforms, as well as on Windows systems. (Tk itself is not part of Python; it
-is maintained at ActiveState.) You can check that :mod:`tkinter` is properly
-installed on your system by running ``python -m tkinter`` from the command line;
-this should open a window demonstrating a simple Tk interface.
+is maintained at ActiveState.)
+
+Running ``python -m tkinter`` from the command line should open a window
+demonstrating a simple Tk interface, letting you know that :mod:`tkinter` is
+properly installed on your system, and also showing what version of Tcl/Tk is
+installed, so you can read the Tcl/Tk documentation specific to that version.
.. seealso::
+ Tkinter documentation:
+
`Python Tkinter Resources `_
The Python Tkinter Topic Guide provides a great deal of information on using Tk
from Python and links to other sources of information on Tk.
@@ -32,17 +37,32 @@ this should open a window demonstrating a simple Tk interface.
`Tkinter docs from effbot `_
Online reference for tkinter supported by effbot.org.
- `Tcl/Tk manual `_
- Official manual for the latest tcl/tk version.
-
- `Programming Python `_
+ `Programming Python `_
Book by Mark Lutz, has excellent coverage of Tkinter.
- `Modern Tkinter for Busy Python Developers `_
+ `Modern Tkinter for Busy Python Developers `_
Book by Mark Rozerman about building attractive and modern graphical user interfaces with Python and Tkinter.
`Python and Tkinter Programming `_
- The book by John Grayson (ISBN 1-884777-81-3).
+ Book by John Grayson (ISBN 1-884777-81-3).
+
+ Tcl/Tk documentation:
+
+ `Tk commands `_
+ Most commands are available as :mod:`tkinter` or :mod:`tkinter.ttk` classes.
+ Change '8.6' to match the version of your Tcl/Tk installation.
+
+ `Tcl/Tk recent man pages `_
+ Recent Tcl/Tk manuals on www.tcl.tk.
+
+ `ActiveState Tcl Home Page `_
+ The Tk/Tcl development is largely taking place at ActiveState.
+
+ `Tcl and the Tk Toolkit `_
+ Book by John Ousterhout, the inventor of Tcl.
+
+ `Practical Programming in Tcl and Tk `_
+ Brent Welch's encyclopedic book.
Tkinter Modules
@@ -175,21 +195,6 @@ documentation that exists. Here are some hints:
place to go when nothing else makes sense.
-.. seealso::
-
- `Tcl/Tk 8.6 man pages `_
- The Tcl/Tk manual on www.tcl.tk.
-
- `ActiveState Tcl Home Page `_
- The Tk/Tcl development is largely taking place at ActiveState.
-
- `Tcl and the Tk Toolkit `_
- The book by John Ousterhout, the inventor of Tcl.
-
- `Practical Programming in Tcl and Tk `_
- Brent Welch's encyclopedic book.
-
-
A Simple Hello World Program
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -783,12 +788,13 @@ Menu indexes (menu.invoke(), menu.entryconfig(), etc.)
Images
^^^^^^
-Bitmap/Pixelmap images can be created through the subclasses of
-:class:`tkinter.Image`:
+Images of different formats can be created through the corresponding subclass
+of :class:`tkinter.Image`:
-* :class:`BitmapImage` can be used for X11 bitmap data.
+* :class:`BitmapImage` for images in XBM format.
-* :class:`PhotoImage` can be used for GIF and PPM/PGM color bitmaps.
+* :class:`PhotoImage` for images in PGM, PPM, GIF and PNG formats. The latter
+ is supported starting with Tk 8.6.
Either type of image is created through either the ``file`` or the ``data``
option (other options are available as well).
@@ -799,6 +805,10 @@ reference to the image. When the last Python reference to the image object is
deleted, the image data is deleted as well, and Tk will display an empty box
wherever the image was used.
+.. seealso::
+
+ The `Pillow `_ package adds support for
+ formats such as BMP, JPEG, TIFF, and WebP, among others.
.. _tkinter-file-handlers:
diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst
index afed36b..ba5b83c 100644
--- a/Doc/library/tokenize.rst
+++ b/Doc/library/tokenize.rst
@@ -237,7 +237,7 @@ will be tokenized to the following output where the first column is the range
of the line/column coordinates where the token is found, the second column is
the name of the token, and the final column is the value of the token (if any)
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m tokenize hello.py
0,0-0,0: ENCODING 'utf-8'
@@ -263,7 +263,7 @@ the name of the token, and the final column is the value of the token (if any)
The exact token type names can be displayed using the ``-e`` option:
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m tokenize -e hello.py
0,0-0,0: ENCODING 'utf-8'
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 9c4777a..bd6f3a9 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -666,6 +666,13 @@ The module defines the following classes, functions and decorators:
.. versionadded:: 3.6
+.. class:: AsyncContextManager(Generic[T_co])
+
+ An ABC with async abstract :meth:`__aenter__` and :meth:`__aexit__`
+ methods.
+
+ .. versionadded:: 3.6
+
.. class:: Dict(dict, MutableMapping[KT, VT])
A generic version of :class:`dict`.
@@ -931,6 +938,18 @@ The module defines the following classes, functions and decorators:
* Every type is compatible with :data:`Any`.
* :data:`Any` is compatible with every type.
+.. data:: NoReturn
+
+ Special type indicating that a function never returns.
+ For example::
+
+ from typing import NoReturn
+
+ def stop() -> NoReturn:
+ raise RuntimeError('no way')
+
+ .. versionadded:: 3.6.5
+
.. data:: Union
Union type; ``Union[X, Y]`` means either X or Y.
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index a552cbf..9d4d36f 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -35,7 +35,7 @@ is based on the 'action -> assertion' pattern instead of 'record -> replay'
used by many mocking frameworks.
There is a backport of :mod:`unittest.mock` for earlier versions of Python,
-available as `mock on PyPI `_.
+available as `mock on PyPI `_.
Quick Guide
@@ -2084,7 +2084,7 @@ mock_open
the start. If you need more control over the data that you are feeding to
the tested code you will need to customize this mock for yourself. When that
is insufficient, one of the in-memory filesystem packages on `PyPI
- `_ can offer a realistic filesystem for testing.
+ `_ can offer a realistic filesystem for testing.
.. versionchanged:: 3.4
Added :meth:`~io.IOBase.readline` and :meth:`~io.IOBase.readlines` support.
diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst
index a4c4c5c..f0de85f 100644
--- a/Doc/library/unittest.rst
+++ b/Doc/library/unittest.rst
@@ -342,8 +342,9 @@ testing code::
Note that in order to test something, we use one of the :meth:`assert\*`
methods provided by the :class:`TestCase` base class. If the test fails, an
-exception will be raised, and :mod:`unittest` will identify the test case as a
-:dfn:`failure`. Any other exceptions will be treated as :dfn:`errors`.
+exception will be raised with an explanatory message, and :mod:`unittest`
+will identify the test case as a :dfn:`failure`. Any other exceptions will be
+treated as :dfn:`errors`.
Tests can be numerous, and their set-up can be repetitive. Luckily, we
can factor out set-up code by implementing a method called
@@ -389,13 +390,18 @@ after the test method has been run::
If :meth:`~TestCase.setUp` succeeded, :meth:`~TestCase.tearDown` will be
run whether the test method succeeded or not.
-Such a working environment for the testing code is called a :dfn:`fixture`.
-
-Test case instances are grouped together according to the features they test.
-:mod:`unittest` provides a mechanism for this: the :dfn:`test suite`,
-represented by :mod:`unittest`'s :class:`TestSuite` class. In most cases,
-calling :func:`unittest.main` will do the right thing and collect all the
-module's test cases for you, and then execute them.
+Such a working environment for the testing code is called a
+:dfn:`test fixture`. A new TestCase instance is created as a unique
+test fixture used to execute each individual test method. Thus
+`~TestCase.setUp`, `~TestCase.tearDown`, and `~TestCase.__init__`
+will be called once per test.
+
+It is recommended that you use TestCase implementations to group tests together
+according to the features they test. :mod:`unittest` provides a mechanism for
+this: the :dfn:`test suite`, represented by :mod:`unittest`'s
+:class:`TestSuite` class. In most cases, calling :func:`unittest.main` will do
+the right thing and collect all the module's test cases for you and execute
+them.
However, should you want to customize the building of your test suite,
you can do it yourself::
diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst
index 5517b04..f7d47ed 100644
--- a/Doc/library/urllib.error.rst
+++ b/Doc/library/urllib.error.rst
@@ -41,8 +41,7 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate:
.. attribute:: code
- An HTTP status code as defined in `RFC 2616
- `_. This numeric value corresponds
+ An HTTP status code as defined in :rfc:`2616`. This numeric value corresponds
to a value found in the dictionary of codes as found in
:attr:`http.server.BaseHTTPRequestHandler.responses`.
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index 5a10f95..705517a 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -232,7 +232,7 @@ The following classes are provided:
containing the image.
*unverifiable* should indicate whether the request is unverifiable,
- as defined by RFC 2965. It defaults to ``False``. An unverifiable
+ as defined by :rfc:`2965`. It defaults to ``False``. An unverifiable
request is one whose URL the user did not have the option to
approve. For example, if the request is for an image in an HTML
document, and the user had no option to approve the automatic
@@ -504,7 +504,7 @@ request.
.. attribute:: Request.unverifiable
boolean, indicates whether the request is unverifiable as defined
- by RFC 2965.
+ by :rfc:`2965`.
.. attribute:: Request.method
diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst
index edbf832..b3193d7 100644
--- a/Doc/library/uuid.rst
+++ b/Doc/library/uuid.rst
@@ -1,5 +1,5 @@
-:mod:`uuid` --- UUID objects according to RFC 4122
-==================================================
+:mod:`uuid` --- UUID objects according to :rfc:`4122`
+=====================================================
.. module:: uuid
:synopsis: UUID objects (universally unique identifiers) according to RFC 4122
@@ -23,12 +23,13 @@ random UUID.
.. class:: UUID(hex=None, bytes=None, bytes_le=None, fields=None, int=None, version=None)
Create a UUID from either a string of 32 hexadecimal digits, a string of 16
- bytes as the *bytes* argument, a string of 16 bytes in little-endian order as
- the *bytes_le* argument, a tuple of six integers (32-bit *time_low*, 16-bit
- *time_mid*, 16-bit *time_hi_version*, 8-bit *clock_seq_hi_variant*, 8-bit
- *clock_seq_low*, 48-bit *node*) as the *fields* argument, or a single 128-bit
- integer as the *int* argument. When a string of hex digits is given, curly
- braces, hyphens, and a URN prefix are all optional. For example, these
+ bytes in big-endian order as the *bytes* argument, a string of 16 bytes in
+ little-endian order as the *bytes_le* argument, a tuple of six integers
+ (32-bit *time_low*, 16-bit *time_mid*, 16-bit *time_hi_version*,
+ 8-bit *clock_seq_hi_variant*, 8-bit *clock_seq_low*, 48-bit *node*) as the
+ *fields* argument, or a single 128-bit integer as the *int* argument.
+ When a string of hex digits is given, curly braces, hyphens,
+ and a URN prefix are all optional. For example, these
expressions all yield the same UUID::
UUID('{12345678-1234-5678-1234-567812345678}')
@@ -42,7 +43,7 @@ random UUID.
Exactly one of *hex*, *bytes*, *bytes_le*, *fields*, or *int* must be given.
The *version* argument is optional; if given, the resulting UUID will have its
- variant and version number set according to RFC 4122, overriding bits in the
+ variant and version number set according to :rfc:`4122`, overriding bits in the
given *hex*, *bytes*, *bytes_le*, *fields*, or *int*.
Comparison of UUID objects are made by way of comparing their
@@ -105,7 +106,7 @@ random UUID.
.. attribute:: UUID.urn
- The UUID as a URN as specified in RFC 4122.
+ The UUID as a URN as specified in :rfc:`4122`.
.. attribute:: UUID.variant
@@ -128,7 +129,7 @@ The :mod:`uuid` module defines the following functions:
Get the hardware address as a 48-bit positive integer. The first time this
runs, it may launch a separate program, which could be quite slow. If all
attempts to obtain the hardware address fail, we choose a random 48-bit number
- with its eighth bit set to 1 as recommended in RFC 4122. "Hardware address"
+ with its eighth bit set to 1 as recommended in :rfc:`4122`. "Hardware address"
means the MAC address of a network interface, and on a machine with multiple
network interfaces the MAC address of any one of them may be returned.
diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst
index 17c80c8..c50231e 100644
--- a/Doc/library/venv.rst
+++ b/Doc/library/venv.rst
@@ -109,8 +109,7 @@ creation according to their needs, the :class:`EnvBuilder` class.
* ``symlinks`` -- a Boolean value indicating whether to attempt to symlink the
Python binary (and any necessary DLLs or other binaries,
- e.g. ``pythonw.exe``), rather than copying. Defaults to ``True`` on Linux and
- Unix systems, but ``False`` on Windows.
+ e.g. ``pythonw.exe``), rather than copying.
* ``upgrade`` -- a Boolean value which, if true, will upgrade an existing
environment with the running Python - for use when that Python has been
diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst
index a1d4469..ddfc2e5 100644
--- a/Doc/library/wsgiref.rst
+++ b/Doc/library/wsgiref.rst
@@ -397,7 +397,7 @@ Paste" library.
Wrap *application* and return a new WSGI application object. The returned
application will forward all requests to the original *application*, and will
check that both the *application* and the server invoking it are conforming to
- the WSGI specification and to RFC 2616.
+ the WSGI specification and to :rfc:`2616`.
Any detected nonconformance results in an :exc:`AssertionError` being raised;
note, however, that how these errors are handled is server-dependent. For
diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst
index d833b7f..63c24f8 100644
--- a/Doc/library/xml.rst
+++ b/Doc/library/xml.rst
@@ -130,8 +130,8 @@ but will not be included in any bugfix releases of
Python because they break backward compatibility.
-.. _defusedxml: https://pypi.python.org/pypi/defusedxml/
-.. _defusedexpat: https://pypi.python.org/pypi/defusedexpat/
+.. _defusedxml: https://pypi.org/project/defusedxml/
+.. _defusedexpat: https://pypi.org/project/defusedexpat/
.. _Billion Laughs: https://en.wikipedia.org/wiki/Billion_laughs
.. _ZIP bomb: https://en.wikipedia.org/wiki/Zip_bomb
.. _DTD: https://en.wikipedia.org/wiki/Document_type_definition
diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst
index 390828e..ed2ccae 100644
--- a/Doc/library/xmlrpc.client.rst
+++ b/Doc/library/xmlrpc.client.rst
@@ -328,7 +328,7 @@ Binary Objects
Write the XML-RPC base 64 encoding of this binary item to the *out* stream object.
The encoded data will have newlines every 76 characters as per
- `RFC 2045 section 6.8 `_,
+ :rfc:`RFC 2045 section 6.8 <2045#section-6.8>`,
which was the de facto standard base64 specification when the
XML-RPC spec was written.
diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst
index 9dee9a5..9658694 100644
--- a/Doc/library/zipapp.rst
+++ b/Doc/library/zipapp.rst
@@ -27,7 +27,7 @@ can be used to create an executable archive from a directory containing
Python code. When run, the archive will execute the ``main`` function from
the module ``myapp`` in the archive.
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m zipapp myapp -m "myapp:main"
$ python myapp.pyz
@@ -41,7 +41,7 @@ Command-Line Interface
When called as a program from the command line, the following form is used:
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m zipapp source [options]
@@ -167,7 +167,7 @@ Examples
Pack up a directory into an archive, and run it.
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m zipapp myapp
$ python myapp.pyz
@@ -181,7 +181,7 @@ The same can be done using the :func:`create_archive` functon::
To make the application directly executable on POSIX, specify an interpreter
to use.
-.. code-block:: sh
+.. code-block:: shell-session
$ python -m zipapp myapp -p "/usr/bin/env python"
$ ./myapp.pyz
@@ -207,6 +207,12 @@ fits in memory::
>>> with open('myapp.pyz', 'wb') as f:
>>> f.write(temp.getvalue())
+
+.. _zipapp-specifying-the-interpreter:
+
+Specifying the Interpreter
+--------------------------
+
Note that if you specify an interpreter and then distribute your application
archive, you need to ensure that the interpreter used is portable. The Python
launcher for Windows supports most common forms of POSIX ``#!`` line, but there
@@ -223,6 +229,169 @@ are other issues to consider:
exact version like "/usr/bin/env python3.4" as you will need to change your
shebang line for users of Python 3.5, for example.
+Typically, you should use an "/usr/bin/env python2" or "/usr/bin/env python3",
+depending on whether your code is written for Python 2 or 3.
+
+
+Creating Standalone Applications with zipapp
+--------------------------------------------
+
+Using the :mod:`zipapp` module, it is possible to create self-contained Python
+programs, which can be distributed to end users who only need to have a
+suitable version of Python installed on their system. The key to doing this
+is to bundle all of the application's dependencies into the archive, along
+with the application code.
+
+The steps to create a standalone archive are as follows:
+
+1. Create your application in a directory as normal, so you have a ``myapp``
+ directory containing a ``__main__.py`` file, and any supporting application
+ code.
+
+2. Install all of your application's dependencies into the ``myapp`` directory,
+ using pip:
+
+ .. code-block:: shell-session
+
+ $ python -m pip install -r requirements.txt --target myapp
+
+ (this assumes you have your project requirements in a ``requirements.txt``
+ file - if not, you can just list the dependencies manually on the pip command
+ line).
+
+3. Optionally, delete the ``.dist-info`` directories created by pip in the
+ ``myapp`` directory. These hold metadata for pip to manage the packages, and
+ as you won't be making any further use of pip they aren't required -
+ although it won't do any harm if you leave them.
+
+4. Package the application using:
+
+ .. code-block:: shell-session
+
+ $ python -m zipapp -p "interpreter" myapp
+
+This will produce a standalone executable, which can be run on any machine with
+the appropriate interpreter available. See :ref:`zipapp-specifying-the-interpreter`
+for details. It can be shipped to users as a single file.
+
+On Unix, the ``myapp.pyz`` file is executable as it stands. You can rename the
+file to remove the ``.pyz`` extension if you prefer a "plain" command name. On
+Windows, the ``myapp.pyz[w]`` file is executable by virtue of the fact that
+the Python interpreter registers the ``.pyz`` and ``.pyzw`` file extensions
+when installed.
+
+
+Making a Windows executable
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+On Windows, registration of the ``.pyz`` extension is optional, and
+furthermore, there are certain places that don't recognise registered
+extensions "transparently" (the simplest example is that
+``subprocess.run(['myapp'])`` won't find your application - you need to
+explicitly specify the extension).
+
+On Windows, therefore, it is often preferable to create an executable from the
+zipapp. This is relatively easy, although it does require a C compiler. The
+basic approach relies on the fact that zipfiles can have arbitrary data
+prepended, and Windows exe files can have arbitrary data appended. So by
+creating a suitable launcher and tacking the ``.pyz`` file onto the end of it,
+you end up with a single-file executable that runs your application.
+
+A suitable launcher can be as simple as the following::
+
+ #define Py_LIMITED_API 1
+ #include "Python.h"
+
+ #define WIN32_LEAN_AND_MEAN
+ #include
+
+ #ifdef WINDOWS
+ int WINAPI wWinMain(
+ HINSTANCE hInstance, /* handle to current instance */
+ HINSTANCE hPrevInstance, /* handle to previous instance */
+ LPWSTR lpCmdLine, /* pointer to command line */
+ int nCmdShow /* show state of window */
+ )
+ #else
+ int wmain()
+ #endif
+ {
+ wchar_t **myargv = _alloca((__argc + 1) * sizeof(wchar_t*));
+ myargv[0] = __wargv[0];
+ memcpy(myargv + 1, __wargv, __argc * sizeof(wchar_t *));
+ return Py_Main(__argc+1, myargv);
+ }
+
+If you define the ``WINDOWS`` preprocessor symbol, this will generate a
+GUI executable, and without it, a console executable.
+
+To compile the executable, you can either just use the standard MSVC
+command line tools, or you can take advantage of the fact that distutils
+knows how to compile Python source::
+
+ >>> from distutils.ccompiler import new_compiler
+ >>> import distutils.sysconfig
+ >>> import sys
+ >>> import os
+ >>> from pathlib import Path
+
+ >>> def compile(src):
+ >>> src = Path(src)
+ >>> cc = new_compiler()
+ >>> exe = src.stem
+ >>> cc.add_include_dir(distutils.sysconfig.get_python_inc())
+ >>> cc.add_library_dir(os.path.join(sys.base_exec_prefix, 'libs'))
+ >>> # First the CLI executable
+ >>> objs = cc.compile([str(src)])
+ >>> cc.link_executable(objs, exe)
+ >>> # Now the GUI executable
+ >>> cc.define_macro('WINDOWS')
+ >>> objs = cc.compile([str(src)])
+ >>> cc.link_executable(objs, exe + 'w')
+
+ >>> if __name__ == "__main__":
+ >>> compile("zastub.c")
+
+The resulting launcher uses the "Limited ABI", so it will run unchanged with
+any version of Python 3.x. All it needs is for Python (``python3.dll``) to be
+on the user's ``PATH``.
+
+For a fully standalone distribution, you can distribute the launcher with your
+application appended, bundled with the Python "embedded" distribution. This
+will run on any PC with the appropriate architecture (32 bit or 64 bit).
+
+
+Caveats
+~~~~~~~
+
+There are some limitations to the process of bundling your application into
+a single file. In most, if not all, cases they can be addressed without
+needing major changes to your application.
+
+1. If your application depends on a package that includes a C extension, that
+ package cannot be run from a zip file (this is an OS limitation, as executable
+ code must be present in the filesystem for the OS loader to load it). In this
+ case, you can exclude that dependency from the zipfile, and either require
+ your users to have it installed, or ship it alongside your zipfile and add code
+ to your ``__main__.py`` to include the directory containing the unzipped
+ module in ``sys.path``. In this case, you will need to make sure to ship
+ appropriate binaries for your target architecture(s) (and potentially pick the
+ correct version to add to ``sys.path`` at runtime, based on the user's machine).
+
+2. If you are shipping a Windows executable as described above, you either need to
+ ensure that your users have ``python3.dll`` on their PATH (which is not the
+ default behaviour of the installer) or you should bundle your application with
+ the embedded distribution.
+
+3. The suggested launcher above uses the Python embedding API. This means that in
+ your application, ``sys.executable`` will be your application, and *not* a
+ conventional Python interpreter. Your code and its dependencies need to be
+ prepared for this possibility. For example, if your application uses the
+ :mod:`multiprocessing` module, it will need to call
+ :func:`multiprocessing.set_executable` to let the module know where to find the
+ standard Python interpreter.
+
+
The Python Zip Application Archive Format
-----------------------------------------
diff --git a/Doc/make.bat b/Doc/make.bat
index 968b20b..8c6cb9a 100644
--- a/Doc/make.bat
+++ b/Doc/make.bat
@@ -5,18 +5,28 @@ pushd %~dp0
set this=%~n0
-call ..\PCBuild\find_python.bat %PYTHON%
-if not defined SPHINXBUILD if defined PYTHON (
+call ..\PCbuild\find_python.bat %PYTHON%
+
+if not defined PYTHON set PYTHON=py
+
+if not defined SPHINXBUILD (
%PYTHON% -c "import sphinx" > nul 2> nul
if errorlevel 1 (
echo Installing sphinx with %PYTHON%
%PYTHON% -m pip install sphinx
if errorlevel 1 exit /B
)
- set SPHINXBUILD=%PYTHON% -c "import sphinx, sys; sys.argv[0] = 'sphinx-build'; sphinx.main()"
+ set SPHINXBUILD=%PYTHON% -c "import sphinx, sys; sys.argv[0] = 'sphinx-build'; sys.exit(sphinx.main())"
+)
+
+%PYTHON% -c "import python_docs_theme" > nul 2> nul
+if errorlevel 1 (
+ echo Installing python-docs-theme with %PYTHON%
+ %PYTHON% -m pip install python-docs-theme
+ if errorlevel 1 exit /B
)
-if not defined BLURB if defined PYTHON (
+if not defined BLURB (
%PYTHON% -c "import blurb" > nul 2> nul
if errorlevel 1 (
echo Installing blurb with %PYTHON%
@@ -26,10 +36,6 @@ if not defined BLURB if defined PYTHON (
set BLURB=%PYTHON% -m blurb
)
-if not defined PYTHON set PYTHON=py
-if not defined SPHINXBUILD set SPHINXBUILD=sphinx-build
-if not defined BLURB set BLURB=blurb
-
if "%1" NEQ "htmlhelp" goto :skiphhcsearch
if exist "%HTMLHELP%" goto :skiphhcsearch
@@ -150,7 +156,7 @@ cmd /C %this% html
if EXIST "%BUILDDIR%\html\index.html" (
echo.Opening "%BUILDDIR%\html\index.html" in the default web browser...
- start "%BUILDDIR%\html\index.html"
+ start "" "%BUILDDIR%\html\index.html"
)
goto end
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index c08986f..8386df1 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -762,7 +762,7 @@ Custom classes
When a class attribute reference (for class :class:`C`, say) would yield a
class method object, it is transformed into an instance method object whose
- :attr:`__self__` attributes is :class:`C`. When it would yield a static
+ :attr:`__self__` attribute is :class:`C`. When it would yield a static
method object, it is transformed into the object wrapped by the static method
object. See section :ref:`descriptors` for another way in which attributes
retrieved from a class may differ from those actually contained in its
@@ -1887,7 +1887,7 @@ current call is identified based on the first argument passed to the method.
be propagated up to the ``type.__new__`` call in order for the class to be
initialised correctly.
Failing to do so will result in a :exc:`DeprecationWarning` in Python 3.6,
- and a :exc:`RuntimeWarning` in the future.
+ and a :exc:`RuntimeError` in Python 3.8.
When using the default metaclass :class:`type`, or any metaclass that ultimately
calls ``type.__new__``, the following additional customisation steps are
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index ff890a8..57ae639 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -1571,12 +1571,12 @@ Lambdas
lambda_expr_nocond: "lambda" [`parameter_list`]: `expression_nocond`
Lambda expressions (sometimes called lambda forms) are used to create anonymous
-functions. The expression ``lambda arguments: expression`` yields a function
+functions. The expression ``lambda parameters: expression`` yields a function
object. The unnamed object behaves like a function object defined with:
.. code-block:: none
- def (arguments):
+ def (parameters):
return expression
See section :ref:`function` for the syntax of parameter lists. Note that
diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst
index 7fbf8ed..61f5853 100644
--- a/Doc/reference/import.rst
+++ b/Doc/reference/import.rst
@@ -617,8 +617,7 @@ the module.
module.__path__
---------------
-By definition, if a module has a ``__path__`` attribute, it is a package,
-regardless of its value.
+By definition, if a module has a ``__path__`` attribute, it is a package.
A package's ``__path__`` attribute is used during imports of its subpackages.
Within the import machinery, it functions much the same as :data:`sys.path`,
diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst
index 6d093dc..a861996 100644
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -47,11 +47,12 @@ Physical lines
--------------
A physical line is a sequence of characters terminated by an end-of-line
-sequence. In source files, any of the standard platform line termination
-sequences can be used - the Unix form using ASCII LF (linefeed), the Windows
-form using the ASCII sequence CR LF (return followed by linefeed), or the old
-Macintosh form using the ASCII CR (return) character. All of these forms can be
-used equally, regardless of platform.
+sequence. In source files and strings, any of the standard platform line
+termination sequences can be used - the Unix form using ASCII LF (linefeed),
+the Windows form using the ASCII sequence CR LF (return followed by linefeed),
+or the old Macintosh form using the ASCII CR (return) character. All of these
+forms can be used equally, regardless of platform. The end of input also serves
+as an implicit terminator for the final physical line.
When embedding Python, source code strings should be passed to Python APIs using
the standard C conventions for newline characters (the ``\n`` character,
diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py
index f533ac4..02e7a13 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -23,9 +23,10 @@ from docutils import nodes, utils
from sphinx import addnodes
from sphinx.builders import Builder
from sphinx.locale import translators
+from sphinx.util import status_iterator
from sphinx.util.nodes import split_explicit_title
from sphinx.writers.html import HTMLTranslator
-from sphinx.writers.text import TextWriter
+from sphinx.writers.text import TextWriter, TextTranslator
from sphinx.writers.latex import LaTeXTranslator
from sphinx.domains.python import PyModulelevel, PyClassmember
@@ -298,8 +299,11 @@ pydoc_topic_labels = [
class PydocTopicsBuilder(Builder):
name = 'pydoc-topics'
+ default_translator_class = TextTranslator
+
def init(self):
self.topics = {}
+ self.secnumbers = {}
def get_outdated_docs(self):
return 'all pydoc topics'
@@ -309,9 +313,9 @@ class PydocTopicsBuilder(Builder):
def write(self, *ignored):
writer = TextWriter(self)
- for label in self.status_iterator(pydoc_topic_labels,
- 'building topics... ',
- length=len(pydoc_topic_labels)):
+ for label in status_iterator(pydoc_topic_labels,
+ 'building topics... ',
+ length=len(pydoc_topic_labels)):
if label not in self.env.domaindata['std']['labels']:
self.warn('label %r not in documentation' % label)
continue
diff --git a/Doc/tools/static/switchers.js b/Doc/tools/static/switchers.js
index 8e0c5ea..d885ff2 100644
--- a/Doc/tools/static/switchers.js
+++ b/Doc/tools/static/switchers.js
@@ -11,7 +11,7 @@
var all_versions = {
'3.8': 'dev (3.8)',
- '3.7': 'pre (3.7)',
+ '3.7': '3.7',
'3.6': '3.6',
'3.5': '3.5',
'2.7': '2.7',
@@ -21,6 +21,7 @@
'en': 'English',
'fr': 'French',
'ja': 'Japanese',
+ 'ko': 'Korean',
};
function build_version_select(current_version, current_release) {
diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html
index 20e66e0..3131050 100644
--- a/Doc/tools/templates/indexsidebar.html
+++ b/Doc/tools/templates/indexsidebar.html
@@ -3,8 +3,8 @@
diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst
index ffd16aa..241a812 100644
--- a/Doc/tutorial/appendix.rst
+++ b/Doc/tutorial/appendix.rst
@@ -52,7 +52,7 @@ comment in Python.
The script can be given an executable mode, or permission, using the
:program:`chmod` command.
-.. code-block:: bash
+.. code-block:: shell-session
$ chmod +x myscript.py
diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst
index 30ef159..4bcdafd 100644
--- a/Doc/tutorial/controlflow.rst
+++ b/Doc/tutorial/controlflow.rst
@@ -678,8 +678,8 @@ Function Annotations
single: -> (return annotation assignment)
:ref:`Function annotations ` are completely optional metadata
-information about the types used by user-defined functions (see :pep:`484`
-for more information).
+information about the types used by user-defined functions (see :pep:`3107` and
+:pep:`484` for more information).
Annotations are stored in the :attr:`__annotations__` attribute of the function
as a dictionary and have no effect on any other part of the function. Parameter
diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst
index 3bd100d..d04f7ce 100644
--- a/Doc/tutorial/interpreter.rst
+++ b/Doc/tutorial/interpreter.rst
@@ -148,14 +148,14 @@ where *encoding* is one of the valid :mod:`codecs` supported by Python.
For example, to declare that Windows-1252 encoding is to be used, the first
line of your source code file should be::
- # -*- coding: cp-1252 -*-
+ # -*- coding: cp1252 -*-
One exception to the *first line* rule is when the source code starts with a
:ref:`UNIX "shebang" line `. In this case, the encoding
declaration should be added as the second line of the file. For example::
#!/usr/bin/env python3
- # -*- coding: cp-1252 -*-
+ # -*- coding: cp1252 -*-
.. rubric:: Footnotes
diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst
index 8c26318..a4c766e 100644
--- a/Doc/tutorial/modules.rst
+++ b/Doc/tutorial/modules.rst
@@ -382,7 +382,7 @@ module names". For example, the module name :mod:`A.B` designates a submodule
named ``B`` in a package named ``A``. Just like the use of modules saves the
authors of different modules from having to worry about each other's global
variable names, the use of dotted module names saves the authors of multi-module
-packages like NumPy or the Python Imaging Library from having to worry about
+packages like NumPy or Pillow from having to worry about
each other's module names.
Suppose you want to design a collection of modules (a "package") for the uniform
diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst
index 1dd06c2..110e6e5 100644
--- a/Doc/tutorial/stdlib.rst
+++ b/Doc/tutorial/stdlib.rst
@@ -317,7 +317,7 @@ sophisticated and robust capabilities of its larger packages. For example:
names, no direct knowledge or handling of XML is needed.
* The :mod:`email` package is a library for managing email messages, including
- MIME and other RFC 2822-based message documents. Unlike :mod:`smtplib` and
+ MIME and other :rfc:`2822`-based message documents. Unlike :mod:`smtplib` and
:mod:`poplib` which actually send and receive messages, the email package has
a complete toolset for building or decoding complex message structures
(including attachments) and for implementing internet encoding and header
diff --git a/Doc/tutorial/venv.rst b/Doc/tutorial/venv.rst
index e2dd57d..dc4136e 100644
--- a/Doc/tutorial/venv.rst
+++ b/Doc/tutorial/venv.rst
@@ -88,7 +88,7 @@ Managing Packages with pip
You can install, upgrade, and remove packages using a program called
:program:`pip`. By default ``pip`` will install packages from the Python
-Package Index, . You can browse the Python
+Package Index, . You can browse the Python
Package Index by going to it in your web browser, or you can use ``pip``'s
limited search feature:
diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst
index 1ea22ae..d876d07 100644
--- a/Doc/tutorial/whatnow.rst
+++ b/Doc/tutorial/whatnow.rst
@@ -38,7 +38,7 @@ More Python resources:
* https://docs.python.org: Fast access to Python's documentation.
-* https://pypi.python.org/pypi: The Python Package Index, previously also nicknamed
+* https://pypi.org: The Python Package Index, previously also nicknamed
the Cheese Shop, is an index of user-created Python modules that are available
for download. Once you begin releasing code, you can register it here so that
others can find it.
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index 8463ad9..d14793a 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -178,11 +178,15 @@ Generic options
.. cmdoption:: -V
--version
- Print the Python version number and exit. Example output could be::
+ Print the Python version number and exit. Example output could be:
+
+ .. code-block:: none
Python 3.6.0b2+
- When given twice, print more information about the build, like::
+ When given twice, print more information about the build, like:
+
+ .. code-block:: none
Python 3.6.0b2+ (3.6:84a3c5003510+, Oct 26 2016, 02:33:55)
[GCC 6.2.0 20161005]
@@ -336,7 +340,9 @@ Miscellaneous options
Warning control. Python's warning machinery by default prints warning
messages to :data:`sys.stderr`. A typical warning message has the following
- form::
+ form:
+
+ .. code-block:: none
file:line: category: message
diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst
index dc05e0d..858d2e1 100644
--- a/Doc/using/unix.rst
+++ b/Doc/using/unix.rst
@@ -118,7 +118,9 @@ Miscellaneous
=============
To easily use Python scripts on Unix, you need to make them executable,
-e.g. with ::
+e.g. with
+
+.. code-block:: shell-session
$ chmod +x script
diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst
index 3d47d7c..c6624fe 100644
--- a/Doc/using/windows.rst
+++ b/Doc/using/windows.rst
@@ -210,7 +210,9 @@ The options listed above can also be provided in a file named ``unattend.xml``
alongside the executable. This file specifies a list of options and values.
When a value is provided as an attribute, it will be converted to a number if
possible. Values provided as element text are always left as strings. This
-example file sets the same options and the previous example::
+example file sets the same options and the previous example:
+
+.. code-block:: xml
@@ -343,7 +345,9 @@ Windows allows environment variables to be configured permanently at both the
User level and the System level, or temporarily in a command prompt.
To temporarily set environment variables, open Command Prompt and use the
-:command:`set` command::
+:command:`set` command:
+
+.. code-block:: doscon
C:\>set PATH=C:\Program Files\Python 3.6;%PATH%
C:\>set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib
@@ -503,7 +507,7 @@ From a script
Let's create a test Python script - create a file called ``hello.py`` with the
following contents
-::
+.. code-block:: python
#! python
import sys
@@ -518,7 +522,7 @@ From the directory in which hello.py lives, execute the command:
You should notice the version number of your latest Python 2.x installation
is printed. Now try changing the first line to be:
-::
+.. code-block:: python
#! python3
@@ -566,7 +570,7 @@ which interpreter to use. The supported virtual commands are:
For example, if the first line of your script starts with
-::
+.. code-block:: sh
#! /usr/bin/python
@@ -592,7 +596,7 @@ Arguments in shebang lines
The shebang lines can also specify additional options to be passed to the
Python interpreter. For example, if you have a shebang line:
-::
+.. code-block:: sh
#! /usr/bin/python -v
@@ -683,7 +687,7 @@ For example:
* Setting ``PY_PYTHON=3.1`` is equivalent to the INI file containing:
-::
+.. code-block:: ini
[defaults]
python=3.1
@@ -691,7 +695,7 @@ For example:
* Setting ``PY_PYTHON=3`` and ``PY_PYTHON3=3.1`` is equivalent to the INI file
containing:
-::
+.. code-block:: ini
[defaults]
python=3
@@ -844,7 +848,7 @@ The Windows-specific standard modules are documented in
PyWin32
-------
-The `PyWin32 `_ module by Mark Hammond
+The `PyWin32 `_ module by Mark Hammond
is a collection of modules for advanced Windows-specific support. This includes
utilities for:
diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst
index cebfb21..5cdd51b 100644
--- a/Doc/whatsnew/2.3.rst
+++ b/Doc/whatsnew/2.3.rst
@@ -659,7 +659,7 @@ The heart of the catalog is the new Distutils :command:`register` command.
Running ``python setup.py register`` will collect the metadata describing a
package, such as its name, version, maintainer, description, &c., and send it to
a central catalog server. The resulting catalog is available from
-https://pypi.python.org/pypi.
+https://pypi.org.
To make the catalog a bit more useful, a new optional *classifiers* keyword
argument has been added to the Distutils :func:`setup` function. A list of
diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst
index 7c125ff..7e11c98 100644
--- a/Doc/whatsnew/2.4.rst
+++ b/Doc/whatsnew/2.4.rst
@@ -998,7 +998,7 @@ complete list of changes, or look through the CVS logs for all the details.
that lets you perform a limited number of passes through the polling loop. The
default is still to loop forever.
-* The :mod:`base64` module now has more complete RFC 3548 support for Base64,
+* The :mod:`base64` module now has more complete :rfc:`3548` support for Base64,
Base32, and Base16 encoding and decoding, including optional case folding and
optional alternative alphabets. (Contributed by Barry Warsaw.)
diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst
index 4d48291..b0defba 100644
--- a/Doc/whatsnew/2.5.rst
+++ b/Doc/whatsnew/2.5.rst
@@ -229,7 +229,7 @@ required packages. ::
)
Another new enhancement to the Python package index at
-https://pypi.python.org is storing source and binary archives for a
+https://pypi.org is storing source and binary archives for a
package. The new :command:`upload` Distutils command will upload a package to
the repository.
diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst
index 45b0ab9..e57efee 100644
--- a/Doc/whatsnew/2.6.rst
+++ b/Doc/whatsnew/2.6.rst
@@ -2611,7 +2611,7 @@ changes, or look through the Subversion logs for all the details.
* The XML-RPC :class:`SimpleXMLRPCServer` and :class:`DocXMLRPCServer`
classes can now be prevented from immediately opening and binding to
- their socket by passing True as the ``bind_and_activate``
+ their socket by passing ``False`` as the *bind_and_activate*
constructor parameter. This can be used to modify the instance's
:attr:`allow_reuse_address` attribute before calling the
:meth:`server_bind` and :meth:`server_activate` methods to
diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst
index 55392fc..fd59c16 100644
--- a/Doc/whatsnew/2.7.rst
+++ b/Doc/whatsnew/2.7.rst
@@ -1545,7 +1545,7 @@ changes, or look through the Subversion logs for all the details.
*ciphers* argument that's a string listing the encryption algorithms
to be allowed; the format of the string is described
`in the OpenSSL documentation
- `__.
+ `__.
(Added by Antoine Pitrou; :issue:`8322`.)
Another change makes the extension load all of OpenSSL's ciphers and
@@ -1809,7 +1809,7 @@ wish to read the Tcl/Tk manual page describing the
Ttk theme engine, available at
https://www.tcl.tk/man/tcl8.5/TkCmd/ttk_intro.htm. Some
screenshots of the Python/Ttk code in use are at
-http://code.google.com/p/python-ttk/wiki/Screenshots.
+https://code.google.com/archive/p/python-ttk/wikis/Screenshots.wiki.
The :mod:`ttk` module was written by Guilherme Polo and added in
:issue:`2983`. An alternate version called ``Tile.py``, written by
@@ -1828,12 +1828,12 @@ new features were added. Most of these features were implemented
by Michael Foord, unless otherwise noted. The enhanced version of
the module is downloadable separately for use with Python versions 2.4 to 2.6,
packaged as the :mod:`unittest2` package, from
-https://pypi.python.org/pypi/unittest2.
+https://pypi.org/project/unittest2.
When used from the command line, the module can automatically discover
tests. It's not as fancy as `py.test `__ or
-`nose `__, but provides a simple way
-to run tests kept within a set of package directories. For example,
+`nose `__, but provides a
+simple way to run tests kept within a set of package directories. For example,
the following command will search the :file:`test/` subdirectory for
any importable test files named ``test*.py``::
@@ -2367,6 +2367,18 @@ Port-Specific Changes: Mac OS X
installation and a user-installed copy of the same version.
(Changed by Ronald Oussoren; :issue:`4865`.)
+ .. versionchanged:: 2.7.13
+
+ As of 2.7.13, this change was removed.
+ ``/Library/Python/2.7/site-packages``, the site-packages directory
+ used by the Apple-supplied system Python 2.7 is no longer appended to
+ ``sys.path`` for user-installed Pythons such as from the python.org
+ installers. As of macOS 10.12, Apple changed how the system
+ site-packages directory is configured, which could cause installation
+ of pip components, like setuptools, to fail. Packages installed for
+ the system Python will no longer be shared with user-installed
+ Pythons. (:issue:`28440`)
+
Port-Specific Changes: FreeBSD
-----------------------------------
@@ -2558,6 +2570,21 @@ exemption allowing new ``-3`` warnings to be added in any Python 2.7
maintenance release.
+Two new environment variables for debug mode
+--------------------------------------------
+
+In debug mode, the ``[xxx refs]`` statistic is not written by default, the
+:envvar:`PYTHONSHOWREFCOUNT` environment variable now must also be set.
+(Contributed by Victor Stinner; :issue:`31733`.)
+
+When Python is compiled with ``COUNT_ALLOC`` defined, allocation counts are no
+longer dumped by default anymore: the :envvar:`PYTHONSHOWALLOCCOUNT` environment
+variable must now also be set. Moreover, allocation counts are now dumped into
+stderr, rather than stdout. (Contributed by Victor Stinner; :issue:`31692`.)
+
+.. versionadded:: 2.7.15
+
+
PEP 434: IDLE Enhancement Exception for All Branches
----------------------------------------------------
@@ -2602,10 +2629,162 @@ with the first of those changes appearing in the Python 2.7.7 release.
certificate store, the :class:`~ssl.SSLContext` class, and other
features. (Contributed by Alex Gaynor and David Reid; :issue:`21308`.)
+ Refer to the "Version added: 2.7.9" notes in the module documentation for
+ specific details.
+
* :func:`os.urandom` was changed to cache a file descriptor to ``/dev/urandom``
instead of reopening ``/dev/urandom`` on every call. (Contributed by Alex
Gaynor; :issue:`21305`.)
+* :data:`hashlib.algorithms_guaranteed` and
+ :data:`hashlib.algorithms_available` were backported from Python 3 to make
+ it easier for Python 2 applications to select the strongest available hash
+ algorithm. (Contributed by Alex Gaynor in :issue:`21307`)
+
+
+PEP 477: Backport ensurepip (PEP 453) to Python 2.7
+---------------------------------------------------
+
+:pep:`477` approves the inclusion of the :pep:`453` ensurepip module and the
+improved documentation that was enabled by it in the Python 2.7 maintenance
+releases, appearing first in the Python 2.7.9 release.
+
+
+Bootstrapping pip By Default
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The new :mod:`ensurepip` module (defined in :pep:`453`) provides a standard
+cross-platform mechanism to bootstrap the pip installer into Python
+installations. The version of ``pip`` included with Python 2.7.9 is ``pip``
+1.5.6, and future 2.7.x maintenance releases will update the bundled version to
+the latest version of ``pip`` that is available at the time of creating the
+release candidate.
+
+By default, the commands ``pip``, ``pipX`` and ``pipX.Y`` will be installed on
+all platforms (where X.Y stands for the version of the Python installation),
+along with the ``pip`` Python package and its dependencies.
+
+For CPython :ref:`source builds on POSIX systems `,
+the ``make install`` and ``make altinstall`` commands do not bootstrap ``pip``
+by default. This behaviour can be controlled through configure options, and
+overridden through Makefile options.
+
+On Windows and Mac OS X, the CPython installers now default to installing
+``pip`` along with CPython itself (users may opt out of installing it
+during the installation process). Window users will need to opt in to the
+automatic ``PATH`` modifications to have ``pip`` available from the command
+line by default, otherwise it can still be accessed through the Python
+launcher for Windows as ``py -m pip``.
+
+As `discussed in the PEP`__, platform packagers may choose not to install
+these commands by default, as long as, when invoked, they provide clear and
+simple directions on how to install them on that platform (usually using
+the system package manager).
+
+__ https://www.python.org/dev/peps/pep-0477/#disabling-ensurepip-by-downstream-distributors
+
+
+Documentation Changes
+~~~~~~~~~~~~~~~~~~~~~
+
+As part of this change, the :ref:`installing-index` and
+:ref:`distributing-index` sections of the documentation have been
+completely redesigned as short getting started and FAQ documents. Most
+packaging documentation has now been moved out to the Python Packaging
+Authority maintained `Python Packaging User Guide
+`__ and the documentation of the individual
+projects.
+
+However, as this migration is currently still incomplete, the legacy
+versions of those guides remaining available as :ref:`install-index`
+and :ref:`distutils-index`.
+
+.. seealso::
+
+ :pep:`453` -- Explicit bootstrapping of pip in Python installations
+ PEP written by Donald Stufft and Nick Coghlan, implemented by
+ Donald Stufft, Nick Coghlan, Martin von Löwis and Ned Deily.
+
+PEP 476: Enabling certificate verification by default for stdlib http clients
+-----------------------------------------------------------------------------
+
+:pep:`476` updated :mod:`httplib` and modules which use it, such as
+:mod:`urllib2` and :mod:`xmlrpclib`, to now verify that the server
+presents a certificate which is signed by a Certificate Authority in the
+platform trust store and whose hostname matches the hostname being requested
+by default, significantly improving security for many applications. This
+change was made in the Python 2.7.9 release.
+
+For applications which require the old previous behavior, they can pass an
+alternate context::
+
+ import urllib2
+ import ssl
+
+ # This disables all verification
+ context = ssl._create_unverified_context()
+
+ # This allows using a specific certificate for the host, which doesn't need
+ # to be in the trust store
+ context = ssl.create_default_context(cafile="/path/to/file.crt")
+
+ urllib2.urlopen("https://invalid-cert", context=context)
+
+
+PEP 493: HTTPS verification migration tools for Python 2.7
+----------------------------------------------------------
+
+:pep:`493` provides additional migration tools to support a more incremental
+infrastructure upgrade process for environments containing applications and
+services relying on the historically permissive processing of server
+certificates when establishing client HTTPS connections. These additions were
+made in the Python 2.7.12 release.
+
+These tools are intended for use in cases where affected applications and
+services can't be modified to explicitly pass a more permissive SSL context
+when establishing the connection.
+
+For applications and services which can't be modified at all, the new
+``PYTHONHTTPSVERIFY`` environment variable may be set to ``0`` to revert an
+entire Python process back to the default permissive behaviour of Python 2.7.8
+and earlier.
+
+For cases where the connection establishment code can't be modified, but the
+overall application can be, the new :func:`ssl._https_verify_certificates`
+function can be used to adjust the default behaviour at runtime.
+
+
+New ``make regen-all`` build target
+-----------------------------------
+
+To simplify cross-compilation, and to ensure that CPython can reliably be
+compiled without requiring an existing version of Python to already be
+available, the autotools-based build system no longer attempts to implicitly
+recompile generated files based on file modification times.
+
+Instead, a new ``make regen-all`` command has been added to force regeneration
+of these files when desired (e.g. after an initial version of Python has
+already been built based on the pregenerated versions).
+
+More selective regeneration targets are also defined - see
+:source:`Makefile.pre.in` for details.
+
+(Contributed by Victor Stinner in :issue:`23404`.)
+
+.. versionadded:: 2.7.14
+
+
+Removal of ``make touch`` build target
+--------------------------------------
+
+The ``make touch`` build target previously used to request implicit regeneration
+of generated files by updating their modification times has been removed.
+
+It has been replaced by the new ``make regen-all`` target.
+
+(Contributed by Victor Stinner in :issue:`23404`.)
+
+.. versionchanged:: 2.7.14
.. ======================================================================
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
index a6ba5bb..96f86e6 100644
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -951,7 +951,7 @@ New :class:`~collections.abc.Awaitable`, :class:`~collections.abc.Coroutine`,
(Contributed by Yury Selivanov in :issue:`24184`.)
For earlier Python versions, a backport of the new ABCs is available in an
-external `PyPI package `_.
+external `PyPI package `_.
compileall
@@ -2536,3 +2536,39 @@ Changes in the C API
:c:member:`tp_as_async` slot. Refer to :ref:`coro-objects` for
new types, structures and functions.
+
+Notable changes in Python 3.5.4
+===============================
+
+New ``make regen-all`` build target
+-----------------------------------
+
+To simplify cross-compilation, and to ensure that CPython can reliably be
+compiled without requiring an existing version of Python to already be
+available, the autotools-based build system no longer attempts to implicitly
+recompile generated files based on file modification times.
+
+Instead, a new ``make regen-all`` command has been added to force regeneration
+of these files when desired (e.g. after an initial version of Python has
+already been built based on the pregenerated versions).
+
+More selective regeneration targets are also defined - see
+:source:`Makefile.pre.in` for details.
+
+(Contributed by Victor Stinner in :issue:`23404`.)
+
+.. versionadded:: 3.5.4
+
+
+Removal of ``make touch`` build target
+--------------------------------------
+
+The ``make touch`` build target previously used to request implicit regeneration
+of generated files by updating their modification times has been removed.
+
+It has been replaced by the new ``make regen-all`` target.
+
+(Contributed by Victor Stinner in :issue:`23404`.)
+
+.. versionchanged:: 3.5.4
+
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
index 59329fa..2c675a5 100644
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -147,7 +147,7 @@ Security improvements:
Windows improvements:
-* :ref:`PEP 528 ` and :ref:`PEP 529 `,
+* :ref:`PEP 528 ` and :ref:`PEP 529 `,
Windows filesystem and console encoding changed to UTF-8.
* The ``py.exe`` launcher, when used interactively, no longer prefers
@@ -237,8 +237,8 @@ and the ``__annotations__`` attribute.
and Guido van Rossum. Implemented by Ivan Levkivskyi.
Tools that use or will use the new syntax:
- `mypy `_,
- `pytype `_, PyCharm, etc.
+ `mypy `_,
+ `pytype `_, PyCharm, etc.
.. _whatsnew36-pep515:
@@ -818,7 +818,7 @@ Notable changes in the :mod:`asyncio` module since Python 3.5.0
(all backported to 3.5.x due to the provisional status):
* The :func:`~asyncio.get_event_loop` function has been changed to
- always return the currently running loop when called from couroutines
+ always return the currently running loop when called from coroutines
and callbacks.
(Contributed by Yury Selivanov in :issue:`28613`.)
@@ -907,7 +907,7 @@ return value.
cmath
-----
-The new :const:`cmath.tau` (Ï) constant has been added.
+The new :const:`cmath.tau` (*Ï*) constant has been added.
(Contributed by Lisa Roach in :issue:`12345`, see :pep:`628` for details.)
New constants: :const:`cmath.inf` and :const:`cmath.nan` to
@@ -1016,11 +1016,6 @@ attribute defaults to ``['gztar']``. Although not anticipated,
any code relying on the presence of ``default_format`` may
need to be adapted. See :issue:`27819` for more details.
-The ``upload`` command now longer tries to change CR end-of-line characters
-to CRLF. This fixes a corruption issue with sdists that ended with a byte
-equivalent to CR.
-(Contributed by Bo Bayles in :issue:`32304`.)
-
email
-----
@@ -1146,6 +1141,49 @@ In compensation, the eventual result with be that some idlelib classes will be
easier to use, with better APIs and docstrings explaining them. Additional
useful information will be added to idlelib when available.
+New in 3.6.2:
+
+Multiple fixes for autocompletion. (Contributed by Louie Lu in :issue:`15786`.)
+
+New in 3.6.3:
+
+Module Browser (on the File menu, formerly called Class Browser),
+now displays nested functions and classes in addition to top-level
+functions and classes.
+(Contributed by Guilherme Polo, Cheryl Sabella, and Terry Jan Reedy
+in :issue:`1612262`.)
+
+The IDLE features formerly implemented as extensions have been reimplemented
+as normal features. Their settings have been moved from the Extensions tab
+to other dialog tabs.
+(Contributed by Charles Wohlganger and Terry Jan Reedy in :issue:`27099`.)
+
+The Settings dialog (Options, Configure IDLE) has been partly rewritten
+to improve both appearance and function.
+(Contributed by Cheryl Sabella and Terry Jan Reedy in multiple issues.)
+
+New in 3.6.4:
+
+The font sample now includes a selection of non-Latin characters so that
+users can better see the effect of selecting a particular font.
+(Contributed by Terry Jan Reedy in :issue:`13802`.)
+The sample can be edited to include other characters.
+(Contributed by Serhiy Storchaka in :issue:`31860`.)
+
+New in 3.6.6:
+
+Editor code context option revised. Box displays all context lines up to
+maxlines. Clicking on a context line jumps the editor to that line. Context
+colors for custom themes is added to Highlights tab of Settings dialog.
+(Contributed by Cheryl Sabella and Terry Jan Reedy in :issue:`33642`,
+:issue:`33768`, and :issue:`33679`)
+
+On Windows, a new API call tells Windows that tk scales for DPI. On Windows
+8.1+ or 10, with DPI compatibility properties of the Python binary
+unchanged, and a monitor resolution greater than 96 DPI, this should
+make text and lines sharper. It should otherwise have no effect.
+(Contributed by Terry Jan Reedy in :issue:`33656`).
+
importlib
---------
@@ -1203,7 +1241,7 @@ be reopened.
math
----
-The tau (Ï) constant has been added to the :mod:`math` and :mod:`cmath`
+The tau (*Ï*) constant has been added to the :mod:`math` and :mod:`cmath`
modules.
(Contributed by Lisa Roach in :issue:`12345`, see :pep:`628` for details.)
@@ -1572,7 +1610,7 @@ mark class variables. As introduced in :pep:`526`, a variable annotation
wrapped in ClassVar indicates that a given attribute is intended to be used as
a class variable and should not be set on instances of that class.
(Contributed by Ivan Levkivskyi in `Github #280
-`_.)
+`_.)
A new :const:`~typing.TYPE_CHECKING` constant that is assumed to be
``True`` by the static type chekers, but is ``False`` at runtime.
@@ -1857,11 +1895,6 @@ Build and C API Changes
* The :c:func:`PyUnicode_FSConverter` and :c:func:`PyUnicode_FSDecoder`
functions will now accept :term:`path-like objects `.
-* The ``PyExc_RecursionErrorInst`` singleton that was part of the public API
- has been removed as its members being never cleared may cause a segfault
- during finalization of the interpreter. Contributed by Xavier de Gaye in
- :issue:`22898` and :issue:`30697`.
-
Other Improvements
==================
@@ -2205,7 +2238,9 @@ Changes in the Python API
platform-specific selection is made.
In environments where distributions are
built on Windows and zip distributions are required, configure
- the project with a ``setup.cfg`` file containing the following::
+ the project with a ``setup.cfg`` file containing the following:
+
+ .. code-block:: ini
[sdist]
formats=zip
@@ -2268,7 +2303,8 @@ Changes in the Python API
direct references from methods to the implicit ``__class__`` closure
variable, the implicit ``__classcell__`` namespace entry must now be passed
up to ``type.__new__`` for initialisation. Failing to do so will result in
- a :exc:`DeprecationWarning` in 3.6 and a :exc:`RuntimeWarning` in the future.
+ a :exc:`DeprecationWarning` in Python 3.6 and a :exc:`RuntimeError` in
+ Python 3.8.
Changes in the C API
--------------------
@@ -2353,6 +2389,15 @@ It has been replaced by the new ``make regen-all`` target.
.. versionchanged:: 3.6.2
+Notable changes in Python 3.6.4
+===============================
+
+The ``PyExc_RecursionErrorInst`` singleton that was part of the public API
+has been removed as its members being never cleared may cause a segfault
+during finalization of the interpreter.
+(Contributed by Xavier de Gaye in :issue:`22898` and :issue:`30697`.)
+
+
Notable changes in Python 3.6.5
===============================
diff --git a/Include/patchlevel.h b/Include/patchlevel.h
index 3dd89f6..f20d080 100644
--- a/Include/patchlevel.h
+++ b/Include/patchlevel.h
@@ -18,12 +18,12 @@
/*--start constants--*/
#define PY_MAJOR_VERSION 3
#define PY_MINOR_VERSION 6
-#define PY_MICRO_VERSION 5
+#define PY_MICRO_VERSION 6
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
#define PY_RELEASE_SERIAL 0
/* Version as a string */
-#define PY_VERSION "3.6.5"
+#define PY_VERSION "3.6.6"
/*--end constants--*/
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
diff --git a/Lib/argparse.py b/Lib/argparse.py
index b69c5ad..1dacb7e 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -325,7 +325,11 @@ class HelpFormatter(object):
if len(prefix) + len(usage) > text_width:
# break usage into wrappable parts
- part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
+ part_regexp = (
+ r'\(.*?\)+(?=\s|$)|'
+ r'\[.*?\]+(?=\s|$)|'
+ r'\S+'
+ )
opt_usage = format(optionals, groups)
pos_usage = format(positionals, groups)
opt_parts = _re.findall(part_regexp, opt_usage)
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 90757db..083f45d 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -1153,6 +1153,7 @@ class BaseEventLoop(events.AbstractEventLoop):
if bufsize != 0:
raise ValueError("bufsize must be 0")
protocol = protocol_factory()
+ debug_log = None
if self._debug:
# don't log parameters: they may contain sensitive information
# (password) and may be too long
@@ -1160,7 +1161,7 @@ class BaseEventLoop(events.AbstractEventLoop):
self._log_subprocess(debug_log, stdin, stdout, stderr)
transport = yield from self._make_subprocess_transport(
protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs)
- if self._debug:
+ if self._debug and debug_log is not None:
logger.info('%s: %r', debug_log, transport)
return transport, protocol
@@ -1182,6 +1183,7 @@ class BaseEventLoop(events.AbstractEventLoop):
"a bytes or text string, not %s"
% type(arg).__name__)
protocol = protocol_factory()
+ debug_log = None
if self._debug:
# don't log parameters: they may contain sensitive information
# (password) and may be too long
@@ -1190,7 +1192,7 @@ class BaseEventLoop(events.AbstractEventLoop):
transport = yield from self._make_subprocess_transport(
protocol, popen_args, False, stdin, stdout, stderr,
bufsize, **kwargs)
- if self._debug:
+ if self._debug and debug_log is not None:
logger.info('%s: %r', debug_log, transport)
return transport, protocol
diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py
index 520a309..a9022f9 100644
--- a/Lib/asyncio/coroutines.py
+++ b/Lib/asyncio/coroutines.py
@@ -310,18 +310,25 @@ def _format_coroutine(coro):
if coro_name is None:
coro_name = events._format_callback(func, (), {})
- try:
- coro_code = coro.gi_code
- except AttributeError:
+ coro_code = None
+ if hasattr(coro, 'cr_code') and coro.cr_code:
coro_code = coro.cr_code
+ elif hasattr(coro, 'gi_code') and coro.gi_code:
+ coro_code = coro.gi_code
- try:
- coro_frame = coro.gi_frame
- except AttributeError:
+ coro_frame = None
+ if hasattr(coro, 'cr_frame') and coro.cr_frame:
coro_frame = coro.cr_frame
+ elif hasattr(coro, 'gi_frame') and coro.gi_frame:
+ coro_frame = coro.gi_frame
+
+ filename = ''
+ if coro_code and coro_code.co_filename:
+ filename = coro_code.co_filename
- filename = coro_code.co_filename
lineno = 0
+ coro_repr = coro_name
+
if (isinstance(coro, CoroWrapper) and
not inspect.isgeneratorfunction(coro.func) and
coro.func is not None):
@@ -338,7 +345,7 @@ def _format_coroutine(coro):
lineno = coro_frame.f_lineno
coro_repr = ('%s running at %s:%s'
% (coro_name, filename, lineno))
- else:
+ elif coro_code:
lineno = coro_code.co_firstlineno
coro_repr = ('%s done, defined at %s:%s'
% (coro_name, filename, lineno))
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index 05dc896..e654efc 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -58,10 +58,10 @@ def _format_callback(func, args, kwargs, suffix=''):
suffix = _format_args_and_kwargs(args, kwargs) + suffix
return _format_callback(func.func, func.args, func.keywords, suffix)
- if hasattr(func, '__qualname__'):
- func_repr = getattr(func, '__qualname__')
- elif hasattr(func, '__name__'):
- func_repr = getattr(func, '__name__')
+ if hasattr(func, '__qualname__') and func.__qualname__:
+ func_repr = func.__qualname__
+ elif hasattr(func, '__name__') and func.__name__:
+ func_repr = func.__name__
else:
func_repr = repr(func)
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 9ff1430..3a0b57e 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -408,6 +408,9 @@ def _chain_future(source, destination):
source_loop.call_soon_threadsafe(source.cancel)
def _call_set_state(source):
+ if (destination.cancelled() and
+ dest_loop is not None and dest_loop.is_closed()):
+ return
if dest_loop is None or dest_loop is source_loop:
_set_state(destination, source)
else:
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index a81645d..967a696 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -156,6 +156,7 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport,
extra=None, server=None):
super().__init__(loop, sock, protocol, waiter, extra, server)
self._paused = False
+ self._reschedule_on_resume = False
self._loop.call_soon(self._loop_reading)
def pause_reading(self):
@@ -173,12 +174,15 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport,
self._paused = False
if self._closing:
return
- self._loop.call_soon(self._loop_reading, self._read_fut)
+ if self._reschedule_on_resume:
+ self._loop.call_soon(self._loop_reading, self._read_fut)
+ self._reschedule_on_resume = False
if self._loop.get_debug():
logger.debug("%r resumes reading", self)
def _loop_reading(self, fut=None):
if self._paused:
+ self._reschedule_on_resume = True
return
data = None
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index aa65702..81dfd76 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -673,6 +673,12 @@ class _SelectorTransport(transports._FlowControlMixin,
def get_write_buffer_size(self):
return len(self._buffer)
+ def _add_reader(self, fd, callback, *args):
+ if self._closing:
+ return
+
+ self._loop._add_reader(fd, callback, *args)
+
class _SelectorSocketTransport(_SelectorTransport):
@@ -689,7 +695,7 @@ class _SelectorSocketTransport(_SelectorTransport):
self._loop.call_soon(self._protocol.connection_made, self)
# only start reading when connection_made() has been called
- self._loop.call_soon(self._loop._add_reader,
+ self._loop.call_soon(self._add_reader,
self._sock_fd, self._read_ready)
if waiter is not None:
# only wake up the waiter when connection_made() has been called
@@ -710,9 +716,7 @@ class _SelectorSocketTransport(_SelectorTransport):
if not self._paused:
raise RuntimeError('Not paused')
self._paused = False
- if self._closing:
- return
- self._loop._add_reader(self._sock_fd, self._read_ready)
+ self._add_reader(self._sock_fd, self._read_ready)
if self._loop.get_debug():
logger.debug("%r resumes reading", self)
@@ -800,7 +804,7 @@ class _SelectorSocketTransport(_SelectorTransport):
self._sock.shutdown(socket.SHUT_WR)
def write_eof(self):
- if self._eof:
+ if self._closing or self._eof:
return
self._eof = True
if not self._buffer:
@@ -1052,7 +1056,7 @@ class _SelectorDatagramTransport(_SelectorTransport):
self._address = address
self._loop.call_soon(self._protocol.connection_made, self)
# only start reading when connection_made() has been called
- self._loop.call_soon(self._loop._add_reader,
+ self._loop.call_soon(self._add_reader,
self._sock_fd, self._read_ready)
if waiter is not None:
# only wake up the waiter when connection_made() has been called
diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py
index a82babb..367f7d0 100644
--- a/Lib/asyncio/sslproto.py
+++ b/Lib/asyncio/sslproto.py
@@ -574,7 +574,7 @@ class SSLProtocol(protocols.Protocol):
# (b'', 1) is a special value in _process_write_backlog() to do
# the SSL handshake
self._write_backlog.append((b'', 1))
- self._loop.call_soon(self._process_write_backlog)
+ self._process_write_backlog()
def _on_handshake_complete(self, handshake_exc):
self._in_handshake = False
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 9fe2a2f..4cd2c6a 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -233,7 +233,7 @@ class Task(futures.Future):
self._step,
RuntimeError(
'yield was used instead of yield from for '
- 'generator in task {!r} with {}'.format(
+ 'generator in task {!r} with {!r}'.format(
self, result)))
else:
# Yielding something else is an error.
@@ -548,6 +548,7 @@ class _GatheringFuture(futures.Future):
def __init__(self, children, *, loop=None):
super().__init__(loop=loop)
self._children = children
+ self._cancel_requested = False
def cancel(self):
if self.done():
@@ -556,6 +557,11 @@ class _GatheringFuture(futures.Future):
for child in self._children:
if child.cancel():
ret = True
+ if ret:
+ # If any child tasks were actually cancelled, we should
+ # propagate the cancellation request regardless of
+ # *return_exceptions* argument. See issue 32684.
+ self._cancel_requested = True
return ret
@@ -636,7 +642,10 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False):
results[i] = res
nfinished += 1
if nfinished == nchildren:
- outer.set_result(results)
+ if outer._cancel_requested:
+ outer.set_exception(futures.CancelledError())
+ else:
+ outer.set_result(results)
for i, fut in enumerate(children):
fut.add_done_callback(functools.partial(_done_callback, i))
diff --git a/Lib/cgitb.py b/Lib/cgitb.py
index b291100..0f5f32c 100644
--- a/Lib/cgitb.py
+++ b/Lib/cgitb.py
@@ -124,7 +124,7 @@ function calls leading up to the error, in the order they occurred.